re PR tree-optimization/71522 (Wrong optimization of memcpy through a var of type...
[platform/upstream/gcc.git] / gcc / omp-low.c
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-2016 Free Software Foundation, Inc.
8
9 This file is part of GCC.
10
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 3, or (at your option) any later
14 version.
15
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19 for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING3.  If not see
23 <http://www.gnu.org/licenses/>.  */
24
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "backend.h"
29 #include "target.h"
30 #include "rtl.h"
31 #include "tree.h"
32 #include "gimple.h"
33 #include "cfghooks.h"
34 #include "alloc-pool.h"
35 #include "tree-pass.h"
36 #include "ssa.h"
37 #include "expmed.h"
38 #include "optabs.h"
39 #include "emit-rtl.h"
40 #include "cgraph.h"
41 #include "pretty-print.h"
42 #include "diagnostic-core.h"
43 #include "alias.h"
44 #include "fold-const.h"
45 #include "stor-layout.h"
46 #include "cfganal.h"
47 #include "internal-fn.h"
48 #include "gimple-fold.h"
49 #include "gimplify.h"
50 #include "gimple-iterator.h"
51 #include "gimplify-me.h"
52 #include "gimple-walk.h"
53 #include "tree-iterator.h"
54 #include "tree-inline.h"
55 #include "langhooks.h"
56 #include "tree-cfg.h"
57 #include "tree-into-ssa.h"
58 #include "flags.h"
59 #include "dojump.h"
60 #include "explow.h"
61 #include "calls.h"
62 #include "varasm.h"
63 #include "stmt.h"
64 #include "expr.h"
65 #include "tree-dfa.h"
66 #include "tree-ssa.h"
67 #include "except.h"
68 #include "splay-tree.h"
69 #include "cfgloop.h"
70 #include "common/common-target.h"
71 #include "omp-low.h"
72 #include "gimple-low.h"
73 #include "tree-cfgcleanup.h"
74 #include "symbol-summary.h"
75 #include "ipa-prop.h"
76 #include "tree-nested.h"
77 #include "tree-eh.h"
78 #include "cilk.h"
79 #include "context.h"
80 #include "lto-section-names.h"
81 #include "gomp-constants.h"
82 #include "gimple-pretty-print.h"
83 #include "symbol-summary.h"
84 #include "hsa.h"
85 #include "params.h"
86
87 /* Lowering of OMP parallel and workshare constructs proceeds in two
88    phases.  The first phase scans the function looking for OMP statements
89    and then for variables that must be replaced to satisfy data sharing
90    clauses.  The second phase expands code for the constructs, as well as
91    re-gimplifying things when variables have been replaced with complex
92    expressions.
93
94    Final code generation is done by pass_expand_omp.  The flowgraph is
95    scanned for regions which are then moved to a new
96    function, to be invoked by the thread library, or offloaded.  */
97
98 /* OMP region information.  Every parallel and workshare
99    directive is enclosed between two markers, the OMP_* directive
100    and a corresponding GIMPLE_OMP_RETURN statement.  */
101
102 struct omp_region
103 {
104   /* The enclosing region.  */
105   struct omp_region *outer;
106
107   /* First child region.  */
108   struct omp_region *inner;
109
110   /* Next peer region.  */
111   struct omp_region *next;
112
113   /* Block containing the omp directive as its last stmt.  */
114   basic_block entry;
115
116   /* Block containing the GIMPLE_OMP_RETURN as its last stmt.  */
117   basic_block exit;
118
119   /* Block containing the GIMPLE_OMP_CONTINUE as its last stmt.  */
120   basic_block cont;
121
122   /* If this is a combined parallel+workshare region, this is a list
123      of additional arguments needed by the combined parallel+workshare
124      library call.  */
125   vec<tree, va_gc> *ws_args;
126
127   /* The code for the omp directive of this region.  */
128   enum gimple_code type;
129
130   /* Schedule kind, only used for GIMPLE_OMP_FOR type regions.  */
131   enum omp_clause_schedule_kind sched_kind;
132
133   /* Schedule modifiers.  */
134   unsigned char sched_modifiers;
135
136   /* True if this is a combined parallel+workshare region.  */
137   bool is_combined_parallel;
138
139   /* The ordered stmt if type is GIMPLE_OMP_ORDERED and it has
140      a depend clause.  */
141   gomp_ordered *ord_stmt;
142 };
143
144 /* Context structure.  Used to store information about each parallel
145    directive in the code.  */
146
147 struct omp_context
148 {
149   /* This field must be at the beginning, as we do "inheritance": Some
150      callback functions for tree-inline.c (e.g., omp_copy_decl)
151      receive a copy_body_data pointer that is up-casted to an
152      omp_context pointer.  */
153   copy_body_data cb;
154
155   /* The tree of contexts corresponding to the encountered constructs.  */
156   struct omp_context *outer;
157   gimple *stmt;
158
159   /* Map variables to fields in a structure that allows communication
160      between sending and receiving threads.  */
161   splay_tree field_map;
162   tree record_type;
163   tree sender_decl;
164   tree receiver_decl;
165
166   /* These are used just by task contexts, if task firstprivate fn is
167      needed.  srecord_type is used to communicate from the thread
168      that encountered the task construct to task firstprivate fn,
169      record_type is allocated by GOMP_task, initialized by task firstprivate
170      fn and passed to the task body fn.  */
171   splay_tree sfield_map;
172   tree srecord_type;
173
174   /* A chain of variables to add to the top-level block surrounding the
175      construct.  In the case of a parallel, this is in the child function.  */
176   tree block_vars;
177
178   /* Label to which GOMP_cancel{,llation_point} and explicit and implicit
179      barriers should jump to during omplower pass.  */
180   tree cancel_label;
181
182   /* What to do with variables with implicitly determined sharing
183      attributes.  */
184   enum omp_clause_default_kind default_kind;
185
186   /* Nesting depth of this context.  Used to beautify error messages re
187      invalid gotos.  The outermost ctx is depth 1, with depth 0 being
188      reserved for the main body of the function.  */
189   int depth;
190
191   /* True if this parallel directive is nested within another.  */
192   bool is_nested;
193
194   /* True if this construct can be cancelled.  */
195   bool cancellable;
196 };
197
198 /* A structure holding the elements of:
199    for (V = N1; V cond N2; V += STEP) [...] */
200
201 struct omp_for_data_loop
202 {
203   tree v, n1, n2, step;
204   enum tree_code cond_code;
205 };
206
207 /* A structure describing the main elements of a parallel loop.  */
208
209 struct omp_for_data
210 {
211   struct omp_for_data_loop loop;
212   tree chunk_size;
213   gomp_for *for_stmt;
214   tree pre, iter_type;
215   int collapse;
216   int ordered;
217   bool have_nowait, have_ordered, simd_schedule;
218   unsigned char sched_modifiers;
219   enum omp_clause_schedule_kind sched_kind;
220   struct omp_for_data_loop *loops;
221 };
222
223 /* Describe the OpenACC looping structure of a function.  The entire
224    function is held in a 'NULL' loop.  */
225
226 struct oacc_loop
227 {
228   oacc_loop *parent; /* Containing loop.  */
229
230   oacc_loop *child; /* First inner loop.  */
231
232   oacc_loop *sibling; /* Next loop within same parent.  */
233
234   location_t loc; /* Location of the loop start.  */
235
236   gcall *marker; /* Initial head marker.  */
237   
238   gcall *heads[GOMP_DIM_MAX];  /* Head marker functions. */
239   gcall *tails[GOMP_DIM_MAX];  /* Tail marker functions. */
240
241   tree routine;  /* Pseudo-loop enclosing a routine.  */
242
243   unsigned mask;   /* Partitioning mask.  */
244   unsigned inner;  /* Partitioning of inner loops.  */
245   unsigned flags;  /* Partitioning flags.  */
246   unsigned ifns;   /* Contained loop abstraction functions.  */
247   tree chunk_size; /* Chunk size.  */
248   gcall *head_end; /* Final marker of head sequence.  */
249 };
250
251 /*  Flags for an OpenACC loop.  */
252
253 enum oacc_loop_flags {
254   OLF_SEQ       = 1u << 0,  /* Explicitly sequential  */
255   OLF_AUTO      = 1u << 1,      /* Compiler chooses axes.  */
256   OLF_INDEPENDENT = 1u << 2,    /* Iterations are known independent.  */
257   OLF_GANG_STATIC = 1u << 3,    /* Gang partitioning is static (has op). */
258
259   /* Explicitly specified loop axes.  */
260   OLF_DIM_BASE = 4,
261   OLF_DIM_GANG   = 1u << (OLF_DIM_BASE + GOMP_DIM_GANG),
262   OLF_DIM_WORKER = 1u << (OLF_DIM_BASE + GOMP_DIM_WORKER),
263   OLF_DIM_VECTOR = 1u << (OLF_DIM_BASE + GOMP_DIM_VECTOR),
264
265   OLF_MAX = OLF_DIM_BASE + GOMP_DIM_MAX
266 };
267
268
269 static splay_tree all_contexts;
270 static int taskreg_nesting_level;
271 static int target_nesting_level;
272 static struct omp_region *root_omp_region;
273 static bitmap task_shared_vars;
274 static vec<omp_context *> taskreg_contexts;
275 static bool omp_any_child_fn_dumped;
276
277 static void scan_omp (gimple_seq *, omp_context *);
278 static tree scan_omp_1_op (tree *, int *, void *);
279 static gphi *find_phi_with_arg_on_edge (tree, edge);
280
281 #define WALK_SUBSTMTS  \
282     case GIMPLE_BIND: \
283     case GIMPLE_TRY: \
284     case GIMPLE_CATCH: \
285     case GIMPLE_EH_FILTER: \
286     case GIMPLE_TRANSACTION: \
287       /* The sub-statements for these should be walked.  */ \
288       *handled_ops_p = false; \
289       break;
290
291 /* Return true if CTX corresponds to an oacc parallel region.  */
292
293 static bool
294 is_oacc_parallel (omp_context *ctx)
295 {
296   enum gimple_code outer_type = gimple_code (ctx->stmt);
297   return ((outer_type == GIMPLE_OMP_TARGET)
298           && (gimple_omp_target_kind (ctx->stmt)
299               == GF_OMP_TARGET_KIND_OACC_PARALLEL));
300 }
301
302 /* Return true if CTX corresponds to an oacc kernels region.  */
303
304 static bool
305 is_oacc_kernels (omp_context *ctx)
306 {
307   enum gimple_code outer_type = gimple_code (ctx->stmt);
308   return ((outer_type == GIMPLE_OMP_TARGET)
309           && (gimple_omp_target_kind (ctx->stmt)
310               == GF_OMP_TARGET_KIND_OACC_KERNELS));
311 }
312
313 /* If DECL is the artificial dummy VAR_DECL created for non-static
314    data member privatization, return the underlying "this" parameter,
315    otherwise return NULL.  */
316
317 tree
318 omp_member_access_dummy_var (tree decl)
319 {
320   if (!VAR_P (decl)
321       || !DECL_ARTIFICIAL (decl)
322       || !DECL_IGNORED_P (decl)
323       || !DECL_HAS_VALUE_EXPR_P (decl)
324       || !lang_hooks.decls.omp_disregard_value_expr (decl, false))
325     return NULL_TREE;
326
327   tree v = DECL_VALUE_EXPR (decl);
328   if (TREE_CODE (v) != COMPONENT_REF)
329     return NULL_TREE;
330
331   while (1)
332     switch (TREE_CODE (v))
333       {
334       case COMPONENT_REF:
335       case MEM_REF:
336       case INDIRECT_REF:
337       CASE_CONVERT:
338       case POINTER_PLUS_EXPR:
339         v = TREE_OPERAND (v, 0);
340         continue;
341       case PARM_DECL:
342         if (DECL_CONTEXT (v) == current_function_decl
343             && DECL_ARTIFICIAL (v)
344             && TREE_CODE (TREE_TYPE (v)) == POINTER_TYPE)
345           return v;
346         return NULL_TREE;
347       default:
348         return NULL_TREE;
349       }
350 }
351
352 /* Helper for unshare_and_remap, called through walk_tree.  */
353
354 static tree
355 unshare_and_remap_1 (tree *tp, int *walk_subtrees, void *data)
356 {
357   tree *pair = (tree *) data;
358   if (*tp == pair[0])
359     {
360       *tp = unshare_expr (pair[1]);
361       *walk_subtrees = 0;
362     }
363   else if (IS_TYPE_OR_DECL_P (*tp))
364     *walk_subtrees = 0;
365   return NULL_TREE;
366 }
367
368 /* Return unshare_expr (X) with all occurrences of FROM
369    replaced with TO.  */
370
371 static tree
372 unshare_and_remap (tree x, tree from, tree to)
373 {
374   tree pair[2] = { from, to };
375   x = unshare_expr (x);
376   walk_tree (&x, unshare_and_remap_1, pair, NULL);
377   return x;
378 }
379
380 /* Holds offload tables with decls.  */
381 vec<tree, va_gc> *offload_funcs, *offload_vars;
382
383 /* Convenience function for calling scan_omp_1_op on tree operands.  */
384
385 static inline tree
386 scan_omp_op (tree *tp, omp_context *ctx)
387 {
388   struct walk_stmt_info wi;
389
390   memset (&wi, 0, sizeof (wi));
391   wi.info = ctx;
392   wi.want_locations = true;
393
394   return walk_tree (tp, scan_omp_1_op, &wi, NULL);
395 }
396
397 static void lower_omp (gimple_seq *, omp_context *);
398 static tree lookup_decl_in_outer_ctx (tree, omp_context *);
399 static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
400
401 /* Find an OMP clause of type KIND within CLAUSES.  */
402
403 tree
404 find_omp_clause (tree clauses, enum omp_clause_code kind)
405 {
406   for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
407     if (OMP_CLAUSE_CODE (clauses) == kind)
408       return clauses;
409
410   return NULL_TREE;
411 }
412
413 /* Return true if CTX is for an omp parallel.  */
414
415 static inline bool
416 is_parallel_ctx (omp_context *ctx)
417 {
418   return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL;
419 }
420
421
422 /* Return true if CTX is for an omp task.  */
423
424 static inline bool
425 is_task_ctx (omp_context *ctx)
426 {
427   return gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
428 }
429
430
431 /* Return true if CTX is for an omp taskloop.  */
432
433 static inline bool
434 is_taskloop_ctx (omp_context *ctx)
435 {
436   return gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
437          && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_TASKLOOP;
438 }
439
440
441 /* Return true if CTX is for an omp parallel or omp task.  */
442
443 static inline bool
444 is_taskreg_ctx (omp_context *ctx)
445 {
446   return is_parallel_ctx (ctx) || is_task_ctx (ctx);
447 }
448
449
450 /* Return true if REGION is a combined parallel+workshare region.  */
451
452 static inline bool
453 is_combined_parallel (struct omp_region *region)
454 {
455   return region->is_combined_parallel;
456 }
457
458 /* Adjust *COND_CODE and *N2 so that the former is either LT_EXPR or
459    GT_EXPR.  */
460
461 static void
462 adjust_for_condition (location_t loc, enum tree_code *cond_code, tree *n2)
463 {
464   switch (*cond_code)
465     {
466     case LT_EXPR:
467     case GT_EXPR:
468     case NE_EXPR:
469       break;
470     case LE_EXPR:
471       if (POINTER_TYPE_P (TREE_TYPE (*n2)))
472         *n2 = fold_build_pointer_plus_hwi_loc (loc, *n2, 1);
473       else
474         *n2 = fold_build2_loc (loc, PLUS_EXPR, TREE_TYPE (*n2), *n2,
475                                build_int_cst (TREE_TYPE (*n2), 1));
476       *cond_code = LT_EXPR;
477       break;
478     case GE_EXPR:
479       if (POINTER_TYPE_P (TREE_TYPE (*n2)))
480         *n2 = fold_build_pointer_plus_hwi_loc (loc, *n2, -1);
481       else
482         *n2 = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (*n2), *n2,
483                                build_int_cst (TREE_TYPE (*n2), 1));
484       *cond_code = GT_EXPR;
485       break;
486     default:
487       gcc_unreachable ();
488     }
489 }
490
491 /* Return the looping step from INCR, extracted from the step of a gimple omp
492    for statement.  */
493
494 static tree
495 get_omp_for_step_from_incr (location_t loc, tree incr)
496 {
497   tree step;
498   switch (TREE_CODE (incr))
499     {
500     case PLUS_EXPR:
501       step = TREE_OPERAND (incr, 1);
502       break;
503     case POINTER_PLUS_EXPR:
504       step = fold_convert (ssizetype, TREE_OPERAND (incr, 1));
505       break;
506     case MINUS_EXPR:
507       step = TREE_OPERAND (incr, 1);
508       step = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (step), step);
509       break;
510     default:
511       gcc_unreachable ();
512     }
513   return step;
514 }
515
516 /* Extract the header elements of parallel loop FOR_STMT and store
517    them into *FD.  */
518
519 static void
520 extract_omp_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
521                       struct omp_for_data_loop *loops)
522 {
523   tree t, var, *collapse_iter, *collapse_count;
524   tree count = NULL_TREE, iter_type = long_integer_type_node;
525   struct omp_for_data_loop *loop;
526   int i;
527   struct omp_for_data_loop dummy_loop;
528   location_t loc = gimple_location (for_stmt);
529   bool simd = gimple_omp_for_kind (for_stmt) & GF_OMP_FOR_SIMD;
530   bool distribute = gimple_omp_for_kind (for_stmt)
531                     == GF_OMP_FOR_KIND_DISTRIBUTE;
532   bool taskloop = gimple_omp_for_kind (for_stmt)
533                   == GF_OMP_FOR_KIND_TASKLOOP;
534   tree iterv, countv;
535
536   fd->for_stmt = for_stmt;
537   fd->pre = NULL;
538   if (gimple_omp_for_collapse (for_stmt) > 1)
539     fd->loops = loops;
540   else
541     fd->loops = &fd->loop;
542
543   fd->have_nowait = distribute || simd;
544   fd->have_ordered = false;
545   fd->collapse = 1;
546   fd->ordered = 0;
547   fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
548   fd->sched_modifiers = 0;
549   fd->chunk_size = NULL_TREE;
550   fd->simd_schedule = false;
551   if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_CILKFOR)
552     fd->sched_kind = OMP_CLAUSE_SCHEDULE_CILKFOR;
553   collapse_iter = NULL;
554   collapse_count = NULL;
555
556   for (t = gimple_omp_for_clauses (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
557     switch (OMP_CLAUSE_CODE (t))
558       {
559       case OMP_CLAUSE_NOWAIT:
560         fd->have_nowait = true;
561         break;
562       case OMP_CLAUSE_ORDERED:
563         fd->have_ordered = true;
564         if (OMP_CLAUSE_ORDERED_EXPR (t))
565           fd->ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (t));
566         break;
567       case OMP_CLAUSE_SCHEDULE:
568         gcc_assert (!distribute && !taskloop);
569         fd->sched_kind
570           = (enum omp_clause_schedule_kind)
571             (OMP_CLAUSE_SCHEDULE_KIND (t) & OMP_CLAUSE_SCHEDULE_MASK);
572         fd->sched_modifiers = (OMP_CLAUSE_SCHEDULE_KIND (t)
573                                & ~OMP_CLAUSE_SCHEDULE_MASK);
574         fd->chunk_size = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t);
575         fd->simd_schedule = OMP_CLAUSE_SCHEDULE_SIMD (t);
576         break;
577       case OMP_CLAUSE_DIST_SCHEDULE:
578         gcc_assert (distribute);
579         fd->chunk_size = OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (t);
580         break;
581       case OMP_CLAUSE_COLLAPSE:
582         fd->collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (t));
583         if (fd->collapse > 1)
584           {
585             collapse_iter = &OMP_CLAUSE_COLLAPSE_ITERVAR (t);
586             collapse_count = &OMP_CLAUSE_COLLAPSE_COUNT (t);
587           }
588         break;
589       default:
590         break;
591       }
592   if (fd->ordered && fd->collapse == 1 && loops != NULL)
593     {
594       fd->loops = loops;
595       iterv = NULL_TREE;
596       countv = NULL_TREE;
597       collapse_iter = &iterv;
598       collapse_count = &countv;
599     }
600
601   /* FIXME: for now map schedule(auto) to schedule(static).
602      There should be analysis to determine whether all iterations
603      are approximately the same amount of work (then schedule(static)
604      is best) or if it varies (then schedule(dynamic,N) is better).  */
605   if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_AUTO)
606     {
607       fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
608       gcc_assert (fd->chunk_size == NULL);
609     }
610   gcc_assert (fd->collapse == 1 || collapse_iter != NULL);
611   if (taskloop)
612     fd->sched_kind = OMP_CLAUSE_SCHEDULE_RUNTIME;
613   if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
614     gcc_assert (fd->chunk_size == NULL);
615   else if (fd->chunk_size == NULL)
616     {
617       /* We only need to compute a default chunk size for ordered
618          static loops and dynamic loops.  */
619       if (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
620           || fd->have_ordered)
621         fd->chunk_size = (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
622                          ? integer_zero_node : integer_one_node;
623     }
624
625   int cnt = fd->ordered ? fd->ordered : fd->collapse;
626   for (i = 0; i < cnt; i++)
627     {
628       if (i == 0 && fd->collapse == 1 && (fd->ordered == 0 || loops == NULL))
629         loop = &fd->loop;
630       else if (loops != NULL)
631         loop = loops + i;
632       else
633         loop = &dummy_loop;
634
635       loop->v = gimple_omp_for_index (for_stmt, i);
636       gcc_assert (SSA_VAR_P (loop->v));
637       gcc_assert (TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
638                   || TREE_CODE (TREE_TYPE (loop->v)) == POINTER_TYPE);
639       var = TREE_CODE (loop->v) == SSA_NAME ? SSA_NAME_VAR (loop->v) : loop->v;
640       loop->n1 = gimple_omp_for_initial (for_stmt, i);
641
642       loop->cond_code = gimple_omp_for_cond (for_stmt, i);
643       loop->n2 = gimple_omp_for_final (for_stmt, i);
644       gcc_assert (loop->cond_code != NE_EXPR
645                   || gimple_omp_for_kind (for_stmt) == GF_OMP_FOR_KIND_CILKSIMD
646                   || gimple_omp_for_kind (for_stmt) == GF_OMP_FOR_KIND_CILKFOR);
647       adjust_for_condition (loc, &loop->cond_code, &loop->n2);
648
649       t = gimple_omp_for_incr (for_stmt, i);
650       gcc_assert (TREE_OPERAND (t, 0) == var);
651       loop->step = get_omp_for_step_from_incr (loc, t);
652
653       if (simd
654           || (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
655               && !fd->have_ordered))
656         {
657           if (fd->collapse == 1)
658             iter_type = TREE_TYPE (loop->v);
659           else if (i == 0
660                    || TYPE_PRECISION (iter_type)
661                       < TYPE_PRECISION (TREE_TYPE (loop->v)))
662             iter_type
663               = build_nonstandard_integer_type
664                   (TYPE_PRECISION (TREE_TYPE (loop->v)), 1);
665         }
666       else if (iter_type != long_long_unsigned_type_node)
667         {
668           if (POINTER_TYPE_P (TREE_TYPE (loop->v)))
669             iter_type = long_long_unsigned_type_node;
670           else if (TYPE_UNSIGNED (TREE_TYPE (loop->v))
671                    && TYPE_PRECISION (TREE_TYPE (loop->v))
672                       >= TYPE_PRECISION (iter_type))
673             {
674               tree n;
675
676               if (loop->cond_code == LT_EXPR)
677                 n = fold_build2_loc (loc,
678                                  PLUS_EXPR, TREE_TYPE (loop->v),
679                                  loop->n2, loop->step);
680               else
681                 n = loop->n1;
682               if (TREE_CODE (n) != INTEGER_CST
683                   || tree_int_cst_lt (TYPE_MAX_VALUE (iter_type), n))
684                 iter_type = long_long_unsigned_type_node;
685             }
686           else if (TYPE_PRECISION (TREE_TYPE (loop->v))
687                    > TYPE_PRECISION (iter_type))
688             {
689               tree n1, n2;
690
691               if (loop->cond_code == LT_EXPR)
692                 {
693                   n1 = loop->n1;
694                   n2 = fold_build2_loc (loc,
695                                     PLUS_EXPR, TREE_TYPE (loop->v),
696                                     loop->n2, loop->step);
697                 }
698               else
699                 {
700                   n1 = fold_build2_loc (loc,
701                                     MINUS_EXPR, TREE_TYPE (loop->v),
702                                     loop->n2, loop->step);
703                   n2 = loop->n1;
704                 }
705               if (TREE_CODE (n1) != INTEGER_CST
706                   || TREE_CODE (n2) != INTEGER_CST
707                   || !tree_int_cst_lt (TYPE_MIN_VALUE (iter_type), n1)
708                   || !tree_int_cst_lt (n2, TYPE_MAX_VALUE (iter_type)))
709                 iter_type = long_long_unsigned_type_node;
710             }
711         }
712
713       if (i >= fd->collapse)
714         continue;
715
716       if (collapse_count && *collapse_count == NULL)
717         {
718           t = fold_binary (loop->cond_code, boolean_type_node,
719                            fold_convert (TREE_TYPE (loop->v), loop->n1),
720                            fold_convert (TREE_TYPE (loop->v), loop->n2));
721           if (t && integer_zerop (t))
722             count = build_zero_cst (long_long_unsigned_type_node);
723           else if ((i == 0 || count != NULL_TREE)
724                    && TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
725                    && TREE_CONSTANT (loop->n1)
726                    && TREE_CONSTANT (loop->n2)
727                    && TREE_CODE (loop->step) == INTEGER_CST)
728             {
729               tree itype = TREE_TYPE (loop->v);
730
731               if (POINTER_TYPE_P (itype))
732                 itype = signed_type_for (itype);
733               t = build_int_cst (itype, (loop->cond_code == LT_EXPR ? -1 : 1));
734               t = fold_build2_loc (loc,
735                                PLUS_EXPR, itype,
736                                fold_convert_loc (loc, itype, loop->step), t);
737               t = fold_build2_loc (loc, PLUS_EXPR, itype, t,
738                                fold_convert_loc (loc, itype, loop->n2));
739               t = fold_build2_loc (loc, MINUS_EXPR, itype, t,
740                                fold_convert_loc (loc, itype, loop->n1));
741               if (TYPE_UNSIGNED (itype) && loop->cond_code == GT_EXPR)
742                 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
743                                  fold_build1_loc (loc, NEGATE_EXPR, itype, t),
744                                  fold_build1_loc (loc, NEGATE_EXPR, itype,
745                                               fold_convert_loc (loc, itype,
746                                                                 loop->step)));
747               else
748                 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
749                                  fold_convert_loc (loc, itype, loop->step));
750               t = fold_convert_loc (loc, long_long_unsigned_type_node, t);
751               if (count != NULL_TREE)
752                 count = fold_build2_loc (loc,
753                                      MULT_EXPR, long_long_unsigned_type_node,
754                                      count, t);
755               else
756                 count = t;
757               if (TREE_CODE (count) != INTEGER_CST)
758                 count = NULL_TREE;
759             }
760           else if (count && !integer_zerop (count))
761             count = NULL_TREE;
762         }
763     }
764
765   if (count
766       && !simd
767       && (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
768           || fd->have_ordered))
769     {
770       if (!tree_int_cst_lt (count, TYPE_MAX_VALUE (long_integer_type_node)))
771         iter_type = long_long_unsigned_type_node;
772       else
773         iter_type = long_integer_type_node;
774     }
775   else if (collapse_iter && *collapse_iter != NULL)
776     iter_type = TREE_TYPE (*collapse_iter);
777   fd->iter_type = iter_type;
778   if (collapse_iter && *collapse_iter == NULL)
779     *collapse_iter = create_tmp_var (iter_type, ".iter");
780   if (collapse_count && *collapse_count == NULL)
781     {
782       if (count)
783         *collapse_count = fold_convert_loc (loc, iter_type, count);
784       else
785         *collapse_count = create_tmp_var (iter_type, ".count");
786     }
787
788   if (fd->collapse > 1 || (fd->ordered && loops))
789     {
790       fd->loop.v = *collapse_iter;
791       fd->loop.n1 = build_int_cst (TREE_TYPE (fd->loop.v), 0);
792       fd->loop.n2 = *collapse_count;
793       fd->loop.step = build_int_cst (TREE_TYPE (fd->loop.v), 1);
794       fd->loop.cond_code = LT_EXPR;
795     }
796   else if (loops)
797     loops[0] = fd->loop;
798 }
799
800
801 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
802    is the immediate dominator of PAR_ENTRY_BB, return true if there
803    are no data dependencies that would prevent expanding the parallel
804    directive at PAR_ENTRY_BB as a combined parallel+workshare region.
805
806    When expanding a combined parallel+workshare region, the call to
807    the child function may need additional arguments in the case of
808    GIMPLE_OMP_FOR regions.  In some cases, these arguments are
809    computed out of variables passed in from the parent to the child
810    via 'struct .omp_data_s'.  For instance:
811
812         #pragma omp parallel for schedule (guided, i * 4)
813         for (j ...)
814
815    Is lowered into:
816
817         # BLOCK 2 (PAR_ENTRY_BB)
818         .omp_data_o.i = i;
819         #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
820
821         # BLOCK 3 (WS_ENTRY_BB)
822         .omp_data_i = &.omp_data_o;
823         D.1667 = .omp_data_i->i;
824         D.1598 = D.1667 * 4;
825         #pragma omp for schedule (guided, D.1598)
826
827    When we outline the parallel region, the call to the child function
828    'bar.omp_fn.0' will need the value D.1598 in its argument list, but
829    that value is computed *after* the call site.  So, in principle we
830    cannot do the transformation.
831
832    To see whether the code in WS_ENTRY_BB blocks the combined
833    parallel+workshare call, we collect all the variables used in the
834    GIMPLE_OMP_FOR header check whether they appear on the LHS of any
835    statement in WS_ENTRY_BB.  If so, then we cannot emit the combined
836    call.
837
838    FIXME.  If we had the SSA form built at this point, we could merely
839    hoist the code in block 3 into block 2 and be done with it.  But at
840    this point we don't have dataflow information and though we could
841    hack something up here, it is really not worth the aggravation.  */
842
843 static bool
844 workshare_safe_to_combine_p (basic_block ws_entry_bb)
845 {
846   struct omp_for_data fd;
847   gimple *ws_stmt = last_stmt (ws_entry_bb);
848
849   if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
850     return true;
851
852   gcc_assert (gimple_code (ws_stmt) == GIMPLE_OMP_FOR);
853
854   extract_omp_for_data (as_a <gomp_for *> (ws_stmt), &fd, NULL);
855
856   if (fd.collapse > 1 && TREE_CODE (fd.loop.n2) != INTEGER_CST)
857     return false;
858   if (fd.iter_type != long_integer_type_node)
859     return false;
860
861   /* FIXME.  We give up too easily here.  If any of these arguments
862      are not constants, they will likely involve variables that have
863      been mapped into fields of .omp_data_s for sharing with the child
864      function.  With appropriate data flow, it would be possible to
865      see through this.  */
866   if (!is_gimple_min_invariant (fd.loop.n1)
867       || !is_gimple_min_invariant (fd.loop.n2)
868       || !is_gimple_min_invariant (fd.loop.step)
869       || (fd.chunk_size && !is_gimple_min_invariant (fd.chunk_size)))
870     return false;
871
872   return true;
873 }
874
875
876 static int omp_max_vf (void);
877
878 /* Adjust CHUNK_SIZE from SCHEDULE clause, depending on simd modifier
879    presence (SIMD_SCHEDULE).  */
880
881 static tree
882 omp_adjust_chunk_size (tree chunk_size, bool simd_schedule)
883 {
884   if (!simd_schedule)
885     return chunk_size;
886
887   int vf = omp_max_vf ();
888   if (vf == 1)
889     return chunk_size;
890
891   tree type = TREE_TYPE (chunk_size);
892   chunk_size = fold_build2 (PLUS_EXPR, type, chunk_size,
893                             build_int_cst (type, vf - 1));
894   return fold_build2 (BIT_AND_EXPR, type, chunk_size,
895                       build_int_cst (type, -vf));
896 }
897
898
899 /* Collect additional arguments needed to emit a combined
900    parallel+workshare call.  WS_STMT is the workshare directive being
901    expanded.  */
902
903 static vec<tree, va_gc> *
904 get_ws_args_for (gimple *par_stmt, gimple *ws_stmt)
905 {
906   tree t;
907   location_t loc = gimple_location (ws_stmt);
908   vec<tree, va_gc> *ws_args;
909
910   if (gomp_for *for_stmt = dyn_cast <gomp_for *> (ws_stmt))
911     {
912       struct omp_for_data fd;
913       tree n1, n2;
914
915       extract_omp_for_data (for_stmt, &fd, NULL);
916       n1 = fd.loop.n1;
917       n2 = fd.loop.n2;
918
919       if (gimple_omp_for_combined_into_p (for_stmt))
920         {
921           tree innerc
922             = find_omp_clause (gimple_omp_parallel_clauses (par_stmt),
923                                OMP_CLAUSE__LOOPTEMP_);
924           gcc_assert (innerc);
925           n1 = OMP_CLAUSE_DECL (innerc);
926           innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
927                                     OMP_CLAUSE__LOOPTEMP_);
928           gcc_assert (innerc);
929           n2 = OMP_CLAUSE_DECL (innerc);
930         }
931
932       vec_alloc (ws_args, 3 + (fd.chunk_size != 0));
933
934       t = fold_convert_loc (loc, long_integer_type_node, n1);
935       ws_args->quick_push (t);
936
937       t = fold_convert_loc (loc, long_integer_type_node, n2);
938       ws_args->quick_push (t);
939
940       t = fold_convert_loc (loc, long_integer_type_node, fd.loop.step);
941       ws_args->quick_push (t);
942
943       if (fd.chunk_size)
944         {
945           t = fold_convert_loc (loc, long_integer_type_node, fd.chunk_size);
946           t = omp_adjust_chunk_size (t, fd.simd_schedule);
947           ws_args->quick_push (t);
948         }
949
950       return ws_args;
951     }
952   else if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
953     {
954       /* Number of sections is equal to the number of edges from the
955          GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
956          the exit of the sections region.  */
957       basic_block bb = single_succ (gimple_bb (ws_stmt));
958       t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
959       vec_alloc (ws_args, 1);
960       ws_args->quick_push (t);
961       return ws_args;
962     }
963
964   gcc_unreachable ();
965 }
966
967
968 /* Discover whether REGION is a combined parallel+workshare region.  */
969
970 static void
971 determine_parallel_type (struct omp_region *region)
972 {
973   basic_block par_entry_bb, par_exit_bb;
974   basic_block ws_entry_bb, ws_exit_bb;
975
976   if (region == NULL || region->inner == NULL
977       || region->exit == NULL || region->inner->exit == NULL
978       || region->inner->cont == NULL)
979     return;
980
981   /* We only support parallel+for and parallel+sections.  */
982   if (region->type != GIMPLE_OMP_PARALLEL
983       || (region->inner->type != GIMPLE_OMP_FOR
984           && region->inner->type != GIMPLE_OMP_SECTIONS))
985     return;
986
987   /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
988      WS_EXIT_BB -> PAR_EXIT_BB.  */
989   par_entry_bb = region->entry;
990   par_exit_bb = region->exit;
991   ws_entry_bb = region->inner->entry;
992   ws_exit_bb = region->inner->exit;
993
994   if (single_succ (par_entry_bb) == ws_entry_bb
995       && single_succ (ws_exit_bb) == par_exit_bb
996       && workshare_safe_to_combine_p (ws_entry_bb)
997       && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb))
998           || (last_and_only_stmt (ws_entry_bb)
999               && last_and_only_stmt (par_exit_bb))))
1000     {
1001       gimple *par_stmt = last_stmt (par_entry_bb);
1002       gimple *ws_stmt = last_stmt (ws_entry_bb);
1003
1004       if (region->inner->type == GIMPLE_OMP_FOR)
1005         {
1006           /* If this is a combined parallel loop, we need to determine
1007              whether or not to use the combined library calls.  There
1008              are two cases where we do not apply the transformation:
1009              static loops and any kind of ordered loop.  In the first
1010              case, we already open code the loop so there is no need
1011              to do anything else.  In the latter case, the combined
1012              parallel loop call would still need extra synchronization
1013              to implement ordered semantics, so there would not be any
1014              gain in using the combined call.  */
1015           tree clauses = gimple_omp_for_clauses (ws_stmt);
1016           tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
1017           if (c == NULL
1018               || ((OMP_CLAUSE_SCHEDULE_KIND (c) & OMP_CLAUSE_SCHEDULE_MASK)
1019                   == OMP_CLAUSE_SCHEDULE_STATIC)
1020               || find_omp_clause (clauses, OMP_CLAUSE_ORDERED))
1021             {
1022               region->is_combined_parallel = false;
1023               region->inner->is_combined_parallel = false;
1024               return;
1025             }
1026         }
1027
1028       region->is_combined_parallel = true;
1029       region->inner->is_combined_parallel = true;
1030       region->ws_args = get_ws_args_for (par_stmt, ws_stmt);
1031     }
1032 }
1033
1034
1035 /* Return true if EXPR is variable sized.  */
1036
1037 static inline bool
1038 is_variable_sized (const_tree expr)
1039 {
1040   return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
1041 }
1042
1043 /* Return true if DECL is a reference type.  */
1044
1045 static inline bool
1046 is_reference (tree decl)
1047 {
1048   return lang_hooks.decls.omp_privatize_by_reference (decl);
1049 }
1050
1051 /* Return the type of a decl.  If the decl is reference type,
1052    return its base type.  */
1053 static inline tree
1054 get_base_type (tree decl)
1055 {
1056   tree type = TREE_TYPE (decl);
1057   if (is_reference (decl))
1058     type = TREE_TYPE (type);
1059   return type;
1060 }
1061
1062 /* Lookup variables.  The "maybe" form
1063    allows for the variable form to not have been entered, otherwise we
1064    assert that the variable must have been entered.  */
1065
1066 static inline tree
1067 lookup_decl (tree var, omp_context *ctx)
1068 {
1069   tree *n = ctx->cb.decl_map->get (var);
1070   return *n;
1071 }
1072
1073 static inline tree
1074 maybe_lookup_decl (const_tree var, omp_context *ctx)
1075 {
1076   tree *n = ctx->cb.decl_map->get (const_cast<tree> (var));
1077   return n ? *n : NULL_TREE;
1078 }
1079
1080 static inline tree
1081 lookup_field (tree var, omp_context *ctx)
1082 {
1083   splay_tree_node n;
1084   n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
1085   return (tree) n->value;
1086 }
1087
1088 static inline tree
1089 lookup_sfield (splay_tree_key key, omp_context *ctx)
1090 {
1091   splay_tree_node n;
1092   n = splay_tree_lookup (ctx->sfield_map
1093                          ? ctx->sfield_map : ctx->field_map, key);
1094   return (tree) n->value;
1095 }
1096
1097 static inline tree
1098 lookup_sfield (tree var, omp_context *ctx)
1099 {
1100   return lookup_sfield ((splay_tree_key) var, ctx);
1101 }
1102
1103 static inline tree
1104 maybe_lookup_field (splay_tree_key key, omp_context *ctx)
1105 {
1106   splay_tree_node n;
1107   n = splay_tree_lookup (ctx->field_map, key);
1108   return n ? (tree) n->value : NULL_TREE;
1109 }
1110
1111 static inline tree
1112 maybe_lookup_field (tree var, omp_context *ctx)
1113 {
1114   return maybe_lookup_field ((splay_tree_key) var, ctx);
1115 }
1116
1117 /* Return true if DECL should be copied by pointer.  SHARED_CTX is
1118    the parallel context if DECL is to be shared.  */
1119
1120 static bool
1121 use_pointer_for_field (tree decl, omp_context *shared_ctx)
1122 {
1123   if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
1124     return true;
1125
1126   /* We can only use copy-in/copy-out semantics for shared variables
1127      when we know the value is not accessible from an outer scope.  */
1128   if (shared_ctx)
1129     {
1130       gcc_assert (!is_gimple_omp_oacc (shared_ctx->stmt));
1131
1132       /* ??? Trivially accessible from anywhere.  But why would we even
1133          be passing an address in this case?  Should we simply assert
1134          this to be false, or should we have a cleanup pass that removes
1135          these from the list of mappings?  */
1136       if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
1137         return true;
1138
1139       /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
1140          without analyzing the expression whether or not its location
1141          is accessible to anyone else.  In the case of nested parallel
1142          regions it certainly may be.  */
1143       if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
1144         return true;
1145
1146       /* Do not use copy-in/copy-out for variables that have their
1147          address taken.  */
1148       if (TREE_ADDRESSABLE (decl))
1149         return true;
1150
1151       /* lower_send_shared_vars only uses copy-in, but not copy-out
1152          for these.  */
1153       if (TREE_READONLY (decl)
1154           || ((TREE_CODE (decl) == RESULT_DECL
1155                || TREE_CODE (decl) == PARM_DECL)
1156               && DECL_BY_REFERENCE (decl)))
1157         return false;
1158
1159       /* Disallow copy-in/out in nested parallel if
1160          decl is shared in outer parallel, otherwise
1161          each thread could store the shared variable
1162          in its own copy-in location, making the
1163          variable no longer really shared.  */
1164       if (shared_ctx->is_nested)
1165         {
1166           omp_context *up;
1167
1168           for (up = shared_ctx->outer; up; up = up->outer)
1169             if (is_taskreg_ctx (up) && maybe_lookup_decl (decl, up))
1170               break;
1171
1172           if (up)
1173             {
1174               tree c;
1175
1176               for (c = gimple_omp_taskreg_clauses (up->stmt);
1177                    c; c = OMP_CLAUSE_CHAIN (c))
1178                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
1179                     && OMP_CLAUSE_DECL (c) == decl)
1180                   break;
1181
1182               if (c)
1183                 goto maybe_mark_addressable_and_ret;
1184             }
1185         }
1186
1187       /* For tasks avoid using copy-in/out.  As tasks can be
1188          deferred or executed in different thread, when GOMP_task
1189          returns, the task hasn't necessarily terminated.  */
1190       if (is_task_ctx (shared_ctx))
1191         {
1192           tree outer;
1193         maybe_mark_addressable_and_ret:
1194           outer = maybe_lookup_decl_in_outer_ctx (decl, shared_ctx);
1195           if (is_gimple_reg (outer) && !omp_member_access_dummy_var (outer))
1196             {
1197               /* Taking address of OUTER in lower_send_shared_vars
1198                  might need regimplification of everything that uses the
1199                  variable.  */
1200               if (!task_shared_vars)
1201                 task_shared_vars = BITMAP_ALLOC (NULL);
1202               bitmap_set_bit (task_shared_vars, DECL_UID (outer));
1203               TREE_ADDRESSABLE (outer) = 1;
1204             }
1205           return true;
1206         }
1207     }
1208
1209   return false;
1210 }
1211
1212 /* Construct a new automatic decl similar to VAR.  */
1213
1214 static tree
1215 omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
1216 {
1217   tree copy = copy_var_decl (var, name, type);
1218
1219   DECL_CONTEXT (copy) = current_function_decl;
1220   DECL_CHAIN (copy) = ctx->block_vars;
1221   /* If VAR is listed in task_shared_vars, it means it wasn't
1222      originally addressable and is just because task needs to take
1223      it's address.  But we don't need to take address of privatizations
1224      from that var.  */
1225   if (TREE_ADDRESSABLE (var)
1226       && task_shared_vars
1227       && bitmap_bit_p (task_shared_vars, DECL_UID (var)))
1228     TREE_ADDRESSABLE (copy) = 0;
1229   ctx->block_vars = copy;
1230
1231   return copy;
1232 }
1233
1234 static tree
1235 omp_copy_decl_1 (tree var, omp_context *ctx)
1236 {
1237   return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
1238 }
1239
1240 /* Build COMPONENT_REF and set TREE_THIS_VOLATILE and TREE_READONLY on it
1241    as appropriate.  */
1242 static tree
1243 omp_build_component_ref (tree obj, tree field)
1244 {
1245   tree ret = build3 (COMPONENT_REF, TREE_TYPE (field), obj, field, NULL);
1246   if (TREE_THIS_VOLATILE (field))
1247     TREE_THIS_VOLATILE (ret) |= 1;
1248   if (TREE_READONLY (field))
1249     TREE_READONLY (ret) |= 1;
1250   return ret;
1251 }
1252
1253 /* Build tree nodes to access the field for VAR on the receiver side.  */
1254
1255 static tree
1256 build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
1257 {
1258   tree x, field = lookup_field (var, ctx);
1259
1260   /* If the receiver record type was remapped in the child function,
1261      remap the field into the new record type.  */
1262   x = maybe_lookup_field (field, ctx);
1263   if (x != NULL)
1264     field = x;
1265
1266   x = build_simple_mem_ref (ctx->receiver_decl);
1267   TREE_THIS_NOTRAP (x) = 1;
1268   x = omp_build_component_ref (x, field);
1269   if (by_ref)
1270     {
1271       x = build_simple_mem_ref (x);
1272       TREE_THIS_NOTRAP (x) = 1;
1273     }
1274
1275   return x;
1276 }
1277
1278 /* Build tree nodes to access VAR in the scope outer to CTX.  In the case
1279    of a parallel, this is a component reference; for workshare constructs
1280    this is some variable.  */
1281
1282 static tree
1283 build_outer_var_ref (tree var, omp_context *ctx, bool lastprivate = false)
1284 {
1285   tree x;
1286
1287   if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
1288     x = var;
1289   else if (is_variable_sized (var))
1290     {
1291       x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
1292       x = build_outer_var_ref (x, ctx, lastprivate);
1293       x = build_simple_mem_ref (x);
1294     }
1295   else if (is_taskreg_ctx (ctx))
1296     {
1297       bool by_ref = use_pointer_for_field (var, NULL);
1298       x = build_receiver_ref (var, by_ref, ctx);
1299     }
1300   else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
1301            && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
1302     {
1303       /* #pragma omp simd isn't a worksharing construct, and can reference even
1304          private vars in its linear etc. clauses.  */
1305       x = NULL_TREE;
1306       if (ctx->outer && is_taskreg_ctx (ctx))
1307         x = lookup_decl (var, ctx->outer);
1308       else if (ctx->outer)
1309         x = maybe_lookup_decl_in_outer_ctx (var, ctx);
1310       if (x == NULL_TREE)
1311         x = var;
1312     }
1313   else if (lastprivate && is_taskloop_ctx (ctx))
1314     {
1315       gcc_assert (ctx->outer);
1316       splay_tree_node n
1317         = splay_tree_lookup (ctx->outer->field_map,
1318                              (splay_tree_key) &DECL_UID (var));
1319       if (n == NULL)
1320         {
1321           if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx->outer)))
1322             x = var;
1323           else
1324             x = lookup_decl (var, ctx->outer);
1325         }
1326       else
1327         {
1328           tree field = (tree) n->value;
1329           /* If the receiver record type was remapped in the child function,
1330              remap the field into the new record type.  */
1331           x = maybe_lookup_field (field, ctx->outer);
1332           if (x != NULL)
1333             field = x;
1334
1335           x = build_simple_mem_ref (ctx->outer->receiver_decl);
1336           x = omp_build_component_ref (x, field);
1337           if (use_pointer_for_field (var, ctx->outer))
1338             x = build_simple_mem_ref (x);
1339         }
1340     }
1341   else if (ctx->outer)
1342     {
1343       omp_context *outer = ctx->outer;
1344       if (gimple_code (outer->stmt) == GIMPLE_OMP_GRID_BODY)
1345         {
1346           outer = outer->outer;
1347           gcc_assert (outer
1348                       && gimple_code (outer->stmt) != GIMPLE_OMP_GRID_BODY);
1349         }
1350         x = lookup_decl (var, outer);
1351     }
1352   else if (is_reference (var))
1353     /* This can happen with orphaned constructs.  If var is reference, it is
1354        possible it is shared and as such valid.  */
1355     x = var;
1356   else if (omp_member_access_dummy_var (var))
1357     x = var;
1358   else
1359     gcc_unreachable ();
1360
1361   if (x == var)
1362     {
1363       tree t = omp_member_access_dummy_var (var);
1364       if (t)
1365         {
1366           x = DECL_VALUE_EXPR (var);
1367           tree o = maybe_lookup_decl_in_outer_ctx (t, ctx);
1368           if (o != t)
1369             x = unshare_and_remap (x, t, o);
1370           else
1371             x = unshare_expr (x);
1372         }
1373     }
1374
1375   if (is_reference (var))
1376     x = build_simple_mem_ref (x);
1377
1378   return x;
1379 }
1380
1381 /* Build tree nodes to access the field for VAR on the sender side.  */
1382
1383 static tree
1384 build_sender_ref (splay_tree_key key, omp_context *ctx)
1385 {
1386   tree field = lookup_sfield (key, ctx);
1387   return omp_build_component_ref (ctx->sender_decl, field);
1388 }
1389
1390 static tree
1391 build_sender_ref (tree var, omp_context *ctx)
1392 {
1393   return build_sender_ref ((splay_tree_key) var, ctx);
1394 }
1395
1396 /* Add a new field for VAR inside the structure CTX->SENDER_DECL.  If
1397    BASE_POINTERS_RESTRICT, declare the field with restrict.  */
1398
1399 static void
1400 install_var_field (tree var, bool by_ref, int mask, omp_context *ctx,
1401                    bool base_pointers_restrict = false)
1402 {
1403   tree field, type, sfield = NULL_TREE;
1404   splay_tree_key key = (splay_tree_key) var;
1405
1406   if ((mask & 8) != 0)
1407     {
1408       key = (splay_tree_key) &DECL_UID (var);
1409       gcc_checking_assert (key != (splay_tree_key) var);
1410     }
1411   gcc_assert ((mask & 1) == 0
1412               || !splay_tree_lookup (ctx->field_map, key));
1413   gcc_assert ((mask & 2) == 0 || !ctx->sfield_map
1414               || !splay_tree_lookup (ctx->sfield_map, key));
1415   gcc_assert ((mask & 3) == 3
1416               || !is_gimple_omp_oacc (ctx->stmt));
1417
1418   type = TREE_TYPE (var);
1419   /* Prevent redeclaring the var in the split-off function with a restrict
1420      pointer type.  Note that we only clear type itself, restrict qualifiers in
1421      the pointed-to type will be ignored by points-to analysis.  */
1422   if (POINTER_TYPE_P (type)
1423       && TYPE_RESTRICT (type))
1424     type = build_qualified_type (type, TYPE_QUALS (type) & ~TYPE_QUAL_RESTRICT);
1425
1426   if (mask & 4)
1427     {
1428       gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
1429       type = build_pointer_type (build_pointer_type (type));
1430     }
1431   else if (by_ref)
1432     {
1433       type = build_pointer_type (type);
1434       if (base_pointers_restrict)
1435         type = build_qualified_type (type, TYPE_QUAL_RESTRICT);
1436     }
1437   else if ((mask & 3) == 1 && is_reference (var))
1438     type = TREE_TYPE (type);
1439
1440   field = build_decl (DECL_SOURCE_LOCATION (var),
1441                       FIELD_DECL, DECL_NAME (var), type);
1442
1443   /* Remember what variable this field was created for.  This does have a
1444      side effect of making dwarf2out ignore this member, so for helpful
1445      debugging we clear it later in delete_omp_context.  */
1446   DECL_ABSTRACT_ORIGIN (field) = var;
1447   if (type == TREE_TYPE (var))
1448     {
1449       SET_DECL_ALIGN (field, DECL_ALIGN (var));
1450       DECL_USER_ALIGN (field) = DECL_USER_ALIGN (var);
1451       TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (var);
1452     }
1453   else
1454     SET_DECL_ALIGN (field, TYPE_ALIGN (type));
1455
1456   if ((mask & 3) == 3)
1457     {
1458       insert_field_into_struct (ctx->record_type, field);
1459       if (ctx->srecord_type)
1460         {
1461           sfield = build_decl (DECL_SOURCE_LOCATION (var),
1462                                FIELD_DECL, DECL_NAME (var), type);
1463           DECL_ABSTRACT_ORIGIN (sfield) = var;
1464           SET_DECL_ALIGN (sfield, DECL_ALIGN (field));
1465           DECL_USER_ALIGN (sfield) = DECL_USER_ALIGN (field);
1466           TREE_THIS_VOLATILE (sfield) = TREE_THIS_VOLATILE (field);
1467           insert_field_into_struct (ctx->srecord_type, sfield);
1468         }
1469     }
1470   else
1471     {
1472       if (ctx->srecord_type == NULL_TREE)
1473         {
1474           tree t;
1475
1476           ctx->srecord_type = lang_hooks.types.make_type (RECORD_TYPE);
1477           ctx->sfield_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1478           for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
1479             {
1480               sfield = build_decl (DECL_SOURCE_LOCATION (t),
1481                                    FIELD_DECL, DECL_NAME (t), TREE_TYPE (t));
1482               DECL_ABSTRACT_ORIGIN (sfield) = DECL_ABSTRACT_ORIGIN (t);
1483               insert_field_into_struct (ctx->srecord_type, sfield);
1484               splay_tree_insert (ctx->sfield_map,
1485                                  (splay_tree_key) DECL_ABSTRACT_ORIGIN (t),
1486                                  (splay_tree_value) sfield);
1487             }
1488         }
1489       sfield = field;
1490       insert_field_into_struct ((mask & 1) ? ctx->record_type
1491                                 : ctx->srecord_type, field);
1492     }
1493
1494   if (mask & 1)
1495     splay_tree_insert (ctx->field_map, key, (splay_tree_value) field);
1496   if ((mask & 2) && ctx->sfield_map)
1497     splay_tree_insert (ctx->sfield_map, key, (splay_tree_value) sfield);
1498 }
1499
1500 static tree
1501 install_var_local (tree var, omp_context *ctx)
1502 {
1503   tree new_var = omp_copy_decl_1 (var, ctx);
1504   insert_decl_map (&ctx->cb, var, new_var);
1505   return new_var;
1506 }
1507
1508 /* Adjust the replacement for DECL in CTX for the new context.  This means
1509    copying the DECL_VALUE_EXPR, and fixing up the type.  */
1510
1511 static void
1512 fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
1513 {
1514   tree new_decl, size;
1515
1516   new_decl = lookup_decl (decl, ctx);
1517
1518   TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
1519
1520   if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
1521       && DECL_HAS_VALUE_EXPR_P (decl))
1522     {
1523       tree ve = DECL_VALUE_EXPR (decl);
1524       walk_tree (&ve, copy_tree_body_r, &ctx->cb, NULL);
1525       SET_DECL_VALUE_EXPR (new_decl, ve);
1526       DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
1527     }
1528
1529   if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
1530     {
1531       size = remap_decl (DECL_SIZE (decl), &ctx->cb);
1532       if (size == error_mark_node)
1533         size = TYPE_SIZE (TREE_TYPE (new_decl));
1534       DECL_SIZE (new_decl) = size;
1535
1536       size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
1537       if (size == error_mark_node)
1538         size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
1539       DECL_SIZE_UNIT (new_decl) = size;
1540     }
1541 }
1542
1543 /* The callback for remap_decl.  Search all containing contexts for a
1544    mapping of the variable; this avoids having to duplicate the splay
1545    tree ahead of time.  We know a mapping doesn't already exist in the
1546    given context.  Create new mappings to implement default semantics.  */
1547
1548 static tree
1549 omp_copy_decl (tree var, copy_body_data *cb)
1550 {
1551   omp_context *ctx = (omp_context *) cb;
1552   tree new_var;
1553
1554   if (TREE_CODE (var) == LABEL_DECL)
1555     {
1556       new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
1557       DECL_CONTEXT (new_var) = current_function_decl;
1558       insert_decl_map (&ctx->cb, var, new_var);
1559       return new_var;
1560     }
1561
1562   while (!is_taskreg_ctx (ctx))
1563     {
1564       ctx = ctx->outer;
1565       if (ctx == NULL)
1566         return var;
1567       new_var = maybe_lookup_decl (var, ctx);
1568       if (new_var)
1569         return new_var;
1570     }
1571
1572   if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
1573     return var;
1574
1575   return error_mark_node;
1576 }
1577
1578
1579 /* Debugging dumps for parallel regions.  */
1580 void dump_omp_region (FILE *, struct omp_region *, int);
1581 void debug_omp_region (struct omp_region *);
1582 void debug_all_omp_regions (void);
1583
1584 /* Dump the parallel region tree rooted at REGION.  */
1585
1586 void
1587 dump_omp_region (FILE *file, struct omp_region *region, int indent)
1588 {
1589   fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
1590            gimple_code_name[region->type]);
1591
1592   if (region->inner)
1593     dump_omp_region (file, region->inner, indent + 4);
1594
1595   if (region->cont)
1596     {
1597       fprintf (file, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent, "",
1598                region->cont->index);
1599     }
1600
1601   if (region->exit)
1602     fprintf (file, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent, "",
1603              region->exit->index);
1604   else
1605     fprintf (file, "%*s[no exit marker]\n", indent, "");
1606
1607   if (region->next)
1608     dump_omp_region (file, region->next, indent);
1609 }
1610
1611 DEBUG_FUNCTION void
1612 debug_omp_region (struct omp_region *region)
1613 {
1614   dump_omp_region (stderr, region, 0);
1615 }
1616
1617 DEBUG_FUNCTION void
1618 debug_all_omp_regions (void)
1619 {
1620   dump_omp_region (stderr, root_omp_region, 0);
1621 }
1622
1623
1624 /* Create a new parallel region starting at STMT inside region PARENT.  */
1625
1626 static struct omp_region *
1627 new_omp_region (basic_block bb, enum gimple_code type,
1628                 struct omp_region *parent)
1629 {
1630   struct omp_region *region = XCNEW (struct omp_region);
1631
1632   region->outer = parent;
1633   region->entry = bb;
1634   region->type = type;
1635
1636   if (parent)
1637     {
1638       /* This is a nested region.  Add it to the list of inner
1639          regions in PARENT.  */
1640       region->next = parent->inner;
1641       parent->inner = region;
1642     }
1643   else
1644     {
1645       /* This is a toplevel region.  Add it to the list of toplevel
1646          regions in ROOT_OMP_REGION.  */
1647       region->next = root_omp_region;
1648       root_omp_region = region;
1649     }
1650
1651   return region;
1652 }
1653
1654 /* Release the memory associated with the region tree rooted at REGION.  */
1655
1656 static void
1657 free_omp_region_1 (struct omp_region *region)
1658 {
1659   struct omp_region *i, *n;
1660
1661   for (i = region->inner; i ; i = n)
1662     {
1663       n = i->next;
1664       free_omp_region_1 (i);
1665     }
1666
1667   free (region);
1668 }
1669
1670 /* Release the memory for the entire omp region tree.  */
1671
1672 void
1673 free_omp_regions (void)
1674 {
1675   struct omp_region *r, *n;
1676   for (r = root_omp_region; r ; r = n)
1677     {
1678       n = r->next;
1679       free_omp_region_1 (r);
1680     }
1681   root_omp_region = NULL;
1682 }
1683
1684
1685 /* Create a new context, with OUTER_CTX being the surrounding context.  */
1686
1687 static omp_context *
1688 new_omp_context (gimple *stmt, omp_context *outer_ctx)
1689 {
1690   omp_context *ctx = XCNEW (omp_context);
1691
1692   splay_tree_insert (all_contexts, (splay_tree_key) stmt,
1693                      (splay_tree_value) ctx);
1694   ctx->stmt = stmt;
1695
1696   if (outer_ctx)
1697     {
1698       ctx->outer = outer_ctx;
1699       ctx->cb = outer_ctx->cb;
1700       ctx->cb.block = NULL;
1701       ctx->depth = outer_ctx->depth + 1;
1702     }
1703   else
1704     {
1705       ctx->cb.src_fn = current_function_decl;
1706       ctx->cb.dst_fn = current_function_decl;
1707       ctx->cb.src_node = cgraph_node::get (current_function_decl);
1708       gcc_checking_assert (ctx->cb.src_node);
1709       ctx->cb.dst_node = ctx->cb.src_node;
1710       ctx->cb.src_cfun = cfun;
1711       ctx->cb.copy_decl = omp_copy_decl;
1712       ctx->cb.eh_lp_nr = 0;
1713       ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
1714       ctx->depth = 1;
1715     }
1716
1717   ctx->cb.decl_map = new hash_map<tree, tree>;
1718
1719   return ctx;
1720 }
1721
1722 static gimple_seq maybe_catch_exception (gimple_seq);
1723
1724 /* Finalize task copyfn.  */
1725
1726 static void
1727 finalize_task_copyfn (gomp_task *task_stmt)
1728 {
1729   struct function *child_cfun;
1730   tree child_fn;
1731   gimple_seq seq = NULL, new_seq;
1732   gbind *bind;
1733
1734   child_fn = gimple_omp_task_copy_fn (task_stmt);
1735   if (child_fn == NULL_TREE)
1736     return;
1737
1738   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
1739   DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
1740
1741   push_cfun (child_cfun);
1742   bind = gimplify_body (child_fn, false);
1743   gimple_seq_add_stmt (&seq, bind);
1744   new_seq = maybe_catch_exception (seq);
1745   if (new_seq != seq)
1746     {
1747       bind = gimple_build_bind (NULL, new_seq, NULL);
1748       seq = NULL;
1749       gimple_seq_add_stmt (&seq, bind);
1750     }
1751   gimple_set_body (child_fn, seq);
1752   pop_cfun ();
1753
1754   /* Inform the callgraph about the new function.  */
1755   cgraph_node *node = cgraph_node::get_create (child_fn);
1756   node->parallelized_function = 1;
1757   cgraph_node::add_new_function (child_fn, false);
1758 }
1759
1760 /* Destroy a omp_context data structures.  Called through the splay tree
1761    value delete callback.  */
1762
1763 static void
1764 delete_omp_context (splay_tree_value value)
1765 {
1766   omp_context *ctx = (omp_context *) value;
1767
1768   delete ctx->cb.decl_map;
1769
1770   if (ctx->field_map)
1771     splay_tree_delete (ctx->field_map);
1772   if (ctx->sfield_map)
1773     splay_tree_delete (ctx->sfield_map);
1774
1775   /* We hijacked DECL_ABSTRACT_ORIGIN earlier.  We need to clear it before
1776      it produces corrupt debug information.  */
1777   if (ctx->record_type)
1778     {
1779       tree t;
1780       for (t = TYPE_FIELDS (ctx->record_type); t ; t = DECL_CHAIN (t))
1781         DECL_ABSTRACT_ORIGIN (t) = NULL;
1782     }
1783   if (ctx->srecord_type)
1784     {
1785       tree t;
1786       for (t = TYPE_FIELDS (ctx->srecord_type); t ; t = DECL_CHAIN (t))
1787         DECL_ABSTRACT_ORIGIN (t) = NULL;
1788     }
1789
1790   if (is_task_ctx (ctx))
1791     finalize_task_copyfn (as_a <gomp_task *> (ctx->stmt));
1792
1793   XDELETE (ctx);
1794 }
1795
1796 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
1797    context.  */
1798
1799 static void
1800 fixup_child_record_type (omp_context *ctx)
1801 {
1802   tree f, type = ctx->record_type;
1803
1804   if (!ctx->receiver_decl)
1805     return;
1806   /* ??? It isn't sufficient to just call remap_type here, because
1807      variably_modified_type_p doesn't work the way we expect for
1808      record types.  Testing each field for whether it needs remapping
1809      and creating a new record by hand works, however.  */
1810   for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
1811     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
1812       break;
1813   if (f)
1814     {
1815       tree name, new_fields = NULL;
1816
1817       type = lang_hooks.types.make_type (RECORD_TYPE);
1818       name = DECL_NAME (TYPE_NAME (ctx->record_type));
1819       name = build_decl (DECL_SOURCE_LOCATION (ctx->receiver_decl),
1820                          TYPE_DECL, name, type);
1821       TYPE_NAME (type) = name;
1822
1823       for (f = TYPE_FIELDS (ctx->record_type); f ; f = DECL_CHAIN (f))
1824         {
1825           tree new_f = copy_node (f);
1826           DECL_CONTEXT (new_f) = type;
1827           TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
1828           DECL_CHAIN (new_f) = new_fields;
1829           walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &ctx->cb, NULL);
1830           walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r,
1831                      &ctx->cb, NULL);
1832           walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
1833                      &ctx->cb, NULL);
1834           new_fields = new_f;
1835
1836           /* Arrange to be able to look up the receiver field
1837              given the sender field.  */
1838           splay_tree_insert (ctx->field_map, (splay_tree_key) f,
1839                              (splay_tree_value) new_f);
1840         }
1841       TYPE_FIELDS (type) = nreverse (new_fields);
1842       layout_type (type);
1843     }
1844
1845   /* In a target region we never modify any of the pointers in *.omp_data_i,
1846      so attempt to help the optimizers.  */
1847   if (is_gimple_omp_offloaded (ctx->stmt))
1848     type = build_qualified_type (type, TYPE_QUAL_CONST);
1849
1850   TREE_TYPE (ctx->receiver_decl)
1851     = build_qualified_type (build_reference_type (type), TYPE_QUAL_RESTRICT);
1852 }
1853
1854 /* Instantiate decls as necessary in CTX to satisfy the data sharing
1855    specified by CLAUSES.  If BASE_POINTERS_RESTRICT, install var field with
1856    restrict.  */
1857
1858 static void
1859 scan_sharing_clauses (tree clauses, omp_context *ctx,
1860                       bool base_pointers_restrict = false)
1861 {
1862   tree c, decl;
1863   bool scan_array_reductions = false;
1864
1865   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1866     {
1867       bool by_ref;
1868
1869       switch (OMP_CLAUSE_CODE (c))
1870         {
1871         case OMP_CLAUSE_PRIVATE:
1872           decl = OMP_CLAUSE_DECL (c);
1873           if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
1874             goto do_private;
1875           else if (!is_variable_sized (decl))
1876             install_var_local (decl, ctx);
1877           break;
1878
1879         case OMP_CLAUSE_SHARED:
1880           decl = OMP_CLAUSE_DECL (c);
1881           /* Ignore shared directives in teams construct.  */
1882           if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
1883             {
1884               /* Global variables don't need to be copied,
1885                  the receiver side will use them directly.  */
1886               tree odecl = maybe_lookup_decl_in_outer_ctx (decl, ctx);
1887               if (is_global_var (odecl))
1888                 break;
1889               insert_decl_map (&ctx->cb, decl, odecl);
1890               break;
1891             }
1892           gcc_assert (is_taskreg_ctx (ctx));
1893           gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl))
1894                       || !is_variable_sized (decl));
1895           /* Global variables don't need to be copied,
1896              the receiver side will use them directly.  */
1897           if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1898             break;
1899           if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
1900             {
1901               use_pointer_for_field (decl, ctx);
1902               break;
1903             }
1904           by_ref = use_pointer_for_field (decl, NULL);
1905           if ((! TREE_READONLY (decl) && !OMP_CLAUSE_SHARED_READONLY (c))
1906               || TREE_ADDRESSABLE (decl)
1907               || by_ref
1908               || is_reference (decl))
1909             {
1910               by_ref = use_pointer_for_field (decl, ctx);
1911               install_var_field (decl, by_ref, 3, ctx);
1912               install_var_local (decl, ctx);
1913               break;
1914             }
1915           /* We don't need to copy const scalar vars back.  */
1916           OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
1917           goto do_private;
1918
1919         case OMP_CLAUSE_REDUCTION:
1920           decl = OMP_CLAUSE_DECL (c);
1921           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1922               && TREE_CODE (decl) == MEM_REF)
1923             {
1924               tree t = TREE_OPERAND (decl, 0);
1925               if (TREE_CODE (t) == POINTER_PLUS_EXPR)
1926                 t = TREE_OPERAND (t, 0);
1927               if (TREE_CODE (t) == INDIRECT_REF
1928                   || TREE_CODE (t) == ADDR_EXPR)
1929                 t = TREE_OPERAND (t, 0);
1930               install_var_local (t, ctx);
1931               if (is_taskreg_ctx (ctx)
1932                   && !is_global_var (maybe_lookup_decl_in_outer_ctx (t, ctx))
1933                   && !is_variable_sized (t))
1934                 {
1935                   by_ref = use_pointer_for_field (t, ctx);
1936                   install_var_field (t, by_ref, 3, ctx);
1937                 }
1938               break;
1939             }
1940           goto do_private;
1941
1942         case OMP_CLAUSE_LASTPRIVATE:
1943           /* Let the corresponding firstprivate clause create
1944              the variable.  */
1945           if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1946             break;
1947           /* FALLTHRU */
1948
1949         case OMP_CLAUSE_FIRSTPRIVATE:
1950         case OMP_CLAUSE_LINEAR:
1951           decl = OMP_CLAUSE_DECL (c);
1952         do_private:
1953           if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
1954                || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR)
1955               && is_gimple_omp_offloaded (ctx->stmt))
1956             {
1957               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
1958                 install_var_field (decl, !is_reference (decl), 3, ctx);
1959               else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
1960                 install_var_field (decl, true, 3, ctx);
1961               else
1962                 install_var_field (decl, false, 3, ctx);
1963             }
1964           if (is_variable_sized (decl))
1965             {
1966               if (is_task_ctx (ctx))
1967                 install_var_field (decl, false, 1, ctx);
1968               break;
1969             }
1970           else if (is_taskreg_ctx (ctx))
1971             {
1972               bool global
1973                 = is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx));
1974               by_ref = use_pointer_for_field (decl, NULL);
1975
1976               if (is_task_ctx (ctx)
1977                   && (global || by_ref || is_reference (decl)))
1978                 {
1979                   install_var_field (decl, false, 1, ctx);
1980                   if (!global)
1981                     install_var_field (decl, by_ref, 2, ctx);
1982                 }
1983               else if (!global)
1984                 install_var_field (decl, by_ref, 3, ctx);
1985             }
1986           install_var_local (decl, ctx);
1987           break;
1988
1989         case OMP_CLAUSE_USE_DEVICE_PTR:
1990           decl = OMP_CLAUSE_DECL (c);
1991           if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
1992             install_var_field (decl, true, 3, ctx);
1993           else
1994             install_var_field (decl, false, 3, ctx);
1995           if (DECL_SIZE (decl)
1996               && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
1997             {
1998               tree decl2 = DECL_VALUE_EXPR (decl);
1999               gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
2000               decl2 = TREE_OPERAND (decl2, 0);
2001               gcc_assert (DECL_P (decl2));
2002               install_var_local (decl2, ctx);
2003             }
2004           install_var_local (decl, ctx);
2005           break;
2006
2007         case OMP_CLAUSE_IS_DEVICE_PTR:
2008           decl = OMP_CLAUSE_DECL (c);
2009           goto do_private;
2010
2011         case OMP_CLAUSE__LOOPTEMP_:
2012           gcc_assert (is_taskreg_ctx (ctx));
2013           decl = OMP_CLAUSE_DECL (c);
2014           install_var_field (decl, false, 3, ctx);
2015           install_var_local (decl, ctx);
2016           break;
2017
2018         case OMP_CLAUSE_COPYPRIVATE:
2019         case OMP_CLAUSE_COPYIN:
2020           decl = OMP_CLAUSE_DECL (c);
2021           by_ref = use_pointer_for_field (decl, NULL);
2022           install_var_field (decl, by_ref, 3, ctx);
2023           break;
2024
2025         case OMP_CLAUSE_DEFAULT:
2026           ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
2027           break;
2028
2029         case OMP_CLAUSE_FINAL:
2030         case OMP_CLAUSE_IF:
2031         case OMP_CLAUSE_NUM_THREADS:
2032         case OMP_CLAUSE_NUM_TEAMS:
2033         case OMP_CLAUSE_THREAD_LIMIT:
2034         case OMP_CLAUSE_DEVICE:
2035         case OMP_CLAUSE_SCHEDULE:
2036         case OMP_CLAUSE_DIST_SCHEDULE:
2037         case OMP_CLAUSE_DEPEND:
2038         case OMP_CLAUSE_PRIORITY:
2039         case OMP_CLAUSE_GRAINSIZE:
2040         case OMP_CLAUSE_NUM_TASKS:
2041         case OMP_CLAUSE__CILK_FOR_COUNT_:
2042         case OMP_CLAUSE_NUM_GANGS:
2043         case OMP_CLAUSE_NUM_WORKERS:
2044         case OMP_CLAUSE_VECTOR_LENGTH:
2045           if (ctx->outer)
2046             scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
2047           break;
2048
2049         case OMP_CLAUSE_TO:
2050         case OMP_CLAUSE_FROM:
2051         case OMP_CLAUSE_MAP:
2052           if (ctx->outer)
2053             scan_omp_op (&OMP_CLAUSE_SIZE (c), ctx->outer);
2054           decl = OMP_CLAUSE_DECL (c);
2055           /* Global variables with "omp declare target" attribute
2056              don't need to be copied, the receiver side will use them
2057              directly.  However, global variables with "omp declare target link"
2058              attribute need to be copied.  */
2059           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
2060               && DECL_P (decl)
2061               && ((OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
2062                    && (OMP_CLAUSE_MAP_KIND (c)
2063                        != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
2064                   || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
2065               && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
2066               && varpool_node::get_create (decl)->offloadable
2067               && !lookup_attribute ("omp declare target link",
2068                                     DECL_ATTRIBUTES (decl)))
2069             break;
2070           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
2071               && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER)
2072             {
2073               /* Ignore GOMP_MAP_POINTER kind for arrays in regions that are
2074                  not offloaded; there is nothing to map for those.  */
2075               if (!is_gimple_omp_offloaded (ctx->stmt)
2076                   && !POINTER_TYPE_P (TREE_TYPE (decl))
2077                   && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
2078                 break;
2079             }
2080           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
2081               && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
2082                   || (OMP_CLAUSE_MAP_KIND (c)
2083                       == GOMP_MAP_FIRSTPRIVATE_REFERENCE)))
2084             {
2085               if (TREE_CODE (decl) == COMPONENT_REF
2086                   || (TREE_CODE (decl) == INDIRECT_REF
2087                       && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
2088                       && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
2089                           == REFERENCE_TYPE)))
2090                 break;
2091               if (DECL_SIZE (decl)
2092                   && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
2093                 {
2094                   tree decl2 = DECL_VALUE_EXPR (decl);
2095                   gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
2096                   decl2 = TREE_OPERAND (decl2, 0);
2097                   gcc_assert (DECL_P (decl2));
2098                   install_var_local (decl2, ctx);
2099                 }
2100               install_var_local (decl, ctx);
2101               break;
2102             }
2103           if (DECL_P (decl))
2104             {
2105               if (DECL_SIZE (decl)
2106                   && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
2107                 {
2108                   tree decl2 = DECL_VALUE_EXPR (decl);
2109                   gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
2110                   decl2 = TREE_OPERAND (decl2, 0);
2111                   gcc_assert (DECL_P (decl2));
2112                   install_var_field (decl2, true, 3, ctx);
2113                   install_var_local (decl2, ctx);
2114                   install_var_local (decl, ctx);
2115                 }
2116               else
2117                 {
2118                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
2119                       && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
2120                       && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
2121                       && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
2122                     install_var_field (decl, true, 7, ctx);
2123                   else
2124                     install_var_field (decl, true, 3, ctx,
2125                                        base_pointers_restrict);
2126                   if (is_gimple_omp_offloaded (ctx->stmt)
2127                       && !OMP_CLAUSE_MAP_IN_REDUCTION (c))
2128                     install_var_local (decl, ctx);
2129                 }
2130             }
2131           else
2132             {
2133               tree base = get_base_address (decl);
2134               tree nc = OMP_CLAUSE_CHAIN (c);
2135               if (DECL_P (base)
2136                   && nc != NULL_TREE
2137                   && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
2138                   && OMP_CLAUSE_DECL (nc) == base
2139                   && OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_POINTER
2140                   && integer_zerop (OMP_CLAUSE_SIZE (nc)))
2141                 {
2142                   OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c) = 1;
2143                   OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (nc) = 1;
2144                 }
2145               else
2146                 {
2147                   if (ctx->outer)
2148                     {
2149                       scan_omp_op (&OMP_CLAUSE_DECL (c), ctx->outer);
2150                       decl = OMP_CLAUSE_DECL (c);
2151                     }
2152                   gcc_assert (!splay_tree_lookup (ctx->field_map,
2153                                                   (splay_tree_key) decl));
2154                   tree field
2155                     = build_decl (OMP_CLAUSE_LOCATION (c),
2156                                   FIELD_DECL, NULL_TREE, ptr_type_node);
2157                   SET_DECL_ALIGN (field, TYPE_ALIGN (ptr_type_node));
2158                   insert_field_into_struct (ctx->record_type, field);
2159                   splay_tree_insert (ctx->field_map, (splay_tree_key) decl,
2160                                      (splay_tree_value) field);
2161                 }
2162             }
2163           break;
2164
2165         case OMP_CLAUSE__GRIDDIM_:
2166           if (ctx->outer)
2167             {
2168               scan_omp_op (&OMP_CLAUSE__GRIDDIM__SIZE (c), ctx->outer);
2169               scan_omp_op (&OMP_CLAUSE__GRIDDIM__GROUP (c), ctx->outer);
2170             }
2171           break;
2172
2173         case OMP_CLAUSE_NOWAIT:
2174         case OMP_CLAUSE_ORDERED:
2175         case OMP_CLAUSE_COLLAPSE:
2176         case OMP_CLAUSE_UNTIED:
2177         case OMP_CLAUSE_MERGEABLE:
2178         case OMP_CLAUSE_PROC_BIND:
2179         case OMP_CLAUSE_SAFELEN:
2180         case OMP_CLAUSE_SIMDLEN:
2181         case OMP_CLAUSE_THREADS:
2182         case OMP_CLAUSE_SIMD:
2183         case OMP_CLAUSE_NOGROUP:
2184         case OMP_CLAUSE_DEFAULTMAP:
2185         case OMP_CLAUSE_ASYNC:
2186         case OMP_CLAUSE_WAIT:
2187         case OMP_CLAUSE_GANG:
2188         case OMP_CLAUSE_WORKER:
2189         case OMP_CLAUSE_VECTOR:
2190         case OMP_CLAUSE_INDEPENDENT:
2191         case OMP_CLAUSE_AUTO:
2192         case OMP_CLAUSE_SEQ:
2193           break;
2194
2195         case OMP_CLAUSE_ALIGNED:
2196           decl = OMP_CLAUSE_DECL (c);
2197           if (is_global_var (decl)
2198               && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
2199             install_var_local (decl, ctx);
2200           break;
2201
2202         case OMP_CLAUSE_TILE:
2203         case OMP_CLAUSE__CACHE_:
2204         default:
2205           gcc_unreachable ();
2206         }
2207     }
2208
2209   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
2210     {
2211       switch (OMP_CLAUSE_CODE (c))
2212         {
2213         case OMP_CLAUSE_LASTPRIVATE:
2214           /* Let the corresponding firstprivate clause create
2215              the variable.  */
2216           if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
2217             scan_array_reductions = true;
2218           if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2219             break;
2220           /* FALLTHRU */
2221
2222         case OMP_CLAUSE_FIRSTPRIVATE:
2223         case OMP_CLAUSE_PRIVATE:
2224         case OMP_CLAUSE_LINEAR:
2225         case OMP_CLAUSE_IS_DEVICE_PTR:
2226           decl = OMP_CLAUSE_DECL (c);
2227           if (is_variable_sized (decl))
2228             {
2229               if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
2230                    || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR)
2231                   && is_gimple_omp_offloaded (ctx->stmt))
2232                 {
2233                   tree decl2 = DECL_VALUE_EXPR (decl);
2234                   gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
2235                   decl2 = TREE_OPERAND (decl2, 0);
2236                   gcc_assert (DECL_P (decl2));
2237                   install_var_local (decl2, ctx);
2238                   fixup_remapped_decl (decl2, ctx, false);
2239                 }
2240               install_var_local (decl, ctx);
2241             }
2242           fixup_remapped_decl (decl, ctx,
2243                                OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
2244                                && OMP_CLAUSE_PRIVATE_DEBUG (c));
2245           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
2246               && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
2247             scan_array_reductions = true;
2248           break;
2249
2250         case OMP_CLAUSE_REDUCTION:
2251           decl = OMP_CLAUSE_DECL (c);
2252           if (TREE_CODE (decl) != MEM_REF)
2253             {
2254               if (is_variable_sized (decl))
2255                 install_var_local (decl, ctx);
2256               fixup_remapped_decl (decl, ctx, false);
2257             }
2258           if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2259             scan_array_reductions = true;
2260           break;
2261
2262         case OMP_CLAUSE_SHARED:
2263           /* Ignore shared directives in teams construct.  */
2264           if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
2265             break;
2266           decl = OMP_CLAUSE_DECL (c);
2267           if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
2268             break;
2269           if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
2270             {
2271               if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl,
2272                                                                  ctx->outer)))
2273                 break;
2274               bool by_ref = use_pointer_for_field (decl, ctx);
2275               install_var_field (decl, by_ref, 11, ctx);
2276               break;
2277             }
2278           fixup_remapped_decl (decl, ctx, false);
2279           break;
2280
2281         case OMP_CLAUSE_MAP:
2282           if (!is_gimple_omp_offloaded (ctx->stmt))
2283             break;
2284           decl = OMP_CLAUSE_DECL (c);
2285           if (DECL_P (decl)
2286               && ((OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
2287                    && (OMP_CLAUSE_MAP_KIND (c)
2288                        != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
2289                   || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
2290               && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
2291               && varpool_node::get_create (decl)->offloadable)
2292             break;
2293           if (DECL_P (decl))
2294             {
2295               if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
2296                    || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
2297                   && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
2298                   && !COMPLETE_TYPE_P (TREE_TYPE (decl)))
2299                 {
2300                   tree new_decl = lookup_decl (decl, ctx);
2301                   TREE_TYPE (new_decl)
2302                     = remap_type (TREE_TYPE (decl), &ctx->cb);
2303                 }
2304               else if (DECL_SIZE (decl)
2305                        && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
2306                 {
2307                   tree decl2 = DECL_VALUE_EXPR (decl);
2308                   gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
2309                   decl2 = TREE_OPERAND (decl2, 0);
2310                   gcc_assert (DECL_P (decl2));
2311                   fixup_remapped_decl (decl2, ctx, false);
2312                   fixup_remapped_decl (decl, ctx, true);
2313                 }
2314               else
2315                 fixup_remapped_decl (decl, ctx, false);
2316             }
2317           break;
2318
2319         case OMP_CLAUSE_COPYPRIVATE:
2320         case OMP_CLAUSE_COPYIN:
2321         case OMP_CLAUSE_DEFAULT:
2322         case OMP_CLAUSE_IF:
2323         case OMP_CLAUSE_NUM_THREADS:
2324         case OMP_CLAUSE_NUM_TEAMS:
2325         case OMP_CLAUSE_THREAD_LIMIT:
2326         case OMP_CLAUSE_DEVICE:
2327         case OMP_CLAUSE_SCHEDULE:
2328         case OMP_CLAUSE_DIST_SCHEDULE:
2329         case OMP_CLAUSE_NOWAIT:
2330         case OMP_CLAUSE_ORDERED:
2331         case OMP_CLAUSE_COLLAPSE:
2332         case OMP_CLAUSE_UNTIED:
2333         case OMP_CLAUSE_FINAL:
2334         case OMP_CLAUSE_MERGEABLE:
2335         case OMP_CLAUSE_PROC_BIND:
2336         case OMP_CLAUSE_SAFELEN:
2337         case OMP_CLAUSE_SIMDLEN:
2338         case OMP_CLAUSE_ALIGNED:
2339         case OMP_CLAUSE_DEPEND:
2340         case OMP_CLAUSE__LOOPTEMP_:
2341         case OMP_CLAUSE_TO:
2342         case OMP_CLAUSE_FROM:
2343         case OMP_CLAUSE_PRIORITY:
2344         case OMP_CLAUSE_GRAINSIZE:
2345         case OMP_CLAUSE_NUM_TASKS:
2346         case OMP_CLAUSE_THREADS:
2347         case OMP_CLAUSE_SIMD:
2348         case OMP_CLAUSE_NOGROUP:
2349         case OMP_CLAUSE_DEFAULTMAP:
2350         case OMP_CLAUSE_USE_DEVICE_PTR:
2351         case OMP_CLAUSE__CILK_FOR_COUNT_:
2352         case OMP_CLAUSE_ASYNC:
2353         case OMP_CLAUSE_WAIT:
2354         case OMP_CLAUSE_NUM_GANGS:
2355         case OMP_CLAUSE_NUM_WORKERS:
2356         case OMP_CLAUSE_VECTOR_LENGTH:
2357         case OMP_CLAUSE_GANG:
2358         case OMP_CLAUSE_WORKER:
2359         case OMP_CLAUSE_VECTOR:
2360         case OMP_CLAUSE_INDEPENDENT:
2361         case OMP_CLAUSE_AUTO:
2362         case OMP_CLAUSE_SEQ:
2363         case OMP_CLAUSE__GRIDDIM_:
2364           break;
2365
2366         case OMP_CLAUSE_TILE:
2367         case OMP_CLAUSE__CACHE_:
2368         default:
2369           gcc_unreachable ();
2370         }
2371     }
2372
2373   gcc_checking_assert (!scan_array_reductions
2374                        || !is_gimple_omp_oacc (ctx->stmt));
2375   if (scan_array_reductions)
2376     {
2377       for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
2378         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
2379             && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2380           {
2381             scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
2382             scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
2383           }
2384         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
2385                  && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
2386           scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
2387         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
2388                  && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
2389           scan_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
2390     }
2391 }
2392
2393 /* Create a new name for omp child function.  Returns an identifier.  If
2394    IS_CILK_FOR is true then the suffix for the child function is
2395    "_cilk_for_fn."  */
2396
2397 static tree
2398 create_omp_child_function_name (bool task_copy, bool is_cilk_for)
2399 {
2400   if (is_cilk_for)
2401     return clone_function_name (current_function_decl, "_cilk_for_fn");
2402   return clone_function_name (current_function_decl,
2403                               task_copy ? "_omp_cpyfn" : "_omp_fn");
2404 }
2405
2406 /* Returns the type of the induction variable for the child function for
2407    _Cilk_for and the types for _high and _low variables based on TYPE.  */
2408
2409 static tree
2410 cilk_for_check_loop_diff_type (tree type)
2411 {
2412   if (TYPE_PRECISION (type) <= TYPE_PRECISION (uint32_type_node))
2413     {
2414       if (TYPE_UNSIGNED (type))
2415         return uint32_type_node;
2416       else
2417         return integer_type_node;
2418     }
2419   else
2420     {
2421       if (TYPE_UNSIGNED (type))
2422         return uint64_type_node;
2423       else
2424         return long_long_integer_type_node;
2425     }
2426 }
2427
2428 /* Build a decl for the omp child function.  It'll not contain a body
2429    yet, just the bare decl.  */
2430
2431 static void
2432 create_omp_child_function (omp_context *ctx, bool task_copy)
2433 {
2434   tree decl, type, name, t;
2435
2436   tree cilk_for_count
2437     = (flag_cilkplus && gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
2438       ? find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2439                          OMP_CLAUSE__CILK_FOR_COUNT_) : NULL_TREE;
2440   tree cilk_var_type = NULL_TREE;
2441
2442   name = create_omp_child_function_name (task_copy,
2443                                          cilk_for_count != NULL_TREE);
2444   if (task_copy)
2445     type = build_function_type_list (void_type_node, ptr_type_node,
2446                                      ptr_type_node, NULL_TREE);
2447   else if (cilk_for_count)
2448     {
2449       type = TREE_TYPE (OMP_CLAUSE_OPERAND (cilk_for_count, 0));
2450       cilk_var_type = cilk_for_check_loop_diff_type (type);
2451       type = build_function_type_list (void_type_node, ptr_type_node,
2452                                        cilk_var_type, cilk_var_type, NULL_TREE);
2453     }
2454   else
2455     type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
2456
2457   decl = build_decl (gimple_location (ctx->stmt), FUNCTION_DECL, name, type);
2458
2459   gcc_checking_assert (!is_gimple_omp_oacc (ctx->stmt)
2460                        || !task_copy);
2461   if (!task_copy)
2462     ctx->cb.dst_fn = decl;
2463   else
2464     gimple_omp_task_set_copy_fn (ctx->stmt, decl);
2465
2466   TREE_STATIC (decl) = 1;
2467   TREE_USED (decl) = 1;
2468   DECL_ARTIFICIAL (decl) = 1;
2469   DECL_IGNORED_P (decl) = 0;
2470   TREE_PUBLIC (decl) = 0;
2471   DECL_UNINLINABLE (decl) = 1;
2472   DECL_EXTERNAL (decl) = 0;
2473   DECL_CONTEXT (decl) = NULL_TREE;
2474   DECL_INITIAL (decl) = make_node (BLOCK);
2475   if (cgraph_node::get (current_function_decl)->offloadable)
2476     cgraph_node::get_create (decl)->offloadable = 1;
2477   else
2478     {
2479       omp_context *octx;
2480       for (octx = ctx; octx; octx = octx->outer)
2481         if (is_gimple_omp_offloaded (octx->stmt))
2482           {
2483             cgraph_node::get_create (decl)->offloadable = 1;
2484             if (ENABLE_OFFLOADING)
2485               g->have_offload = true;
2486
2487             break;
2488           }
2489     }
2490
2491   if (cgraph_node::get_create (decl)->offloadable
2492       && !lookup_attribute ("omp declare target",
2493                            DECL_ATTRIBUTES (current_function_decl)))
2494     DECL_ATTRIBUTES (decl)
2495       = tree_cons (get_identifier ("omp target entrypoint"),
2496                    NULL_TREE, DECL_ATTRIBUTES (decl));
2497
2498   t = build_decl (DECL_SOURCE_LOCATION (decl),
2499                   RESULT_DECL, NULL_TREE, void_type_node);
2500   DECL_ARTIFICIAL (t) = 1;
2501   DECL_IGNORED_P (t) = 1;
2502   DECL_CONTEXT (t) = decl;
2503   DECL_RESULT (decl) = t;
2504
2505   /* _Cilk_for's child function requires two extra parameters called
2506      __low and __high that are set the by Cilk runtime when it calls this
2507      function.  */
2508   if (cilk_for_count)
2509     {
2510       t = build_decl (DECL_SOURCE_LOCATION (decl),
2511                       PARM_DECL, get_identifier ("__high"), cilk_var_type);
2512       DECL_ARTIFICIAL (t) = 1;
2513       DECL_NAMELESS (t) = 1;
2514       DECL_ARG_TYPE (t) = ptr_type_node;
2515       DECL_CONTEXT (t) = current_function_decl;
2516       TREE_USED (t) = 1;
2517       DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
2518       DECL_ARGUMENTS (decl) = t;
2519
2520       t = build_decl (DECL_SOURCE_LOCATION (decl),
2521                       PARM_DECL, get_identifier ("__low"), cilk_var_type);
2522       DECL_ARTIFICIAL (t) = 1;
2523       DECL_NAMELESS (t) = 1;
2524       DECL_ARG_TYPE (t) = ptr_type_node;
2525       DECL_CONTEXT (t) = current_function_decl;
2526       TREE_USED (t) = 1;
2527       DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
2528       DECL_ARGUMENTS (decl) = t;
2529     }
2530
2531   tree data_name = get_identifier (".omp_data_i");
2532   t = build_decl (DECL_SOURCE_LOCATION (decl), PARM_DECL, data_name,
2533                   ptr_type_node);
2534   DECL_ARTIFICIAL (t) = 1;
2535   DECL_NAMELESS (t) = 1;
2536   DECL_ARG_TYPE (t) = ptr_type_node;
2537   DECL_CONTEXT (t) = current_function_decl;
2538   TREE_USED (t) = 1;
2539   TREE_READONLY (t) = 1;
2540   if (cilk_for_count)
2541     DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
2542   DECL_ARGUMENTS (decl) = t;
2543   if (!task_copy)
2544     ctx->receiver_decl = t;
2545   else
2546     {
2547       t = build_decl (DECL_SOURCE_LOCATION (decl),
2548                       PARM_DECL, get_identifier (".omp_data_o"),
2549                       ptr_type_node);
2550       DECL_ARTIFICIAL (t) = 1;
2551       DECL_NAMELESS (t) = 1;
2552       DECL_ARG_TYPE (t) = ptr_type_node;
2553       DECL_CONTEXT (t) = current_function_decl;
2554       TREE_USED (t) = 1;
2555       TREE_ADDRESSABLE (t) = 1;
2556       DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
2557       DECL_ARGUMENTS (decl) = t;
2558     }
2559
2560   /* Allocate memory for the function structure.  The call to
2561      allocate_struct_function clobbers CFUN, so we need to restore
2562      it afterward.  */
2563   push_struct_function (decl);
2564   cfun->function_end_locus = gimple_location (ctx->stmt);
2565   init_tree_ssa (cfun);
2566   pop_cfun ();
2567 }
2568
2569 /* Callback for walk_gimple_seq.  Check if combined parallel
2570    contains gimple_omp_for_combined_into_p OMP_FOR.  */
2571
2572 static tree
2573 find_combined_for (gimple_stmt_iterator *gsi_p,
2574                    bool *handled_ops_p,
2575                    struct walk_stmt_info *wi)
2576 {
2577   gimple *stmt = gsi_stmt (*gsi_p);
2578
2579   *handled_ops_p = true;
2580   switch (gimple_code (stmt))
2581     {
2582     WALK_SUBSTMTS;
2583
2584     case GIMPLE_OMP_FOR:
2585       if (gimple_omp_for_combined_into_p (stmt)
2586           && gimple_omp_for_kind (stmt)
2587              == *(const enum gf_mask *) (wi->info))
2588         {
2589           wi->info = stmt;
2590           return integer_zero_node;
2591         }
2592       break;
2593     default:
2594       break;
2595     }
2596   return NULL;
2597 }
2598
2599 /* Add _LOOPTEMP_ clauses on OpenMP parallel or task.  */
2600
2601 static void
2602 add_taskreg_looptemp_clauses (enum gf_mask msk, gimple *stmt,
2603                               omp_context *outer_ctx)
2604 {
2605   struct walk_stmt_info wi;
2606
2607   memset (&wi, 0, sizeof (wi));
2608   wi.val_only = true;
2609   wi.info = (void *) &msk;
2610   walk_gimple_seq (gimple_omp_body (stmt), find_combined_for, NULL, &wi);
2611   if (wi.info != (void *) &msk)
2612     {
2613       gomp_for *for_stmt = as_a <gomp_for *> ((gimple *) wi.info);
2614       struct omp_for_data fd;
2615       extract_omp_for_data (for_stmt, &fd, NULL);
2616       /* We need two temporaries with fd.loop.v type (istart/iend)
2617          and then (fd.collapse - 1) temporaries with the same
2618          type for count2 ... countN-1 vars if not constant.  */
2619       size_t count = 2, i;
2620       tree type = fd.iter_type;
2621       if (fd.collapse > 1
2622           && TREE_CODE (fd.loop.n2) != INTEGER_CST)
2623         {
2624           count += fd.collapse - 1;
2625           /* If there are lastprivate clauses on the inner
2626              GIMPLE_OMP_FOR, add one more temporaries for the total number
2627              of iterations (product of count1 ... countN-1).  */
2628           if (find_omp_clause (gimple_omp_for_clauses (for_stmt),
2629                                OMP_CLAUSE_LASTPRIVATE))
2630             count++;
2631           else if (msk == GF_OMP_FOR_KIND_FOR
2632                    && find_omp_clause (gimple_omp_parallel_clauses (stmt),
2633                                        OMP_CLAUSE_LASTPRIVATE))
2634             count++;
2635         }
2636       for (i = 0; i < count; i++)
2637         {
2638           tree temp = create_tmp_var (type);
2639           tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__LOOPTEMP_);
2640           insert_decl_map (&outer_ctx->cb, temp, temp);
2641           OMP_CLAUSE_DECL (c) = temp;
2642           OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
2643           gimple_omp_taskreg_set_clauses (stmt, c);
2644         }
2645     }
2646 }
2647
2648 /* Scan an OpenMP parallel directive.  */
2649
2650 static void
2651 scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
2652 {
2653   omp_context *ctx;
2654   tree name;
2655   gomp_parallel *stmt = as_a <gomp_parallel *> (gsi_stmt (*gsi));
2656
2657   /* Ignore parallel directives with empty bodies, unless there
2658      are copyin clauses.  */
2659   if (optimize > 0
2660       && empty_body_p (gimple_omp_body (stmt))
2661       && find_omp_clause (gimple_omp_parallel_clauses (stmt),
2662                           OMP_CLAUSE_COPYIN) == NULL)
2663     {
2664       gsi_replace (gsi, gimple_build_nop (), false);
2665       return;
2666     }
2667
2668   if (gimple_omp_parallel_combined_p (stmt))
2669     add_taskreg_looptemp_clauses (GF_OMP_FOR_KIND_FOR, stmt, outer_ctx);
2670
2671   ctx = new_omp_context (stmt, outer_ctx);
2672   taskreg_contexts.safe_push (ctx);
2673   if (taskreg_nesting_level > 1)
2674     ctx->is_nested = true;
2675   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
2676   ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
2677   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
2678   name = create_tmp_var_name (".omp_data_s");
2679   name = build_decl (gimple_location (stmt),
2680                      TYPE_DECL, name, ctx->record_type);
2681   DECL_ARTIFICIAL (name) = 1;
2682   DECL_NAMELESS (name) = 1;
2683   TYPE_NAME (ctx->record_type) = name;
2684   TYPE_ARTIFICIAL (ctx->record_type) = 1;
2685   if (!gimple_omp_parallel_grid_phony (stmt))
2686     {
2687       create_omp_child_function (ctx, false);
2688       gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
2689     }
2690
2691   scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
2692   scan_omp (gimple_omp_body_ptr (stmt), ctx);
2693
2694   if (TYPE_FIELDS (ctx->record_type) == NULL)
2695     ctx->record_type = ctx->receiver_decl = NULL;
2696 }
2697
2698 /* Scan an OpenMP task directive.  */
2699
2700 static void
2701 scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
2702 {
2703   omp_context *ctx;
2704   tree name, t;
2705   gomp_task *stmt = as_a <gomp_task *> (gsi_stmt (*gsi));
2706
2707   /* Ignore task directives with empty bodies.  */
2708   if (optimize > 0
2709       && empty_body_p (gimple_omp_body (stmt)))
2710     {
2711       gsi_replace (gsi, gimple_build_nop (), false);
2712       return;
2713     }
2714
2715   if (gimple_omp_task_taskloop_p (stmt))
2716     add_taskreg_looptemp_clauses (GF_OMP_FOR_KIND_TASKLOOP, stmt, outer_ctx);
2717
2718   ctx = new_omp_context (stmt, outer_ctx);
2719   taskreg_contexts.safe_push (ctx);
2720   if (taskreg_nesting_level > 1)
2721     ctx->is_nested = true;
2722   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
2723   ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
2724   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
2725   name = create_tmp_var_name (".omp_data_s");
2726   name = build_decl (gimple_location (stmt),
2727                      TYPE_DECL, name, ctx->record_type);
2728   DECL_ARTIFICIAL (name) = 1;
2729   DECL_NAMELESS (name) = 1;
2730   TYPE_NAME (ctx->record_type) = name;
2731   TYPE_ARTIFICIAL (ctx->record_type) = 1;
2732   create_omp_child_function (ctx, false);
2733   gimple_omp_task_set_child_fn (stmt, ctx->cb.dst_fn);
2734
2735   scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);
2736
2737   if (ctx->srecord_type)
2738     {
2739       name = create_tmp_var_name (".omp_data_a");
2740       name = build_decl (gimple_location (stmt),
2741                          TYPE_DECL, name, ctx->srecord_type);
2742       DECL_ARTIFICIAL (name) = 1;
2743       DECL_NAMELESS (name) = 1;
2744       TYPE_NAME (ctx->srecord_type) = name;
2745       TYPE_ARTIFICIAL (ctx->srecord_type) = 1;
2746       create_omp_child_function (ctx, true);
2747     }
2748
2749   scan_omp (gimple_omp_body_ptr (stmt), ctx);
2750
2751   if (TYPE_FIELDS (ctx->record_type) == NULL)
2752     {
2753       ctx->record_type = ctx->receiver_decl = NULL;
2754       t = build_int_cst (long_integer_type_node, 0);
2755       gimple_omp_task_set_arg_size (stmt, t);
2756       t = build_int_cst (long_integer_type_node, 1);
2757       gimple_omp_task_set_arg_align (stmt, t);
2758     }
2759 }
2760
2761
2762 /* If any decls have been made addressable during scan_omp,
2763    adjust their fields if needed, and layout record types
2764    of parallel/task constructs.  */
2765
2766 static void
2767 finish_taskreg_scan (omp_context *ctx)
2768 {
2769   if (ctx->record_type == NULL_TREE)
2770     return;
2771
2772   /* If any task_shared_vars were needed, verify all
2773      OMP_CLAUSE_SHARED clauses on GIMPLE_OMP_{PARALLEL,TASK}
2774      statements if use_pointer_for_field hasn't changed
2775      because of that.  If it did, update field types now.  */
2776   if (task_shared_vars)
2777     {
2778       tree c;
2779
2780       for (c = gimple_omp_taskreg_clauses (ctx->stmt);
2781            c; c = OMP_CLAUSE_CHAIN (c))
2782         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
2783             && !OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
2784           {
2785             tree decl = OMP_CLAUSE_DECL (c);
2786
2787             /* Global variables don't need to be copied,
2788                the receiver side will use them directly.  */
2789             if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
2790               continue;
2791             if (!bitmap_bit_p (task_shared_vars, DECL_UID (decl))
2792                 || !use_pointer_for_field (decl, ctx))
2793               continue;
2794             tree field = lookup_field (decl, ctx);
2795             if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE
2796                 && TREE_TYPE (TREE_TYPE (field)) == TREE_TYPE (decl))
2797               continue;
2798             TREE_TYPE (field) = build_pointer_type (TREE_TYPE (decl));
2799             TREE_THIS_VOLATILE (field) = 0;
2800             DECL_USER_ALIGN (field) = 0;
2801             SET_DECL_ALIGN (field, TYPE_ALIGN (TREE_TYPE (field)));
2802             if (TYPE_ALIGN (ctx->record_type) < DECL_ALIGN (field))
2803               SET_TYPE_ALIGN (ctx->record_type, DECL_ALIGN (field));
2804             if (ctx->srecord_type)
2805               {
2806                 tree sfield = lookup_sfield (decl, ctx);
2807                 TREE_TYPE (sfield) = TREE_TYPE (field);
2808                 TREE_THIS_VOLATILE (sfield) = 0;
2809                 DECL_USER_ALIGN (sfield) = 0;
2810                 SET_DECL_ALIGN (sfield, DECL_ALIGN (field));
2811                 if (TYPE_ALIGN (ctx->srecord_type) < DECL_ALIGN (sfield))
2812                   SET_TYPE_ALIGN (ctx->srecord_type, DECL_ALIGN (sfield));
2813               }
2814           }
2815     }
2816
2817   if (gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
2818     {
2819       layout_type (ctx->record_type);
2820       fixup_child_record_type (ctx);
2821     }
2822   else
2823     {
2824       location_t loc = gimple_location (ctx->stmt);
2825       tree *p, vla_fields = NULL_TREE, *q = &vla_fields;
2826       /* Move VLA fields to the end.  */
2827       p = &TYPE_FIELDS (ctx->record_type);
2828       while (*p)
2829         if (!TYPE_SIZE_UNIT (TREE_TYPE (*p))
2830             || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p))))
2831           {
2832             *q = *p;
2833             *p = TREE_CHAIN (*p);
2834             TREE_CHAIN (*q) = NULL_TREE;
2835             q = &TREE_CHAIN (*q);
2836           }
2837         else
2838           p = &DECL_CHAIN (*p);
2839       *p = vla_fields;
2840       if (gimple_omp_task_taskloop_p (ctx->stmt))
2841         {
2842           /* Move fields corresponding to first and second _looptemp_
2843              clause first.  There are filled by GOMP_taskloop
2844              and thus need to be in specific positions.  */
2845           tree c1 = gimple_omp_task_clauses (ctx->stmt);
2846           c1 = find_omp_clause (c1, OMP_CLAUSE__LOOPTEMP_);
2847           tree c2 = find_omp_clause (OMP_CLAUSE_CHAIN (c1),
2848                                      OMP_CLAUSE__LOOPTEMP_);
2849           tree f1 = lookup_field (OMP_CLAUSE_DECL (c1), ctx);
2850           tree f2 = lookup_field (OMP_CLAUSE_DECL (c2), ctx);
2851           p = &TYPE_FIELDS (ctx->record_type);
2852           while (*p)
2853             if (*p == f1 || *p == f2)
2854               *p = DECL_CHAIN (*p);
2855             else
2856               p = &DECL_CHAIN (*p);
2857           DECL_CHAIN (f1) = f2;
2858           DECL_CHAIN (f2) = TYPE_FIELDS (ctx->record_type);
2859           TYPE_FIELDS (ctx->record_type) = f1;
2860           if (ctx->srecord_type)
2861             {
2862               f1 = lookup_sfield (OMP_CLAUSE_DECL (c1), ctx);
2863               f2 = lookup_sfield (OMP_CLAUSE_DECL (c2), ctx);
2864               p = &TYPE_FIELDS (ctx->srecord_type);
2865               while (*p)
2866                 if (*p == f1 || *p == f2)
2867                   *p = DECL_CHAIN (*p);
2868                 else
2869                   p = &DECL_CHAIN (*p);
2870               DECL_CHAIN (f1) = f2;
2871               DECL_CHAIN (f2) = TYPE_FIELDS (ctx->srecord_type);
2872               TYPE_FIELDS (ctx->srecord_type) = f1;
2873             }
2874         }
2875       layout_type (ctx->record_type);
2876       fixup_child_record_type (ctx);
2877       if (ctx->srecord_type)
2878         layout_type (ctx->srecord_type);
2879       tree t = fold_convert_loc (loc, long_integer_type_node,
2880                                  TYPE_SIZE_UNIT (ctx->record_type));
2881       gimple_omp_task_set_arg_size (ctx->stmt, t);
2882       t = build_int_cst (long_integer_type_node,
2883                          TYPE_ALIGN_UNIT (ctx->record_type));
2884       gimple_omp_task_set_arg_align (ctx->stmt, t);
2885     }
2886 }
2887
2888 /* Find the enclosing offload context.  */
2889
2890 static omp_context *
2891 enclosing_target_ctx (omp_context *ctx)
2892 {
2893   for (; ctx; ctx = ctx->outer)
2894     if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET)
2895       break;
2896
2897   return ctx;
2898 }
2899
2900 /* Return true if ctx is part of an oacc kernels region.  */
2901
2902 static bool
2903 ctx_in_oacc_kernels_region (omp_context *ctx)
2904 {
2905   for (;ctx != NULL; ctx = ctx->outer)
2906     {
2907       gimple *stmt = ctx->stmt;
2908       if (gimple_code (stmt) == GIMPLE_OMP_TARGET
2909           && gimple_omp_target_kind (stmt) == GF_OMP_TARGET_KIND_OACC_KERNELS)
2910         return true;
2911     }
2912
2913   return false;
2914 }
2915
2916 /* Check the parallelism clauses inside a kernels regions.
2917    Until kernels handling moves to use the same loop indirection
2918    scheme as parallel, we need to do this checking early.  */
2919
2920 static unsigned
2921 check_oacc_kernel_gwv (gomp_for *stmt, omp_context *ctx)
2922 {
2923   bool checking = true;
2924   unsigned outer_mask = 0;
2925   unsigned this_mask = 0;
2926   bool has_seq = false, has_auto = false;
2927
2928   if (ctx->outer)
2929     outer_mask = check_oacc_kernel_gwv (NULL,  ctx->outer);
2930   if (!stmt)
2931     {
2932       checking = false;
2933       if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR)
2934         return outer_mask;
2935       stmt = as_a <gomp_for *> (ctx->stmt);
2936     }
2937
2938   for (tree c = gimple_omp_for_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
2939     {
2940       switch (OMP_CLAUSE_CODE (c))
2941         {
2942         case OMP_CLAUSE_GANG:
2943           this_mask |= GOMP_DIM_MASK (GOMP_DIM_GANG);
2944           break;
2945         case OMP_CLAUSE_WORKER:
2946           this_mask |= GOMP_DIM_MASK (GOMP_DIM_WORKER);
2947           break;
2948         case OMP_CLAUSE_VECTOR:
2949           this_mask |= GOMP_DIM_MASK (GOMP_DIM_VECTOR);
2950           break;
2951         case OMP_CLAUSE_SEQ:
2952           has_seq = true;
2953           break;
2954         case OMP_CLAUSE_AUTO:
2955           has_auto = true;
2956           break;
2957         default:
2958           break;
2959         }
2960     }
2961
2962   if (checking)
2963     {
2964       if (has_seq && (this_mask || has_auto))
2965         error_at (gimple_location (stmt), "%<seq%> overrides other"
2966                   " OpenACC loop specifiers");
2967       else if (has_auto && this_mask)
2968         error_at (gimple_location (stmt), "%<auto%> conflicts with other"
2969                   " OpenACC loop specifiers");
2970
2971       if (this_mask & outer_mask)
2972         error_at (gimple_location (stmt), "inner loop uses same"
2973                   " OpenACC parallelism as containing loop");
2974     }
2975
2976   return outer_mask | this_mask;
2977 }
2978
2979 /* Scan a GIMPLE_OMP_FOR.  */
2980
2981 static void
2982 scan_omp_for (gomp_for *stmt, omp_context *outer_ctx)
2983 {
2984   omp_context *ctx;
2985   size_t i;
2986   tree clauses = gimple_omp_for_clauses (stmt);
2987
2988   ctx = new_omp_context (stmt, outer_ctx);
2989
2990   if (is_gimple_omp_oacc (stmt))
2991     {
2992       omp_context *tgt = enclosing_target_ctx (outer_ctx);
2993
2994       if (!tgt || is_oacc_parallel (tgt))
2995         for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
2996           {
2997             char const *check = NULL;
2998
2999             switch (OMP_CLAUSE_CODE (c))
3000               {
3001               case OMP_CLAUSE_GANG:
3002                 check = "gang";
3003                 break;
3004
3005               case OMP_CLAUSE_WORKER:
3006                 check = "worker";
3007                 break;
3008
3009               case OMP_CLAUSE_VECTOR:
3010                 check = "vector";
3011                 break;
3012
3013               default:
3014                 break;
3015               }
3016
3017             if (check && OMP_CLAUSE_OPERAND (c, 0))
3018               error_at (gimple_location (stmt),
3019                         "argument not permitted on %qs clause in"
3020                         " OpenACC %<parallel%>", check);
3021           }
3022
3023       if (tgt && is_oacc_kernels (tgt))
3024         {
3025           /* Strip out reductions, as they are not  handled yet.  */
3026           tree *prev_ptr = &clauses;
3027
3028           while (tree probe = *prev_ptr)
3029             {
3030               tree *next_ptr = &OMP_CLAUSE_CHAIN (probe);
3031               
3032               if (OMP_CLAUSE_CODE (probe) == OMP_CLAUSE_REDUCTION)
3033                 *prev_ptr = *next_ptr;
3034               else
3035                 prev_ptr = next_ptr;
3036             }
3037
3038           gimple_omp_for_set_clauses (stmt, clauses);
3039           check_oacc_kernel_gwv (stmt, ctx);
3040         }
3041     }
3042
3043   scan_sharing_clauses (clauses, ctx);
3044
3045   scan_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
3046   for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
3047     {
3048       scan_omp_op (gimple_omp_for_index_ptr (stmt, i), ctx);
3049       scan_omp_op (gimple_omp_for_initial_ptr (stmt, i), ctx);
3050       scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
3051       scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
3052     }
3053   scan_omp (gimple_omp_body_ptr (stmt), ctx);
3054 }
3055
3056 /* Scan an OpenMP sections directive.  */
3057
3058 static void
3059 scan_omp_sections (gomp_sections *stmt, omp_context *outer_ctx)
3060 {
3061   omp_context *ctx;
3062
3063   ctx = new_omp_context (stmt, outer_ctx);
3064   scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
3065   scan_omp (gimple_omp_body_ptr (stmt), ctx);
3066 }
3067
3068 /* Scan an OpenMP single directive.  */
3069
3070 static void
3071 scan_omp_single (gomp_single *stmt, omp_context *outer_ctx)
3072 {
3073   omp_context *ctx;
3074   tree name;
3075
3076   ctx = new_omp_context (stmt, outer_ctx);
3077   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
3078   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
3079   name = create_tmp_var_name (".omp_copy_s");
3080   name = build_decl (gimple_location (stmt),
3081                      TYPE_DECL, name, ctx->record_type);
3082   TYPE_NAME (ctx->record_type) = name;
3083
3084   scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
3085   scan_omp (gimple_omp_body_ptr (stmt), ctx);
3086
3087   if (TYPE_FIELDS (ctx->record_type) == NULL)
3088     ctx->record_type = NULL;
3089   else
3090     layout_type (ctx->record_type);
3091 }
3092
3093 /* Return true if the CLAUSES of an omp target guarantee that the base pointers
3094    used in the corresponding offloaded function are restrict.  */
3095
3096 static bool
3097 omp_target_base_pointers_restrict_p (tree clauses)
3098 {
3099   /* The analysis relies on the GOMP_MAP_FORCE_* mapping kinds, which are only
3100      used by OpenACC.  */
3101   if (flag_openacc == 0)
3102     return false;
3103
3104   /* I.  Basic example:
3105
3106        void foo (void)
3107        {
3108          unsigned int a[2], b[2];
3109
3110          #pragma acc kernels \
3111            copyout (a) \
3112            copyout (b)
3113          {
3114            a[0] = 0;
3115            b[0] = 1;
3116          }
3117        }
3118
3119      After gimplification, we have:
3120
3121        #pragma omp target oacc_kernels \
3122          map(force_from:a [len: 8]) \
3123          map(force_from:b [len: 8])
3124        {
3125          a[0] = 0;
3126          b[0] = 1;
3127        }
3128
3129      Because both mappings have the force prefix, we know that they will be
3130      allocated when calling the corresponding offloaded function, which means we
3131      can mark the base pointers for a and b in the offloaded function as
3132      restrict.  */
3133
3134   tree c;
3135   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
3136     {
3137       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
3138         return false;
3139
3140       switch (OMP_CLAUSE_MAP_KIND (c))
3141         {
3142         case GOMP_MAP_FORCE_ALLOC:
3143         case GOMP_MAP_FORCE_TO:
3144         case GOMP_MAP_FORCE_FROM:
3145         case GOMP_MAP_FORCE_TOFROM:
3146           break;
3147         default:
3148           return false;
3149         }
3150     }
3151
3152   return true;
3153 }
3154
3155 /* Scan a GIMPLE_OMP_TARGET.  */
3156
3157 static void
3158 scan_omp_target (gomp_target *stmt, omp_context *outer_ctx)
3159 {
3160   omp_context *ctx;
3161   tree name;
3162   bool offloaded = is_gimple_omp_offloaded (stmt);
3163   tree clauses = gimple_omp_target_clauses (stmt);
3164
3165   ctx = new_omp_context (stmt, outer_ctx);
3166   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
3167   ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
3168   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
3169   name = create_tmp_var_name (".omp_data_t");
3170   name = build_decl (gimple_location (stmt),
3171                      TYPE_DECL, name, ctx->record_type);
3172   DECL_ARTIFICIAL (name) = 1;
3173   DECL_NAMELESS (name) = 1;
3174   TYPE_NAME (ctx->record_type) = name;
3175   TYPE_ARTIFICIAL (ctx->record_type) = 1;
3176
3177   bool base_pointers_restrict = false;
3178   if (offloaded)
3179     {
3180       create_omp_child_function (ctx, false);
3181       gimple_omp_target_set_child_fn (stmt, ctx->cb.dst_fn);
3182
3183       base_pointers_restrict = omp_target_base_pointers_restrict_p (clauses);
3184       if (base_pointers_restrict
3185           && dump_file && (dump_flags & TDF_DETAILS))
3186         fprintf (dump_file,
3187                  "Base pointers in offloaded function are restrict\n");
3188     }
3189
3190   scan_sharing_clauses (clauses, ctx, base_pointers_restrict);
3191   scan_omp (gimple_omp_body_ptr (stmt), ctx);
3192
3193   if (TYPE_FIELDS (ctx->record_type) == NULL)
3194     ctx->record_type = ctx->receiver_decl = NULL;
3195   else
3196     {
3197       TYPE_FIELDS (ctx->record_type)
3198         = nreverse (TYPE_FIELDS (ctx->record_type));
3199       if (flag_checking)
3200         {
3201           unsigned int align = DECL_ALIGN (TYPE_FIELDS (ctx->record_type));
3202           for (tree field = TYPE_FIELDS (ctx->record_type);
3203                field;
3204                field = DECL_CHAIN (field))
3205             gcc_assert (DECL_ALIGN (field) == align);
3206         }
3207       layout_type (ctx->record_type);
3208       if (offloaded)
3209         fixup_child_record_type (ctx);
3210     }
3211 }
3212
3213 /* Scan an OpenMP teams directive.  */
3214
3215 static void
3216 scan_omp_teams (gomp_teams *stmt, omp_context *outer_ctx)
3217 {
3218   omp_context *ctx = new_omp_context (stmt, outer_ctx);
3219   scan_sharing_clauses (gimple_omp_teams_clauses (stmt), ctx);
3220   scan_omp (gimple_omp_body_ptr (stmt), ctx);
3221 }
3222
3223 /* Check nesting restrictions.  */
3224 static bool
3225 check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
3226 {
3227   tree c;
3228
3229   if (ctx && gimple_code (ctx->stmt) == GIMPLE_OMP_GRID_BODY)
3230     /* GRID_BODY is an artificial construct, nesting rules will be checked in
3231        the original copy of its contents.  */
3232     return true;
3233
3234   /* No nesting of non-OpenACC STMT (that is, an OpenMP one, or a GOMP builtin)
3235      inside an OpenACC CTX.  */
3236   if (!(is_gimple_omp (stmt)
3237         && is_gimple_omp_oacc (stmt))
3238       /* Except for atomic codes that we share with OpenMP.  */
3239       && !(gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD
3240            || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE))
3241     {
3242       if (get_oacc_fn_attrib (cfun->decl) != NULL)
3243         {
3244           error_at (gimple_location (stmt),
3245                     "non-OpenACC construct inside of OpenACC routine");
3246           return false;
3247         }
3248       else
3249         for (omp_context *octx = ctx; octx != NULL; octx = octx->outer)
3250           if (is_gimple_omp (octx->stmt)
3251               && is_gimple_omp_oacc (octx->stmt))
3252             {
3253               error_at (gimple_location (stmt),
3254                         "non-OpenACC construct inside of OpenACC region");
3255               return false;
3256             }
3257     }
3258
3259   if (ctx != NULL)
3260     {
3261       if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
3262           && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
3263         {
3264           c = NULL_TREE;
3265           if (gimple_code (stmt) == GIMPLE_OMP_ORDERED)
3266             {
3267               c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
3268               if (find_omp_clause (c, OMP_CLAUSE_SIMD))
3269                 {
3270                   if (find_omp_clause (c, OMP_CLAUSE_THREADS)
3271                       && (ctx->outer == NULL
3272                           || !gimple_omp_for_combined_into_p (ctx->stmt)
3273                           || gimple_code (ctx->outer->stmt) != GIMPLE_OMP_FOR
3274                           || (gimple_omp_for_kind (ctx->outer->stmt)
3275                               != GF_OMP_FOR_KIND_FOR)
3276                           || !gimple_omp_for_combined_p (ctx->outer->stmt)))
3277                     {
3278                       error_at (gimple_location (stmt),
3279                                 "%<ordered simd threads%> must be closely "
3280                                 "nested inside of %<for simd%> region");
3281                       return false;
3282                     }
3283                   return true;
3284                 }
3285             }
3286           error_at (gimple_location (stmt),
3287                     "OpenMP constructs other than %<#pragma omp ordered simd%>"
3288                     " may not be nested inside %<simd%> region");
3289           return false;
3290         }
3291       else if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
3292         {
3293           if ((gimple_code (stmt) != GIMPLE_OMP_FOR
3294                || (gimple_omp_for_kind (stmt)
3295                    != GF_OMP_FOR_KIND_DISTRIBUTE))
3296               && gimple_code (stmt) != GIMPLE_OMP_PARALLEL)
3297             {
3298               error_at (gimple_location (stmt),
3299                         "only %<distribute%> or %<parallel%> regions are "
3300                         "allowed to be strictly nested inside %<teams%> "
3301                         "region");
3302               return false;
3303             }
3304         }
3305     }
3306   switch (gimple_code (stmt))
3307     {
3308     case GIMPLE_OMP_FOR:
3309       if (gimple_omp_for_kind (stmt) & GF_OMP_FOR_SIMD)
3310         return true;
3311       if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_DISTRIBUTE)
3312         {
3313           if (ctx != NULL && gimple_code (ctx->stmt) != GIMPLE_OMP_TEAMS)
3314             {
3315               error_at (gimple_location (stmt),
3316                         "%<distribute%> region must be strictly nested "
3317                         "inside %<teams%> construct");
3318               return false;
3319             }
3320           return true;
3321         }
3322       /* We split taskloop into task and nested taskloop in it.  */
3323       if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_TASKLOOP)
3324         return true;
3325       if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
3326         {
3327           bool ok = false;
3328           
3329           if (ctx)
3330             switch (gimple_code (ctx->stmt))
3331               {
3332               case GIMPLE_OMP_FOR:
3333                 ok = (gimple_omp_for_kind (ctx->stmt)
3334                       == GF_OMP_FOR_KIND_OACC_LOOP);
3335                 break;
3336
3337               case GIMPLE_OMP_TARGET:
3338                 switch (gimple_omp_target_kind (ctx->stmt))
3339                   {
3340                   case GF_OMP_TARGET_KIND_OACC_PARALLEL:
3341                   case GF_OMP_TARGET_KIND_OACC_KERNELS:
3342                     ok = true;
3343                     break;
3344
3345                   default:
3346                     break;
3347                   }
3348
3349               default:
3350                 break;
3351               }
3352           else if (get_oacc_fn_attrib (current_function_decl))
3353             ok = true;
3354           if (!ok)
3355             {
3356               error_at (gimple_location (stmt),
3357                         "OpenACC loop directive must be associated with"
3358                         " an OpenACC compute region");
3359               return false;
3360             }
3361         }
3362       /* FALLTHRU */
3363     case GIMPLE_CALL:
3364       if (is_gimple_call (stmt)
3365           && (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
3366               == BUILT_IN_GOMP_CANCEL
3367               || DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
3368                  == BUILT_IN_GOMP_CANCELLATION_POINT))
3369         {
3370           const char *bad = NULL;
3371           const char *kind = NULL;
3372           const char *construct
3373             = (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
3374                == BUILT_IN_GOMP_CANCEL)
3375               ? "#pragma omp cancel"
3376               : "#pragma omp cancellation point";
3377           if (ctx == NULL)
3378             {
3379               error_at (gimple_location (stmt), "orphaned %qs construct",
3380                         construct);
3381               return false;
3382             }
3383           switch (tree_fits_shwi_p (gimple_call_arg (stmt, 0))
3384                   ? tree_to_shwi (gimple_call_arg (stmt, 0))
3385                   : 0)
3386             {
3387             case 1:
3388               if (gimple_code (ctx->stmt) != GIMPLE_OMP_PARALLEL)
3389                 bad = "#pragma omp parallel";
3390               else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
3391                        == BUILT_IN_GOMP_CANCEL
3392                        && !integer_zerop (gimple_call_arg (stmt, 1)))
3393                 ctx->cancellable = true;
3394               kind = "parallel";
3395               break;
3396             case 2:
3397               if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
3398                   || gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR)
3399                 bad = "#pragma omp for";
3400               else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
3401                        == BUILT_IN_GOMP_CANCEL
3402                        && !integer_zerop (gimple_call_arg (stmt, 1)))
3403                 {
3404                   ctx->cancellable = true;
3405                   if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
3406                                        OMP_CLAUSE_NOWAIT))
3407                     warning_at (gimple_location (stmt), 0,
3408                                 "%<#pragma omp cancel for%> inside "
3409                                 "%<nowait%> for construct");
3410                   if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
3411                                        OMP_CLAUSE_ORDERED))
3412                     warning_at (gimple_location (stmt), 0,
3413                                 "%<#pragma omp cancel for%> inside "
3414                                 "%<ordered%> for construct");
3415                 }
3416               kind = "for";
3417               break;
3418             case 4:
3419               if (gimple_code (ctx->stmt) != GIMPLE_OMP_SECTIONS
3420                   && gimple_code (ctx->stmt) != GIMPLE_OMP_SECTION)
3421                 bad = "#pragma omp sections";
3422               else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
3423                        == BUILT_IN_GOMP_CANCEL
3424                        && !integer_zerop (gimple_call_arg (stmt, 1)))
3425                 {
3426                   if (gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS)
3427                     {
3428                       ctx->cancellable = true;
3429                       if (find_omp_clause (gimple_omp_sections_clauses
3430                                                                 (ctx->stmt),
3431                                            OMP_CLAUSE_NOWAIT))
3432                         warning_at (gimple_location (stmt), 0,
3433                                     "%<#pragma omp cancel sections%> inside "
3434                                     "%<nowait%> sections construct");
3435                     }
3436                   else
3437                     {
3438                       gcc_assert (ctx->outer
3439                                   && gimple_code (ctx->outer->stmt)
3440                                      == GIMPLE_OMP_SECTIONS);
3441                       ctx->outer->cancellable = true;
3442                       if (find_omp_clause (gimple_omp_sections_clauses
3443                                                         (ctx->outer->stmt),
3444                                            OMP_CLAUSE_NOWAIT))
3445                         warning_at (gimple_location (stmt), 0,
3446                                     "%<#pragma omp cancel sections%> inside "
3447                                     "%<nowait%> sections construct");
3448                     }
3449                 }
3450               kind = "sections";
3451               break;
3452             case 8:
3453               if (gimple_code (ctx->stmt) != GIMPLE_OMP_TASK)
3454                 bad = "#pragma omp task";
3455               else
3456                 {
3457                   for (omp_context *octx = ctx->outer;
3458                        octx; octx = octx->outer)
3459                     {
3460                       switch (gimple_code (octx->stmt))
3461                         {
3462                         case GIMPLE_OMP_TASKGROUP:
3463                           break;
3464                         case GIMPLE_OMP_TARGET:
3465                           if (gimple_omp_target_kind (octx->stmt)
3466                               != GF_OMP_TARGET_KIND_REGION)
3467                             continue;
3468                           /* FALLTHRU */
3469                         case GIMPLE_OMP_PARALLEL:
3470                         case GIMPLE_OMP_TEAMS:
3471                           error_at (gimple_location (stmt),
3472                                     "%<%s taskgroup%> construct not closely "
3473                                     "nested inside of %<taskgroup%> region",
3474                                     construct);
3475                           return false;
3476                         default:
3477                           continue;
3478                         }
3479                       break;
3480                     }
3481                   ctx->cancellable = true;
3482                 }
3483               kind = "taskgroup";
3484               break;
3485             default:
3486               error_at (gimple_location (stmt), "invalid arguments");
3487               return false;
3488             }
3489           if (bad)
3490             {
3491               error_at (gimple_location (stmt),
3492                         "%<%s %s%> construct not closely nested inside of %qs",
3493                         construct, kind, bad);
3494               return false;
3495             }
3496         }
3497       /* FALLTHRU */
3498     case GIMPLE_OMP_SECTIONS:
3499     case GIMPLE_OMP_SINGLE:
3500       for (; ctx != NULL; ctx = ctx->outer)
3501         switch (gimple_code (ctx->stmt))
3502           {
3503           case GIMPLE_OMP_FOR:
3504             if (gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR
3505                 && gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_TASKLOOP)
3506               break;
3507             /* FALLTHRU */
3508           case GIMPLE_OMP_SECTIONS:
3509           case GIMPLE_OMP_SINGLE:
3510           case GIMPLE_OMP_ORDERED:
3511           case GIMPLE_OMP_MASTER:
3512           case GIMPLE_OMP_TASK:
3513           case GIMPLE_OMP_CRITICAL:
3514             if (is_gimple_call (stmt))
3515               {
3516                 if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
3517                     != BUILT_IN_GOMP_BARRIER)
3518                   return true;
3519                 error_at (gimple_location (stmt),
3520                           "barrier region may not be closely nested inside "
3521                           "of work-sharing, %<critical%>, %<ordered%>, "
3522                           "%<master%>, explicit %<task%> or %<taskloop%> "
3523                           "region");
3524                 return false;
3525               }
3526             error_at (gimple_location (stmt),
3527                       "work-sharing region may not be closely nested inside "
3528                       "of work-sharing, %<critical%>, %<ordered%>, "
3529                       "%<master%>, explicit %<task%> or %<taskloop%> region");
3530             return false;
3531           case GIMPLE_OMP_PARALLEL:
3532           case GIMPLE_OMP_TEAMS:
3533             return true;
3534           case GIMPLE_OMP_TARGET:
3535             if (gimple_omp_target_kind (ctx->stmt)
3536                 == GF_OMP_TARGET_KIND_REGION)
3537               return true;
3538             break;
3539           default:
3540             break;
3541           }
3542       break;
3543     case GIMPLE_OMP_MASTER:
3544       for (; ctx != NULL; ctx = ctx->outer)
3545         switch (gimple_code (ctx->stmt))
3546           {
3547           case GIMPLE_OMP_FOR:
3548             if (gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR
3549                 && gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_TASKLOOP)
3550               break;
3551             /* FALLTHRU */
3552           case GIMPLE_OMP_SECTIONS:
3553           case GIMPLE_OMP_SINGLE:
3554           case GIMPLE_OMP_TASK:
3555             error_at (gimple_location (stmt),
3556                       "%<master%> region may not be closely nested inside "
3557                       "of work-sharing, explicit %<task%> or %<taskloop%> "
3558                       "region");
3559             return false;
3560           case GIMPLE_OMP_PARALLEL:
3561           case GIMPLE_OMP_TEAMS:
3562             return true;
3563           case GIMPLE_OMP_TARGET:
3564             if (gimple_omp_target_kind (ctx->stmt)
3565                 == GF_OMP_TARGET_KIND_REGION)
3566               return true;
3567             break;
3568           default:
3569             break;
3570           }
3571       break;
3572     case GIMPLE_OMP_TASK:
3573       for (c = gimple_omp_task_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
3574         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
3575             && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE
3576                 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK))
3577           {
3578             enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_KIND (c);
3579             error_at (OMP_CLAUSE_LOCATION (c),
3580                       "%<depend(%s)%> is only allowed in %<omp ordered%>",
3581                       kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
3582             return false;
3583           }
3584       break;
3585     case GIMPLE_OMP_ORDERED:
3586       for (c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
3587            c; c = OMP_CLAUSE_CHAIN (c))
3588         {
3589           if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
3590             {
3591               gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREADS
3592                           || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SIMD);
3593               continue;
3594             }
3595           enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_KIND (c);
3596           if (kind == OMP_CLAUSE_DEPEND_SOURCE
3597               || kind == OMP_CLAUSE_DEPEND_SINK)
3598             {
3599               tree oclause;
3600               /* Look for containing ordered(N) loop.  */
3601               if (ctx == NULL
3602                   || gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
3603                   || (oclause
3604                         = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
3605                                            OMP_CLAUSE_ORDERED)) == NULL_TREE)
3606                 {
3607                   error_at (OMP_CLAUSE_LOCATION (c),
3608                             "%<ordered%> construct with %<depend%> clause "
3609                             "must be closely nested inside an %<ordered%> "
3610                             "loop");
3611                   return false;
3612                 }
3613               else if (OMP_CLAUSE_ORDERED_EXPR (oclause) == NULL_TREE)
3614                 {
3615                   error_at (OMP_CLAUSE_LOCATION (c),
3616                             "%<ordered%> construct with %<depend%> clause "
3617                             "must be closely nested inside a loop with "
3618                             "%<ordered%> clause with a parameter");
3619                   return false;
3620                 }
3621             }
3622           else
3623             {
3624               error_at (OMP_CLAUSE_LOCATION (c),
3625                         "invalid depend kind in omp %<ordered%> %<depend%>");
3626               return false;
3627             }
3628         }
3629       c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
3630       if (find_omp_clause (c, OMP_CLAUSE_SIMD))
3631         {
3632           /* ordered simd must be closely nested inside of simd region,
3633              and simd region must not encounter constructs other than
3634              ordered simd, therefore ordered simd may be either orphaned,
3635              or ctx->stmt must be simd.  The latter case is handled already
3636              earlier.  */
3637           if (ctx != NULL)
3638             {
3639               error_at (gimple_location (stmt),
3640                         "%<ordered%> %<simd%> must be closely nested inside "
3641                         "%<simd%> region");
3642               return false;
3643             }
3644         }
3645       for (; ctx != NULL; ctx = ctx->outer)
3646         switch (gimple_code (ctx->stmt))
3647           {
3648           case GIMPLE_OMP_CRITICAL:
3649           case GIMPLE_OMP_TASK:
3650           case GIMPLE_OMP_ORDERED:
3651           ordered_in_taskloop:
3652             error_at (gimple_location (stmt),
3653                       "%<ordered%> region may not be closely nested inside "
3654                       "of %<critical%>, %<ordered%>, explicit %<task%> or "
3655                       "%<taskloop%> region");
3656             return false;
3657           case GIMPLE_OMP_FOR:
3658             if (gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_TASKLOOP)
3659               goto ordered_in_taskloop;
3660             if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
3661                                  OMP_CLAUSE_ORDERED) == NULL)
3662               {
3663                 error_at (gimple_location (stmt),
3664                           "%<ordered%> region must be closely nested inside "
3665                           "a loop region with an %<ordered%> clause");
3666                 return false;
3667               }
3668             return true;
3669           case GIMPLE_OMP_TARGET:
3670             if (gimple_omp_target_kind (ctx->stmt)
3671                 != GF_OMP_TARGET_KIND_REGION)
3672               break;
3673             /* FALLTHRU */
3674           case GIMPLE_OMP_PARALLEL:
3675           case GIMPLE_OMP_TEAMS:
3676             error_at (gimple_location (stmt),
3677                       "%<ordered%> region must be closely nested inside "
3678                       "a loop region with an %<ordered%> clause");
3679             return false;
3680           default:
3681             break;
3682           }
3683       break;
3684     case GIMPLE_OMP_CRITICAL:
3685       {
3686         tree this_stmt_name
3687           = gimple_omp_critical_name (as_a <gomp_critical *> (stmt));
3688         for (; ctx != NULL; ctx = ctx->outer)
3689           if (gomp_critical *other_crit
3690                 = dyn_cast <gomp_critical *> (ctx->stmt))
3691             if (this_stmt_name == gimple_omp_critical_name (other_crit))
3692               {
3693                 error_at (gimple_location (stmt),
3694                           "%<critical%> region may not be nested inside "
3695                            "a %<critical%> region with the same name");
3696                 return false;
3697               }
3698       }
3699       break;
3700     case GIMPLE_OMP_TEAMS:
3701       if (ctx == NULL
3702           || gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET
3703           || gimple_omp_target_kind (ctx->stmt) != GF_OMP_TARGET_KIND_REGION)
3704         {
3705           error_at (gimple_location (stmt),
3706                     "%<teams%> construct not closely nested inside of "
3707                     "%<target%> construct");
3708           return false;
3709         }
3710       break;
3711     case GIMPLE_OMP_TARGET:
3712       for (c = gimple_omp_target_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
3713         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
3714             && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE
3715                 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK))
3716           {
3717             enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_KIND (c);
3718             error_at (OMP_CLAUSE_LOCATION (c),
3719                       "%<depend(%s)%> is only allowed in %<omp ordered%>",
3720                       kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
3721             return false;
3722           }
3723       if (is_gimple_omp_offloaded (stmt)
3724           && get_oacc_fn_attrib (cfun->decl) != NULL)
3725         {
3726           error_at (gimple_location (stmt),
3727                     "OpenACC region inside of OpenACC routine, nested "
3728                     "parallelism not supported yet");
3729           return false;
3730         }
3731       for (; ctx != NULL; ctx = ctx->outer)
3732         {
3733           if (gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET)
3734             {
3735               if (is_gimple_omp (stmt)
3736                   && is_gimple_omp_oacc (stmt)
3737                   && is_gimple_omp (ctx->stmt))
3738                 {
3739                   error_at (gimple_location (stmt),
3740                             "OpenACC construct inside of non-OpenACC region");
3741                   return false;
3742                 }
3743               continue;
3744             }
3745
3746           const char *stmt_name, *ctx_stmt_name;
3747           switch (gimple_omp_target_kind (stmt))
3748             {
3749             case GF_OMP_TARGET_KIND_REGION: stmt_name = "target"; break;
3750             case GF_OMP_TARGET_KIND_DATA: stmt_name = "target data"; break;
3751             case GF_OMP_TARGET_KIND_UPDATE: stmt_name = "target update"; break;
3752             case GF_OMP_TARGET_KIND_ENTER_DATA:
3753               stmt_name = "target enter data"; break;
3754             case GF_OMP_TARGET_KIND_EXIT_DATA:
3755               stmt_name = "target exit data"; break;
3756             case GF_OMP_TARGET_KIND_OACC_PARALLEL: stmt_name = "parallel"; break;
3757             case GF_OMP_TARGET_KIND_OACC_KERNELS: stmt_name = "kernels"; break;
3758             case GF_OMP_TARGET_KIND_OACC_DATA: stmt_name = "data"; break;
3759             case GF_OMP_TARGET_KIND_OACC_UPDATE: stmt_name = "update"; break;
3760             case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
3761               stmt_name = "enter/exit data"; break;
3762             case GF_OMP_TARGET_KIND_OACC_HOST_DATA: stmt_name = "host_data";
3763               break;
3764             default: gcc_unreachable ();
3765             }
3766           switch (gimple_omp_target_kind (ctx->stmt))
3767             {
3768             case GF_OMP_TARGET_KIND_REGION: ctx_stmt_name = "target"; break;
3769             case GF_OMP_TARGET_KIND_DATA: ctx_stmt_name = "target data"; break;
3770             case GF_OMP_TARGET_KIND_OACC_PARALLEL:
3771               ctx_stmt_name = "parallel"; break;
3772             case GF_OMP_TARGET_KIND_OACC_KERNELS:
3773               ctx_stmt_name = "kernels"; break;
3774             case GF_OMP_TARGET_KIND_OACC_DATA: ctx_stmt_name = "data"; break;
3775             case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
3776               ctx_stmt_name = "host_data"; break;
3777             default: gcc_unreachable ();
3778             }
3779
3780           /* OpenACC/OpenMP mismatch?  */
3781           if (is_gimple_omp_oacc (stmt)
3782               != is_gimple_omp_oacc (ctx->stmt))
3783             {
3784               error_at (gimple_location (stmt),
3785                         "%s %qs construct inside of %s %qs region",
3786                         (is_gimple_omp_oacc (stmt)
3787                          ? "OpenACC" : "OpenMP"), stmt_name,
3788                         (is_gimple_omp_oacc (ctx->stmt)
3789                          ? "OpenACC" : "OpenMP"), ctx_stmt_name);
3790               return false;
3791             }
3792           if (is_gimple_omp_offloaded (ctx->stmt))
3793             {
3794               /* No GIMPLE_OMP_TARGET inside offloaded OpenACC CTX.  */
3795               if (is_gimple_omp_oacc (ctx->stmt))
3796                 {
3797                   error_at (gimple_location (stmt),
3798                             "%qs construct inside of %qs region",
3799                             stmt_name, ctx_stmt_name);
3800                   return false;
3801                 }
3802               else
3803                 {
3804                   warning_at (gimple_location (stmt), 0,
3805                               "%qs construct inside of %qs region",
3806                               stmt_name, ctx_stmt_name);
3807                 }
3808             }
3809         }
3810       break;
3811     default:
3812       break;
3813     }
3814   return true;
3815 }
3816
3817
3818 /* Helper function scan_omp.
3819
3820    Callback for walk_tree or operators in walk_gimple_stmt used to
3821    scan for OMP directives in TP.  */
3822
3823 static tree
3824 scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
3825 {
3826   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
3827   omp_context *ctx = (omp_context *) wi->info;
3828   tree t = *tp;
3829
3830   switch (TREE_CODE (t))
3831     {
3832     case VAR_DECL:
3833     case PARM_DECL:
3834     case LABEL_DECL:
3835     case RESULT_DECL:
3836       if (ctx)
3837         {
3838           tree repl = remap_decl (t, &ctx->cb);
3839           gcc_checking_assert (TREE_CODE (repl) != ERROR_MARK);
3840           *tp = repl;
3841         }
3842       break;
3843
3844     default:
3845       if (ctx && TYPE_P (t))
3846         *tp = remap_type (t, &ctx->cb);
3847       else if (!DECL_P (t))
3848         {
3849           *walk_subtrees = 1;
3850           if (ctx)
3851             {
3852               tree tem = remap_type (TREE_TYPE (t), &ctx->cb);
3853               if (tem != TREE_TYPE (t))
3854                 {
3855                   if (TREE_CODE (t) == INTEGER_CST)
3856                     *tp = wide_int_to_tree (tem, t);
3857                   else
3858                     TREE_TYPE (t) = tem;
3859                 }
3860             }
3861         }
3862       break;
3863     }
3864
3865   return NULL_TREE;
3866 }
3867
3868 /* Return true if FNDECL is a setjmp or a longjmp.  */
3869
3870 static bool
3871 setjmp_or_longjmp_p (const_tree fndecl)
3872 {
3873   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
3874       && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SETJMP
3875           || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LONGJMP))
3876     return true;
3877
3878   tree declname = DECL_NAME (fndecl);
3879   if (!declname)
3880     return false;
3881   const char *name = IDENTIFIER_POINTER (declname);
3882   return !strcmp (name, "setjmp") || !strcmp (name, "longjmp");
3883 }
3884
3885
3886 /* Helper function for scan_omp.
3887
3888    Callback for walk_gimple_stmt used to scan for OMP directives in
3889    the current statement in GSI.  */
3890
3891 static tree
3892 scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
3893                  struct walk_stmt_info *wi)
3894 {
3895   gimple *stmt = gsi_stmt (*gsi);
3896   omp_context *ctx = (omp_context *) wi->info;
3897
3898   if (gimple_has_location (stmt))
3899     input_location = gimple_location (stmt);
3900
3901   /* Check the nesting restrictions.  */
3902   bool remove = false;
3903   if (is_gimple_omp (stmt))
3904     remove = !check_omp_nesting_restrictions (stmt, ctx);
3905   else if (is_gimple_call (stmt))
3906     {
3907       tree fndecl = gimple_call_fndecl (stmt);
3908       if (fndecl)
3909         {
3910           if (setjmp_or_longjmp_p (fndecl)
3911               && ctx
3912               && gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
3913               && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
3914             {
3915               remove = true;
3916               error_at (gimple_location (stmt),
3917                         "setjmp/longjmp inside simd construct");
3918             }
3919           else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3920             switch (DECL_FUNCTION_CODE (fndecl))
3921               {
3922               case BUILT_IN_GOMP_BARRIER:
3923               case BUILT_IN_GOMP_CANCEL:
3924               case BUILT_IN_GOMP_CANCELLATION_POINT:
3925               case BUILT_IN_GOMP_TASKYIELD:
3926               case BUILT_IN_GOMP_TASKWAIT:
3927               case BUILT_IN_GOMP_TASKGROUP_START:
3928               case BUILT_IN_GOMP_TASKGROUP_END:
3929                 remove = !check_omp_nesting_restrictions (stmt, ctx);
3930                 break;
3931               default:
3932                 break;
3933               }
3934         }
3935     }
3936   if (remove)
3937     {
3938       stmt = gimple_build_nop ();
3939       gsi_replace (gsi, stmt, false);
3940     }
3941
3942   *handled_ops_p = true;
3943
3944   switch (gimple_code (stmt))
3945     {
3946     case GIMPLE_OMP_PARALLEL:
3947       taskreg_nesting_level++;
3948       scan_omp_parallel (gsi, ctx);
3949       taskreg_nesting_level--;
3950       break;
3951
3952     case GIMPLE_OMP_TASK:
3953       taskreg_nesting_level++;
3954       scan_omp_task (gsi, ctx);
3955       taskreg_nesting_level--;
3956       break;
3957
3958     case GIMPLE_OMP_FOR:
3959       scan_omp_for (as_a <gomp_for *> (stmt), ctx);
3960       break;
3961
3962     case GIMPLE_OMP_SECTIONS:
3963       scan_omp_sections (as_a <gomp_sections *> (stmt), ctx);
3964       break;
3965
3966     case GIMPLE_OMP_SINGLE:
3967       scan_omp_single (as_a <gomp_single *> (stmt), ctx);
3968       break;
3969
3970     case GIMPLE_OMP_SECTION:
3971     case GIMPLE_OMP_MASTER:
3972     case GIMPLE_OMP_TASKGROUP:
3973     case GIMPLE_OMP_ORDERED:
3974     case GIMPLE_OMP_CRITICAL:
3975     case GIMPLE_OMP_GRID_BODY:
3976       ctx = new_omp_context (stmt, ctx);
3977       scan_omp (gimple_omp_body_ptr (stmt), ctx);
3978       break;
3979
3980     case GIMPLE_OMP_TARGET:
3981       scan_omp_target (as_a <gomp_target *> (stmt), ctx);
3982       break;
3983
3984     case GIMPLE_OMP_TEAMS:
3985       scan_omp_teams (as_a <gomp_teams *> (stmt), ctx);
3986       break;
3987
3988     case GIMPLE_BIND:
3989       {
3990         tree var;
3991
3992         *handled_ops_p = false;
3993         if (ctx)
3994           for (var = gimple_bind_vars (as_a <gbind *> (stmt));
3995                var ;
3996                var = DECL_CHAIN (var))
3997             insert_decl_map (&ctx->cb, var, var);
3998       }
3999       break;
4000     default:
4001       *handled_ops_p = false;
4002       break;
4003     }
4004
4005   return NULL_TREE;
4006 }
4007
4008
4009 /* Scan all the statements starting at the current statement.  CTX
4010    contains context information about the OMP directives and
4011    clauses found during the scan.  */
4012
4013 static void
4014 scan_omp (gimple_seq *body_p, omp_context *ctx)
4015 {
4016   location_t saved_location;
4017   struct walk_stmt_info wi;
4018
4019   memset (&wi, 0, sizeof (wi));
4020   wi.info = ctx;
4021   wi.want_locations = true;
4022
4023   saved_location = input_location;
4024   walk_gimple_seq_mod (body_p, scan_omp_1_stmt, scan_omp_1_op, &wi);
4025   input_location = saved_location;
4026 }
4027 \f
4028 /* Re-gimplification and code generation routines.  */
4029
4030 /* Build a call to GOMP_barrier.  */
4031
4032 static gimple *
4033 build_omp_barrier (tree lhs)
4034 {
4035   tree fndecl = builtin_decl_explicit (lhs ? BUILT_IN_GOMP_BARRIER_CANCEL
4036                                            : BUILT_IN_GOMP_BARRIER);
4037   gcall *g = gimple_build_call (fndecl, 0);
4038   if (lhs)
4039     gimple_call_set_lhs (g, lhs);
4040   return g;
4041 }
4042
4043 /* If a context was created for STMT when it was scanned, return it.  */
4044
4045 static omp_context *
4046 maybe_lookup_ctx (gimple *stmt)
4047 {
4048   splay_tree_node n;
4049   n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
4050   return n ? (omp_context *) n->value : NULL;
4051 }
4052
4053
4054 /* Find the mapping for DECL in CTX or the immediately enclosing
4055    context that has a mapping for DECL.
4056
4057    If CTX is a nested parallel directive, we may have to use the decl
4058    mappings created in CTX's parent context.  Suppose that we have the
4059    following parallel nesting (variable UIDs showed for clarity):
4060
4061         iD.1562 = 0;
4062         #omp parallel shared(iD.1562)           -> outer parallel
4063           iD.1562 = iD.1562 + 1;
4064
4065           #omp parallel shared (iD.1562)        -> inner parallel
4066              iD.1562 = iD.1562 - 1;
4067
4068    Each parallel structure will create a distinct .omp_data_s structure
4069    for copying iD.1562 in/out of the directive:
4070
4071         outer parallel          .omp_data_s.1.i -> iD.1562
4072         inner parallel          .omp_data_s.2.i -> iD.1562
4073
4074    A shared variable mapping will produce a copy-out operation before
4075    the parallel directive and a copy-in operation after it.  So, in
4076    this case we would have:
4077
4078         iD.1562 = 0;
4079         .omp_data_o.1.i = iD.1562;
4080         #omp parallel shared(iD.1562)           -> outer parallel
4081           .omp_data_i.1 = &.omp_data_o.1
4082           .omp_data_i.1->i = .omp_data_i.1->i + 1;
4083
4084           .omp_data_o.2.i = iD.1562;            -> **
4085           #omp parallel shared(iD.1562)         -> inner parallel
4086             .omp_data_i.2 = &.omp_data_o.2
4087             .omp_data_i.2->i = .omp_data_i.2->i - 1;
4088
4089
4090     ** This is a problem.  The symbol iD.1562 cannot be referenced
4091        inside the body of the outer parallel region.  But since we are
4092        emitting this copy operation while expanding the inner parallel
4093        directive, we need to access the CTX structure of the outer
4094        parallel directive to get the correct mapping:
4095
4096           .omp_data_o.2.i = .omp_data_i.1->i
4097
4098     Since there may be other workshare or parallel directives enclosing
4099     the parallel directive, it may be necessary to walk up the context
4100     parent chain.  This is not a problem in general because nested
4101     parallelism happens only rarely.  */
4102
4103 static tree
4104 lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
4105 {
4106   tree t;
4107   omp_context *up;
4108
4109   for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
4110     t = maybe_lookup_decl (decl, up);
4111
4112   gcc_assert (!ctx->is_nested || t || is_global_var (decl));
4113
4114   return t ? t : decl;
4115 }
4116
4117
4118 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
4119    in outer contexts.  */
4120
4121 static tree
4122 maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
4123 {
4124   tree t = NULL;
4125   omp_context *up;
4126
4127   for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
4128     t = maybe_lookup_decl (decl, up);
4129
4130   return t ? t : decl;
4131 }
4132
4133
4134 /* Construct the initialization value for reduction operation OP.  */
4135
4136 tree
4137 omp_reduction_init_op (location_t loc, enum tree_code op, tree type)
4138 {
4139   switch (op)
4140     {
4141     case PLUS_EXPR:
4142     case MINUS_EXPR:
4143     case BIT_IOR_EXPR:
4144     case BIT_XOR_EXPR:
4145     case TRUTH_OR_EXPR:
4146     case TRUTH_ORIF_EXPR:
4147     case TRUTH_XOR_EXPR:
4148     case NE_EXPR:
4149       return build_zero_cst (type);
4150
4151     case MULT_EXPR:
4152     case TRUTH_AND_EXPR:
4153     case TRUTH_ANDIF_EXPR:
4154     case EQ_EXPR:
4155       return fold_convert_loc (loc, type, integer_one_node);
4156
4157     case BIT_AND_EXPR:
4158       return fold_convert_loc (loc, type, integer_minus_one_node);
4159
4160     case MAX_EXPR:
4161       if (SCALAR_FLOAT_TYPE_P (type))
4162         {
4163           REAL_VALUE_TYPE max, min;
4164           if (HONOR_INFINITIES (type))
4165             {
4166               real_inf (&max);
4167               real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
4168             }
4169           else
4170             real_maxval (&min, 1, TYPE_MODE (type));
4171           return build_real (type, min);
4172         }
4173       else if (POINTER_TYPE_P (type))
4174         {
4175           wide_int min
4176             = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
4177           return wide_int_to_tree (type, min);
4178         }
4179       else
4180         {
4181           gcc_assert (INTEGRAL_TYPE_P (type));
4182           return TYPE_MIN_VALUE (type);
4183         }
4184
4185     case MIN_EXPR:
4186       if (SCALAR_FLOAT_TYPE_P (type))
4187         {
4188           REAL_VALUE_TYPE max;
4189           if (HONOR_INFINITIES (type))
4190             real_inf (&max);
4191           else
4192             real_maxval (&max, 0, TYPE_MODE (type));
4193           return build_real (type, max);
4194         }
4195       else if (POINTER_TYPE_P (type))
4196         {
4197           wide_int max
4198             = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
4199           return wide_int_to_tree (type, max);
4200         }
4201       else
4202         {
4203           gcc_assert (INTEGRAL_TYPE_P (type));
4204           return TYPE_MAX_VALUE (type);
4205         }
4206
4207     default:
4208       gcc_unreachable ();
4209     }
4210 }
4211
4212 /* Construct the initialization value for reduction CLAUSE.  */
4213
4214 tree
4215 omp_reduction_init (tree clause, tree type)
4216 {
4217   return omp_reduction_init_op (OMP_CLAUSE_LOCATION (clause),
4218                                 OMP_CLAUSE_REDUCTION_CODE (clause), type);
4219 }
4220
4221 /* Return alignment to be assumed for var in CLAUSE, which should be
4222    OMP_CLAUSE_ALIGNED.  */
4223
4224 static tree
4225 omp_clause_aligned_alignment (tree clause)
4226 {
4227   if (OMP_CLAUSE_ALIGNED_ALIGNMENT (clause))
4228     return OMP_CLAUSE_ALIGNED_ALIGNMENT (clause);
4229
4230   /* Otherwise return implementation defined alignment.  */
4231   unsigned int al = 1;
4232   machine_mode mode, vmode;
4233   int vs = targetm.vectorize.autovectorize_vector_sizes ();
4234   if (vs)
4235     vs = 1 << floor_log2 (vs);
4236   static enum mode_class classes[]
4237     = { MODE_INT, MODE_VECTOR_INT, MODE_FLOAT, MODE_VECTOR_FLOAT };
4238   for (int i = 0; i < 4; i += 2)
4239     for (mode = GET_CLASS_NARROWEST_MODE (classes[i]);
4240          mode != VOIDmode;
4241          mode = GET_MODE_WIDER_MODE (mode))
4242       {
4243         vmode = targetm.vectorize.preferred_simd_mode (mode);
4244         if (GET_MODE_CLASS (vmode) != classes[i + 1])
4245           continue;
4246         while (vs
4247                && GET_MODE_SIZE (vmode) < vs
4248                && GET_MODE_2XWIDER_MODE (vmode) != VOIDmode)
4249           vmode = GET_MODE_2XWIDER_MODE (vmode);
4250         
4251         tree type = lang_hooks.types.type_for_mode (mode, 1);
4252         if (type == NULL_TREE || TYPE_MODE (type) != mode)
4253           continue;
4254         type = build_vector_type (type, GET_MODE_SIZE (vmode)
4255                                         / GET_MODE_SIZE (mode));
4256         if (TYPE_MODE (type) != vmode)
4257           continue;
4258         if (TYPE_ALIGN_UNIT (type) > al)
4259           al = TYPE_ALIGN_UNIT (type);
4260       }
4261   return build_int_cst (integer_type_node, al);
4262 }
4263
4264 /* Return maximum possible vectorization factor for the target.  */
4265
4266 static int
4267 omp_max_vf (void)
4268 {
4269   if (!optimize
4270       || optimize_debug
4271       || !flag_tree_loop_optimize
4272       || (!flag_tree_loop_vectorize
4273           && (global_options_set.x_flag_tree_loop_vectorize
4274               || global_options_set.x_flag_tree_vectorize)))
4275     return 1;
4276
4277   int vs = targetm.vectorize.autovectorize_vector_sizes ();
4278   if (vs)
4279     {
4280       vs = 1 << floor_log2 (vs);
4281       return vs;
4282     }
4283   machine_mode vqimode = targetm.vectorize.preferred_simd_mode (QImode);
4284   if (GET_MODE_CLASS (vqimode) == MODE_VECTOR_INT)
4285     return GET_MODE_NUNITS (vqimode);
4286   return 1;
4287 }
4288
4289 /* Helper function of lower_rec_input_clauses, used for #pragma omp simd
4290    privatization.  */
4291
4292 static bool
4293 lower_rec_simd_input_clauses (tree new_var, omp_context *ctx, int &max_vf,
4294                               tree &idx, tree &lane, tree &ivar, tree &lvar)
4295 {
4296   if (max_vf == 0)
4297     {
4298       max_vf = omp_max_vf ();
4299       if (max_vf > 1)
4300         {
4301           tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
4302                                     OMP_CLAUSE_SAFELEN);
4303           if (c && TREE_CODE (OMP_CLAUSE_SAFELEN_EXPR (c)) != INTEGER_CST)
4304             max_vf = 1;
4305           else if (c && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c),
4306                                           max_vf) == -1)
4307             max_vf = tree_to_shwi (OMP_CLAUSE_SAFELEN_EXPR (c));
4308         }
4309       if (max_vf > 1)
4310         {
4311           idx = create_tmp_var (unsigned_type_node);
4312           lane = create_tmp_var (unsigned_type_node);
4313         }
4314     }
4315   if (max_vf == 1)
4316     return false;
4317
4318   tree atype = build_array_type_nelts (TREE_TYPE (new_var), max_vf);
4319   tree avar = create_tmp_var_raw (atype);
4320   if (TREE_ADDRESSABLE (new_var))
4321     TREE_ADDRESSABLE (avar) = 1;
4322   DECL_ATTRIBUTES (avar)
4323     = tree_cons (get_identifier ("omp simd array"), NULL,
4324                  DECL_ATTRIBUTES (avar));
4325   gimple_add_tmp_var (avar);
4326   ivar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, idx,
4327                  NULL_TREE, NULL_TREE);
4328   lvar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, lane,
4329                  NULL_TREE, NULL_TREE);
4330   if (DECL_P (new_var))
4331     {
4332       SET_DECL_VALUE_EXPR (new_var, lvar);
4333       DECL_HAS_VALUE_EXPR_P (new_var) = 1;
4334     }
4335   return true;
4336 }
4337
4338 /* Helper function of lower_rec_input_clauses.  For a reference
4339    in simd reduction, add an underlying variable it will reference.  */
4340
4341 static void
4342 handle_simd_reference (location_t loc, tree new_vard, gimple_seq *ilist)
4343 {
4344   tree z = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_vard)));
4345   if (TREE_CONSTANT (z))
4346     {
4347       z = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_vard)),
4348                               get_name (new_vard));
4349       gimple_add_tmp_var (z);
4350       TREE_ADDRESSABLE (z) = 1;
4351       z = build_fold_addr_expr_loc (loc, z);
4352       gimplify_assign (new_vard, z, ilist);
4353     }
4354 }
4355
4356 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
4357    from the receiver (aka child) side and initializers for REFERENCE_TYPE
4358    private variables.  Initialization statements go in ILIST, while calls
4359    to destructors go in DLIST.  */
4360
4361 static void
4362 lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
4363                          omp_context *ctx, struct omp_for_data *fd)
4364 {
4365   tree c, dtor, copyin_seq, x, ptr;
4366   bool copyin_by_ref = false;
4367   bool lastprivate_firstprivate = false;
4368   bool reduction_omp_orig_ref = false;
4369   int pass;
4370   bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
4371                   && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD);
4372   int max_vf = 0;
4373   tree lane = NULL_TREE, idx = NULL_TREE;
4374   tree ivar = NULL_TREE, lvar = NULL_TREE;
4375   gimple_seq llist[2] = { NULL, NULL };
4376
4377   copyin_seq = NULL;
4378
4379   /* Set max_vf=1 (which will later enforce safelen=1) in simd loops
4380      with data sharing clauses referencing variable sized vars.  That
4381      is unnecessarily hard to support and very unlikely to result in
4382      vectorized code anyway.  */
4383   if (is_simd)
4384     for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
4385       switch (OMP_CLAUSE_CODE (c))
4386         {
4387         case OMP_CLAUSE_LINEAR:
4388           if (OMP_CLAUSE_LINEAR_ARRAY (c))
4389             max_vf = 1;
4390           /* FALLTHRU */
4391         case OMP_CLAUSE_PRIVATE:
4392         case OMP_CLAUSE_FIRSTPRIVATE:
4393         case OMP_CLAUSE_LASTPRIVATE:
4394           if (is_variable_sized (OMP_CLAUSE_DECL (c)))
4395             max_vf = 1;
4396           break;
4397         case OMP_CLAUSE_REDUCTION:
4398           if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
4399               || is_variable_sized (OMP_CLAUSE_DECL (c)))
4400             max_vf = 1;
4401           break;
4402         default:
4403           continue;
4404         }
4405
4406   /* Do all the fixed sized types in the first pass, and the variable sized
4407      types in the second pass.  This makes sure that the scalar arguments to
4408      the variable sized types are processed before we use them in the
4409      variable sized operations.  */
4410   for (pass = 0; pass < 2; ++pass)
4411     {
4412       for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
4413         {
4414           enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
4415           tree var, new_var;
4416           bool by_ref;
4417           location_t clause_loc = OMP_CLAUSE_LOCATION (c);
4418
4419           switch (c_kind)
4420             {
4421             case OMP_CLAUSE_PRIVATE:
4422               if (OMP_CLAUSE_PRIVATE_DEBUG (c))
4423                 continue;
4424               break;
4425             case OMP_CLAUSE_SHARED:
4426               /* Ignore shared directives in teams construct.  */
4427               if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
4428                 continue;
4429               if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
4430                 {
4431                   gcc_assert (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c)
4432                               || is_global_var (OMP_CLAUSE_DECL (c)));
4433                   continue;
4434                 }
4435             case OMP_CLAUSE_FIRSTPRIVATE:
4436             case OMP_CLAUSE_COPYIN:
4437               break;
4438             case OMP_CLAUSE_LINEAR:
4439               if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
4440                   && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
4441                 lastprivate_firstprivate = true;
4442               break;
4443             case OMP_CLAUSE_REDUCTION:
4444               if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
4445                 reduction_omp_orig_ref = true;
4446               break;
4447             case OMP_CLAUSE__LOOPTEMP_:
4448               /* Handle _looptemp_ clauses only on parallel/task.  */
4449               if (fd)
4450                 continue;
4451               break;
4452             case OMP_CLAUSE_LASTPRIVATE:
4453               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
4454                 {
4455                   lastprivate_firstprivate = true;
4456                   if (pass != 0 || is_taskloop_ctx (ctx))
4457                     continue;
4458                 }
4459               /* Even without corresponding firstprivate, if
4460                  decl is Fortran allocatable, it needs outer var
4461                  reference.  */
4462               else if (pass == 0
4463                        && lang_hooks.decls.omp_private_outer_ref
4464                                                         (OMP_CLAUSE_DECL (c)))
4465                 lastprivate_firstprivate = true;
4466               break;
4467             case OMP_CLAUSE_ALIGNED:
4468               if (pass == 0)
4469                 continue;
4470               var = OMP_CLAUSE_DECL (c);
4471               if (TREE_CODE (TREE_TYPE (var)) == POINTER_TYPE
4472                   && !is_global_var (var))
4473                 {
4474                   new_var = maybe_lookup_decl (var, ctx);
4475                   if (new_var == NULL_TREE)
4476                     new_var = maybe_lookup_decl_in_outer_ctx (var, ctx);
4477                   x = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
4478                   x = build_call_expr_loc (clause_loc, x, 2, new_var,
4479                                            omp_clause_aligned_alignment (c));
4480                   x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
4481                   x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
4482                   gimplify_and_add (x, ilist);
4483                 }
4484               else if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE
4485                        && is_global_var (var))
4486                 {
4487                   tree ptype = build_pointer_type (TREE_TYPE (var)), t, t2;
4488                   new_var = lookup_decl (var, ctx);
4489                   t = maybe_lookup_decl_in_outer_ctx (var, ctx);
4490                   t = build_fold_addr_expr_loc (clause_loc, t);
4491                   t2 = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
4492                   t = build_call_expr_loc (clause_loc, t2, 2, t,
4493                                            omp_clause_aligned_alignment (c));
4494                   t = fold_convert_loc (clause_loc, ptype, t);
4495                   x = create_tmp_var (ptype);
4496                   t = build2 (MODIFY_EXPR, ptype, x, t);
4497                   gimplify_and_add (t, ilist);
4498                   t = build_simple_mem_ref_loc (clause_loc, x);
4499                   SET_DECL_VALUE_EXPR (new_var, t);
4500                   DECL_HAS_VALUE_EXPR_P (new_var) = 1;
4501                 }
4502               continue;
4503             default:
4504               continue;
4505             }
4506
4507           new_var = var = OMP_CLAUSE_DECL (c);
4508           if (c_kind == OMP_CLAUSE_REDUCTION && TREE_CODE (var) == MEM_REF)
4509             {
4510               var = TREE_OPERAND (var, 0);
4511               if (TREE_CODE (var) == POINTER_PLUS_EXPR)
4512                 var = TREE_OPERAND (var, 0);
4513               if (TREE_CODE (var) == INDIRECT_REF
4514                   || TREE_CODE (var) == ADDR_EXPR)
4515                 var = TREE_OPERAND (var, 0);
4516               if (is_variable_sized (var))
4517                 {
4518                   gcc_assert (DECL_HAS_VALUE_EXPR_P (var));
4519                   var = DECL_VALUE_EXPR (var);
4520                   gcc_assert (TREE_CODE (var) == INDIRECT_REF);
4521                   var = TREE_OPERAND (var, 0);
4522                   gcc_assert (DECL_P (var));
4523                 }
4524               new_var = var;
4525             }
4526           if (c_kind != OMP_CLAUSE_COPYIN)
4527             new_var = lookup_decl (var, ctx);
4528
4529           if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
4530             {
4531               if (pass != 0)
4532                 continue;
4533             }
4534           /* C/C++ array section reductions.  */
4535           else if (c_kind == OMP_CLAUSE_REDUCTION
4536                    && var != OMP_CLAUSE_DECL (c))
4537             {
4538               if (pass == 0)
4539                 continue;
4540
4541               tree bias = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
4542               tree orig_var = TREE_OPERAND (OMP_CLAUSE_DECL (c), 0);
4543               if (TREE_CODE (orig_var) == POINTER_PLUS_EXPR)
4544                 {
4545                   tree b = TREE_OPERAND (orig_var, 1);
4546                   b = maybe_lookup_decl (b, ctx);
4547                   if (b == NULL)
4548                     {
4549                       b = TREE_OPERAND (orig_var, 1);
4550                       b = maybe_lookup_decl_in_outer_ctx (b, ctx);
4551                     }
4552                   if (integer_zerop (bias))
4553                     bias = b;
4554                   else
4555                     {
4556                       bias = fold_convert_loc (clause_loc,
4557                                                TREE_TYPE (b), bias);
4558                       bias = fold_build2_loc (clause_loc, PLUS_EXPR,
4559                                               TREE_TYPE (b), b, bias);
4560                     }
4561                   orig_var = TREE_OPERAND (orig_var, 0);
4562                 }
4563               if (TREE_CODE (orig_var) == INDIRECT_REF
4564                   || TREE_CODE (orig_var) == ADDR_EXPR)
4565                 orig_var = TREE_OPERAND (orig_var, 0);
4566               tree d = OMP_CLAUSE_DECL (c);
4567               tree type = TREE_TYPE (d);
4568               gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
4569               tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
4570               const char *name = get_name (orig_var);
4571               if (TREE_CONSTANT (v))
4572                 {
4573                   x = create_tmp_var_raw (type, name);
4574                   gimple_add_tmp_var (x);
4575                   TREE_ADDRESSABLE (x) = 1;
4576                   x = build_fold_addr_expr_loc (clause_loc, x);
4577                 }
4578               else
4579                 {
4580                   tree atmp
4581                     = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
4582                   tree t = maybe_lookup_decl (v, ctx);
4583                   if (t)
4584                     v = t;
4585                   else
4586                     v = maybe_lookup_decl_in_outer_ctx (v, ctx);
4587                   gimplify_expr (&v, ilist, NULL, is_gimple_val, fb_rvalue);
4588                   t = fold_build2_loc (clause_loc, PLUS_EXPR,
4589                                        TREE_TYPE (v), v,
4590                                        build_int_cst (TREE_TYPE (v), 1));
4591                   t = fold_build2_loc (clause_loc, MULT_EXPR,
4592                                        TREE_TYPE (v), t,
4593                                        TYPE_SIZE_UNIT (TREE_TYPE (type)));
4594                   tree al = size_int (TYPE_ALIGN (TREE_TYPE (type)));
4595                   x = build_call_expr_loc (clause_loc, atmp, 2, t, al);
4596                 }
4597
4598               tree ptype = build_pointer_type (TREE_TYPE (type));
4599               x = fold_convert_loc (clause_loc, ptype, x);
4600               tree y = create_tmp_var (ptype, name);
4601               gimplify_assign (y, x, ilist);
4602               x = y;
4603               tree yb = y;
4604
4605               if (!integer_zerop (bias))
4606                 {
4607                   bias = fold_convert_loc (clause_loc, pointer_sized_int_node,
4608                                            bias);
4609                   yb = fold_convert_loc (clause_loc, pointer_sized_int_node,
4610                                          x);
4611                   yb = fold_build2_loc (clause_loc, MINUS_EXPR,
4612                                         pointer_sized_int_node, yb, bias);
4613                   x = fold_convert_loc (clause_loc, TREE_TYPE (x), yb);
4614                   yb = create_tmp_var (ptype, name);
4615                   gimplify_assign (yb, x, ilist);
4616                   x = yb;
4617                 }
4618
4619               d = TREE_OPERAND (d, 0);
4620               if (TREE_CODE (d) == POINTER_PLUS_EXPR)
4621                 d = TREE_OPERAND (d, 0);
4622               if (TREE_CODE (d) == ADDR_EXPR)
4623                 {
4624                   if (orig_var != var)
4625                     {
4626                       gcc_assert (is_variable_sized (orig_var));
4627                       x = fold_convert_loc (clause_loc, TREE_TYPE (new_var),
4628                                             x);
4629                       gimplify_assign (new_var, x, ilist);
4630                       tree new_orig_var = lookup_decl (orig_var, ctx);
4631                       tree t = build_fold_indirect_ref (new_var);
4632                       DECL_IGNORED_P (new_var) = 0;
4633                       TREE_THIS_NOTRAP (t);
4634                       SET_DECL_VALUE_EXPR (new_orig_var, t);
4635                       DECL_HAS_VALUE_EXPR_P (new_orig_var) = 1;
4636                     }
4637                   else
4638                     {
4639                       x = build2 (MEM_REF, TREE_TYPE (new_var), x,
4640                                   build_int_cst (ptype, 0));
4641                       SET_DECL_VALUE_EXPR (new_var, x);
4642                       DECL_HAS_VALUE_EXPR_P (new_var) = 1;
4643                     }
4644                 }
4645               else
4646                 {
4647                   gcc_assert (orig_var == var);
4648                   if (TREE_CODE (d) == INDIRECT_REF)
4649                     {
4650                       x = create_tmp_var (ptype, name);
4651                       TREE_ADDRESSABLE (x) = 1;
4652                       gimplify_assign (x, yb, ilist);
4653                       x = build_fold_addr_expr_loc (clause_loc, x);
4654                     }
4655                   x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
4656                   gimplify_assign (new_var, x, ilist);
4657                 }
4658               tree y1 = create_tmp_var (ptype, NULL);
4659               gimplify_assign (y1, y, ilist);
4660               tree i2 = NULL_TREE, y2 = NULL_TREE;
4661               tree body2 = NULL_TREE, end2 = NULL_TREE;
4662               tree y3 = NULL_TREE, y4 = NULL_TREE;
4663               if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) || is_simd)
4664                 {
4665                   y2 = create_tmp_var (ptype, NULL);
4666                   gimplify_assign (y2, y, ilist);
4667                   tree ref = build_outer_var_ref (var, ctx);
4668                   /* For ref build_outer_var_ref already performs this.  */
4669                   if (TREE_CODE (d) == INDIRECT_REF)
4670                     gcc_assert (is_reference (var));
4671                   else if (TREE_CODE (d) == ADDR_EXPR)
4672                     ref = build_fold_addr_expr (ref);
4673                   else if (is_reference (var))
4674                     ref = build_fold_addr_expr (ref);
4675                   ref = fold_convert_loc (clause_loc, ptype, ref);
4676                   if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
4677                       && OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
4678                     {
4679                       y3 = create_tmp_var (ptype, NULL);
4680                       gimplify_assign (y3, unshare_expr (ref), ilist);
4681                     }
4682                   if (is_simd)
4683                     {
4684                       y4 = create_tmp_var (ptype, NULL);
4685                       gimplify_assign (y4, ref, dlist);
4686                     }
4687                 }
4688               tree i = create_tmp_var (TREE_TYPE (v), NULL);
4689               gimplify_assign (i, build_int_cst (TREE_TYPE (v), 0), ilist);
4690               tree body = create_artificial_label (UNKNOWN_LOCATION);
4691               tree end = create_artificial_label (UNKNOWN_LOCATION);
4692               gimple_seq_add_stmt (ilist, gimple_build_label (body));
4693               if (y2)
4694                 {
4695                   i2 = create_tmp_var (TREE_TYPE (v), NULL);
4696                   gimplify_assign (i2, build_int_cst (TREE_TYPE (v), 0), dlist);
4697                   body2 = create_artificial_label (UNKNOWN_LOCATION);
4698                   end2 = create_artificial_label (UNKNOWN_LOCATION);
4699                   gimple_seq_add_stmt (dlist, gimple_build_label (body2));
4700                 }
4701               if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
4702                 {
4703                   tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
4704                   tree decl_placeholder
4705                     = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c);
4706                   SET_DECL_VALUE_EXPR (decl_placeholder,
4707                                        build_simple_mem_ref (y1));
4708                   DECL_HAS_VALUE_EXPR_P (decl_placeholder) = 1;
4709                   SET_DECL_VALUE_EXPR (placeholder,
4710                                        y3 ? build_simple_mem_ref (y3)
4711                                        : error_mark_node);
4712                   DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
4713                   x = lang_hooks.decls.omp_clause_default_ctor
4714                                 (c, build_simple_mem_ref (y1),
4715                                  y3 ? build_simple_mem_ref (y3) : NULL_TREE);
4716                   if (x)
4717                     gimplify_and_add (x, ilist);
4718                   if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
4719                     {
4720                       gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
4721                       lower_omp (&tseq, ctx);
4722                       gimple_seq_add_seq (ilist, tseq);
4723                     }
4724                   OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
4725                   if (is_simd)
4726                     {
4727                       SET_DECL_VALUE_EXPR (decl_placeholder,
4728                                            build_simple_mem_ref (y2));
4729                       SET_DECL_VALUE_EXPR (placeholder,
4730                                            build_simple_mem_ref (y4));
4731                       gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
4732                       lower_omp (&tseq, ctx);
4733                       gimple_seq_add_seq (dlist, tseq);
4734                       OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
4735                     }
4736                   DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
4737                   DECL_HAS_VALUE_EXPR_P (decl_placeholder) = 0;
4738                   x = lang_hooks.decls.omp_clause_dtor
4739                                         (c, build_simple_mem_ref (y2));
4740                   if (x)
4741                     {
4742                       gimple_seq tseq = NULL;
4743                       dtor = x;
4744                       gimplify_stmt (&dtor, &tseq);
4745                       gimple_seq_add_seq (dlist, tseq);
4746                     }
4747                 }
4748               else
4749                 {
4750                   x = omp_reduction_init (c, TREE_TYPE (type));
4751                   enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
4752
4753                   /* reduction(-:var) sums up the partial results, so it
4754                      acts identically to reduction(+:var).  */
4755                   if (code == MINUS_EXPR)
4756                     code = PLUS_EXPR;
4757
4758                   gimplify_assign (build_simple_mem_ref (y1), x, ilist);
4759                   if (is_simd)
4760                     {
4761                       x = build2 (code, TREE_TYPE (type),
4762                                   build_simple_mem_ref (y4),
4763                                   build_simple_mem_ref (y2));
4764                       gimplify_assign (build_simple_mem_ref (y4), x, dlist);
4765                     }
4766                 }
4767               gimple *g
4768                 = gimple_build_assign (y1, POINTER_PLUS_EXPR, y1,
4769                                        TYPE_SIZE_UNIT (TREE_TYPE (type)));
4770               gimple_seq_add_stmt (ilist, g);
4771               if (y3)
4772                 {
4773                   g = gimple_build_assign (y3, POINTER_PLUS_EXPR, y3,
4774                                            TYPE_SIZE_UNIT (TREE_TYPE (type)));
4775                   gimple_seq_add_stmt (ilist, g);
4776                 }
4777               g = gimple_build_assign (i, PLUS_EXPR, i,
4778                                        build_int_cst (TREE_TYPE (i), 1));
4779               gimple_seq_add_stmt (ilist, g);
4780               g = gimple_build_cond (LE_EXPR, i, v, body, end);
4781               gimple_seq_add_stmt (ilist, g);
4782               gimple_seq_add_stmt (ilist, gimple_build_label (end));
4783               if (y2)
4784                 {
4785                   g = gimple_build_assign (y2, POINTER_PLUS_EXPR, y2,
4786                                            TYPE_SIZE_UNIT (TREE_TYPE (type)));
4787                   gimple_seq_add_stmt (dlist, g);
4788                   if (y4)
4789                     {
4790                       g = gimple_build_assign
4791                                         (y4, POINTER_PLUS_EXPR, y4,
4792                                          TYPE_SIZE_UNIT (TREE_TYPE (type)));
4793                       gimple_seq_add_stmt (dlist, g);
4794                     }
4795                   g = gimple_build_assign (i2, PLUS_EXPR, i2,
4796                                            build_int_cst (TREE_TYPE (i2), 1));
4797                   gimple_seq_add_stmt (dlist, g);
4798                   g = gimple_build_cond (LE_EXPR, i2, v, body2, end2);
4799                   gimple_seq_add_stmt (dlist, g);
4800                   gimple_seq_add_stmt (dlist, gimple_build_label (end2));
4801                 }
4802               continue;
4803             }
4804           else if (is_variable_sized (var))
4805             {
4806               /* For variable sized types, we need to allocate the
4807                  actual storage here.  Call alloca and store the
4808                  result in the pointer decl that we created elsewhere.  */
4809               if (pass == 0)
4810                 continue;
4811
4812               if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
4813                 {
4814                   gcall *stmt;
4815                   tree tmp, atmp;
4816
4817                   ptr = DECL_VALUE_EXPR (new_var);
4818                   gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
4819                   ptr = TREE_OPERAND (ptr, 0);
4820                   gcc_assert (DECL_P (ptr));
4821                   x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
4822
4823                   /* void *tmp = __builtin_alloca */
4824                   atmp = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
4825                   stmt = gimple_build_call (atmp, 2, x,
4826                                             size_int (DECL_ALIGN (var)));
4827                   tmp = create_tmp_var_raw (ptr_type_node);
4828                   gimple_add_tmp_var (tmp);
4829                   gimple_call_set_lhs (stmt, tmp);
4830
4831                   gimple_seq_add_stmt (ilist, stmt);
4832
4833                   x = fold_convert_loc (clause_loc, TREE_TYPE (ptr), tmp);
4834                   gimplify_assign (ptr, x, ilist);
4835                 }
4836             }
4837           else if (is_reference (var))
4838             {
4839               /* For references that are being privatized for Fortran,
4840                  allocate new backing storage for the new pointer
4841                  variable.  This allows us to avoid changing all the
4842                  code that expects a pointer to something that expects
4843                  a direct variable.  */
4844               if (pass == 0)
4845                 continue;
4846
4847               x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
4848               if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
4849                 {
4850                   x = build_receiver_ref (var, false, ctx);
4851                   x = build_fold_addr_expr_loc (clause_loc, x);
4852                 }
4853               else if (TREE_CONSTANT (x))
4854                 {
4855                   /* For reduction in SIMD loop, defer adding the
4856                      initialization of the reference, because if we decide
4857                      to use SIMD array for it, the initilization could cause
4858                      expansion ICE.  */
4859                   if (c_kind == OMP_CLAUSE_REDUCTION && is_simd)
4860                     x = NULL_TREE;
4861                   else
4862                     {
4863                       x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
4864                                               get_name (var));
4865                       gimple_add_tmp_var (x);
4866                       TREE_ADDRESSABLE (x) = 1;
4867                       x = build_fold_addr_expr_loc (clause_loc, x);
4868                     }
4869                 }
4870               else
4871                 {
4872                   tree atmp
4873                     = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
4874                   tree rtype = TREE_TYPE (TREE_TYPE (new_var));
4875                   tree al = size_int (TYPE_ALIGN (rtype));
4876                   x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
4877                 }
4878
4879               if (x)
4880                 {
4881                   x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
4882                   gimplify_assign (new_var, x, ilist);
4883                 }
4884
4885               new_var = build_simple_mem_ref_loc (clause_loc, new_var);
4886             }
4887           else if (c_kind == OMP_CLAUSE_REDUCTION
4888                    && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
4889             {
4890               if (pass == 0)
4891                 continue;
4892             }
4893           else if (pass != 0)
4894             continue;
4895
4896           switch (OMP_CLAUSE_CODE (c))
4897             {
4898             case OMP_CLAUSE_SHARED:
4899               /* Ignore shared directives in teams construct.  */
4900               if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
4901                 continue;
4902               /* Shared global vars are just accessed directly.  */
4903               if (is_global_var (new_var))
4904                 break;
4905               /* For taskloop firstprivate/lastprivate, represented
4906                  as firstprivate and shared clause on the task, new_var
4907                  is the firstprivate var.  */
4908               if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
4909                 break;
4910               /* Set up the DECL_VALUE_EXPR for shared variables now.  This
4911                  needs to be delayed until after fixup_child_record_type so
4912                  that we get the correct type during the dereference.  */
4913               by_ref = use_pointer_for_field (var, ctx);
4914               x = build_receiver_ref (var, by_ref, ctx);
4915               SET_DECL_VALUE_EXPR (new_var, x);
4916               DECL_HAS_VALUE_EXPR_P (new_var) = 1;
4917
4918               /* ??? If VAR is not passed by reference, and the variable
4919                  hasn't been initialized yet, then we'll get a warning for
4920                  the store into the omp_data_s structure.  Ideally, we'd be
4921                  able to notice this and not store anything at all, but
4922                  we're generating code too early.  Suppress the warning.  */
4923               if (!by_ref)
4924                 TREE_NO_WARNING (var) = 1;
4925               break;
4926
4927             case OMP_CLAUSE_LASTPRIVATE:
4928               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
4929                 break;
4930               /* FALLTHRU */
4931
4932             case OMP_CLAUSE_PRIVATE:
4933               if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE)
4934                 x = build_outer_var_ref (var, ctx);
4935               else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
4936                 {
4937                   if (is_task_ctx (ctx))
4938                     x = build_receiver_ref (var, false, ctx);
4939                   else
4940                     x = build_outer_var_ref (var, ctx);
4941                 }
4942               else
4943                 x = NULL;
4944             do_private:
4945               tree nx;
4946               nx = lang_hooks.decls.omp_clause_default_ctor
4947                                                 (c, unshare_expr (new_var), x);
4948               if (is_simd)
4949                 {
4950                   tree y = lang_hooks.decls.omp_clause_dtor (c, new_var);
4951                   if ((TREE_ADDRESSABLE (new_var) || nx || y
4952                        || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
4953                       && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
4954                                                        idx, lane, ivar, lvar))
4955                     {
4956                       if (nx)
4957                         x = lang_hooks.decls.omp_clause_default_ctor
4958                                                 (c, unshare_expr (ivar), x);
4959                       if (nx && x)
4960                         gimplify_and_add (x, &llist[0]);
4961                       if (y)
4962                         {
4963                           y = lang_hooks.decls.omp_clause_dtor (c, ivar);
4964                           if (y)
4965                             {
4966                               gimple_seq tseq = NULL;
4967
4968                               dtor = y;
4969                               gimplify_stmt (&dtor, &tseq);
4970                               gimple_seq_add_seq (&llist[1], tseq);
4971                             }
4972                         }
4973                       break;
4974                     }
4975                 }
4976               if (nx)
4977                 gimplify_and_add (nx, ilist);
4978               /* FALLTHRU */
4979
4980             do_dtor:
4981               x = lang_hooks.decls.omp_clause_dtor (c, new_var);
4982               if (x)
4983                 {
4984                   gimple_seq tseq = NULL;
4985
4986                   dtor = x;
4987                   gimplify_stmt (&dtor, &tseq);
4988                   gimple_seq_add_seq (dlist, tseq);
4989                 }
4990               break;
4991
4992             case OMP_CLAUSE_LINEAR:
4993               if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
4994                 goto do_firstprivate;
4995               if (OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
4996                 x = NULL;
4997               else
4998                 x = build_outer_var_ref (var, ctx);
4999               goto do_private;
5000
5001             case OMP_CLAUSE_FIRSTPRIVATE:
5002               if (is_task_ctx (ctx))
5003                 {
5004                   if (is_reference (var) || is_variable_sized (var))
5005                     goto do_dtor;
5006                   else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var,
5007                                                                           ctx))
5008                            || use_pointer_for_field (var, NULL))
5009                     {
5010                       x = build_receiver_ref (var, false, ctx);
5011                       SET_DECL_VALUE_EXPR (new_var, x);
5012                       DECL_HAS_VALUE_EXPR_P (new_var) = 1;
5013                       goto do_dtor;
5014                     }
5015                 }
5016             do_firstprivate:
5017               x = build_outer_var_ref (var, ctx);
5018               if (is_simd)
5019                 {
5020                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
5021                       && gimple_omp_for_combined_into_p (ctx->stmt))
5022                     {
5023                       tree t = OMP_CLAUSE_LINEAR_STEP (c);
5024                       tree stept = TREE_TYPE (t);
5025                       tree ct = find_omp_clause (clauses,
5026                                                  OMP_CLAUSE__LOOPTEMP_);
5027                       gcc_assert (ct);
5028                       tree l = OMP_CLAUSE_DECL (ct);
5029                       tree n1 = fd->loop.n1;
5030                       tree step = fd->loop.step;
5031                       tree itype = TREE_TYPE (l);
5032                       if (POINTER_TYPE_P (itype))
5033                         itype = signed_type_for (itype);
5034                       l = fold_build2 (MINUS_EXPR, itype, l, n1);
5035                       if (TYPE_UNSIGNED (itype)
5036                           && fd->loop.cond_code == GT_EXPR)
5037                         l = fold_build2 (TRUNC_DIV_EXPR, itype,
5038                                          fold_build1 (NEGATE_EXPR, itype, l),
5039                                          fold_build1 (NEGATE_EXPR,
5040                                                       itype, step));
5041                       else
5042                         l = fold_build2 (TRUNC_DIV_EXPR, itype, l, step);
5043                       t = fold_build2 (MULT_EXPR, stept,
5044                                        fold_convert (stept, l), t);
5045
5046                       if (OMP_CLAUSE_LINEAR_ARRAY (c))
5047                         {
5048                           x = lang_hooks.decls.omp_clause_linear_ctor
5049                                                         (c, new_var, x, t);
5050                           gimplify_and_add (x, ilist);
5051                           goto do_dtor;
5052                         }
5053
5054                       if (POINTER_TYPE_P (TREE_TYPE (x)))
5055                         x = fold_build2 (POINTER_PLUS_EXPR,
5056                                          TREE_TYPE (x), x, t);
5057                       else
5058                         x = fold_build2 (PLUS_EXPR, TREE_TYPE (x), x, t);
5059                     }
5060
5061                   if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
5062                        || TREE_ADDRESSABLE (new_var))
5063                       && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
5064                                                        idx, lane, ivar, lvar))
5065                     {
5066                       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
5067                         {
5068                           tree iv = create_tmp_var (TREE_TYPE (new_var));
5069                           x = lang_hooks.decls.omp_clause_copy_ctor (c, iv, x);
5070                           gimplify_and_add (x, ilist);
5071                           gimple_stmt_iterator gsi
5072                             = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt));
5073                           gassign *g
5074                             = gimple_build_assign (unshare_expr (lvar), iv);
5075                           gsi_insert_before_without_update (&gsi, g,
5076                                                             GSI_SAME_STMT);
5077                           tree t = OMP_CLAUSE_LINEAR_STEP (c);
5078                           enum tree_code code = PLUS_EXPR;
5079                           if (POINTER_TYPE_P (TREE_TYPE (new_var)))
5080                             code = POINTER_PLUS_EXPR;
5081                           g = gimple_build_assign (iv, code, iv, t);
5082                           gsi_insert_before_without_update (&gsi, g,
5083                                                             GSI_SAME_STMT);
5084                           break;
5085                         }
5086                       x = lang_hooks.decls.omp_clause_copy_ctor
5087                                                 (c, unshare_expr (ivar), x);
5088                       gimplify_and_add (x, &llist[0]);
5089                       x = lang_hooks.decls.omp_clause_dtor (c, ivar);
5090                       if (x)
5091                         {
5092                           gimple_seq tseq = NULL;
5093
5094                           dtor = x;
5095                           gimplify_stmt (&dtor, &tseq);
5096                           gimple_seq_add_seq (&llist[1], tseq);
5097                         }
5098                       break;
5099                     }
5100                 }
5101               x = lang_hooks.decls.omp_clause_copy_ctor
5102                                                 (c, unshare_expr (new_var), x);
5103               gimplify_and_add (x, ilist);
5104               goto do_dtor;
5105
5106             case OMP_CLAUSE__LOOPTEMP_:
5107               gcc_assert (is_taskreg_ctx (ctx));
5108               x = build_outer_var_ref (var, ctx);
5109               x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
5110               gimplify_and_add (x, ilist);
5111               break;
5112
5113             case OMP_CLAUSE_COPYIN:
5114               by_ref = use_pointer_for_field (var, NULL);
5115               x = build_receiver_ref (var, by_ref, ctx);
5116               x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
5117               append_to_statement_list (x, &copyin_seq);
5118               copyin_by_ref |= by_ref;
5119               break;
5120
5121             case OMP_CLAUSE_REDUCTION:
5122               /* OpenACC reductions are initialized using the
5123                  GOACC_REDUCTION internal function.  */
5124               if (is_gimple_omp_oacc (ctx->stmt))
5125                 break;
5126               if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
5127                 {
5128                   tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
5129                   gimple *tseq;
5130                   x = build_outer_var_ref (var, ctx);
5131
5132                   if (is_reference (var)
5133                       && !useless_type_conversion_p (TREE_TYPE (placeholder),
5134                                                      TREE_TYPE (x)))
5135                     x = build_fold_addr_expr_loc (clause_loc, x);
5136                   SET_DECL_VALUE_EXPR (placeholder, x);
5137                   DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
5138                   tree new_vard = new_var;
5139                   if (is_reference (var))
5140                     {
5141                       gcc_assert (TREE_CODE (new_var) == MEM_REF);
5142                       new_vard = TREE_OPERAND (new_var, 0);
5143                       gcc_assert (DECL_P (new_vard));
5144                     }
5145                   if (is_simd
5146                       && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
5147                                                        idx, lane, ivar, lvar))
5148                     {
5149                       if (new_vard == new_var)
5150                         {
5151                           gcc_assert (DECL_VALUE_EXPR (new_var) == lvar);
5152                           SET_DECL_VALUE_EXPR (new_var, ivar);
5153                         }
5154                       else
5155                         {
5156                           SET_DECL_VALUE_EXPR (new_vard,
5157                                                build_fold_addr_expr (ivar));
5158                           DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
5159                         }
5160                       x = lang_hooks.decls.omp_clause_default_ctor
5161                                 (c, unshare_expr (ivar),
5162                                  build_outer_var_ref (var, ctx));
5163                       if (x)
5164                         gimplify_and_add (x, &llist[0]);
5165                       if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
5166                         {
5167                           tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
5168                           lower_omp (&tseq, ctx);
5169                           gimple_seq_add_seq (&llist[0], tseq);
5170                         }
5171                       OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
5172                       tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
5173                       lower_omp (&tseq, ctx);
5174                       gimple_seq_add_seq (&llist[1], tseq);
5175                       OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
5176                       DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
5177                       if (new_vard == new_var)
5178                         SET_DECL_VALUE_EXPR (new_var, lvar);
5179                       else
5180                         SET_DECL_VALUE_EXPR (new_vard,
5181                                              build_fold_addr_expr (lvar));
5182                       x = lang_hooks.decls.omp_clause_dtor (c, ivar);
5183                       if (x)
5184                         {
5185                           tseq = NULL;
5186                           dtor = x;
5187                           gimplify_stmt (&dtor, &tseq);
5188                           gimple_seq_add_seq (&llist[1], tseq);
5189                         }
5190                       break;
5191                     }
5192                   /* If this is a reference to constant size reduction var
5193                      with placeholder, we haven't emitted the initializer
5194                      for it because it is undesirable if SIMD arrays are used.
5195                      But if they aren't used, we need to emit the deferred
5196                      initialization now.  */
5197                   else if (is_reference (var) && is_simd)
5198                     handle_simd_reference (clause_loc, new_vard, ilist);
5199                   x = lang_hooks.decls.omp_clause_default_ctor
5200                                 (c, unshare_expr (new_var),
5201                                  build_outer_var_ref (var, ctx));
5202                   if (x)
5203                     gimplify_and_add (x, ilist);
5204                   if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
5205                     {
5206                       tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
5207                       lower_omp (&tseq, ctx);
5208                       gimple_seq_add_seq (ilist, tseq);
5209                     }
5210                   OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
5211                   if (is_simd)
5212                     {
5213                       tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
5214                       lower_omp (&tseq, ctx);
5215                       gimple_seq_add_seq (dlist, tseq);
5216                       OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
5217                     }
5218                   DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
5219                   goto do_dtor;
5220                 }
5221               else
5222                 {
5223                   x = omp_reduction_init (c, TREE_TYPE (new_var));
5224                   gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
5225                   enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
5226
5227                   /* reduction(-:var) sums up the partial results, so it
5228                      acts identically to reduction(+:var).  */
5229                   if (code == MINUS_EXPR)
5230                     code = PLUS_EXPR;
5231
5232                   tree new_vard = new_var;
5233                   if (is_simd && is_reference (var))
5234                     {
5235                       gcc_assert (TREE_CODE (new_var) == MEM_REF);
5236                       new_vard = TREE_OPERAND (new_var, 0);
5237                       gcc_assert (DECL_P (new_vard));
5238                     }
5239                   if (is_simd
5240                       && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
5241                                                        idx, lane, ivar, lvar))
5242                     {
5243                       tree ref = build_outer_var_ref (var, ctx);
5244
5245                       gimplify_assign (unshare_expr (ivar), x, &llist[0]);
5246
5247                       x = build2 (code, TREE_TYPE (ref), ref, ivar);
5248                       ref = build_outer_var_ref (var, ctx);
5249                       gimplify_assign (ref, x, &llist[1]);
5250
5251                       if (new_vard != new_var)
5252                         {
5253                           SET_DECL_VALUE_EXPR (new_vard,
5254                                                build_fold_addr_expr (lvar));
5255                           DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
5256                         }
5257                     }
5258                   else
5259                     {
5260                       if (is_reference (var) && is_simd)
5261                         handle_simd_reference (clause_loc, new_vard, ilist);
5262                       gimplify_assign (new_var, x, ilist);
5263                       if (is_simd)
5264                         {
5265                           tree ref = build_outer_var_ref (var, ctx);
5266
5267                           x = build2 (code, TREE_TYPE (ref), ref, new_var);
5268                           ref = build_outer_var_ref (var, ctx);
5269                           gimplify_assign (ref, x, dlist);
5270                         }
5271                     }
5272                 }
5273               break;
5274
5275             default:
5276               gcc_unreachable ();
5277             }
5278         }
5279     }
5280
5281   if (lane)
5282     {
5283       tree uid = create_tmp_var (ptr_type_node, "simduid");
5284       /* Don't want uninit warnings on simduid, it is always uninitialized,
5285          but we use it not for the value, but for the DECL_UID only.  */
5286       TREE_NO_WARNING (uid) = 1;
5287       gimple *g
5288         = gimple_build_call_internal (IFN_GOMP_SIMD_LANE, 1, uid);
5289       gimple_call_set_lhs (g, lane);
5290       gimple_stmt_iterator gsi = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt));
5291       gsi_insert_before_without_update (&gsi, g, GSI_SAME_STMT);
5292       c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SIMDUID_);
5293       OMP_CLAUSE__SIMDUID__DECL (c) = uid;
5294       OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
5295       gimple_omp_for_set_clauses (ctx->stmt, c);
5296       g = gimple_build_assign (lane, INTEGER_CST,
5297                                build_int_cst (unsigned_type_node, 0));
5298       gimple_seq_add_stmt (ilist, g);
5299       for (int i = 0; i < 2; i++)
5300         if (llist[i])
5301           {
5302             tree vf = create_tmp_var (unsigned_type_node);
5303             g = gimple_build_call_internal (IFN_GOMP_SIMD_VF, 1, uid);
5304             gimple_call_set_lhs (g, vf);
5305             gimple_seq *seq = i == 0 ? ilist : dlist;
5306             gimple_seq_add_stmt (seq, g);
5307             tree t = build_int_cst (unsigned_type_node, 0);
5308             g = gimple_build_assign (idx, INTEGER_CST, t);
5309             gimple_seq_add_stmt (seq, g);
5310             tree body = create_artificial_label (UNKNOWN_LOCATION);
5311             tree header = create_artificial_label (UNKNOWN_LOCATION);
5312             tree end = create_artificial_label (UNKNOWN_LOCATION);
5313             gimple_seq_add_stmt (seq, gimple_build_goto (header));
5314             gimple_seq_add_stmt (seq, gimple_build_label (body));
5315             gimple_seq_add_seq (seq, llist[i]);
5316             t = build_int_cst (unsigned_type_node, 1);
5317             g = gimple_build_assign (idx, PLUS_EXPR, idx, t);
5318             gimple_seq_add_stmt (seq, g);
5319             gimple_seq_add_stmt (seq, gimple_build_label (header));
5320             g = gimple_build_cond (LT_EXPR, idx, vf, body, end);
5321             gimple_seq_add_stmt (seq, g);
5322             gimple_seq_add_stmt (seq, gimple_build_label (end));
5323           }
5324     }
5325
5326   /* The copyin sequence is not to be executed by the main thread, since
5327      that would result in self-copies.  Perhaps not visible to scalars,
5328      but it certainly is to C++ operator=.  */
5329   if (copyin_seq)
5330     {
5331       x = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM),
5332                            0);
5333       x = build2 (NE_EXPR, boolean_type_node, x,
5334                   build_int_cst (TREE_TYPE (x), 0));
5335       x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
5336       gimplify_and_add (x, ilist);
5337     }
5338
5339   /* If any copyin variable is passed by reference, we must ensure the
5340      master thread doesn't modify it before it is copied over in all
5341      threads.  Similarly for variables in both firstprivate and
5342      lastprivate clauses we need to ensure the lastprivate copying
5343      happens after firstprivate copying in all threads.  And similarly
5344      for UDRs if initializer expression refers to omp_orig.  */
5345   if (copyin_by_ref || lastprivate_firstprivate || reduction_omp_orig_ref)
5346     {
5347       /* Don't add any barrier for #pragma omp simd or
5348          #pragma omp distribute.  */
5349       if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
5350           || gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_FOR)
5351         gimple_seq_add_stmt (ilist, build_omp_barrier (NULL_TREE));
5352     }
5353
5354   /* If max_vf is non-zero, then we can use only a vectorization factor
5355      up to the max_vf we chose.  So stick it into the safelen clause.  */
5356   if (max_vf)
5357     {
5358       tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
5359                                 OMP_CLAUSE_SAFELEN);
5360       if (c == NULL_TREE
5361           || (TREE_CODE (OMP_CLAUSE_SAFELEN_EXPR (c)) == INTEGER_CST
5362               && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c),
5363                                    max_vf) == 1))
5364         {
5365           c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
5366           OMP_CLAUSE_SAFELEN_EXPR (c) = build_int_cst (integer_type_node,
5367                                                        max_vf);
5368           OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
5369           gimple_omp_for_set_clauses (ctx->stmt, c);
5370         }
5371     }
5372 }
5373
5374
5375 /* Generate code to implement the LASTPRIVATE clauses.  This is used for
5376    both parallel and workshare constructs.  PREDICATE may be NULL if it's
5377    always true.   */
5378
5379 static void
5380 lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
5381                            omp_context *ctx)
5382 {
5383   tree x, c, label = NULL, orig_clauses = clauses;
5384   bool par_clauses = false;
5385   tree simduid = NULL, lastlane = NULL;
5386
5387   /* Early exit if there are no lastprivate or linear clauses.  */
5388   for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
5389     if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LASTPRIVATE
5390         || (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LINEAR
5391             && !OMP_CLAUSE_LINEAR_NO_COPYOUT (clauses)))
5392       break;
5393   if (clauses == NULL)
5394     {
5395       /* If this was a workshare clause, see if it had been combined
5396          with its parallel.  In that case, look for the clauses on the
5397          parallel statement itself.  */
5398       if (is_parallel_ctx (ctx))
5399         return;
5400
5401       ctx = ctx->outer;
5402       if (ctx == NULL || !is_parallel_ctx (ctx))
5403         return;
5404
5405       clauses = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
5406                                  OMP_CLAUSE_LASTPRIVATE);
5407       if (clauses == NULL)
5408         return;
5409       par_clauses = true;
5410     }
5411
5412   if (predicate)
5413     {
5414       gcond *stmt;
5415       tree label_true, arm1, arm2;
5416
5417       label = create_artificial_label (UNKNOWN_LOCATION);
5418       label_true = create_artificial_label (UNKNOWN_LOCATION);
5419       arm1 = TREE_OPERAND (predicate, 0);
5420       arm2 = TREE_OPERAND (predicate, 1);
5421       gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
5422       gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
5423       stmt = gimple_build_cond (TREE_CODE (predicate), arm1, arm2,
5424                                 label_true, label);
5425       gimple_seq_add_stmt (stmt_list, stmt);
5426       gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
5427     }
5428
5429   if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
5430       && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
5431     {
5432       simduid = find_omp_clause (orig_clauses, OMP_CLAUSE__SIMDUID_);
5433       if (simduid)
5434         simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
5435     }
5436
5437   for (c = clauses; c ;)
5438     {
5439       tree var, new_var;
5440       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
5441
5442       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
5443           || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
5444               && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
5445         {
5446           var = OMP_CLAUSE_DECL (c);
5447           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
5448               && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
5449               && is_taskloop_ctx (ctx))
5450             {
5451               gcc_checking_assert (ctx->outer && is_task_ctx (ctx->outer));
5452               new_var = lookup_decl (var, ctx->outer);
5453             }
5454           else
5455             new_var = lookup_decl (var, ctx);
5456
5457           if (simduid && DECL_HAS_VALUE_EXPR_P (new_var))
5458             {
5459               tree val = DECL_VALUE_EXPR (new_var);
5460               if (TREE_CODE (val) == ARRAY_REF
5461                   && VAR_P (TREE_OPERAND (val, 0))
5462                   && lookup_attribute ("omp simd array",
5463                                        DECL_ATTRIBUTES (TREE_OPERAND (val,
5464                                                                       0))))
5465                 {
5466                   if (lastlane == NULL)
5467                     {
5468                       lastlane = create_tmp_var (unsigned_type_node);
5469                       gcall *g
5470                         = gimple_build_call_internal (IFN_GOMP_SIMD_LAST_LANE,
5471                                                       2, simduid,
5472                                                       TREE_OPERAND (val, 1));
5473                       gimple_call_set_lhs (g, lastlane);
5474                       gimple_seq_add_stmt (stmt_list, g);
5475                     }
5476                   new_var = build4 (ARRAY_REF, TREE_TYPE (val),
5477                                     TREE_OPERAND (val, 0), lastlane,
5478                                     NULL_TREE, NULL_TREE);
5479                 }
5480             }
5481
5482           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
5483               && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
5484             {
5485               lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
5486               gimple_seq_add_seq (stmt_list,
5487                                   OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
5488               OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
5489             }
5490           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
5491                    && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
5492             {
5493               lower_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
5494               gimple_seq_add_seq (stmt_list,
5495                                   OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
5496               OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) = NULL;
5497             }
5498
5499           x = NULL_TREE;
5500           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
5501               && OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c))
5502             {
5503               gcc_checking_assert (is_taskloop_ctx (ctx));
5504               tree ovar = maybe_lookup_decl_in_outer_ctx (var,
5505                                                           ctx->outer->outer);
5506               if (is_global_var (ovar))
5507                 x = ovar;
5508             }
5509           if (!x)
5510             x = build_outer_var_ref (var, ctx, true);
5511           if (is_reference (var))
5512             new_var = build_simple_mem_ref_loc (clause_loc, new_var);
5513           x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
5514           gimplify_and_add (x, stmt_list);
5515         }
5516       c = OMP_CLAUSE_CHAIN (c);
5517       if (c == NULL && !par_clauses)
5518         {
5519           /* If this was a workshare clause, see if it had been combined
5520              with its parallel.  In that case, continue looking for the
5521              clauses also on the parallel statement itself.  */
5522           if (is_parallel_ctx (ctx))
5523             break;
5524
5525           ctx = ctx->outer;
5526           if (ctx == NULL || !is_parallel_ctx (ctx))
5527             break;
5528
5529           c = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
5530                                OMP_CLAUSE_LASTPRIVATE);
5531           par_clauses = true;
5532         }
5533     }
5534
5535   if (label)
5536     gimple_seq_add_stmt (stmt_list, gimple_build_label (label));
5537 }
5538
5539 /* Lower the OpenACC reductions of CLAUSES for compute axis LEVEL
5540    (which might be a placeholder).  INNER is true if this is an inner
5541    axis of a multi-axis loop.  FORK and JOIN are (optional) fork and
5542    join markers.  Generate the before-loop forking sequence in
5543    FORK_SEQ and the after-loop joining sequence to JOIN_SEQ.  The
5544    general form of these sequences is
5545
5546      GOACC_REDUCTION_SETUP
5547      GOACC_FORK
5548      GOACC_REDUCTION_INIT
5549      ...
5550      GOACC_REDUCTION_FINI
5551      GOACC_JOIN
5552      GOACC_REDUCTION_TEARDOWN.  */
5553
5554 static void
5555 lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner,
5556                        gcall *fork, gcall *join, gimple_seq *fork_seq,
5557                        gimple_seq *join_seq, omp_context *ctx)
5558 {
5559   gimple_seq before_fork = NULL;
5560   gimple_seq after_fork = NULL;
5561   gimple_seq before_join = NULL;
5562   gimple_seq after_join = NULL;
5563   tree init_code = NULL_TREE, fini_code = NULL_TREE,
5564     setup_code = NULL_TREE, teardown_code = NULL_TREE;
5565   unsigned offset = 0;
5566
5567   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
5568     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
5569       {
5570         tree orig = OMP_CLAUSE_DECL (c);
5571         tree var = maybe_lookup_decl (orig, ctx);
5572         tree ref_to_res = NULL_TREE;
5573         tree incoming, outgoing, v1, v2, v3;
5574         bool is_private = false;
5575
5576         enum tree_code rcode = OMP_CLAUSE_REDUCTION_CODE (c);
5577         if (rcode == MINUS_EXPR)
5578           rcode = PLUS_EXPR;
5579         else if (rcode == TRUTH_ANDIF_EXPR)
5580           rcode = BIT_AND_EXPR;
5581         else if (rcode == TRUTH_ORIF_EXPR)
5582           rcode = BIT_IOR_EXPR;
5583         tree op = build_int_cst (unsigned_type_node, rcode);
5584
5585         if (!var)
5586           var = orig;
5587
5588         incoming = outgoing = var;
5589         
5590         if (!inner)
5591           {
5592             /* See if an outer construct also reduces this variable.  */
5593             omp_context *outer = ctx;
5594
5595             while (omp_context *probe = outer->outer)
5596               {
5597                 enum gimple_code type = gimple_code (probe->stmt);
5598                 tree cls;
5599
5600                 switch (type)
5601                   {
5602                   case GIMPLE_OMP_FOR:
5603                     cls = gimple_omp_for_clauses (probe->stmt);
5604                     break;
5605
5606                   case GIMPLE_OMP_TARGET:
5607                     if (gimple_omp_target_kind (probe->stmt)
5608                         != GF_OMP_TARGET_KIND_OACC_PARALLEL)
5609                       goto do_lookup;
5610
5611                     cls = gimple_omp_target_clauses (probe->stmt);
5612                     break;
5613
5614                   default:
5615                     goto do_lookup;
5616                   }
5617                 
5618                 outer = probe;
5619                 for (; cls;  cls = OMP_CLAUSE_CHAIN (cls))
5620                   if (OMP_CLAUSE_CODE (cls) == OMP_CLAUSE_REDUCTION
5621                       && orig == OMP_CLAUSE_DECL (cls))
5622                     {
5623                       incoming = outgoing = lookup_decl (orig, probe);
5624                       goto has_outer_reduction;
5625                     }
5626                   else if ((OMP_CLAUSE_CODE (cls) == OMP_CLAUSE_FIRSTPRIVATE
5627                             || OMP_CLAUSE_CODE (cls) == OMP_CLAUSE_PRIVATE)
5628                            && orig == OMP_CLAUSE_DECL (cls))
5629                     {
5630                       is_private = true;
5631                       goto do_lookup;
5632                     }
5633               }
5634
5635           do_lookup:
5636             /* This is the outermost construct with this reduction,
5637                see if there's a mapping for it.  */
5638             if (gimple_code (outer->stmt) == GIMPLE_OMP_TARGET
5639                 && maybe_lookup_field (orig, outer) && !is_private)
5640               {
5641                 ref_to_res = build_receiver_ref (orig, false, outer);
5642                 if (is_reference (orig))
5643                   ref_to_res = build_simple_mem_ref (ref_to_res);
5644
5645                 tree type = TREE_TYPE (var);
5646                 if (POINTER_TYPE_P (type))
5647                   type = TREE_TYPE (type);
5648
5649                 outgoing = var;
5650                 incoming = omp_reduction_init_op (loc, rcode, type);
5651               }
5652             else if (ctx->outer)
5653               incoming = outgoing = lookup_decl (orig, ctx->outer);
5654             else
5655               incoming = outgoing = orig;
5656               
5657           has_outer_reduction:;
5658           }
5659
5660         if (!ref_to_res)
5661           ref_to_res = integer_zero_node;
5662
5663         if (is_reference (orig))
5664           {
5665             tree type = TREE_TYPE (var);
5666             const char *id = IDENTIFIER_POINTER (DECL_NAME (var));
5667
5668             if (!inner)
5669               {
5670                 tree x = create_tmp_var (TREE_TYPE (type), id);
5671                 gimplify_assign (var, build_fold_addr_expr (x), fork_seq);
5672               }
5673
5674             v1 = create_tmp_var (type, id);
5675             v2 = create_tmp_var (type, id);
5676             v3 = create_tmp_var (type, id);
5677
5678             gimplify_assign (v1, var, fork_seq);
5679             gimplify_assign (v2, var, fork_seq);
5680             gimplify_assign (v3, var, fork_seq);
5681
5682             var = build_simple_mem_ref (var);
5683             v1 = build_simple_mem_ref (v1);
5684             v2 = build_simple_mem_ref (v2);
5685             v3 = build_simple_mem_ref (v3);
5686             outgoing = build_simple_mem_ref (outgoing);
5687
5688             if (!TREE_CONSTANT (incoming))
5689               incoming = build_simple_mem_ref (incoming);
5690           }
5691         else
5692           v1 = v2 = v3 = var;
5693
5694         /* Determine position in reduction buffer, which may be used
5695            by target.  */
5696         enum machine_mode mode = TYPE_MODE (TREE_TYPE (var));
5697         unsigned align = GET_MODE_ALIGNMENT (mode) /  BITS_PER_UNIT;
5698         offset = (offset + align - 1) & ~(align - 1);
5699         tree off = build_int_cst (sizetype, offset);
5700         offset += GET_MODE_SIZE (mode);
5701
5702         if (!init_code)
5703           {
5704             init_code = build_int_cst (integer_type_node,
5705                                        IFN_GOACC_REDUCTION_INIT);
5706             fini_code = build_int_cst (integer_type_node,
5707                                        IFN_GOACC_REDUCTION_FINI);
5708             setup_code = build_int_cst (integer_type_node,
5709                                         IFN_GOACC_REDUCTION_SETUP);
5710             teardown_code = build_int_cst (integer_type_node,
5711                                            IFN_GOACC_REDUCTION_TEARDOWN);
5712           }
5713
5714         tree setup_call
5715           = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
5716                                           TREE_TYPE (var), 6, setup_code,
5717                                           unshare_expr (ref_to_res),
5718                                           incoming, level, op, off);
5719         tree init_call
5720           = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
5721                                           TREE_TYPE (var), 6, init_code,
5722                                           unshare_expr (ref_to_res),
5723                                           v1, level, op, off);
5724         tree fini_call
5725           = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
5726                                           TREE_TYPE (var), 6, fini_code,
5727                                           unshare_expr (ref_to_res),
5728                                           v2, level, op, off);
5729         tree teardown_call
5730           = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
5731                                           TREE_TYPE (var), 6, teardown_code,
5732                                           ref_to_res, v3, level, op, off);
5733
5734         gimplify_assign (v1, setup_call, &before_fork);
5735         gimplify_assign (v2, init_call, &after_fork);
5736         gimplify_assign (v3, fini_call, &before_join);
5737         gimplify_assign (outgoing, teardown_call, &after_join);
5738       }
5739
5740   /* Now stitch things together.  */
5741   gimple_seq_add_seq (fork_seq, before_fork);
5742   if (fork)
5743     gimple_seq_add_stmt (fork_seq, fork);
5744   gimple_seq_add_seq (fork_seq, after_fork);
5745
5746   gimple_seq_add_seq (join_seq, before_join);
5747   if (join)
5748     gimple_seq_add_stmt (join_seq, join);
5749   gimple_seq_add_seq (join_seq, after_join);
5750 }
5751
5752 /* Generate code to implement the REDUCTION clauses.  */
5753
5754 static void
5755 lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
5756 {
5757   gimple_seq sub_seq = NULL;
5758   gimple *stmt;
5759   tree x, c;
5760   int count = 0;
5761
5762   /* OpenACC loop reductions are handled elsewhere.  */
5763   if (is_gimple_omp_oacc (ctx->stmt))
5764     return;
5765
5766   /* SIMD reductions are handled in lower_rec_input_clauses.  */
5767   if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
5768       && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
5769     return;
5770
5771   /* First see if there is exactly one reduction clause.  Use OMP_ATOMIC
5772      update in that case, otherwise use a lock.  */
5773   for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
5774     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
5775       {
5776         if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
5777             || TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF)
5778           {
5779             /* Never use OMP_ATOMIC for array reductions or UDRs.  */
5780             count = -1;
5781             break;
5782           }
5783         count++;
5784       }
5785
5786   if (count == 0)
5787     return;
5788
5789   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
5790     {
5791       tree var, ref, new_var, orig_var;
5792       enum tree_code code;
5793       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
5794
5795       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
5796         continue;
5797
5798       orig_var = var = OMP_CLAUSE_DECL (c);
5799       if (TREE_CODE (var) == MEM_REF)
5800         {
5801           var = TREE_OPERAND (var, 0);
5802           if (TREE_CODE (var) == POINTER_PLUS_EXPR)
5803             var = TREE_OPERAND (var, 0);
5804           if (TREE_CODE (var) == INDIRECT_REF
5805               || TREE_CODE (var) == ADDR_EXPR)
5806             var = TREE_OPERAND (var, 0);
5807           orig_var = var;
5808           if (is_variable_sized (var))
5809             {
5810               gcc_assert (DECL_HAS_VALUE_EXPR_P (var));
5811               var = DECL_VALUE_EXPR (var);
5812               gcc_assert (TREE_CODE (var) == INDIRECT_REF);
5813               var = TREE_OPERAND (var, 0);
5814               gcc_assert (DECL_P (var));
5815             }
5816         }
5817       new_var = lookup_decl (var, ctx);
5818       if (var == OMP_CLAUSE_DECL (c) && is_reference (var))
5819         new_var = build_simple_mem_ref_loc (clause_loc, new_var);
5820       ref = build_outer_var_ref (var, ctx);
5821       code = OMP_CLAUSE_REDUCTION_CODE (c);
5822
5823       /* reduction(-:var) sums up the partial results, so it acts
5824          identically to reduction(+:var).  */
5825       if (code == MINUS_EXPR)
5826         code = PLUS_EXPR;
5827
5828       if (count == 1)
5829         {
5830           tree addr = build_fold_addr_expr_loc (clause_loc, ref);
5831
5832           addr = save_expr (addr);
5833           ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
5834           x = fold_build2_loc (clause_loc, code, TREE_TYPE (ref), ref, new_var);
5835           x = build2 (OMP_ATOMIC, void_type_node, addr, x);
5836           gimplify_and_add (x, stmt_seqp);
5837           return;
5838         }
5839       else if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF)
5840         {
5841           tree d = OMP_CLAUSE_DECL (c);
5842           tree type = TREE_TYPE (d);
5843           tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
5844           tree i = create_tmp_var (TREE_TYPE (v), NULL);
5845           tree ptype = build_pointer_type (TREE_TYPE (type));
5846           tree bias = TREE_OPERAND (d, 1);
5847           d = TREE_OPERAND (d, 0);
5848           if (TREE_CODE (d) == POINTER_PLUS_EXPR)
5849             {
5850               tree b = TREE_OPERAND (d, 1);
5851               b = maybe_lookup_decl (b, ctx);
5852               if (b == NULL)
5853                 {
5854                   b = TREE_OPERAND (d, 1);
5855                   b = maybe_lookup_decl_in_outer_ctx (b, ctx);
5856                 }
5857               if (integer_zerop (bias))
5858                 bias = b;
5859               else
5860                 {
5861                   bias = fold_convert_loc (clause_loc, TREE_TYPE (b), bias);
5862                   bias = fold_build2_loc (clause_loc, PLUS_EXPR,
5863                                           TREE_TYPE (b), b, bias);
5864                 }
5865               d = TREE_OPERAND (d, 0);
5866             }
5867           /* For ref build_outer_var_ref already performs this, so
5868              only new_var needs a dereference.  */
5869           if (TREE_CODE (d) == INDIRECT_REF)
5870             {
5871               new_var = build_simple_mem_ref_loc (clause_loc, new_var);
5872               gcc_assert (is_reference (var) && var == orig_var);
5873             }
5874           else if (TREE_CODE (d) == ADDR_EXPR)
5875             {
5876               if (orig_var == var)
5877                 {
5878                   new_var = build_fold_addr_expr (new_var);
5879                   ref = build_fold_addr_expr (ref);
5880                 }
5881             }
5882           else
5883             {
5884               gcc_assert (orig_var == var);
5885               if (is_reference (var))
5886                 ref = build_fold_addr_expr (ref);
5887             }
5888           if (DECL_P (v))
5889             {
5890               tree t = maybe_lookup_decl (v, ctx);
5891               if (t)
5892                 v = t;
5893               else
5894                 v = maybe_lookup_decl_in_outer_ctx (v, ctx);
5895               gimplify_expr (&v, stmt_seqp, NULL, is_gimple_val, fb_rvalue);
5896             }
5897           if (!integer_zerop (bias))
5898             {
5899               bias = fold_convert_loc (clause_loc, sizetype, bias);
5900               new_var = fold_build2_loc (clause_loc, POINTER_PLUS_EXPR,
5901                                          TREE_TYPE (new_var), new_var,
5902                                          unshare_expr (bias));
5903               ref = fold_build2_loc (clause_loc, POINTER_PLUS_EXPR,
5904                                          TREE_TYPE (ref), ref, bias);
5905             }
5906           new_var = fold_convert_loc (clause_loc, ptype, new_var);
5907           ref = fold_convert_loc (clause_loc, ptype, ref);
5908           tree m = create_tmp_var (ptype, NULL);
5909           gimplify_assign (m, new_var, stmt_seqp);
5910           new_var = m;
5911           m = create_tmp_var (ptype, NULL);
5912           gimplify_assign (m, ref, stmt_seqp);
5913           ref = m;
5914           gimplify_assign (i, build_int_cst (TREE_TYPE (v), 0), stmt_seqp);
5915           tree body = create_artificial_label (UNKNOWN_LOCATION);
5916           tree end = create_artificial_label (UNKNOWN_LOCATION);
5917           gimple_seq_add_stmt (&sub_seq, gimple_build_label (body));
5918           tree priv = build_simple_mem_ref_loc (clause_loc, new_var);
5919           tree out = build_simple_mem_ref_loc (clause_loc, ref);
5920           if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
5921             {
5922               tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
5923               tree decl_placeholder
5924                 = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c);
5925               SET_DECL_VALUE_EXPR (placeholder, out);
5926               DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
5927               SET_DECL_VALUE_EXPR (decl_placeholder, priv);
5928               DECL_HAS_VALUE_EXPR_P (decl_placeholder) = 1;
5929               lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
5930               gimple_seq_add_seq (&sub_seq,
5931                                   OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
5932               OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
5933               OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
5934               OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c) = NULL;
5935             }
5936           else
5937             {
5938               x = build2 (code, TREE_TYPE (out), out, priv);
5939               out = unshare_expr (out);
5940               gimplify_assign (out, x, &sub_seq);
5941             }
5942           gimple *g = gimple_build_assign (new_var, POINTER_PLUS_EXPR, new_var,
5943                                            TYPE_SIZE_UNIT (TREE_TYPE (type)));
5944           gimple_seq_add_stmt (&sub_seq, g);
5945           g = gimple_build_assign (ref, POINTER_PLUS_EXPR, ref,
5946                                    TYPE_SIZE_UNIT (TREE_TYPE (type)));
5947           gimple_seq_add_stmt (&sub_seq, g);
5948           g = gimple_build_assign (i, PLUS_EXPR, i,
5949                                    build_int_cst (TREE_TYPE (i), 1));
5950           gimple_seq_add_stmt (&sub_seq, g);
5951           g = gimple_build_cond (LE_EXPR, i, v, body, end);
5952           gimple_seq_add_stmt (&sub_seq, g);
5953           gimple_seq_add_stmt (&sub_seq, gimple_build_label (end));
5954         }
5955       else if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
5956         {
5957           tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
5958
5959           if (is_reference (var)
5960               && !useless_type_conversion_p (TREE_TYPE (placeholder),
5961                                              TREE_TYPE (ref)))
5962             ref = build_fold_addr_expr_loc (clause_loc, ref);
5963           SET_DECL_VALUE_EXPR (placeholder, ref);
5964           DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
5965           lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
5966           gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
5967           OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
5968           OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
5969         }
5970       else
5971         {
5972           x = build2 (code, TREE_TYPE (ref), ref, new_var);
5973           ref = build_outer_var_ref (var, ctx);
5974           gimplify_assign (ref, x, &sub_seq);
5975         }
5976     }
5977
5978   stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START),
5979                             0);
5980   gimple_seq_add_stmt (stmt_seqp, stmt);
5981
5982   gimple_seq_add_seq (stmt_seqp, sub_seq);
5983
5984   stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END),
5985                             0);
5986   gimple_seq_add_stmt (stmt_seqp, stmt);
5987 }
5988
5989
5990 /* Generate code to implement the COPYPRIVATE clauses.  */
5991
5992 static void
5993 lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist,
5994                             omp_context *ctx)
5995 {
5996   tree c;
5997
5998   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
5999     {
6000       tree var, new_var, ref, x;
6001       bool by_ref;
6002       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
6003
6004       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
6005         continue;
6006
6007       var = OMP_CLAUSE_DECL (c);
6008       by_ref = use_pointer_for_field (var, NULL);
6009
6010       ref = build_sender_ref (var, ctx);
6011       x = new_var = lookup_decl_in_outer_ctx (var, ctx);
6012       if (by_ref)
6013         {
6014           x = build_fold_addr_expr_loc (clause_loc, new_var);
6015           x = fold_convert_loc (clause_loc, TREE_TYPE (ref), x);
6016         }
6017       gimplify_assign (ref, x, slist);
6018
6019       ref = build_receiver_ref (var, false, ctx);
6020       if (by_ref)
6021         {
6022           ref = fold_convert_loc (clause_loc,
6023                                   build_pointer_type (TREE_TYPE (new_var)),
6024                                   ref);
6025           ref = build_fold_indirect_ref_loc (clause_loc, ref);
6026         }
6027       if (is_reference (var))
6028         {
6029           ref = fold_convert_loc (clause_loc, TREE_TYPE (new_var), ref);
6030           ref = build_simple_mem_ref_loc (clause_loc, ref);
6031           new_var = build_simple_mem_ref_loc (clause_loc, new_var);
6032         }
6033       x = lang_hooks.decls.omp_clause_assign_op (c, new_var, ref);
6034       gimplify_and_add (x, rlist);
6035     }
6036 }
6037
6038
6039 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
6040    and REDUCTION from the sender (aka parent) side.  */
6041
6042 static void
6043 lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist,
6044                     omp_context *ctx)
6045 {
6046   tree c, t;
6047   int ignored_looptemp = 0;
6048   bool is_taskloop = false;
6049
6050   /* For taskloop, ignore first two _looptemp_ clauses, those are initialized
6051      by GOMP_taskloop.  */
6052   if (is_task_ctx (ctx) && gimple_omp_task_taskloop_p (ctx->stmt))
6053     {
6054       ignored_looptemp = 2;
6055       is_taskloop = true;
6056     }
6057
6058   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
6059     {
6060       tree val, ref, x, var;
6061       bool by_ref, do_in = false, do_out = false;
6062       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
6063
6064       switch (OMP_CLAUSE_CODE (c))
6065         {
6066         case OMP_CLAUSE_PRIVATE:
6067           if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
6068             break;
6069           continue;
6070         case OMP_CLAUSE_FIRSTPRIVATE:
6071         case OMP_CLAUSE_COPYIN:
6072         case OMP_CLAUSE_LASTPRIVATE:
6073         case OMP_CLAUSE_REDUCTION:
6074           break;
6075         case OMP_CLAUSE_SHARED:
6076           if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
6077             break;
6078           continue;
6079         case OMP_CLAUSE__LOOPTEMP_:
6080           if (ignored_looptemp)
6081             {
6082               ignored_looptemp--;
6083               continue;
6084             }
6085           break;
6086         default:
6087           continue;
6088         }
6089
6090       val = OMP_CLAUSE_DECL (c);
6091       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6092           && TREE_CODE (val) == MEM_REF)
6093         {
6094           val = TREE_OPERAND (val, 0);
6095           if (TREE_CODE (val) == POINTER_PLUS_EXPR)
6096             val = TREE_OPERAND (val, 0);
6097           if (TREE_CODE (val) == INDIRECT_REF
6098               || TREE_CODE (val) == ADDR_EXPR)
6099             val = TREE_OPERAND (val, 0);
6100           if (is_variable_sized (val))
6101             continue;
6102         }
6103
6104       /* For OMP_CLAUSE_SHARED_FIRSTPRIVATE, look beyond the
6105          outer taskloop region.  */
6106       omp_context *ctx_for_o = ctx;
6107       if (is_taskloop
6108           && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
6109           && OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
6110         ctx_for_o = ctx->outer;
6111
6112       var = lookup_decl_in_outer_ctx (val, ctx_for_o);
6113
6114       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
6115           && is_global_var (var))
6116         continue;
6117
6118       t = omp_member_access_dummy_var (var);
6119       if (t)
6120         {
6121           var = DECL_VALUE_EXPR (var);
6122           tree o = maybe_lookup_decl_in_outer_ctx (t, ctx_for_o);
6123           if (o != t)
6124             var = unshare_and_remap (var, t, o);
6125           else
6126             var = unshare_expr (var);
6127         }
6128
6129       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED)
6130         {
6131           /* Handle taskloop firstprivate/lastprivate, where the
6132              lastprivate on GIMPLE_OMP_TASK is represented as
6133              OMP_CLAUSE_SHARED_FIRSTPRIVATE.  */
6134           tree f = lookup_sfield ((splay_tree_key) &DECL_UID (val), ctx);
6135           x = omp_build_component_ref (ctx->sender_decl, f);
6136           if (use_pointer_for_field (val, ctx))
6137             var = build_fold_addr_expr (var);
6138           gimplify_assign (x, var, ilist);
6139           DECL_ABSTRACT_ORIGIN (f) = NULL;
6140           continue;
6141         }
6142
6143       if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
6144            || val == OMP_CLAUSE_DECL (c))
6145           && is_variable_sized (val))
6146         continue;
6147       by_ref = use_pointer_for_field (val, NULL);
6148
6149       switch (OMP_CLAUSE_CODE (c))
6150         {
6151         case OMP_CLAUSE_FIRSTPRIVATE:
6152           if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)
6153               && !by_ref
6154               && is_task_ctx (ctx))
6155             TREE_NO_WARNING (var) = 1;
6156           do_in = true;
6157           break;
6158
6159         case OMP_CLAUSE_PRIVATE:
6160         case OMP_CLAUSE_COPYIN:
6161         case OMP_CLAUSE__LOOPTEMP_:
6162           do_in = true;
6163           break;
6164
6165         case OMP_CLAUSE_LASTPRIVATE:
6166           if (by_ref || is_reference (val))
6167             {
6168               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
6169                 continue;
6170               do_in = true;
6171             }
6172           else
6173             {
6174               do_out = true;
6175               if (lang_hooks.decls.omp_private_outer_ref (val))
6176                 do_in = true;
6177             }
6178           break;
6179
6180         case OMP_CLAUSE_REDUCTION:
6181           do_in = true;
6182           if (val == OMP_CLAUSE_DECL (c))
6183             do_out = !(by_ref || is_reference (val));
6184           else
6185             by_ref = TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE;
6186           break;
6187
6188         default:
6189           gcc_unreachable ();
6190         }
6191
6192       if (do_in)
6193         {
6194           ref = build_sender_ref (val, ctx);
6195           x = by_ref ? build_fold_addr_expr_loc (clause_loc, var) : var;
6196           gimplify_assign (ref, x, ilist);
6197           if (is_task_ctx (ctx))
6198             DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref, 1)) = NULL;
6199         }
6200
6201       if (do_out)
6202         {
6203           ref = build_sender_ref (val, ctx);
6204           gimplify_assign (var, ref, olist);
6205         }
6206     }
6207 }
6208
6209 /* Generate code to implement SHARED from the sender (aka parent)
6210    side.  This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
6211    list things that got automatically shared.  */
6212
6213 static void
6214 lower_send_shared_vars (gimple_seq *ilist, gimple_seq *olist, omp_context *ctx)
6215 {
6216   tree var, ovar, nvar, t, f, x, record_type;
6217
6218   if (ctx->record_type == NULL)
6219     return;
6220
6221   record_type = ctx->srecord_type ? ctx->srecord_type : ctx->record_type;
6222   for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
6223     {
6224       ovar = DECL_ABSTRACT_ORIGIN (f);
6225       if (!ovar || TREE_CODE (ovar) == FIELD_DECL)
6226         continue;
6227
6228       nvar = maybe_lookup_decl (ovar, ctx);
6229       if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
6230         continue;
6231
6232       /* If CTX is a nested parallel directive.  Find the immediately
6233          enclosing parallel or workshare construct that contains a
6234          mapping for OVAR.  */
6235       var = lookup_decl_in_outer_ctx (ovar, ctx);
6236
6237       t = omp_member_access_dummy_var (var);
6238       if (t)
6239         {
6240           var = DECL_VALUE_EXPR (var);
6241           tree o = maybe_lookup_decl_in_outer_ctx (t, ctx);
6242           if (o != t)
6243             var = unshare_and_remap (var, t, o);
6244           else
6245             var = unshare_expr (var);
6246         }
6247
6248       if (use_pointer_for_field (ovar, ctx))
6249         {
6250           x = build_sender_ref (ovar, ctx);
6251           var = build_fold_addr_expr (var);
6252           gimplify_assign (x, var, ilist);
6253         }
6254       else
6255         {
6256           x = build_sender_ref (ovar, ctx);
6257           gimplify_assign (x, var, ilist);
6258
6259           if (!TREE_READONLY (var)
6260               /* We don't need to receive a new reference to a result
6261                  or parm decl.  In fact we may not store to it as we will
6262                  invalidate any pending RSO and generate wrong gimple
6263                  during inlining.  */
6264               && !((TREE_CODE (var) == RESULT_DECL
6265                     || TREE_CODE (var) == PARM_DECL)
6266                    && DECL_BY_REFERENCE (var)))
6267             {
6268               x = build_sender_ref (ovar, ctx);
6269               gimplify_assign (var, x, olist);
6270             }
6271         }
6272     }
6273 }
6274
6275 /* Emit an OpenACC head marker call, encapulating the partitioning and
6276    other information that must be processed by the target compiler.
6277    Return the maximum number of dimensions the associated loop might
6278    be partitioned over.  */
6279
6280 static unsigned
6281 lower_oacc_head_mark (location_t loc, tree ddvar, tree clauses,
6282                       gimple_seq *seq, omp_context *ctx)
6283 {
6284   unsigned levels = 0;
6285   unsigned tag = 0;
6286   tree gang_static = NULL_TREE;
6287   auto_vec<tree, 5> args;
6288
6289   args.quick_push (build_int_cst
6290                    (integer_type_node, IFN_UNIQUE_OACC_HEAD_MARK));
6291   args.quick_push (ddvar);
6292   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
6293     {
6294       switch (OMP_CLAUSE_CODE (c))
6295         {
6296         case OMP_CLAUSE_GANG:
6297           tag |= OLF_DIM_GANG;
6298           gang_static = OMP_CLAUSE_GANG_STATIC_EXPR (c);
6299           /* static:* is represented by -1, and we can ignore it, as
6300              scheduling is always static.  */
6301           if (gang_static && integer_minus_onep (gang_static))
6302             gang_static = NULL_TREE;
6303           levels++;
6304           break;
6305
6306         case OMP_CLAUSE_WORKER:
6307           tag |= OLF_DIM_WORKER;
6308           levels++;
6309           break;
6310
6311         case OMP_CLAUSE_VECTOR:
6312           tag |= OLF_DIM_VECTOR;
6313           levels++;
6314           break;
6315
6316         case OMP_CLAUSE_SEQ:
6317           tag |= OLF_SEQ;
6318           break;
6319
6320         case OMP_CLAUSE_AUTO:
6321           tag |= OLF_AUTO;
6322           break;
6323
6324         case OMP_CLAUSE_INDEPENDENT:
6325           tag |= OLF_INDEPENDENT;
6326           break;
6327
6328         default:
6329           continue;
6330         }
6331     }
6332
6333   if (gang_static)
6334     {
6335       if (DECL_P (gang_static))
6336         gang_static = build_outer_var_ref (gang_static, ctx);
6337       tag |= OLF_GANG_STATIC;
6338     }
6339
6340   /* In a parallel region, loops are implicitly INDEPENDENT.  */
6341   omp_context *tgt = enclosing_target_ctx (ctx);
6342   if (!tgt || is_oacc_parallel (tgt))
6343     tag |= OLF_INDEPENDENT;
6344
6345   /* A loop lacking SEQ, GANG, WORKER and/or VECTOR is implicitly AUTO.  */
6346   if (!(tag & (((GOMP_DIM_MASK (GOMP_DIM_MAX) - 1) << OLF_DIM_BASE)
6347                | OLF_SEQ)))
6348       tag |= OLF_AUTO;
6349
6350   /* Ensure at least one level.  */
6351   if (!levels)
6352     levels++;
6353
6354   args.quick_push (build_int_cst (integer_type_node, levels));
6355   args.quick_push (build_int_cst (integer_type_node, tag));
6356   if (gang_static)
6357     args.quick_push (gang_static);
6358
6359   gcall *call = gimple_build_call_internal_vec (IFN_UNIQUE, args);
6360   gimple_set_location (call, loc);
6361   gimple_set_lhs (call, ddvar);
6362   gimple_seq_add_stmt (seq, call);
6363
6364   return levels;
6365 }
6366
6367 /* Emit an OpenACC lopp head or tail marker to SEQ.  LEVEL is the
6368    partitioning level of the enclosed region.  */ 
6369
6370 static void
6371 lower_oacc_loop_marker (location_t loc, tree ddvar, bool head,
6372                         tree tofollow, gimple_seq *seq)
6373 {
6374   int marker_kind = (head ? IFN_UNIQUE_OACC_HEAD_MARK
6375                      : IFN_UNIQUE_OACC_TAIL_MARK);
6376   tree marker = build_int_cst (integer_type_node, marker_kind);
6377   int nargs = 2 + (tofollow != NULL_TREE);
6378   gcall *call = gimple_build_call_internal (IFN_UNIQUE, nargs,
6379                                             marker, ddvar, tofollow);
6380   gimple_set_location (call, loc);
6381   gimple_set_lhs (call, ddvar);
6382   gimple_seq_add_stmt (seq, call);
6383 }
6384
6385 /* Generate the before and after OpenACC loop sequences.  CLAUSES are
6386    the loop clauses, from which we extract reductions.  Initialize
6387    HEAD and TAIL.  */
6388
6389 static void
6390 lower_oacc_head_tail (location_t loc, tree clauses,
6391                       gimple_seq *head, gimple_seq *tail, omp_context *ctx)
6392 {
6393   bool inner = false;
6394   tree ddvar = create_tmp_var (integer_type_node, ".data_dep");
6395   gimple_seq_add_stmt (head, gimple_build_assign (ddvar, integer_zero_node));
6396
6397   unsigned count = lower_oacc_head_mark (loc, ddvar, clauses, head, ctx);
6398   tree fork_kind = build_int_cst (unsigned_type_node, IFN_UNIQUE_OACC_FORK);
6399   tree join_kind = build_int_cst (unsigned_type_node, IFN_UNIQUE_OACC_JOIN);
6400
6401   gcc_assert (count);
6402   for (unsigned done = 1; count; count--, done++)
6403     {
6404       gimple_seq fork_seq = NULL;
6405       gimple_seq join_seq = NULL;
6406
6407       tree place = build_int_cst (integer_type_node, -1);
6408       gcall *fork = gimple_build_call_internal (IFN_UNIQUE, 3,
6409                                                 fork_kind, ddvar, place);
6410       gimple_set_location (fork, loc);
6411       gimple_set_lhs (fork, ddvar);
6412
6413       gcall *join = gimple_build_call_internal (IFN_UNIQUE, 3,
6414                                                 join_kind, ddvar, place);
6415       gimple_set_location (join, loc);
6416       gimple_set_lhs (join, ddvar);
6417
6418       /* Mark the beginning of this level sequence.  */
6419       if (inner)
6420         lower_oacc_loop_marker (loc, ddvar, true,
6421                                 build_int_cst (integer_type_node, count),
6422                                 &fork_seq);
6423       lower_oacc_loop_marker (loc, ddvar, false,
6424                               build_int_cst (integer_type_node, done),
6425                               &join_seq);
6426
6427       lower_oacc_reductions (loc, clauses, place, inner,
6428                              fork, join, &fork_seq, &join_seq,  ctx);
6429
6430       /* Append this level to head. */
6431       gimple_seq_add_seq (head, fork_seq);
6432       /* Prepend it to tail.  */
6433       gimple_seq_add_seq (&join_seq, *tail);
6434       *tail = join_seq;
6435
6436       inner = true;
6437     }
6438
6439   /* Mark the end of the sequence.  */
6440   lower_oacc_loop_marker (loc, ddvar, true, NULL_TREE, head);
6441   lower_oacc_loop_marker (loc, ddvar, false, NULL_TREE, tail);
6442 }
6443
6444 /* A convenience function to build an empty GIMPLE_COND with just the
6445    condition.  */
6446
6447 static gcond *
6448 gimple_build_cond_empty (tree cond)
6449 {
6450   enum tree_code pred_code;
6451   tree lhs, rhs;
6452
6453   gimple_cond_get_ops_from_tree (cond, &pred_code, &lhs, &rhs);
6454   return gimple_build_cond (pred_code, lhs, rhs, NULL_TREE, NULL_TREE);
6455 }
6456
6457 /* Return true if a parallel REGION is within a declare target function or
6458    within a target region and is not a part of a gridified target.  */
6459
6460 static bool
6461 parallel_needs_hsa_kernel_p (struct omp_region *region)
6462 {
6463   bool indirect = false;
6464   for (region = region->outer; region; region = region->outer)
6465     {
6466       if (region->type == GIMPLE_OMP_PARALLEL)
6467         indirect = true;
6468       else if (region->type == GIMPLE_OMP_TARGET)
6469         {
6470           gomp_target *tgt_stmt
6471             = as_a <gomp_target *> (last_stmt (region->entry));
6472
6473           if (find_omp_clause (gimple_omp_target_clauses (tgt_stmt),
6474                                OMP_CLAUSE__GRIDDIM_))
6475             return indirect;
6476           else
6477             return true;
6478         }
6479     }
6480
6481   if (lookup_attribute ("omp declare target",
6482                         DECL_ATTRIBUTES (current_function_decl)))
6483     return true;
6484
6485   return false;
6486 }
6487
6488 static void expand_omp_build_assign (gimple_stmt_iterator *, tree, tree,
6489                                      bool = false);
6490
6491 /* Build the function calls to GOMP_parallel_start etc to actually
6492    generate the parallel operation.  REGION is the parallel region
6493    being expanded.  BB is the block where to insert the code.  WS_ARGS
6494    will be set if this is a call to a combined parallel+workshare
6495    construct, it contains the list of additional arguments needed by
6496    the workshare construct.  */
6497
6498 static void
6499 expand_parallel_call (struct omp_region *region, basic_block bb,
6500                       gomp_parallel *entry_stmt,
6501                       vec<tree, va_gc> *ws_args)
6502 {
6503   tree t, t1, t2, val, cond, c, clauses, flags;
6504   gimple_stmt_iterator gsi;
6505   gimple *stmt;
6506   enum built_in_function start_ix;
6507   int start_ix2;
6508   location_t clause_loc;
6509   vec<tree, va_gc> *args;
6510
6511   clauses = gimple_omp_parallel_clauses (entry_stmt);
6512
6513   /* Determine what flavor of GOMP_parallel we will be
6514      emitting.  */
6515   start_ix = BUILT_IN_GOMP_PARALLEL;
6516   if (is_combined_parallel (region))
6517     {
6518       switch (region->inner->type)
6519         {
6520         case GIMPLE_OMP_FOR:
6521           gcc_assert (region->inner->sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
6522           switch (region->inner->sched_kind)
6523             {
6524             case OMP_CLAUSE_SCHEDULE_RUNTIME:
6525               start_ix2 = 3;
6526               break;
6527             case OMP_CLAUSE_SCHEDULE_DYNAMIC:
6528             case OMP_CLAUSE_SCHEDULE_GUIDED:
6529               if (region->inner->sched_modifiers
6530                   & OMP_CLAUSE_SCHEDULE_NONMONOTONIC)
6531                 {
6532                   start_ix2 = 3 + region->inner->sched_kind;
6533                   break;
6534                 }
6535               /* FALLTHRU */
6536             default:
6537               start_ix2 = region->inner->sched_kind;
6538               break;
6539             }
6540           start_ix2 += (int) BUILT_IN_GOMP_PARALLEL_LOOP_STATIC;
6541           start_ix = (enum built_in_function) start_ix2;
6542           break;
6543         case GIMPLE_OMP_SECTIONS:
6544           start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS;
6545           break;
6546         default:
6547           gcc_unreachable ();
6548         }
6549     }
6550
6551   /* By default, the value of NUM_THREADS is zero (selected at run time)
6552      and there is no conditional.  */
6553   cond = NULL_TREE;
6554   val = build_int_cst (unsigned_type_node, 0);
6555   flags = build_int_cst (unsigned_type_node, 0);
6556
6557   c = find_omp_clause (clauses, OMP_CLAUSE_IF);
6558   if (c)
6559     cond = OMP_CLAUSE_IF_EXPR (c);
6560
6561   c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
6562   if (c)
6563     {
6564       val = OMP_CLAUSE_NUM_THREADS_EXPR (c);
6565       clause_loc = OMP_CLAUSE_LOCATION (c);
6566     }
6567   else
6568     clause_loc = gimple_location (entry_stmt);
6569
6570   c = find_omp_clause (clauses, OMP_CLAUSE_PROC_BIND);
6571   if (c)
6572     flags = build_int_cst (unsigned_type_node, OMP_CLAUSE_PROC_BIND_KIND (c));
6573
6574   /* Ensure 'val' is of the correct type.  */
6575   val = fold_convert_loc (clause_loc, unsigned_type_node, val);
6576
6577   /* If we found the clause 'if (cond)', build either
6578      (cond != 0) or (cond ? val : 1u).  */
6579   if (cond)
6580     {
6581       cond = gimple_boolify (cond);
6582
6583       if (integer_zerop (val))
6584         val = fold_build2_loc (clause_loc,
6585                            EQ_EXPR, unsigned_type_node, cond,
6586                            build_int_cst (TREE_TYPE (cond), 0));
6587       else
6588         {
6589           basic_block cond_bb, then_bb, else_bb;
6590           edge e, e_then, e_else;
6591           tree tmp_then, tmp_else, tmp_join, tmp_var;
6592
6593           tmp_var = create_tmp_var (TREE_TYPE (val));
6594           if (gimple_in_ssa_p (cfun))
6595             {
6596               tmp_then = make_ssa_name (tmp_var);
6597               tmp_else = make_ssa_name (tmp_var);
6598               tmp_join = make_ssa_name (tmp_var);
6599             }
6600           else
6601             {
6602               tmp_then = tmp_var;
6603               tmp_else = tmp_var;
6604               tmp_join = tmp_var;
6605             }
6606
6607           e = split_block_after_labels (bb);
6608           cond_bb = e->src;
6609           bb = e->dest;
6610           remove_edge (e);
6611
6612           then_bb = create_empty_bb (cond_bb);
6613           else_bb = create_empty_bb (then_bb);
6614           set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
6615           set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
6616
6617           stmt = gimple_build_cond_empty (cond);
6618           gsi = gsi_start_bb (cond_bb);
6619           gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
6620
6621           gsi = gsi_start_bb (then_bb);
6622           expand_omp_build_assign (&gsi, tmp_then, val, true);
6623
6624           gsi = gsi_start_bb (else_bb);
6625           expand_omp_build_assign (&gsi, tmp_else,
6626                                    build_int_cst (unsigned_type_node, 1),
6627                                    true);
6628
6629           make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
6630           make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
6631           add_bb_to_loop (then_bb, cond_bb->loop_father);
6632           add_bb_to_loop (else_bb, cond_bb->loop_father);
6633           e_then = make_edge (then_bb, bb, EDGE_FALLTHRU);
6634           e_else = make_edge (else_bb, bb, EDGE_FALLTHRU);
6635
6636           if (gimple_in_ssa_p (cfun))
6637             {
6638               gphi *phi = create_phi_node (tmp_join, bb);
6639               add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION);
6640               add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION);
6641             }
6642
6643           val = tmp_join;
6644         }
6645
6646       gsi = gsi_start_bb (bb);
6647       val = force_gimple_operand_gsi (&gsi, val, true, NULL_TREE,
6648                                       false, GSI_CONTINUE_LINKING);
6649     }
6650
6651   gsi = gsi_last_bb (bb);
6652   t = gimple_omp_parallel_data_arg (entry_stmt);
6653   if (t == NULL)
6654     t1 = null_pointer_node;
6655   else
6656     t1 = build_fold_addr_expr (t);
6657   tree child_fndecl = gimple_omp_parallel_child_fn (entry_stmt);
6658   t2 = build_fold_addr_expr (child_fndecl);
6659
6660   vec_alloc (args, 4 + vec_safe_length (ws_args));
6661   args->quick_push (t2);
6662   args->quick_push (t1);
6663   args->quick_push (val);
6664   if (ws_args)
6665     args->splice (*ws_args);
6666   args->quick_push (flags);
6667
6668   t = build_call_expr_loc_vec (UNKNOWN_LOCATION,
6669                                builtin_decl_explicit (start_ix), args);
6670
6671   force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
6672                             false, GSI_CONTINUE_LINKING);
6673
6674   if (hsa_gen_requested_p ()
6675       && parallel_needs_hsa_kernel_p (region))
6676     {
6677       cgraph_node *child_cnode = cgraph_node::get (child_fndecl);
6678       hsa_register_kernel (child_cnode);
6679     }
6680 }
6681
6682 /* Insert a function call whose name is FUNC_NAME with the information from
6683    ENTRY_STMT into the basic_block BB.  */
6684
6685 static void
6686 expand_cilk_for_call (basic_block bb, gomp_parallel *entry_stmt,
6687                       vec <tree, va_gc> *ws_args)
6688 {
6689   tree t, t1, t2;
6690   gimple_stmt_iterator gsi;
6691   vec <tree, va_gc> *args;
6692
6693   gcc_assert (vec_safe_length (ws_args) == 2);
6694   tree func_name = (*ws_args)[0];
6695   tree grain = (*ws_args)[1];
6696
6697   tree clauses = gimple_omp_parallel_clauses (entry_stmt);
6698   tree count = find_omp_clause (clauses, OMP_CLAUSE__CILK_FOR_COUNT_);
6699   gcc_assert (count != NULL_TREE);
6700   count = OMP_CLAUSE_OPERAND (count, 0);
6701
6702   gsi = gsi_last_bb (bb);
6703   t = gimple_omp_parallel_data_arg (entry_stmt);
6704   if (t == NULL)
6705     t1 = null_pointer_node;
6706   else
6707     t1 = build_fold_addr_expr (t);
6708   t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
6709
6710   vec_alloc (args, 4);
6711   args->quick_push (t2);
6712   args->quick_push (t1);
6713   args->quick_push (count);
6714   args->quick_push (grain);
6715   t = build_call_expr_loc_vec (UNKNOWN_LOCATION, func_name, args);
6716
6717   force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, false,
6718                             GSI_CONTINUE_LINKING);
6719 }
6720
6721 /* Build the function call to GOMP_task to actually
6722    generate the task operation.  BB is the block where to insert the code.  */
6723
6724 static void
6725 expand_task_call (struct omp_region *region, basic_block bb,
6726                   gomp_task *entry_stmt)
6727 {
6728   tree t1, t2, t3;
6729   gimple_stmt_iterator gsi;
6730   location_t loc = gimple_location (entry_stmt);
6731
6732   tree clauses = gimple_omp_task_clauses (entry_stmt);
6733
6734   tree ifc = find_omp_clause (clauses, OMP_CLAUSE_IF);
6735   tree untied = find_omp_clause (clauses, OMP_CLAUSE_UNTIED);
6736   tree mergeable = find_omp_clause (clauses, OMP_CLAUSE_MERGEABLE);
6737   tree depend = find_omp_clause (clauses, OMP_CLAUSE_DEPEND);
6738   tree finalc = find_omp_clause (clauses, OMP_CLAUSE_FINAL);
6739   tree priority = find_omp_clause (clauses, OMP_CLAUSE_PRIORITY);
6740
6741   unsigned int iflags
6742     = (untied ? GOMP_TASK_FLAG_UNTIED : 0)
6743       | (mergeable ? GOMP_TASK_FLAG_MERGEABLE : 0)
6744       | (depend ? GOMP_TASK_FLAG_DEPEND : 0);
6745
6746   bool taskloop_p = gimple_omp_task_taskloop_p (entry_stmt);
6747   tree startvar = NULL_TREE, endvar = NULL_TREE, step = NULL_TREE;
6748   tree num_tasks = NULL_TREE;
6749   bool ull = false;
6750   if (taskloop_p)
6751     {
6752       gimple *g = last_stmt (region->outer->entry);
6753       gcc_assert (gimple_code (g) == GIMPLE_OMP_FOR
6754                   && gimple_omp_for_kind (g) == GF_OMP_FOR_KIND_TASKLOOP);
6755       struct omp_for_data fd;
6756       extract_omp_for_data (as_a <gomp_for *> (g), &fd, NULL);
6757       startvar = find_omp_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
6758       endvar = find_omp_clause (OMP_CLAUSE_CHAIN (startvar),
6759                                 OMP_CLAUSE__LOOPTEMP_);
6760       startvar = OMP_CLAUSE_DECL (startvar);
6761       endvar = OMP_CLAUSE_DECL (endvar);
6762       step = fold_convert_loc (loc, fd.iter_type, fd.loop.step);
6763       if (fd.loop.cond_code == LT_EXPR)
6764         iflags |= GOMP_TASK_FLAG_UP;
6765       tree tclauses = gimple_omp_for_clauses (g);
6766       num_tasks = find_omp_clause (tclauses, OMP_CLAUSE_NUM_TASKS);
6767       if (num_tasks)
6768         num_tasks = OMP_CLAUSE_NUM_TASKS_EXPR (num_tasks);
6769       else
6770         {
6771           num_tasks = find_omp_clause (tclauses, OMP_CLAUSE_GRAINSIZE);
6772           if (num_tasks)
6773             {
6774               iflags |= GOMP_TASK_FLAG_GRAINSIZE;
6775               num_tasks = OMP_CLAUSE_GRAINSIZE_EXPR (num_tasks);
6776             }
6777           else
6778             num_tasks = integer_zero_node;
6779         }
6780       num_tasks = fold_convert_loc (loc, long_integer_type_node, num_tasks);
6781       if (ifc == NULL_TREE)
6782         iflags |= GOMP_TASK_FLAG_IF;
6783       if (find_omp_clause (tclauses, OMP_CLAUSE_NOGROUP))
6784         iflags |= GOMP_TASK_FLAG_NOGROUP;
6785       ull = fd.iter_type == long_long_unsigned_type_node;
6786     }
6787   else if (priority)
6788     iflags |= GOMP_TASK_FLAG_PRIORITY;
6789
6790   tree flags = build_int_cst (unsigned_type_node, iflags);
6791
6792   tree cond = boolean_true_node;
6793   if (ifc)
6794     {
6795       if (taskloop_p)
6796         {
6797           tree t = gimple_boolify (OMP_CLAUSE_IF_EXPR (ifc));
6798           t = fold_build3_loc (loc, COND_EXPR, unsigned_type_node, t,
6799                                build_int_cst (unsigned_type_node,
6800                                               GOMP_TASK_FLAG_IF),
6801                                build_int_cst (unsigned_type_node, 0));
6802           flags = fold_build2_loc (loc, PLUS_EXPR, unsigned_type_node,
6803                                    flags, t);
6804         }
6805       else
6806         cond = gimple_boolify (OMP_CLAUSE_IF_EXPR (ifc));
6807     }
6808
6809   if (finalc)
6810     {
6811       tree t = gimple_boolify (OMP_CLAUSE_FINAL_EXPR (finalc));
6812       t = fold_build3_loc (loc, COND_EXPR, unsigned_type_node, t,
6813                            build_int_cst (unsigned_type_node,
6814                                           GOMP_TASK_FLAG_FINAL),
6815                            build_int_cst (unsigned_type_node, 0));
6816       flags = fold_build2_loc (loc, PLUS_EXPR, unsigned_type_node, flags, t);
6817     }
6818   if (depend)
6819     depend = OMP_CLAUSE_DECL (depend);
6820   else
6821     depend = build_int_cst (ptr_type_node, 0);
6822   if (priority)
6823     priority = fold_convert (integer_type_node,
6824                              OMP_CLAUSE_PRIORITY_EXPR (priority));
6825   else
6826     priority = integer_zero_node;
6827
6828   gsi = gsi_last_bb (bb);
6829   tree t = gimple_omp_task_data_arg (entry_stmt);
6830   if (t == NULL)
6831     t2 = null_pointer_node;
6832   else
6833     t2 = build_fold_addr_expr_loc (loc, t);
6834   t1 = build_fold_addr_expr_loc (loc, gimple_omp_task_child_fn (entry_stmt));
6835   t = gimple_omp_task_copy_fn (entry_stmt);
6836   if (t == NULL)
6837     t3 = null_pointer_node;
6838   else
6839     t3 = build_fold_addr_expr_loc (loc, t);
6840
6841   if (taskloop_p)
6842     t = build_call_expr (ull
6843                          ? builtin_decl_explicit (BUILT_IN_GOMP_TASKLOOP_ULL)
6844                          : builtin_decl_explicit (BUILT_IN_GOMP_TASKLOOP),
6845                          11, t1, t2, t3,
6846                          gimple_omp_task_arg_size (entry_stmt),
6847                          gimple_omp_task_arg_align (entry_stmt), flags,
6848                          num_tasks, priority, startvar, endvar, step);
6849   else
6850     t = build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_TASK),
6851                          9, t1, t2, t3,
6852                          gimple_omp_task_arg_size (entry_stmt),
6853                          gimple_omp_task_arg_align (entry_stmt), cond, flags,
6854                          depend, priority);
6855
6856   force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
6857                             false, GSI_CONTINUE_LINKING);
6858 }
6859
6860
6861 /* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
6862    catch handler and return it.  This prevents programs from violating the
6863    structured block semantics with throws.  */
6864
6865 static gimple_seq
6866 maybe_catch_exception (gimple_seq body)
6867 {
6868   gimple *g;
6869   tree decl;
6870
6871   if (!flag_exceptions)
6872     return body;
6873
6874   if (lang_hooks.eh_protect_cleanup_actions != NULL)
6875     decl = lang_hooks.eh_protect_cleanup_actions ();
6876   else
6877     decl = builtin_decl_explicit (BUILT_IN_TRAP);
6878
6879   g = gimple_build_eh_must_not_throw (decl);
6880   g = gimple_build_try (body, gimple_seq_alloc_with_stmt (g),
6881                         GIMPLE_TRY_CATCH);
6882
6883  return gimple_seq_alloc_with_stmt (g);
6884 }
6885
6886 /* Chain all the DECLs in LIST by their TREE_CHAIN fields.  */
6887
6888 static tree
6889 vec2chain (vec<tree, va_gc> *v)
6890 {
6891   tree chain = NULL_TREE, t;
6892   unsigned ix;
6893
6894   FOR_EACH_VEC_SAFE_ELT_REVERSE (v, ix, t)
6895     {
6896       DECL_CHAIN (t) = chain;
6897       chain = t;
6898     }
6899
6900   return chain;
6901 }
6902
6903
6904 /* Remove barriers in REGION->EXIT's block.  Note that this is only
6905    valid for GIMPLE_OMP_PARALLEL regions.  Since the end of a parallel region
6906    is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
6907    left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
6908    removed.  */
6909
6910 static void
6911 remove_exit_barrier (struct omp_region *region)
6912 {
6913   gimple_stmt_iterator gsi;
6914   basic_block exit_bb;
6915   edge_iterator ei;
6916   edge e;
6917   gimple *stmt;
6918   int any_addressable_vars = -1;
6919
6920   exit_bb = region->exit;
6921
6922   /* If the parallel region doesn't return, we don't have REGION->EXIT
6923      block at all.  */
6924   if (! exit_bb)
6925     return;
6926
6927   /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN.  The
6928      workshare's GIMPLE_OMP_RETURN will be in a preceding block.  The kinds of
6929      statements that can appear in between are extremely limited -- no
6930      memory operations at all.  Here, we allow nothing at all, so the
6931      only thing we allow to precede this GIMPLE_OMP_RETURN is a label.  */
6932   gsi = gsi_last_bb (exit_bb);
6933   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
6934   gsi_prev (&gsi);
6935   if (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
6936     return;
6937
6938   FOR_EACH_EDGE (e, ei, exit_bb->preds)
6939     {
6940       gsi = gsi_last_bb (e->src);
6941       if (gsi_end_p (gsi))
6942         continue;
6943       stmt = gsi_stmt (gsi);
6944       if (gimple_code (stmt) == GIMPLE_OMP_RETURN
6945           && !gimple_omp_return_nowait_p (stmt))
6946         {
6947           /* OpenMP 3.0 tasks unfortunately prevent this optimization
6948              in many cases.  If there could be tasks queued, the barrier
6949              might be needed to let the tasks run before some local
6950              variable of the parallel that the task uses as shared
6951              runs out of scope.  The task can be spawned either
6952              from within current function (this would be easy to check)
6953              or from some function it calls and gets passed an address
6954              of such a variable.  */
6955           if (any_addressable_vars < 0)
6956             {
6957               gomp_parallel *parallel_stmt
6958                 = as_a <gomp_parallel *> (last_stmt (region->entry));
6959               tree child_fun = gimple_omp_parallel_child_fn (parallel_stmt);
6960               tree local_decls, block, decl;
6961               unsigned ix;
6962
6963               any_addressable_vars = 0;
6964               FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (child_fun), ix, decl)
6965                 if (TREE_ADDRESSABLE (decl))
6966                   {
6967                     any_addressable_vars = 1;
6968                     break;
6969                   }
6970               for (block = gimple_block (stmt);
6971                    !any_addressable_vars
6972                    && block
6973                    && TREE_CODE (block) == BLOCK;
6974                    block = BLOCK_SUPERCONTEXT (block))
6975                 {
6976                   for (local_decls = BLOCK_VARS (block);
6977                        local_decls;
6978                        local_decls = DECL_CHAIN (local_decls))
6979                     if (TREE_ADDRESSABLE (local_decls))
6980                       {
6981                         any_addressable_vars = 1;
6982                         break;
6983                       }
6984                   if (block == gimple_block (parallel_stmt))
6985                     break;
6986                 }
6987             }
6988           if (!any_addressable_vars)
6989             gimple_omp_return_set_nowait (stmt);
6990         }
6991     }
6992 }
6993
6994 static void
6995 remove_exit_barriers (struct omp_region *region)
6996 {
6997   if (region->type == GIMPLE_OMP_PARALLEL)
6998     remove_exit_barrier (region);
6999
7000   if (region->inner)
7001     {
7002       region = region->inner;
7003       remove_exit_barriers (region);
7004       while (region->next)
7005         {
7006           region = region->next;
7007           remove_exit_barriers (region);
7008         }
7009     }
7010 }
7011
7012 /* Optimize omp_get_thread_num () and omp_get_num_threads ()
7013    calls.  These can't be declared as const functions, but
7014    within one parallel body they are constant, so they can be
7015    transformed there into __builtin_omp_get_{thread_num,num_threads} ()
7016    which are declared const.  Similarly for task body, except
7017    that in untied task omp_get_thread_num () can change at any task
7018    scheduling point.  */
7019
7020 static void
7021 optimize_omp_library_calls (gimple *entry_stmt)
7022 {
7023   basic_block bb;
7024   gimple_stmt_iterator gsi;
7025   tree thr_num_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
7026   tree thr_num_id = DECL_ASSEMBLER_NAME (thr_num_tree);
7027   tree num_thr_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
7028   tree num_thr_id = DECL_ASSEMBLER_NAME (num_thr_tree);
7029   bool untied_task = (gimple_code (entry_stmt) == GIMPLE_OMP_TASK
7030                       && find_omp_clause (gimple_omp_task_clauses (entry_stmt),
7031                                           OMP_CLAUSE_UNTIED) != NULL);
7032
7033   FOR_EACH_BB_FN (bb, cfun)
7034     for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
7035       {
7036         gimple *call = gsi_stmt (gsi);
7037         tree decl;
7038
7039         if (is_gimple_call (call)
7040             && (decl = gimple_call_fndecl (call))
7041             && DECL_EXTERNAL (decl)
7042             && TREE_PUBLIC (decl)
7043             && DECL_INITIAL (decl) == NULL)
7044           {
7045             tree built_in;
7046
7047             if (DECL_NAME (decl) == thr_num_id)
7048               {
7049                 /* In #pragma omp task untied omp_get_thread_num () can change
7050                    during the execution of the task region.  */
7051                 if (untied_task)
7052                   continue;
7053                 built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
7054               }
7055             else if (DECL_NAME (decl) == num_thr_id)
7056               built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
7057             else
7058               continue;
7059
7060             if (DECL_ASSEMBLER_NAME (decl) != DECL_ASSEMBLER_NAME (built_in)
7061                 || gimple_call_num_args (call) != 0)
7062               continue;
7063
7064             if (flag_exceptions && !TREE_NOTHROW (decl))
7065               continue;
7066
7067             if (TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE
7068                 || !types_compatible_p (TREE_TYPE (TREE_TYPE (decl)),
7069                                         TREE_TYPE (TREE_TYPE (built_in))))
7070               continue;
7071
7072             gimple_call_set_fndecl (call, built_in);
7073           }
7074       }
7075 }
7076
7077 /* Callback for expand_omp_build_assign.  Return non-NULL if *tp needs to be
7078    regimplified.  */
7079
7080 static tree
7081 expand_omp_regimplify_p (tree *tp, int *walk_subtrees, void *)
7082 {
7083   tree t = *tp;
7084
7085   /* Any variable with DECL_VALUE_EXPR needs to be regimplified.  */
7086   if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
7087     return t;
7088
7089   if (TREE_CODE (t) == ADDR_EXPR)
7090     recompute_tree_invariant_for_addr_expr (t);
7091
7092   *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
7093   return NULL_TREE;
7094 }
7095
7096 /* Prepend or append TO = FROM assignment before or after *GSI_P.  */
7097
7098 static void
7099 expand_omp_build_assign (gimple_stmt_iterator *gsi_p, tree to, tree from,
7100                          bool after)
7101 {
7102   bool simple_p = DECL_P (to) && TREE_ADDRESSABLE (to);
7103   from = force_gimple_operand_gsi (gsi_p, from, simple_p, NULL_TREE,
7104                                    !after, after ? GSI_CONTINUE_LINKING
7105                                                  : GSI_SAME_STMT);
7106   gimple *stmt = gimple_build_assign (to, from);
7107   if (after)
7108     gsi_insert_after (gsi_p, stmt, GSI_CONTINUE_LINKING);
7109   else
7110     gsi_insert_before (gsi_p, stmt, GSI_SAME_STMT);
7111   if (walk_tree (&from, expand_omp_regimplify_p, NULL, NULL)
7112       || walk_tree (&to, expand_omp_regimplify_p, NULL, NULL))
7113     {
7114       gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
7115       gimple_regimplify_operands (stmt, &gsi);
7116     }
7117 }
7118
7119 /* Expand the OpenMP parallel or task directive starting at REGION.  */
7120
7121 static void
7122 expand_omp_taskreg (struct omp_region *region)
7123 {
7124   basic_block entry_bb, exit_bb, new_bb;
7125   struct function *child_cfun;
7126   tree child_fn, block, t;
7127   gimple_stmt_iterator gsi;
7128   gimple *entry_stmt, *stmt;
7129   edge e;
7130   vec<tree, va_gc> *ws_args;
7131
7132   entry_stmt = last_stmt (region->entry);
7133   child_fn = gimple_omp_taskreg_child_fn (entry_stmt);
7134   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
7135
7136   entry_bb = region->entry;
7137   if (gimple_code (entry_stmt) == GIMPLE_OMP_TASK)
7138     exit_bb = region->cont;
7139   else
7140     exit_bb = region->exit;
7141
7142   bool is_cilk_for
7143     = (flag_cilkplus
7144        && gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL
7145        && find_omp_clause (gimple_omp_parallel_clauses (entry_stmt),
7146                            OMP_CLAUSE__CILK_FOR_COUNT_) != NULL_TREE);
7147
7148   if (is_cilk_for)
7149     /* If it is a _Cilk_for statement, it is modelled *like* a parallel for,
7150        and the inner statement contains the name of the built-in function
7151        and grain.  */
7152     ws_args = region->inner->ws_args;
7153   else if (is_combined_parallel (region))
7154     ws_args = region->ws_args;
7155   else
7156     ws_args = NULL;
7157
7158   if (child_cfun->cfg)
7159     {
7160       /* Due to inlining, it may happen that we have already outlined
7161          the region, in which case all we need to do is make the
7162          sub-graph unreachable and emit the parallel call.  */
7163       edge entry_succ_e, exit_succ_e;
7164
7165       entry_succ_e = single_succ_edge (entry_bb);
7166
7167       gsi = gsi_last_bb (entry_bb);
7168       gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_PARALLEL
7169                   || gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_TASK);
7170       gsi_remove (&gsi, true);
7171
7172       new_bb = entry_bb;
7173       if (exit_bb)
7174         {
7175           exit_succ_e = single_succ_edge (exit_bb);
7176           make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
7177         }
7178       remove_edge_and_dominated_blocks (entry_succ_e);
7179     }
7180   else
7181     {
7182       unsigned srcidx, dstidx, num;
7183
7184       /* If the parallel region needs data sent from the parent
7185          function, then the very first statement (except possible
7186          tree profile counter updates) of the parallel body
7187          is a copy assignment .OMP_DATA_I = &.OMP_DATA_O.  Since
7188          &.OMP_DATA_O is passed as an argument to the child function,
7189          we need to replace it with the argument as seen by the child
7190          function.
7191
7192          In most cases, this will end up being the identity assignment
7193          .OMP_DATA_I = .OMP_DATA_I.  However, if the parallel body had
7194          a function call that has been inlined, the original PARM_DECL
7195          .OMP_DATA_I may have been converted into a different local
7196          variable.  In which case, we need to keep the assignment.  */
7197       if (gimple_omp_taskreg_data_arg (entry_stmt))
7198         {
7199           basic_block entry_succ_bb
7200             = single_succ_p (entry_bb) ? single_succ (entry_bb)
7201                                        : FALLTHRU_EDGE (entry_bb)->dest;
7202           tree arg;
7203           gimple *parcopy_stmt = NULL;
7204
7205           for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
7206             {
7207               gimple *stmt;
7208
7209               gcc_assert (!gsi_end_p (gsi));
7210               stmt = gsi_stmt (gsi);
7211               if (gimple_code (stmt) != GIMPLE_ASSIGN)
7212                 continue;
7213
7214               if (gimple_num_ops (stmt) == 2)
7215                 {
7216                   tree arg = gimple_assign_rhs1 (stmt);
7217
7218                   /* We're ignore the subcode because we're
7219                      effectively doing a STRIP_NOPS.  */
7220
7221                   if (TREE_CODE (arg) == ADDR_EXPR
7222                       && TREE_OPERAND (arg, 0)
7223                         == gimple_omp_taskreg_data_arg (entry_stmt))
7224                     {
7225                       parcopy_stmt = stmt;
7226                       break;
7227                     }
7228                 }
7229             }
7230
7231           gcc_assert (parcopy_stmt != NULL);
7232           arg = DECL_ARGUMENTS (child_fn);
7233
7234           if (!gimple_in_ssa_p (cfun))
7235             {
7236               if (gimple_assign_lhs (parcopy_stmt) == arg)
7237                 gsi_remove (&gsi, true);
7238               else
7239                 {
7240                   /* ?? Is setting the subcode really necessary ??  */
7241                   gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (arg));
7242                   gimple_assign_set_rhs1 (parcopy_stmt, arg);
7243                 }
7244             }
7245           else
7246             {
7247               tree lhs = gimple_assign_lhs (parcopy_stmt);
7248               gcc_assert (SSA_NAME_VAR (lhs) == arg);
7249               /* We'd like to set the rhs to the default def in the child_fn,
7250                  but it's too early to create ssa names in the child_fn.
7251                  Instead, we set the rhs to the parm.  In
7252                  move_sese_region_to_fn, we introduce a default def for the
7253                  parm, map the parm to it's default def, and once we encounter
7254                  this stmt, replace the parm with the default def.  */
7255               gimple_assign_set_rhs1 (parcopy_stmt, arg);
7256               update_stmt (parcopy_stmt);
7257             }
7258         }
7259
7260       /* Declare local variables needed in CHILD_CFUN.  */
7261       block = DECL_INITIAL (child_fn);
7262       BLOCK_VARS (block) = vec2chain (child_cfun->local_decls);
7263       /* The gimplifier could record temporaries in parallel/task block
7264          rather than in containing function's local_decls chain,
7265          which would mean cgraph missed finalizing them.  Do it now.  */
7266       for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
7267         if (TREE_CODE (t) == VAR_DECL
7268             && TREE_STATIC (t)
7269             && !DECL_EXTERNAL (t))
7270           varpool_node::finalize_decl (t);
7271       DECL_SAVED_TREE (child_fn) = NULL;
7272       /* We'll create a CFG for child_fn, so no gimple body is needed.  */
7273       gimple_set_body (child_fn, NULL);
7274       TREE_USED (block) = 1;
7275
7276       /* Reset DECL_CONTEXT on function arguments.  */
7277       for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
7278         DECL_CONTEXT (t) = child_fn;
7279
7280       /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
7281          so that it can be moved to the child function.  */
7282       gsi = gsi_last_bb (entry_bb);
7283       stmt = gsi_stmt (gsi);
7284       gcc_assert (stmt && (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
7285                            || gimple_code (stmt) == GIMPLE_OMP_TASK));
7286       e = split_block (entry_bb, stmt);
7287       gsi_remove (&gsi, true);
7288       entry_bb = e->dest;
7289       edge e2 = NULL;
7290       if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
7291         single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
7292       else
7293         {
7294           e2 = make_edge (e->src, BRANCH_EDGE (entry_bb)->dest, EDGE_ABNORMAL);
7295           gcc_assert (e2->dest == region->exit);
7296           remove_edge (BRANCH_EDGE (entry_bb));
7297           set_immediate_dominator (CDI_DOMINATORS, e2->dest, e->src);
7298           gsi = gsi_last_bb (region->exit);
7299           gcc_assert (!gsi_end_p (gsi)
7300                       && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
7301           gsi_remove (&gsi, true);
7302         }
7303
7304       /* Convert GIMPLE_OMP_{RETURN,CONTINUE} into a RETURN_EXPR.  */
7305       if (exit_bb)
7306         {
7307           gsi = gsi_last_bb (exit_bb);
7308           gcc_assert (!gsi_end_p (gsi)
7309                       && (gimple_code (gsi_stmt (gsi))
7310                           == (e2 ? GIMPLE_OMP_CONTINUE : GIMPLE_OMP_RETURN)));
7311           stmt = gimple_build_return (NULL);
7312           gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
7313           gsi_remove (&gsi, true);
7314         }
7315
7316       /* Move the parallel region into CHILD_CFUN.  */
7317
7318       if (gimple_in_ssa_p (cfun))
7319         {
7320           init_tree_ssa (child_cfun);
7321           init_ssa_operands (child_cfun);
7322           child_cfun->gimple_df->in_ssa_p = true;
7323           block = NULL_TREE;
7324         }
7325       else
7326         block = gimple_block (entry_stmt);
7327
7328       new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
7329       if (exit_bb)
7330         single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
7331       if (e2)
7332         {
7333           basic_block dest_bb = e2->dest;
7334           if (!exit_bb)
7335             make_edge (new_bb, dest_bb, EDGE_FALLTHRU);
7336           remove_edge (e2);
7337           set_immediate_dominator (CDI_DOMINATORS, dest_bb, new_bb);
7338         }
7339       /* When the OMP expansion process cannot guarantee an up-to-date
7340          loop tree arrange for the child function to fixup loops.  */
7341       if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
7342         child_cfun->x_current_loops->state |= LOOPS_NEED_FIXUP;
7343
7344       /* Remove non-local VAR_DECLs from child_cfun->local_decls list.  */
7345       num = vec_safe_length (child_cfun->local_decls);
7346       for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
7347         {
7348           t = (*child_cfun->local_decls)[srcidx];
7349           if (DECL_CONTEXT (t) == cfun->decl)
7350             continue;
7351           if (srcidx != dstidx)
7352             (*child_cfun->local_decls)[dstidx] = t;
7353           dstidx++;
7354         }
7355       if (dstidx != num)
7356         vec_safe_truncate (child_cfun->local_decls, dstidx);
7357
7358       /* Inform the callgraph about the new function.  */
7359       child_cfun->curr_properties = cfun->curr_properties;
7360       child_cfun->has_simduid_loops |= cfun->has_simduid_loops;
7361       child_cfun->has_force_vectorize_loops |= cfun->has_force_vectorize_loops;
7362       cgraph_node *node = cgraph_node::get_create (child_fn);
7363       node->parallelized_function = 1;
7364       cgraph_node::add_new_function (child_fn, true);
7365
7366       bool need_asm = DECL_ASSEMBLER_NAME_SET_P (current_function_decl)
7367                       && !DECL_ASSEMBLER_NAME_SET_P (child_fn);
7368
7369       /* Fix the callgraph edges for child_cfun.  Those for cfun will be
7370          fixed in a following pass.  */
7371       push_cfun (child_cfun);
7372       if (need_asm)
7373         assign_assembler_name_if_neeeded (child_fn);
7374
7375       if (optimize)
7376         optimize_omp_library_calls (entry_stmt);
7377       cgraph_edge::rebuild_edges ();
7378
7379       /* Some EH regions might become dead, see PR34608.  If
7380          pass_cleanup_cfg isn't the first pass to happen with the
7381          new child, these dead EH edges might cause problems.
7382          Clean them up now.  */
7383       if (flag_exceptions)
7384         {
7385           basic_block bb;
7386           bool changed = false;
7387
7388           FOR_EACH_BB_FN (bb, cfun)
7389             changed |= gimple_purge_dead_eh_edges (bb);
7390           if (changed)
7391             cleanup_tree_cfg ();
7392         }
7393       if (gimple_in_ssa_p (cfun))
7394         update_ssa (TODO_update_ssa);
7395       if (flag_checking && !loops_state_satisfies_p (LOOPS_NEED_FIXUP))
7396         verify_loop_structure ();
7397       pop_cfun ();
7398
7399       if (dump_file && !gimple_in_ssa_p (cfun))
7400         {
7401           omp_any_child_fn_dumped = true;
7402           dump_function_header (dump_file, child_fn, dump_flags);
7403           dump_function_to_file (child_fn, dump_file, dump_flags);
7404         }
7405     }
7406
7407   /* Emit a library call to launch the children threads.  */
7408   if (is_cilk_for)
7409     expand_cilk_for_call (new_bb,
7410                           as_a <gomp_parallel *> (entry_stmt), ws_args);
7411   else if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
7412     expand_parallel_call (region, new_bb,
7413                           as_a <gomp_parallel *> (entry_stmt), ws_args);
7414   else
7415     expand_task_call (region, new_bb, as_a <gomp_task *> (entry_stmt));
7416   if (gimple_in_ssa_p (cfun))
7417     update_ssa (TODO_update_ssa_only_virtuals);
7418 }
7419
7420 /* Information about members of an OpenACC collapsed loop nest.  */
7421
7422 struct oacc_collapse
7423 {
7424   tree base;  /* Base value. */
7425   tree iters; /* Number of steps.  */
7426   tree step;  /* step size.  */
7427 };
7428
7429 /* Helper for expand_oacc_for.  Determine collapsed loop information.
7430    Fill in COUNTS array.  Emit any initialization code before GSI.
7431    Return the calculated outer loop bound of BOUND_TYPE.  */
7432
7433 static tree
7434 expand_oacc_collapse_init (const struct omp_for_data *fd,
7435                            gimple_stmt_iterator *gsi,
7436                            oacc_collapse *counts, tree bound_type)
7437 {
7438   tree total = build_int_cst (bound_type, 1);
7439   int ix;
7440   
7441   gcc_assert (integer_onep (fd->loop.step));
7442   gcc_assert (integer_zerop (fd->loop.n1));
7443
7444   for (ix = 0; ix != fd->collapse; ix++)
7445     {
7446       const omp_for_data_loop *loop = &fd->loops[ix];
7447
7448       tree iter_type = TREE_TYPE (loop->v);
7449       tree diff_type = iter_type;
7450       tree plus_type = iter_type;
7451
7452       gcc_assert (loop->cond_code == fd->loop.cond_code);
7453       
7454       if (POINTER_TYPE_P (iter_type))
7455         plus_type = sizetype;
7456       if (POINTER_TYPE_P (diff_type) || TYPE_UNSIGNED (diff_type))
7457         diff_type = signed_type_for (diff_type);
7458
7459       tree b = loop->n1;
7460       tree e = loop->n2;
7461       tree s = loop->step;
7462       bool up = loop->cond_code == LT_EXPR;
7463       tree dir = build_int_cst (diff_type, up ? +1 : -1);
7464       bool negating;
7465       tree expr;
7466
7467       b = force_gimple_operand_gsi (gsi, b, true, NULL_TREE,
7468                                     true, GSI_SAME_STMT);
7469       e = force_gimple_operand_gsi (gsi, e, true, NULL_TREE,
7470                                     true, GSI_SAME_STMT);
7471
7472       /* Convert the step, avoiding possible unsigned->signed overflow. */
7473       negating = !up && TYPE_UNSIGNED (TREE_TYPE (s));
7474       if (negating)
7475         s = fold_build1 (NEGATE_EXPR, TREE_TYPE (s), s);
7476       s = fold_convert (diff_type, s);
7477       if (negating)
7478         s = fold_build1 (NEGATE_EXPR, diff_type, s);
7479       s = force_gimple_operand_gsi (gsi, s, true, NULL_TREE,
7480                                     true, GSI_SAME_STMT);
7481
7482       /* Determine the range, avoiding possible unsigned->signed overflow. */
7483       negating = !up && TYPE_UNSIGNED (iter_type);
7484       expr = fold_build2 (MINUS_EXPR, plus_type,
7485                           fold_convert (plus_type, negating ? b : e),
7486                           fold_convert (plus_type, negating ? e : b));
7487       expr = fold_convert (diff_type, expr);
7488       if (negating)
7489         expr = fold_build1 (NEGATE_EXPR, diff_type, expr);
7490       tree range = force_gimple_operand_gsi
7491         (gsi, expr, true, NULL_TREE, true, GSI_SAME_STMT);
7492
7493       /* Determine number of iterations.  */
7494       expr = fold_build2 (MINUS_EXPR, diff_type, range, dir);
7495       expr = fold_build2 (PLUS_EXPR, diff_type, expr, s);
7496       expr = fold_build2 (TRUNC_DIV_EXPR, diff_type, expr, s);
7497
7498       tree iters = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
7499                                              true, GSI_SAME_STMT);
7500
7501       counts[ix].base = b;
7502       counts[ix].iters = iters;
7503       counts[ix].step = s;
7504
7505       total = fold_build2 (MULT_EXPR, bound_type, total,
7506                            fold_convert (bound_type, iters));
7507     }
7508
7509   return total;
7510 }
7511
7512 /* Emit initializers for collapsed loop members.  IVAR is the outer
7513    loop iteration variable, from which collapsed loop iteration values
7514    are  calculated.  COUNTS array has been initialized by
7515    expand_oacc_collapse_inits.  */
7516
7517 static void
7518 expand_oacc_collapse_vars (const struct omp_for_data *fd,
7519                            gimple_stmt_iterator *gsi,
7520                            const oacc_collapse *counts, tree ivar)
7521 {
7522   tree ivar_type = TREE_TYPE (ivar);
7523
7524   /*  The most rapidly changing iteration variable is the innermost
7525       one.  */
7526   for (int ix = fd->collapse; ix--;)
7527     {
7528       const omp_for_data_loop *loop = &fd->loops[ix];
7529       const oacc_collapse *collapse = &counts[ix];
7530       tree iter_type = TREE_TYPE (loop->v);
7531       tree diff_type = TREE_TYPE (collapse->step);
7532       tree plus_type = iter_type;
7533       enum tree_code plus_code = PLUS_EXPR;
7534       tree expr;
7535
7536       if (POINTER_TYPE_P (iter_type))
7537         {
7538           plus_code = POINTER_PLUS_EXPR;
7539           plus_type = sizetype;
7540         }
7541
7542       expr = fold_build2 (TRUNC_MOD_EXPR, ivar_type, ivar,
7543                           fold_convert (ivar_type, collapse->iters));
7544       expr = fold_build2 (MULT_EXPR, diff_type, fold_convert (diff_type, expr),
7545                           collapse->step);
7546       expr = fold_build2 (plus_code, iter_type, collapse->base,
7547                           fold_convert (plus_type, expr));
7548       expr = force_gimple_operand_gsi (gsi, expr, false, NULL_TREE,
7549                                        true, GSI_SAME_STMT);
7550       gassign *ass = gimple_build_assign (loop->v, expr);
7551       gsi_insert_before (gsi, ass, GSI_SAME_STMT);
7552
7553       if (ix)
7554         {
7555           expr = fold_build2 (TRUNC_DIV_EXPR, ivar_type, ivar,
7556                               fold_convert (ivar_type, collapse->iters));
7557           ivar = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
7558                                            true, GSI_SAME_STMT);
7559         }
7560     }
7561 }
7562
7563
7564 /* Helper function for expand_omp_{for_*,simd}.  If this is the outermost
7565    of the combined collapse > 1 loop constructs, generate code like:
7566         if (__builtin_expect (N32 cond3 N31, 0)) goto ZERO_ITER_BB;
7567         if (cond3 is <)
7568           adj = STEP3 - 1;
7569         else
7570           adj = STEP3 + 1;
7571         count3 = (adj + N32 - N31) / STEP3;
7572         if (__builtin_expect (N22 cond2 N21, 0)) goto ZERO_ITER_BB;
7573         if (cond2 is <)
7574           adj = STEP2 - 1;
7575         else
7576           adj = STEP2 + 1;
7577         count2 = (adj + N22 - N21) / STEP2;
7578         if (__builtin_expect (N12 cond1 N11, 0)) goto ZERO_ITER_BB;
7579         if (cond1 is <)
7580           adj = STEP1 - 1;
7581         else
7582           adj = STEP1 + 1;
7583         count1 = (adj + N12 - N11) / STEP1;
7584         count = count1 * count2 * count3;
7585    Furthermore, if ZERO_ITER_BB is NULL, create a BB which does:
7586         count = 0;
7587    and set ZERO_ITER_BB to that bb.  If this isn't the outermost
7588    of the combined loop constructs, just initialize COUNTS array
7589    from the _looptemp_ clauses.  */
7590
7591 /* NOTE: It *could* be better to moosh all of the BBs together,
7592    creating one larger BB with all the computation and the unexpected
7593    jump at the end.  I.e.
7594
7595    bool zero3, zero2, zero1, zero;
7596
7597    zero3 = N32 c3 N31;
7598    count3 = (N32 - N31) /[cl] STEP3;
7599    zero2 = N22 c2 N21;
7600    count2 = (N22 - N21) /[cl] STEP2;
7601    zero1 = N12 c1 N11;
7602    count1 = (N12 - N11) /[cl] STEP1;
7603    zero = zero3 || zero2 || zero1;
7604    count = count1 * count2 * count3;
7605    if (__builtin_expect(zero, false)) goto zero_iter_bb;
7606
7607    After all, we expect the zero=false, and thus we expect to have to
7608    evaluate all of the comparison expressions, so short-circuiting
7609    oughtn't be a win.  Since the condition isn't protecting a
7610    denominator, we're not concerned about divide-by-zero, so we can
7611    fully evaluate count even if a numerator turned out to be wrong.
7612
7613    It seems like putting this all together would create much better
7614    scheduling opportunities, and less pressure on the chip's branch
7615    predictor.  */
7616
7617 static void
7618 expand_omp_for_init_counts (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
7619                             basic_block &entry_bb, tree *counts,
7620                             basic_block &zero_iter1_bb, int &first_zero_iter1,
7621                             basic_block &zero_iter2_bb, int &first_zero_iter2,
7622                             basic_block &l2_dom_bb)
7623 {
7624   tree t, type = TREE_TYPE (fd->loop.v);
7625   edge e, ne;
7626   int i;
7627
7628   /* Collapsed loops need work for expansion into SSA form.  */
7629   gcc_assert (!gimple_in_ssa_p (cfun));
7630
7631   if (gimple_omp_for_combined_into_p (fd->for_stmt)
7632       && TREE_CODE (fd->loop.n2) != INTEGER_CST)
7633     {
7634       gcc_assert (fd->ordered == 0);
7635       /* First two _looptemp_ clauses are for istart/iend, counts[0]
7636          isn't supposed to be handled, as the inner loop doesn't
7637          use it.  */
7638       tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
7639                                      OMP_CLAUSE__LOOPTEMP_);
7640       gcc_assert (innerc);
7641       for (i = 0; i < fd->collapse; i++)
7642         {
7643           innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
7644                                     OMP_CLAUSE__LOOPTEMP_);
7645           gcc_assert (innerc);
7646           if (i)
7647             counts[i] = OMP_CLAUSE_DECL (innerc);
7648           else
7649             counts[0] = NULL_TREE;
7650         }
7651       return;
7652     }
7653
7654   for (i = fd->collapse; i < fd->ordered; i++)
7655     {
7656       tree itype = TREE_TYPE (fd->loops[i].v);
7657       counts[i] = NULL_TREE;
7658       t = fold_binary (fd->loops[i].cond_code, boolean_type_node,
7659                        fold_convert (itype, fd->loops[i].n1),
7660                        fold_convert (itype, fd->loops[i].n2));
7661       if (t && integer_zerop (t))
7662         {
7663           for (i = fd->collapse; i < fd->ordered; i++)
7664             counts[i] = build_int_cst (type, 0);
7665           break;
7666         }
7667     }
7668   for (i = 0; i < (fd->ordered ? fd->ordered : fd->collapse); i++)
7669     {
7670       tree itype = TREE_TYPE (fd->loops[i].v);
7671
7672       if (i >= fd->collapse && counts[i])
7673         continue;
7674       if ((SSA_VAR_P (fd->loop.n2) || i >= fd->collapse)
7675           && ((t = fold_binary (fd->loops[i].cond_code, boolean_type_node,
7676                                 fold_convert (itype, fd->loops[i].n1),
7677                                 fold_convert (itype, fd->loops[i].n2)))
7678               == NULL_TREE || !integer_onep (t)))
7679         {
7680           gcond *cond_stmt;
7681           tree n1, n2;
7682           n1 = fold_convert (itype, unshare_expr (fd->loops[i].n1));
7683           n1 = force_gimple_operand_gsi (gsi, n1, true, NULL_TREE,
7684                                          true, GSI_SAME_STMT);
7685           n2 = fold_convert (itype, unshare_expr (fd->loops[i].n2));
7686           n2 = force_gimple_operand_gsi (gsi, n2, true, NULL_TREE,
7687                                          true, GSI_SAME_STMT);
7688           cond_stmt = gimple_build_cond (fd->loops[i].cond_code, n1, n2,
7689                                          NULL_TREE, NULL_TREE);
7690           gsi_insert_before (gsi, cond_stmt, GSI_SAME_STMT);
7691           if (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
7692                          expand_omp_regimplify_p, NULL, NULL)
7693               || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
7694                             expand_omp_regimplify_p, NULL, NULL))
7695             {
7696               *gsi = gsi_for_stmt (cond_stmt);
7697               gimple_regimplify_operands (cond_stmt, gsi);
7698             }
7699           e = split_block (entry_bb, cond_stmt);
7700           basic_block &zero_iter_bb
7701             = i < fd->collapse ? zero_iter1_bb : zero_iter2_bb;
7702           int &first_zero_iter
7703             = i < fd->collapse ? first_zero_iter1 : first_zero_iter2;
7704           if (zero_iter_bb == NULL)
7705             {
7706               gassign *assign_stmt;
7707               first_zero_iter = i;
7708               zero_iter_bb = create_empty_bb (entry_bb);
7709               add_bb_to_loop (zero_iter_bb, entry_bb->loop_father);
7710               *gsi = gsi_after_labels (zero_iter_bb);
7711               if (i < fd->collapse)
7712                 assign_stmt = gimple_build_assign (fd->loop.n2,
7713                                                    build_zero_cst (type));
7714               else
7715                 {
7716                   counts[i] = create_tmp_reg (type, ".count");
7717                   assign_stmt
7718                     = gimple_build_assign (counts[i], build_zero_cst (type));
7719                 }
7720               gsi_insert_before (gsi, assign_stmt, GSI_SAME_STMT);
7721               set_immediate_dominator (CDI_DOMINATORS, zero_iter_bb,
7722                                        entry_bb);
7723             }
7724           ne = make_edge (entry_bb, zero_iter_bb, EDGE_FALSE_VALUE);
7725           ne->probability = REG_BR_PROB_BASE / 2000 - 1;
7726           e->flags = EDGE_TRUE_VALUE;
7727           e->probability = REG_BR_PROB_BASE - ne->probability;
7728           if (l2_dom_bb == NULL)
7729             l2_dom_bb = entry_bb;
7730           entry_bb = e->dest;
7731           *gsi = gsi_last_bb (entry_bb);
7732         }
7733
7734       if (POINTER_TYPE_P (itype))
7735         itype = signed_type_for (itype);
7736       t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR
7737                                  ? -1 : 1));
7738       t = fold_build2 (PLUS_EXPR, itype,
7739                        fold_convert (itype, fd->loops[i].step), t);
7740       t = fold_build2 (PLUS_EXPR, itype, t,
7741                        fold_convert (itype, fd->loops[i].n2));
7742       t = fold_build2 (MINUS_EXPR, itype, t,
7743                        fold_convert (itype, fd->loops[i].n1));
7744       /* ?? We could probably use CEIL_DIV_EXPR instead of
7745          TRUNC_DIV_EXPR and adjusting by hand.  Unless we can't
7746          generate the same code in the end because generically we
7747          don't know that the values involved must be negative for
7748          GT??  */
7749       if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
7750         t = fold_build2 (TRUNC_DIV_EXPR, itype,
7751                          fold_build1 (NEGATE_EXPR, itype, t),
7752                          fold_build1 (NEGATE_EXPR, itype,
7753                                       fold_convert (itype,
7754                                                     fd->loops[i].step)));
7755       else
7756         t = fold_build2 (TRUNC_DIV_EXPR, itype, t,
7757                          fold_convert (itype, fd->loops[i].step));
7758       t = fold_convert (type, t);
7759       if (TREE_CODE (t) == INTEGER_CST)
7760         counts[i] = t;
7761       else
7762         {
7763           if (i < fd->collapse || i != first_zero_iter2)
7764             counts[i] = create_tmp_reg (type, ".count");
7765           expand_omp_build_assign (gsi, counts[i], t);
7766         }
7767       if (SSA_VAR_P (fd->loop.n2) && i < fd->collapse)
7768         {
7769           if (i == 0)
7770             t = counts[0];
7771           else
7772             t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
7773           expand_omp_build_assign (gsi, fd->loop.n2, t);
7774         }
7775     }
7776 }
7777
7778
7779 /* Helper function for expand_omp_{for_*,simd}.  Generate code like:
7780         T = V;
7781         V3 = N31 + (T % count3) * STEP3;
7782         T = T / count3;
7783         V2 = N21 + (T % count2) * STEP2;
7784         T = T / count2;
7785         V1 = N11 + T * STEP1;
7786    if this loop doesn't have an inner loop construct combined with it.
7787    If it does have an inner loop construct combined with it and the
7788    iteration count isn't known constant, store values from counts array
7789    into its _looptemp_ temporaries instead.  */
7790
7791 static void
7792 expand_omp_for_init_vars (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
7793                           tree *counts, gimple *inner_stmt, tree startvar)
7794 {
7795   int i;
7796   if (gimple_omp_for_combined_p (fd->for_stmt))
7797     {
7798       /* If fd->loop.n2 is constant, then no propagation of the counts
7799          is needed, they are constant.  */
7800       if (TREE_CODE (fd->loop.n2) == INTEGER_CST)
7801         return;
7802
7803       tree clauses = gimple_code (inner_stmt) != GIMPLE_OMP_FOR
7804                      ? gimple_omp_taskreg_clauses (inner_stmt)
7805                      : gimple_omp_for_clauses (inner_stmt);
7806       /* First two _looptemp_ clauses are for istart/iend, counts[0]
7807          isn't supposed to be handled, as the inner loop doesn't
7808          use it.  */
7809       tree innerc = find_omp_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
7810       gcc_assert (innerc);
7811       for (i = 0; i < fd->collapse; i++)
7812         {
7813           innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
7814                                     OMP_CLAUSE__LOOPTEMP_);
7815           gcc_assert (innerc);
7816           if (i)
7817             {
7818               tree tem = OMP_CLAUSE_DECL (innerc);
7819               tree t = fold_convert (TREE_TYPE (tem), counts[i]);
7820               t = force_gimple_operand_gsi (gsi, t, false, NULL_TREE,
7821                                             false, GSI_CONTINUE_LINKING);
7822               gassign *stmt = gimple_build_assign (tem, t);
7823               gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
7824             }
7825         }
7826       return;
7827     }
7828
7829   tree type = TREE_TYPE (fd->loop.v);
7830   tree tem = create_tmp_reg (type, ".tem");
7831   gassign *stmt = gimple_build_assign (tem, startvar);
7832   gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
7833
7834   for (i = fd->collapse - 1; i >= 0; i--)
7835     {
7836       tree vtype = TREE_TYPE (fd->loops[i].v), itype, t;
7837       itype = vtype;
7838       if (POINTER_TYPE_P (vtype))
7839         itype = signed_type_for (vtype);
7840       if (i != 0)
7841         t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
7842       else
7843         t = tem;
7844       t = fold_convert (itype, t);
7845       t = fold_build2 (MULT_EXPR, itype, t,
7846                        fold_convert (itype, fd->loops[i].step));
7847       if (POINTER_TYPE_P (vtype))
7848         t = fold_build_pointer_plus (fd->loops[i].n1, t);
7849       else
7850         t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
7851       t = force_gimple_operand_gsi (gsi, t,
7852                                     DECL_P (fd->loops[i].v)
7853                                     && TREE_ADDRESSABLE (fd->loops[i].v),
7854                                     NULL_TREE, false,
7855                                     GSI_CONTINUE_LINKING);
7856       stmt = gimple_build_assign (fd->loops[i].v, t);
7857       gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
7858       if (i != 0)
7859         {
7860           t = fold_build2 (TRUNC_DIV_EXPR, type, tem, counts[i]);
7861           t = force_gimple_operand_gsi (gsi, t, false, NULL_TREE,
7862                                         false, GSI_CONTINUE_LINKING);
7863           stmt = gimple_build_assign (tem, t);
7864           gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
7865         }
7866     }
7867 }
7868
7869
7870 /* Helper function for expand_omp_for_*.  Generate code like:
7871     L10:
7872         V3 += STEP3;
7873         if (V3 cond3 N32) goto BODY_BB; else goto L11;
7874     L11:
7875         V3 = N31;
7876         V2 += STEP2;
7877         if (V2 cond2 N22) goto BODY_BB; else goto L12;
7878     L12:
7879         V2 = N21;
7880         V1 += STEP1;
7881         goto BODY_BB;  */
7882
7883 static basic_block
7884 extract_omp_for_update_vars (struct omp_for_data *fd, basic_block cont_bb,
7885                              basic_block body_bb)
7886 {
7887   basic_block last_bb, bb, collapse_bb = NULL;
7888   int i;
7889   gimple_stmt_iterator gsi;
7890   edge e;
7891   tree t;
7892   gimple *stmt;
7893
7894   last_bb = cont_bb;
7895   for (i = fd->collapse - 1; i >= 0; i--)
7896     {
7897       tree vtype = TREE_TYPE (fd->loops[i].v);
7898
7899       bb = create_empty_bb (last_bb);
7900       add_bb_to_loop (bb, last_bb->loop_father);
7901       gsi = gsi_start_bb (bb);
7902
7903       if (i < fd->collapse - 1)
7904         {
7905           e = make_edge (last_bb, bb, EDGE_FALSE_VALUE);
7906           e->probability = REG_BR_PROB_BASE / 8;
7907
7908           t = fd->loops[i + 1].n1;
7909           t = force_gimple_operand_gsi (&gsi, t,
7910                                         DECL_P (fd->loops[i + 1].v)
7911                                         && TREE_ADDRESSABLE (fd->loops[i
7912                                                                        + 1].v),
7913                                         NULL_TREE, false,
7914                                         GSI_CONTINUE_LINKING);
7915           stmt = gimple_build_assign (fd->loops[i + 1].v, t);
7916           gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
7917         }
7918       else
7919         collapse_bb = bb;
7920
7921       set_immediate_dominator (CDI_DOMINATORS, bb, last_bb);
7922
7923       if (POINTER_TYPE_P (vtype))
7924         t = fold_build_pointer_plus (fd->loops[i].v, fd->loops[i].step);
7925       else
7926         t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v, fd->loops[i].step);
7927       t = force_gimple_operand_gsi (&gsi, t,
7928                                     DECL_P (fd->loops[i].v)
7929                                     && TREE_ADDRESSABLE (fd->loops[i].v),
7930                                     NULL_TREE, false, GSI_CONTINUE_LINKING);
7931       stmt = gimple_build_assign (fd->loops[i].v, t);
7932       gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
7933
7934       if (i > 0)
7935         {
7936           t = fd->loops[i].n2;
7937           t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
7938                                         false, GSI_CONTINUE_LINKING);
7939           tree v = fd->loops[i].v;
7940           if (DECL_P (v) && TREE_ADDRESSABLE (v))
7941             v = force_gimple_operand_gsi (&gsi, v, true, NULL_TREE,
7942                                           false, GSI_CONTINUE_LINKING);
7943           t = fold_build2 (fd->loops[i].cond_code, boolean_type_node, v, t);
7944           stmt = gimple_build_cond_empty (t);
7945           gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
7946           e = make_edge (bb, body_bb, EDGE_TRUE_VALUE);
7947           e->probability = REG_BR_PROB_BASE * 7 / 8;
7948         }
7949       else
7950         make_edge (bb, body_bb, EDGE_FALLTHRU);
7951       last_bb = bb;
7952     }
7953
7954   return collapse_bb;
7955 }
7956
7957
7958 /* Expand #pragma omp ordered depend(source).  */
7959
7960 static void
7961 expand_omp_ordered_source (gimple_stmt_iterator *gsi, struct omp_for_data *fd,
7962                            tree *counts, location_t loc)
7963 {
7964   enum built_in_function source_ix
7965     = fd->iter_type == long_integer_type_node
7966       ? BUILT_IN_GOMP_DOACROSS_POST : BUILT_IN_GOMP_DOACROSS_ULL_POST;
7967   gimple *g
7968     = gimple_build_call (builtin_decl_explicit (source_ix), 1,
7969                          build_fold_addr_expr (counts[fd->ordered]));
7970   gimple_set_location (g, loc);
7971   gsi_insert_before (gsi, g, GSI_SAME_STMT);
7972 }
7973
7974 /* Expand a single depend from #pragma omp ordered depend(sink:...).  */
7975
7976 static void
7977 expand_omp_ordered_sink (gimple_stmt_iterator *gsi, struct omp_for_data *fd,
7978                          tree *counts, tree c, location_t loc)
7979 {
7980   auto_vec<tree, 10> args;
7981   enum built_in_function sink_ix
7982     = fd->iter_type == long_integer_type_node
7983       ? BUILT_IN_GOMP_DOACROSS_WAIT : BUILT_IN_GOMP_DOACROSS_ULL_WAIT;
7984   tree t, off, coff = NULL_TREE, deps = OMP_CLAUSE_DECL (c), cond = NULL_TREE;
7985   int i;
7986   gimple_stmt_iterator gsi2 = *gsi;
7987   bool warned_step = false;
7988
7989   for (i = 0; i < fd->ordered; i++)
7990     {
7991       off = TREE_PURPOSE (deps);
7992       if (!integer_zerop (off))
7993         {
7994           gcc_assert (fd->loops[i].cond_code == LT_EXPR
7995                       || fd->loops[i].cond_code == GT_EXPR);
7996           bool forward = fd->loops[i].cond_code == LT_EXPR;
7997           if (forward ^ OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
7998             warning_at (loc, 0, "%<depend(sink)%> clause waiting for "
7999                                 "lexically later iteration");
8000           break;
8001         }
8002       deps = TREE_CHAIN (deps);
8003     }
8004   /* If all offsets corresponding to the collapsed loops are zero,
8005      this depend clause can be ignored.  FIXME: but there is still a
8006      flush needed.  We need to emit one __sync_synchronize () for it
8007      though (perhaps conditionally)?  Solve this together with the
8008      conservative dependence folding optimization.
8009   if (i >= fd->collapse)
8010     return;  */
8011
8012   deps = OMP_CLAUSE_DECL (c);
8013   gsi_prev (&gsi2);
8014   edge e1 = split_block (gsi_bb (gsi2), gsi_stmt (gsi2));
8015   edge e2 = split_block_after_labels (e1->dest);
8016
8017   *gsi = gsi_after_labels (e1->dest);
8018   for (i = 0; i < fd->ordered; i++)
8019     {
8020       tree itype = TREE_TYPE (fd->loops[i].v);
8021       if (POINTER_TYPE_P (itype))
8022         itype = sizetype;
8023       if (i)
8024         deps = TREE_CHAIN (deps);
8025       off = TREE_PURPOSE (deps);
8026       tree s = fold_convert_loc (loc, itype, fd->loops[i].step);
8027
8028       if (integer_zerop (off))
8029         t = boolean_true_node;
8030       else
8031         {
8032           tree a;
8033           tree co = fold_convert_loc (loc, itype, off);
8034           if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i].v)))
8035             {
8036               if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
8037                 co = fold_build1_loc (loc, NEGATE_EXPR, itype, co);
8038               a = fold_build2_loc (loc, POINTER_PLUS_EXPR,
8039                                    TREE_TYPE (fd->loops[i].v), fd->loops[i].v,
8040                                    co);
8041             }
8042           else if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
8043             a = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (fd->loops[i].v),
8044                                  fd->loops[i].v, co);
8045           else
8046             a = fold_build2_loc (loc, PLUS_EXPR, TREE_TYPE (fd->loops[i].v),
8047                                  fd->loops[i].v, co);
8048           if (fd->loops[i].cond_code == LT_EXPR)
8049             {
8050               if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
8051                 t = fold_build2_loc (loc, GE_EXPR, boolean_type_node, a,
8052                                      fd->loops[i].n1);
8053               else
8054                 t = fold_build2_loc (loc, LT_EXPR, boolean_type_node, a,
8055                                      fd->loops[i].n2);
8056             }
8057           else if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
8058             t = fold_build2_loc (loc, GT_EXPR, boolean_type_node, a,
8059                                  fd->loops[i].n2);
8060           else
8061             t = fold_build2_loc (loc, LE_EXPR, boolean_type_node, a,
8062                                  fd->loops[i].n1);
8063         }
8064       if (cond)
8065         cond = fold_build2_loc (loc, BIT_AND_EXPR, boolean_type_node, cond, t);
8066       else
8067         cond = t;
8068
8069       off = fold_convert_loc (loc, itype, off);
8070
8071       if (fd->loops[i].cond_code == LT_EXPR
8072           ? !integer_onep (fd->loops[i].step)
8073           : !integer_minus_onep (fd->loops[i].step))
8074         {
8075           if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
8076             t = fold_build2_loc (loc, TRUNC_MOD_EXPR, itype, off,
8077                                  fold_build1_loc (loc, NEGATE_EXPR, itype,
8078                                                   s));
8079           else
8080             t = fold_build2_loc (loc, TRUNC_MOD_EXPR, itype, off, s);
8081           t = fold_build2_loc (loc, EQ_EXPR, boolean_type_node, t,
8082                                build_int_cst (itype, 0));
8083           if (integer_zerop (t) && !warned_step)
8084             {
8085               warning_at (loc, 0, "%<depend(sink)%> refers to iteration never "
8086                                   "in the iteration space");
8087               warned_step = true;
8088             }
8089           cond = fold_build2_loc (loc, BIT_AND_EXPR, boolean_type_node,
8090                                   cond, t);
8091         }
8092
8093       if (i <= fd->collapse - 1 && fd->collapse > 1)
8094         t = fd->loop.v;
8095       else if (counts[i])
8096         t = counts[i];
8097       else
8098         {
8099           t = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (fd->loops[i].v),
8100                                fd->loops[i].v, fd->loops[i].n1);
8101           t = fold_convert_loc (loc, fd->iter_type, t);
8102         }
8103       if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
8104         off = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, off,
8105                                fold_build1_loc (loc, NEGATE_EXPR, itype,
8106                                                 s));
8107       else
8108         off = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, off, s);
8109       if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
8110         off = fold_build1_loc (loc, NEGATE_EXPR, itype, off);
8111       off = fold_convert_loc (loc, fd->iter_type, off);
8112       if (i <= fd->collapse - 1 && fd->collapse > 1)
8113         {
8114           if (i)
8115             off = fold_build2_loc (loc, PLUS_EXPR, fd->iter_type, coff,
8116                                    off);
8117           if (i < fd->collapse - 1)
8118             {
8119               coff = fold_build2_loc (loc, MULT_EXPR, fd->iter_type, off,
8120                                       counts[i]);
8121               continue;
8122             }
8123         }
8124       off = unshare_expr (off);
8125       t = fold_build2_loc (loc, PLUS_EXPR, fd->iter_type, t, off);
8126       t = force_gimple_operand_gsi (gsi, t, true, NULL_TREE,
8127                                     true, GSI_SAME_STMT);
8128       args.safe_push (t);
8129     }
8130   gimple *g = gimple_build_call_vec (builtin_decl_explicit (sink_ix), args);
8131   gimple_set_location (g, loc);
8132   gsi_insert_before (gsi, g, GSI_SAME_STMT);
8133
8134   *gsi = gsi_last_bb (e1->src);
8135   cond = unshare_expr (cond);
8136   cond = force_gimple_operand_gsi (gsi, cond, true, NULL_TREE, false,
8137                                    GSI_CONTINUE_LINKING);
8138   gsi_insert_after (gsi, gimple_build_cond_empty (cond), GSI_NEW_STMT);
8139   edge e3 = make_edge (e1->src, e2->dest, EDGE_FALSE_VALUE);
8140   e3->probability = REG_BR_PROB_BASE / 8;
8141   e1->probability = REG_BR_PROB_BASE - e3->probability;
8142   e1->flags = EDGE_TRUE_VALUE;
8143   set_immediate_dominator (CDI_DOMINATORS, e2->dest, e1->src);
8144
8145   *gsi = gsi_after_labels (e2->dest);
8146 }
8147
8148 /* Expand all #pragma omp ordered depend(source) and
8149    #pragma omp ordered depend(sink:...) constructs in the current
8150    #pragma omp for ordered(n) region.  */
8151
8152 static void
8153 expand_omp_ordered_source_sink (struct omp_region *region,
8154                                 struct omp_for_data *fd, tree *counts,
8155                                 basic_block cont_bb)
8156 {
8157   struct omp_region *inner;
8158   int i;
8159   for (i = fd->collapse - 1; i < fd->ordered; i++)
8160     if (i == fd->collapse - 1 && fd->collapse > 1)
8161       counts[i] = NULL_TREE;
8162     else if (i >= fd->collapse && !cont_bb)
8163       counts[i] = build_zero_cst (fd->iter_type);
8164     else if (!POINTER_TYPE_P (TREE_TYPE (fd->loops[i].v))
8165              && integer_onep (fd->loops[i].step))
8166       counts[i] = NULL_TREE;
8167     else
8168       counts[i] = create_tmp_var (fd->iter_type, ".orditer");
8169   tree atype
8170     = build_array_type_nelts (fd->iter_type, fd->ordered - fd->collapse + 1);
8171   counts[fd->ordered] = create_tmp_var (atype, ".orditera");
8172   TREE_ADDRESSABLE (counts[fd->ordered]) = 1;
8173
8174   for (inner = region->inner; inner; inner = inner->next)
8175     if (inner->type == GIMPLE_OMP_ORDERED)
8176       {
8177         gomp_ordered *ord_stmt = inner->ord_stmt;
8178         gimple_stmt_iterator gsi = gsi_for_stmt (ord_stmt);
8179         location_t loc = gimple_location (ord_stmt);
8180         tree c;
8181         for (c = gimple_omp_ordered_clauses (ord_stmt);
8182              c; c = OMP_CLAUSE_CHAIN (c))
8183           if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
8184             break;
8185         if (c)
8186           expand_omp_ordered_source (&gsi, fd, counts, loc);
8187         for (c = gimple_omp_ordered_clauses (ord_stmt);
8188              c; c = OMP_CLAUSE_CHAIN (c))
8189           if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
8190             expand_omp_ordered_sink (&gsi, fd, counts, c, loc);
8191         gsi_remove (&gsi, true);
8192       }
8193 }
8194
8195 /* Wrap the body into fd->ordered - fd->collapse loops that aren't
8196    collapsed.  */
8197
8198 static basic_block
8199 expand_omp_for_ordered_loops (struct omp_for_data *fd, tree *counts,
8200                               basic_block cont_bb, basic_block body_bb,
8201                               bool ordered_lastprivate)
8202 {
8203   if (fd->ordered == fd->collapse)
8204     return cont_bb;
8205
8206   if (!cont_bb)
8207     {
8208       gimple_stmt_iterator gsi = gsi_after_labels (body_bb);
8209       for (int i = fd->collapse; i < fd->ordered; i++)
8210         {
8211           tree type = TREE_TYPE (fd->loops[i].v);
8212           tree n1 = fold_convert (type, fd->loops[i].n1);
8213           expand_omp_build_assign (&gsi, fd->loops[i].v, n1);
8214           tree aref = build4 (ARRAY_REF, fd->iter_type, counts[fd->ordered],
8215                               size_int (i - fd->collapse + 1),
8216                               NULL_TREE, NULL_TREE);
8217           expand_omp_build_assign (&gsi, aref, build_zero_cst (fd->iter_type));
8218         }
8219       return NULL;
8220     }
8221
8222   for (int i = fd->ordered - 1; i >= fd->collapse; i--)
8223     {
8224       tree t, type = TREE_TYPE (fd->loops[i].v);
8225       gimple_stmt_iterator gsi = gsi_after_labels (body_bb);
8226       expand_omp_build_assign (&gsi, fd->loops[i].v,
8227                                fold_convert (type, fd->loops[i].n1));
8228       if (counts[i])
8229         expand_omp_build_assign (&gsi, counts[i],
8230                                  build_zero_cst (fd->iter_type));
8231       tree aref = build4 (ARRAY_REF, fd->iter_type, counts[fd->ordered],
8232                           size_int (i - fd->collapse + 1),
8233                           NULL_TREE, NULL_TREE);
8234       expand_omp_build_assign (&gsi, aref, build_zero_cst (fd->iter_type));
8235       if (!gsi_end_p (gsi))
8236         gsi_prev (&gsi);
8237       else
8238         gsi = gsi_last_bb (body_bb);
8239       edge e1 = split_block (body_bb, gsi_stmt (gsi));
8240       basic_block new_body = e1->dest;
8241       if (body_bb == cont_bb)
8242         cont_bb = new_body;
8243       edge e2 = NULL;
8244       basic_block new_header;
8245       if (EDGE_COUNT (cont_bb->preds) > 0)
8246         {
8247           gsi = gsi_last_bb (cont_bb);
8248           if (POINTER_TYPE_P (type))
8249             t = fold_build_pointer_plus (fd->loops[i].v,
8250                                          fold_convert (sizetype,
8251                                                        fd->loops[i].step));
8252           else
8253             t = fold_build2 (PLUS_EXPR, type, fd->loops[i].v,
8254                              fold_convert (type, fd->loops[i].step));
8255           expand_omp_build_assign (&gsi, fd->loops[i].v, t);
8256           if (counts[i])
8257             {
8258               t = fold_build2 (PLUS_EXPR, fd->iter_type, counts[i],
8259                                build_int_cst (fd->iter_type, 1));
8260               expand_omp_build_assign (&gsi, counts[i], t);
8261               t = counts[i];
8262             }
8263           else
8264             {
8265               t = fold_build2 (MINUS_EXPR, TREE_TYPE (fd->loops[i].v),
8266                                fd->loops[i].v, fd->loops[i].n1);
8267               t = fold_convert (fd->iter_type, t);
8268               t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
8269                                             true, GSI_SAME_STMT);
8270             }
8271           aref = build4 (ARRAY_REF, fd->iter_type, counts[fd->ordered],
8272                          size_int (i - fd->collapse + 1),
8273                          NULL_TREE, NULL_TREE);
8274           expand_omp_build_assign (&gsi, aref, t);
8275           gsi_prev (&gsi);
8276           e2 = split_block (cont_bb, gsi_stmt (gsi));
8277           new_header = e2->dest;
8278         }
8279       else
8280         new_header = cont_bb;
8281       gsi = gsi_after_labels (new_header);
8282       tree v = force_gimple_operand_gsi (&gsi, fd->loops[i].v, true, NULL_TREE,
8283                                          true, GSI_SAME_STMT);
8284       tree n2
8285         = force_gimple_operand_gsi (&gsi, fold_convert (type, fd->loops[i].n2),
8286                                     true, NULL_TREE, true, GSI_SAME_STMT);
8287       t = build2 (fd->loops[i].cond_code, boolean_type_node, v, n2);
8288       gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_NEW_STMT);
8289       edge e3 = split_block (new_header, gsi_stmt (gsi));
8290       cont_bb = e3->dest;
8291       remove_edge (e1);
8292       make_edge (body_bb, new_header, EDGE_FALLTHRU);
8293       e3->flags = EDGE_FALSE_VALUE;
8294       e3->probability = REG_BR_PROB_BASE / 8;
8295       e1 = make_edge (new_header, new_body, EDGE_TRUE_VALUE);
8296       e1->probability = REG_BR_PROB_BASE - e3->probability;
8297
8298       set_immediate_dominator (CDI_DOMINATORS, new_header, body_bb);
8299       set_immediate_dominator (CDI_DOMINATORS, new_body, new_header);
8300
8301       if (e2)
8302         {
8303           struct loop *loop = alloc_loop ();
8304           loop->header = new_header;
8305           loop->latch = e2->src;
8306           add_loop (loop, body_bb->loop_father);
8307         }
8308     }
8309
8310   /* If there are any lastprivate clauses and it is possible some loops
8311      might have zero iterations, ensure all the decls are initialized,
8312      otherwise we could crash evaluating C++ class iterators with lastprivate
8313      clauses.  */
8314   bool need_inits = false;
8315   for (int i = fd->collapse; ordered_lastprivate && i < fd->ordered; i++)
8316     if (need_inits)
8317       {
8318         tree type = TREE_TYPE (fd->loops[i].v);
8319         gimple_stmt_iterator gsi = gsi_after_labels (body_bb);
8320         expand_omp_build_assign (&gsi, fd->loops[i].v,
8321                                  fold_convert (type, fd->loops[i].n1));
8322       }
8323     else
8324       {
8325         tree type = TREE_TYPE (fd->loops[i].v);
8326         tree this_cond = fold_build2 (fd->loops[i].cond_code,
8327                                       boolean_type_node,
8328                                       fold_convert (type, fd->loops[i].n1),
8329                                       fold_convert (type, fd->loops[i].n2));
8330         if (!integer_onep (this_cond))
8331           need_inits = true;
8332       }
8333
8334   return cont_bb;
8335 }
8336
8337
8338 /* A subroutine of expand_omp_for.  Generate code for a parallel
8339    loop with any schedule.  Given parameters:
8340
8341         for (V = N1; V cond N2; V += STEP) BODY;
8342
8343    where COND is "<" or ">", we generate pseudocode
8344
8345         more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
8346         if (more) goto L0; else goto L3;
8347     L0:
8348         V = istart0;
8349         iend = iend0;
8350     L1:
8351         BODY;
8352         V += STEP;
8353         if (V cond iend) goto L1; else goto L2;
8354     L2:
8355         if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
8356     L3:
8357
8358     If this is a combined omp parallel loop, instead of the call to
8359     GOMP_loop_foo_start, we call GOMP_loop_foo_next.
8360     If this is gimple_omp_for_combined_p loop, then instead of assigning
8361     V and iend in L0 we assign the first two _looptemp_ clause decls of the
8362     inner GIMPLE_OMP_FOR and V += STEP; and
8363     if (V cond iend) goto L1; else goto L2; are removed.
8364
8365     For collapsed loops, given parameters:
8366       collapse(3)
8367       for (V1 = N11; V1 cond1 N12; V1 += STEP1)
8368         for (V2 = N21; V2 cond2 N22; V2 += STEP2)
8369           for (V3 = N31; V3 cond3 N32; V3 += STEP3)
8370             BODY;
8371
8372     we generate pseudocode
8373
8374         if (__builtin_expect (N32 cond3 N31, 0)) goto Z0;
8375         if (cond3 is <)
8376           adj = STEP3 - 1;
8377         else
8378           adj = STEP3 + 1;
8379         count3 = (adj + N32 - N31) / STEP3;
8380         if (__builtin_expect (N22 cond2 N21, 0)) goto Z0;
8381         if (cond2 is <)
8382           adj = STEP2 - 1;
8383         else
8384           adj = STEP2 + 1;
8385         count2 = (adj + N22 - N21) / STEP2;
8386         if (__builtin_expect (N12 cond1 N11, 0)) goto Z0;
8387         if (cond1 is <)
8388           adj = STEP1 - 1;
8389         else
8390           adj = STEP1 + 1;
8391         count1 = (adj + N12 - N11) / STEP1;
8392         count = count1 * count2 * count3;
8393         goto Z1;
8394     Z0:
8395         count = 0;
8396     Z1:
8397         more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
8398         if (more) goto L0; else goto L3;
8399     L0:
8400         V = istart0;
8401         T = V;
8402         V3 = N31 + (T % count3) * STEP3;
8403         T = T / count3;
8404         V2 = N21 + (T % count2) * STEP2;
8405         T = T / count2;
8406         V1 = N11 + T * STEP1;
8407         iend = iend0;
8408     L1:
8409         BODY;
8410         V += 1;
8411         if (V < iend) goto L10; else goto L2;
8412     L10:
8413         V3 += STEP3;
8414         if (V3 cond3 N32) goto L1; else goto L11;
8415     L11:
8416         V3 = N31;
8417         V2 += STEP2;
8418         if (V2 cond2 N22) goto L1; else goto L12;
8419     L12:
8420         V2 = N21;
8421         V1 += STEP1;
8422         goto L1;
8423     L2:
8424         if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
8425     L3:
8426
8427       */
8428
8429 static void
8430 expand_omp_for_generic (struct omp_region *region,
8431                         struct omp_for_data *fd,
8432                         enum built_in_function start_fn,
8433                         enum built_in_function next_fn,
8434                         gimple *inner_stmt)
8435 {
8436   tree type, istart0, iend0, iend;
8437   tree t, vmain, vback, bias = NULL_TREE;
8438   basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, collapse_bb;
8439   basic_block l2_bb = NULL, l3_bb = NULL;
8440   gimple_stmt_iterator gsi;
8441   gassign *assign_stmt;
8442   bool in_combined_parallel = is_combined_parallel (region);
8443   bool broken_loop = region->cont == NULL;
8444   edge e, ne;
8445   tree *counts = NULL;
8446   int i;
8447   bool ordered_lastprivate = false;
8448
8449   gcc_assert (!broken_loop || !in_combined_parallel);
8450   gcc_assert (fd->iter_type == long_integer_type_node
8451               || !in_combined_parallel);
8452
8453   entry_bb = region->entry;
8454   cont_bb = region->cont;
8455   collapse_bb = NULL;
8456   gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
8457   gcc_assert (broken_loop
8458               || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
8459   l0_bb = split_edge (FALLTHRU_EDGE (entry_bb));
8460   l1_bb = single_succ (l0_bb);
8461   if (!broken_loop)
8462     {
8463       l2_bb = create_empty_bb (cont_bb);
8464       gcc_assert (BRANCH_EDGE (cont_bb)->dest == l1_bb
8465                   || (single_succ_edge (BRANCH_EDGE (cont_bb)->dest)->dest
8466                       == l1_bb));
8467       gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
8468     }
8469   else
8470     l2_bb = NULL;
8471   l3_bb = BRANCH_EDGE (entry_bb)->dest;
8472   exit_bb = region->exit;
8473
8474   gsi = gsi_last_bb (entry_bb);
8475
8476   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
8477   if (fd->ordered
8478       && find_omp_clause (gimple_omp_for_clauses (gsi_stmt (gsi)),
8479                           OMP_CLAUSE_LASTPRIVATE))
8480     ordered_lastprivate = false;
8481   if (fd->collapse > 1 || fd->ordered)
8482     {
8483       int first_zero_iter1 = -1, first_zero_iter2 = -1;
8484       basic_block zero_iter1_bb = NULL, zero_iter2_bb = NULL, l2_dom_bb = NULL;
8485
8486       counts = XALLOCAVEC (tree, fd->ordered ? fd->ordered + 1 : fd->collapse);
8487       expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
8488                                   zero_iter1_bb, first_zero_iter1,
8489                                   zero_iter2_bb, first_zero_iter2, l2_dom_bb);
8490
8491       if (zero_iter1_bb)
8492         {
8493           /* Some counts[i] vars might be uninitialized if
8494              some loop has zero iterations.  But the body shouldn't
8495              be executed in that case, so just avoid uninit warnings.  */
8496           for (i = first_zero_iter1;
8497                i < (fd->ordered ? fd->ordered : fd->collapse); i++)
8498             if (SSA_VAR_P (counts[i]))
8499               TREE_NO_WARNING (counts[i]) = 1;
8500           gsi_prev (&gsi);
8501           e = split_block (entry_bb, gsi_stmt (gsi));
8502           entry_bb = e->dest;
8503           make_edge (zero_iter1_bb, entry_bb, EDGE_FALLTHRU);
8504           gsi = gsi_last_bb (entry_bb);
8505           set_immediate_dominator (CDI_DOMINATORS, entry_bb,
8506                                    get_immediate_dominator (CDI_DOMINATORS,
8507                                                             zero_iter1_bb));
8508         }
8509       if (zero_iter2_bb)
8510         {
8511           /* Some counts[i] vars might be uninitialized if
8512              some loop has zero iterations.  But the body shouldn't
8513              be executed in that case, so just avoid uninit warnings.  */
8514           for (i = first_zero_iter2; i < fd->ordered; i++)
8515             if (SSA_VAR_P (counts[i]))
8516               TREE_NO_WARNING (counts[i]) = 1;
8517           if (zero_iter1_bb)
8518             make_edge (zero_iter2_bb, entry_bb, EDGE_FALLTHRU);
8519           else
8520             {
8521               gsi_prev (&gsi);
8522               e = split_block (entry_bb, gsi_stmt (gsi));
8523               entry_bb = e->dest;
8524               make_edge (zero_iter2_bb, entry_bb, EDGE_FALLTHRU);
8525               gsi = gsi_last_bb (entry_bb);
8526               set_immediate_dominator (CDI_DOMINATORS, entry_bb,
8527                                        get_immediate_dominator
8528                                          (CDI_DOMINATORS, zero_iter2_bb));
8529             }
8530         }
8531       if (fd->collapse == 1)
8532         {
8533           counts[0] = fd->loop.n2;
8534           fd->loop = fd->loops[0];
8535         }
8536     }
8537
8538   type = TREE_TYPE (fd->loop.v);
8539   istart0 = create_tmp_var (fd->iter_type, ".istart0");
8540   iend0 = create_tmp_var (fd->iter_type, ".iend0");
8541   TREE_ADDRESSABLE (istart0) = 1;
8542   TREE_ADDRESSABLE (iend0) = 1;
8543
8544   /* See if we need to bias by LLONG_MIN.  */
8545   if (fd->iter_type == long_long_unsigned_type_node
8546       && TREE_CODE (type) == INTEGER_TYPE
8547       && !TYPE_UNSIGNED (type)
8548       && fd->ordered == 0)
8549     {
8550       tree n1, n2;
8551
8552       if (fd->loop.cond_code == LT_EXPR)
8553         {
8554           n1 = fd->loop.n1;
8555           n2 = fold_build2 (PLUS_EXPR, type, fd->loop.n2, fd->loop.step);
8556         }
8557       else
8558         {
8559           n1 = fold_build2 (MINUS_EXPR, type, fd->loop.n2, fd->loop.step);
8560           n2 = fd->loop.n1;
8561         }
8562       if (TREE_CODE (n1) != INTEGER_CST
8563           || TREE_CODE (n2) != INTEGER_CST
8564           || ((tree_int_cst_sgn (n1) < 0) ^ (tree_int_cst_sgn (n2) < 0)))
8565         bias = fold_convert (fd->iter_type, TYPE_MIN_VALUE (type));
8566     }
8567
8568   gimple_stmt_iterator gsif = gsi;
8569   gsi_prev (&gsif);
8570
8571   tree arr = NULL_TREE;
8572   if (in_combined_parallel)
8573     {
8574       gcc_assert (fd->ordered == 0);
8575       /* In a combined parallel loop, emit a call to
8576          GOMP_loop_foo_next.  */
8577       t = build_call_expr (builtin_decl_explicit (next_fn), 2,
8578                            build_fold_addr_expr (istart0),
8579                            build_fold_addr_expr (iend0));
8580     }
8581   else
8582     {
8583       tree t0, t1, t2, t3, t4;
8584       /* If this is not a combined parallel loop, emit a call to
8585          GOMP_loop_foo_start in ENTRY_BB.  */
8586       t4 = build_fold_addr_expr (iend0);
8587       t3 = build_fold_addr_expr (istart0);
8588       if (fd->ordered)
8589         {
8590           t0 = build_int_cst (unsigned_type_node,
8591                               fd->ordered - fd->collapse + 1);
8592           arr = create_tmp_var (build_array_type_nelts (fd->iter_type,
8593                                                         fd->ordered
8594                                                         - fd->collapse + 1),
8595                                 ".omp_counts");
8596           DECL_NAMELESS (arr) = 1;
8597           TREE_ADDRESSABLE (arr) = 1;
8598           TREE_STATIC (arr) = 1;
8599           vec<constructor_elt, va_gc> *v;
8600           vec_alloc (v, fd->ordered - fd->collapse + 1);
8601           int idx;
8602
8603           for (idx = 0; idx < fd->ordered - fd->collapse + 1; idx++)
8604             {
8605               tree c;
8606               if (idx == 0 && fd->collapse > 1)
8607                 c = fd->loop.n2;
8608               else
8609                 c = counts[idx + fd->collapse - 1];
8610               tree purpose = size_int (idx);
8611               CONSTRUCTOR_APPEND_ELT (v, purpose, c);
8612               if (TREE_CODE (c) != INTEGER_CST)
8613                 TREE_STATIC (arr) = 0;
8614             }
8615
8616           DECL_INITIAL (arr) = build_constructor (TREE_TYPE (arr), v);
8617           if (!TREE_STATIC (arr))
8618             force_gimple_operand_gsi (&gsi, build1 (DECL_EXPR,
8619                                                     void_type_node, arr),
8620                                       true, NULL_TREE, true, GSI_SAME_STMT);
8621           t1 = build_fold_addr_expr (arr);
8622           t2 = NULL_TREE;
8623         }
8624       else
8625         {
8626           t2 = fold_convert (fd->iter_type, fd->loop.step);
8627           t1 = fd->loop.n2;
8628           t0 = fd->loop.n1;
8629           if (gimple_omp_for_combined_into_p (fd->for_stmt))
8630             {
8631               tree innerc
8632                 = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
8633                                    OMP_CLAUSE__LOOPTEMP_);
8634               gcc_assert (innerc);
8635               t0 = OMP_CLAUSE_DECL (innerc);
8636               innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
8637                                         OMP_CLAUSE__LOOPTEMP_);
8638               gcc_assert (innerc);
8639               t1 = OMP_CLAUSE_DECL (innerc);
8640             }
8641           if (POINTER_TYPE_P (TREE_TYPE (t0))
8642               && TYPE_PRECISION (TREE_TYPE (t0))
8643                  != TYPE_PRECISION (fd->iter_type))
8644             {
8645               /* Avoid casting pointers to integer of a different size.  */
8646               tree itype = signed_type_for (type);
8647               t1 = fold_convert (fd->iter_type, fold_convert (itype, t1));
8648               t0 = fold_convert (fd->iter_type, fold_convert (itype, t0));
8649             }
8650           else
8651             {
8652               t1 = fold_convert (fd->iter_type, t1);
8653               t0 = fold_convert (fd->iter_type, t0);
8654             }
8655           if (bias)
8656             {
8657               t1 = fold_build2 (PLUS_EXPR, fd->iter_type, t1, bias);
8658               t0 = fold_build2 (PLUS_EXPR, fd->iter_type, t0, bias);
8659             }
8660         }
8661       if (fd->iter_type == long_integer_type_node || fd->ordered)
8662         {
8663           if (fd->chunk_size)
8664             {
8665               t = fold_convert (fd->iter_type, fd->chunk_size);
8666               t = omp_adjust_chunk_size (t, fd->simd_schedule);
8667               if (fd->ordered)
8668                 t = build_call_expr (builtin_decl_explicit (start_fn),
8669                                      5, t0, t1, t, t3, t4);
8670               else
8671                 t = build_call_expr (builtin_decl_explicit (start_fn),
8672                                      6, t0, t1, t2, t, t3, t4);
8673             }
8674           else if (fd->ordered)
8675             t = build_call_expr (builtin_decl_explicit (start_fn),
8676                                  4, t0, t1, t3, t4);
8677           else
8678             t = build_call_expr (builtin_decl_explicit (start_fn),
8679                                  5, t0, t1, t2, t3, t4);
8680         }
8681       else
8682         {
8683           tree t5;
8684           tree c_bool_type;
8685           tree bfn_decl;
8686
8687           /* The GOMP_loop_ull_*start functions have additional boolean
8688              argument, true for < loops and false for > loops.
8689              In Fortran, the C bool type can be different from
8690              boolean_type_node.  */
8691           bfn_decl = builtin_decl_explicit (start_fn);
8692           c_bool_type = TREE_TYPE (TREE_TYPE (bfn_decl));
8693           t5 = build_int_cst (c_bool_type,
8694                               fd->loop.cond_code == LT_EXPR ? 1 : 0);
8695           if (fd->chunk_size)
8696             {
8697               tree bfn_decl = builtin_decl_explicit (start_fn);
8698               t = fold_convert (fd->iter_type, fd->chunk_size);
8699               t = omp_adjust_chunk_size (t, fd->simd_schedule);
8700               t = build_call_expr (bfn_decl, 7, t5, t0, t1, t2, t, t3, t4);
8701             }
8702           else
8703             t = build_call_expr (builtin_decl_explicit (start_fn),
8704                                  6, t5, t0, t1, t2, t3, t4);
8705         }
8706     }
8707   if (TREE_TYPE (t) != boolean_type_node)
8708     t = fold_build2 (NE_EXPR, boolean_type_node,
8709                      t, build_int_cst (TREE_TYPE (t), 0));
8710   t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
8711                                 true, GSI_SAME_STMT);
8712   if (arr && !TREE_STATIC (arr))
8713     {
8714       tree clobber = build_constructor (TREE_TYPE (arr), NULL);
8715       TREE_THIS_VOLATILE (clobber) = 1;
8716       gsi_insert_before (&gsi, gimple_build_assign (arr, clobber),
8717                          GSI_SAME_STMT);
8718     }
8719   gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
8720
8721   /* Remove the GIMPLE_OMP_FOR statement.  */
8722   gsi_remove (&gsi, true);
8723
8724   if (gsi_end_p (gsif))
8725     gsif = gsi_after_labels (gsi_bb (gsif));
8726   gsi_next (&gsif);
8727
8728   /* Iteration setup for sequential loop goes in L0_BB.  */
8729   tree startvar = fd->loop.v;
8730   tree endvar = NULL_TREE;
8731
8732   if (gimple_omp_for_combined_p (fd->for_stmt))
8733     {
8734       gcc_assert (gimple_code (inner_stmt) == GIMPLE_OMP_FOR
8735                   && gimple_omp_for_kind (inner_stmt)
8736                      == GF_OMP_FOR_KIND_SIMD);
8737       tree innerc = find_omp_clause (gimple_omp_for_clauses (inner_stmt),
8738                                      OMP_CLAUSE__LOOPTEMP_);
8739       gcc_assert (innerc);
8740       startvar = OMP_CLAUSE_DECL (innerc);
8741       innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
8742                                 OMP_CLAUSE__LOOPTEMP_);
8743       gcc_assert (innerc);
8744       endvar = OMP_CLAUSE_DECL (innerc);
8745     }
8746
8747   gsi = gsi_start_bb (l0_bb);
8748   t = istart0;
8749   if (fd->ordered && fd->collapse == 1)
8750     t = fold_build2 (MULT_EXPR, fd->iter_type, t,
8751                      fold_convert (fd->iter_type, fd->loop.step));
8752   else if (bias)
8753     t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
8754   if (fd->ordered && fd->collapse == 1)
8755     {
8756       if (POINTER_TYPE_P (TREE_TYPE (startvar)))
8757         t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (startvar),
8758                          fd->loop.n1, fold_convert (sizetype, t));
8759       else
8760         {
8761           t = fold_convert (TREE_TYPE (startvar), t);
8762           t = fold_build2 (PLUS_EXPR, TREE_TYPE (startvar),
8763                            fd->loop.n1, t);
8764         }
8765     }
8766   else
8767     {
8768       if (POINTER_TYPE_P (TREE_TYPE (startvar)))
8769         t = fold_convert (signed_type_for (TREE_TYPE (startvar)), t);
8770       t = fold_convert (TREE_TYPE (startvar), t);
8771     }
8772   t = force_gimple_operand_gsi (&gsi, t,
8773                                 DECL_P (startvar)
8774                                 && TREE_ADDRESSABLE (startvar),
8775                                 NULL_TREE, false, GSI_CONTINUE_LINKING);
8776   assign_stmt = gimple_build_assign (startvar, t);
8777   gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
8778
8779   t = iend0;
8780   if (fd->ordered && fd->collapse == 1)
8781     t = fold_build2 (MULT_EXPR, fd->iter_type, t,
8782                      fold_convert (fd->iter_type, fd->loop.step));
8783   else if (bias)
8784     t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
8785   if (fd->ordered && fd->collapse == 1)
8786     {
8787       if (POINTER_TYPE_P (TREE_TYPE (startvar)))
8788         t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (startvar),
8789                          fd->loop.n1, fold_convert (sizetype, t));
8790       else
8791         {
8792           t = fold_convert (TREE_TYPE (startvar), t);
8793           t = fold_build2 (PLUS_EXPR, TREE_TYPE (startvar),
8794                            fd->loop.n1, t);
8795         }
8796     }
8797   else
8798     {
8799       if (POINTER_TYPE_P (TREE_TYPE (startvar)))
8800         t = fold_convert (signed_type_for (TREE_TYPE (startvar)), t);
8801       t = fold_convert (TREE_TYPE (startvar), t);
8802     }
8803   iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
8804                                    false, GSI_CONTINUE_LINKING);
8805   if (endvar)
8806     {
8807       assign_stmt = gimple_build_assign (endvar, iend);
8808       gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
8809       if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (iend)))
8810         assign_stmt = gimple_build_assign (fd->loop.v, iend);
8811       else
8812         assign_stmt = gimple_build_assign (fd->loop.v, NOP_EXPR, iend);
8813       gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
8814     }
8815   /* Handle linear clause adjustments.  */
8816   tree itercnt = NULL_TREE;
8817   if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_FOR)
8818     for (tree c = gimple_omp_for_clauses (fd->for_stmt);
8819          c; c = OMP_CLAUSE_CHAIN (c))
8820       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
8821           && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
8822         {
8823           tree d = OMP_CLAUSE_DECL (c);
8824           bool is_ref = is_reference (d);
8825           tree t = d, a, dest;
8826           if (is_ref)
8827             t = build_simple_mem_ref_loc (OMP_CLAUSE_LOCATION (c), t);
8828           tree type = TREE_TYPE (t);
8829           if (POINTER_TYPE_P (type))
8830             type = sizetype;
8831           dest = unshare_expr (t);
8832           tree v = create_tmp_var (TREE_TYPE (t), NULL);
8833           expand_omp_build_assign (&gsif, v, t);
8834           if (itercnt == NULL_TREE)
8835             {
8836               itercnt = startvar;
8837               tree n1 = fd->loop.n1;
8838               if (POINTER_TYPE_P (TREE_TYPE (itercnt)))
8839                 {
8840                   itercnt
8841                     = fold_convert (signed_type_for (TREE_TYPE (itercnt)),
8842                                     itercnt);
8843                   n1 = fold_convert (TREE_TYPE (itercnt), n1);
8844                 }
8845               itercnt = fold_build2 (MINUS_EXPR, TREE_TYPE (itercnt),
8846                                      itercnt, n1);
8847               itercnt = fold_build2 (EXACT_DIV_EXPR, TREE_TYPE (itercnt),
8848                                      itercnt, fd->loop.step);
8849               itercnt = force_gimple_operand_gsi (&gsi, itercnt, true,
8850                                                   NULL_TREE, false,
8851                                                   GSI_CONTINUE_LINKING);
8852             }
8853           a = fold_build2 (MULT_EXPR, type,
8854                            fold_convert (type, itercnt),
8855                            fold_convert (type, OMP_CLAUSE_LINEAR_STEP (c)));
8856           t = fold_build2 (type == TREE_TYPE (t) ? PLUS_EXPR
8857                            : POINTER_PLUS_EXPR, TREE_TYPE (t), v, a);
8858           t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
8859                                         false, GSI_CONTINUE_LINKING);
8860           assign_stmt = gimple_build_assign (dest, t);
8861           gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
8862         }
8863   if (fd->collapse > 1)
8864     expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
8865
8866   if (fd->ordered)
8867     {
8868       /* Until now, counts array contained number of iterations or
8869          variable containing it for ith loop.  From now on, we need
8870          those counts only for collapsed loops, and only for the 2nd
8871          till the last collapsed one.  Move those one element earlier,
8872          we'll use counts[fd->collapse - 1] for the first source/sink
8873          iteration counter and so on and counts[fd->ordered]
8874          as the array holding the current counter values for
8875          depend(source).  */
8876       if (fd->collapse > 1)
8877         memmove (counts, counts + 1, (fd->collapse - 1) * sizeof (counts[0]));
8878       if (broken_loop)
8879         {
8880           int i;
8881           for (i = fd->collapse; i < fd->ordered; i++)
8882             {
8883               tree type = TREE_TYPE (fd->loops[i].v);
8884               tree this_cond
8885                 = fold_build2 (fd->loops[i].cond_code, boolean_type_node,
8886                                fold_convert (type, fd->loops[i].n1),
8887                                fold_convert (type, fd->loops[i].n2));
8888               if (!integer_onep (this_cond))
8889                 break;
8890             }
8891           if (i < fd->ordered)
8892             {
8893               cont_bb
8894                 = create_empty_bb (EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb);
8895               add_bb_to_loop (cont_bb, l1_bb->loop_father);
8896               gimple_stmt_iterator gsi = gsi_after_labels (cont_bb);
8897               gimple *g = gimple_build_omp_continue (fd->loop.v, fd->loop.v);
8898               gsi_insert_before (&gsi, g, GSI_SAME_STMT);
8899               make_edge (cont_bb, l3_bb, EDGE_FALLTHRU);
8900               make_edge (cont_bb, l1_bb, 0);
8901               l2_bb = create_empty_bb (cont_bb);
8902               broken_loop = false;
8903             }
8904         }
8905       expand_omp_ordered_source_sink (region, fd, counts, cont_bb);
8906       cont_bb = expand_omp_for_ordered_loops (fd, counts, cont_bb, l1_bb,
8907                                               ordered_lastprivate);
8908       if (counts[fd->collapse - 1])
8909         {
8910           gcc_assert (fd->collapse == 1);
8911           gsi = gsi_last_bb (l0_bb);
8912           expand_omp_build_assign (&gsi, counts[fd->collapse - 1],
8913                                    istart0, true);
8914           gsi = gsi_last_bb (cont_bb);
8915           t = fold_build2 (PLUS_EXPR, fd->iter_type, counts[fd->collapse - 1],
8916                            build_int_cst (fd->iter_type, 1));
8917           expand_omp_build_assign (&gsi, counts[fd->collapse - 1], t);
8918           tree aref = build4 (ARRAY_REF, fd->iter_type, counts[fd->ordered],
8919                               size_zero_node, NULL_TREE, NULL_TREE);
8920           expand_omp_build_assign (&gsi, aref, counts[fd->collapse - 1]);
8921           t = counts[fd->collapse - 1];
8922         }
8923       else if (fd->collapse > 1)
8924         t = fd->loop.v;
8925       else
8926         {
8927           t = fold_build2 (MINUS_EXPR, TREE_TYPE (fd->loops[0].v),
8928                            fd->loops[0].v, fd->loops[0].n1);
8929           t = fold_convert (fd->iter_type, t);
8930         }
8931       gsi = gsi_last_bb (l0_bb);
8932       tree aref = build4 (ARRAY_REF, fd->iter_type, counts[fd->ordered],
8933                           size_zero_node, NULL_TREE, NULL_TREE);
8934       t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
8935                                     false, GSI_CONTINUE_LINKING);
8936       expand_omp_build_assign (&gsi, aref, t, true);
8937     }
8938
8939   if (!broken_loop)
8940     {
8941       /* Code to control the increment and predicate for the sequential
8942          loop goes in the CONT_BB.  */
8943       gsi = gsi_last_bb (cont_bb);
8944       gomp_continue *cont_stmt = as_a <gomp_continue *> (gsi_stmt (gsi));
8945       gcc_assert (gimple_code (cont_stmt) == GIMPLE_OMP_CONTINUE);
8946       vmain = gimple_omp_continue_control_use (cont_stmt);
8947       vback = gimple_omp_continue_control_def (cont_stmt);
8948
8949       if (!gimple_omp_for_combined_p (fd->for_stmt))
8950         {
8951           if (POINTER_TYPE_P (type))
8952             t = fold_build_pointer_plus (vmain, fd->loop.step);
8953           else
8954             t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
8955           t = force_gimple_operand_gsi (&gsi, t,
8956                                         DECL_P (vback)
8957                                         && TREE_ADDRESSABLE (vback),
8958                                         NULL_TREE, true, GSI_SAME_STMT);
8959           assign_stmt = gimple_build_assign (vback, t);
8960           gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
8961
8962           if (fd->ordered && counts[fd->collapse - 1] == NULL_TREE)
8963             {
8964               if (fd->collapse > 1)
8965                 t = fd->loop.v;
8966               else
8967                 {
8968                   t = fold_build2 (MINUS_EXPR, TREE_TYPE (fd->loops[0].v),
8969                                    fd->loops[0].v, fd->loops[0].n1);
8970                   t = fold_convert (fd->iter_type, t);
8971                 }
8972               tree aref = build4 (ARRAY_REF, fd->iter_type,
8973                                   counts[fd->ordered], size_zero_node,
8974                                   NULL_TREE, NULL_TREE);
8975               t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
8976                                             true, GSI_SAME_STMT);
8977               expand_omp_build_assign (&gsi, aref, t);
8978             }
8979
8980           t = build2 (fd->loop.cond_code, boolean_type_node,
8981                       DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback,
8982                       iend);
8983           gcond *cond_stmt = gimple_build_cond_empty (t);
8984           gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
8985         }
8986
8987       /* Remove GIMPLE_OMP_CONTINUE.  */
8988       gsi_remove (&gsi, true);
8989
8990       if (fd->collapse > 1 && !gimple_omp_for_combined_p (fd->for_stmt))
8991         collapse_bb = extract_omp_for_update_vars (fd, cont_bb, l1_bb);
8992
8993       /* Emit code to get the next parallel iteration in L2_BB.  */
8994       gsi = gsi_start_bb (l2_bb);
8995
8996       t = build_call_expr (builtin_decl_explicit (next_fn), 2,
8997                            build_fold_addr_expr (istart0),
8998                            build_fold_addr_expr (iend0));
8999       t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
9000                                     false, GSI_CONTINUE_LINKING);
9001       if (TREE_TYPE (t) != boolean_type_node)
9002         t = fold_build2 (NE_EXPR, boolean_type_node,
9003                          t, build_int_cst (TREE_TYPE (t), 0));
9004       gcond *cond_stmt = gimple_build_cond_empty (t);
9005       gsi_insert_after (&gsi, cond_stmt, GSI_CONTINUE_LINKING);
9006     }
9007
9008   /* Add the loop cleanup function.  */
9009   gsi = gsi_last_bb (exit_bb);
9010   if (gimple_omp_return_nowait_p (gsi_stmt (gsi)))
9011     t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_NOWAIT);
9012   else if (gimple_omp_return_lhs (gsi_stmt (gsi)))
9013     t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_CANCEL);
9014   else
9015     t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END);
9016   gcall *call_stmt = gimple_build_call (t, 0);
9017   if (gimple_omp_return_lhs (gsi_stmt (gsi)))
9018     gimple_call_set_lhs (call_stmt, gimple_omp_return_lhs (gsi_stmt (gsi)));
9019   gsi_insert_after (&gsi, call_stmt, GSI_SAME_STMT);
9020   if (fd->ordered)
9021     {
9022       tree arr = counts[fd->ordered];
9023       tree clobber = build_constructor (TREE_TYPE (arr), NULL);
9024       TREE_THIS_VOLATILE (clobber) = 1;
9025       gsi_insert_after (&gsi, gimple_build_assign (arr, clobber),
9026                         GSI_SAME_STMT);
9027     }
9028   gsi_remove (&gsi, true);
9029
9030   /* Connect the new blocks.  */
9031   find_edge (entry_bb, l0_bb)->flags = EDGE_TRUE_VALUE;
9032   find_edge (entry_bb, l3_bb)->flags = EDGE_FALSE_VALUE;
9033
9034   if (!broken_loop)
9035     {
9036       gimple_seq phis;
9037
9038       e = find_edge (cont_bb, l3_bb);
9039       ne = make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
9040
9041       phis = phi_nodes (l3_bb);
9042       for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
9043         {
9044           gimple *phi = gsi_stmt (gsi);
9045           SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, ne),
9046                    PHI_ARG_DEF_FROM_EDGE (phi, e));
9047         }
9048       remove_edge (e);
9049
9050       make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
9051       e = find_edge (cont_bb, l1_bb);
9052       if (e == NULL)
9053         {
9054           e = BRANCH_EDGE (cont_bb);
9055           gcc_assert (single_succ (e->dest) == l1_bb);
9056         }
9057       if (gimple_omp_for_combined_p (fd->for_stmt))
9058         {
9059           remove_edge (e);
9060           e = NULL;
9061         }
9062       else if (fd->collapse > 1)
9063         {
9064           remove_edge (e);
9065           e = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
9066         }
9067       else
9068         e->flags = EDGE_TRUE_VALUE;
9069       if (e)
9070         {
9071           e->probability = REG_BR_PROB_BASE * 7 / 8;
9072           find_edge (cont_bb, l2_bb)->probability = REG_BR_PROB_BASE / 8;
9073         }
9074       else
9075         {
9076           e = find_edge (cont_bb, l2_bb);
9077           e->flags = EDGE_FALLTHRU;
9078         }
9079       make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
9080
9081       if (gimple_in_ssa_p (cfun))
9082         {
9083           /* Add phis to the outer loop that connect to the phis in the inner,
9084              original loop, and move the loop entry value of the inner phi to
9085              the loop entry value of the outer phi.  */
9086           gphi_iterator psi;
9087           for (psi = gsi_start_phis (l3_bb); !gsi_end_p (psi); gsi_next (&psi))
9088             {
9089               source_location locus;
9090               gphi *nphi;
9091               gphi *exit_phi = psi.phi ();
9092
9093               edge l2_to_l3 = find_edge (l2_bb, l3_bb);
9094               tree exit_res = PHI_ARG_DEF_FROM_EDGE (exit_phi, l2_to_l3);
9095
9096               basic_block latch = BRANCH_EDGE (cont_bb)->dest;
9097               edge latch_to_l1 = find_edge (latch, l1_bb);
9098               gphi *inner_phi
9099                 = find_phi_with_arg_on_edge (exit_res, latch_to_l1);
9100
9101               tree t = gimple_phi_result (exit_phi);
9102               tree new_res = copy_ssa_name (t, NULL);
9103               nphi = create_phi_node (new_res, l0_bb);
9104
9105               edge l0_to_l1 = find_edge (l0_bb, l1_bb);
9106               t = PHI_ARG_DEF_FROM_EDGE (inner_phi, l0_to_l1);
9107               locus = gimple_phi_arg_location_from_edge (inner_phi, l0_to_l1);
9108               edge entry_to_l0 = find_edge (entry_bb, l0_bb);
9109               add_phi_arg (nphi, t, entry_to_l0, locus);
9110
9111               edge l2_to_l0 = find_edge (l2_bb, l0_bb);
9112               add_phi_arg (nphi, exit_res, l2_to_l0, UNKNOWN_LOCATION);
9113
9114               add_phi_arg (inner_phi, new_res, l0_to_l1, UNKNOWN_LOCATION);
9115             };
9116         }
9117
9118       set_immediate_dominator (CDI_DOMINATORS, l2_bb,
9119                                recompute_dominator (CDI_DOMINATORS, l2_bb));
9120       set_immediate_dominator (CDI_DOMINATORS, l3_bb,
9121                                recompute_dominator (CDI_DOMINATORS, l3_bb));
9122       set_immediate_dominator (CDI_DOMINATORS, l0_bb,
9123                                recompute_dominator (CDI_DOMINATORS, l0_bb));
9124       set_immediate_dominator (CDI_DOMINATORS, l1_bb,
9125                                recompute_dominator (CDI_DOMINATORS, l1_bb));
9126
9127       /* We enter expand_omp_for_generic with a loop.  This original loop may
9128          have its own loop struct, or it may be part of an outer loop struct
9129          (which may be the fake loop).  */
9130       struct loop *outer_loop = entry_bb->loop_father;
9131       bool orig_loop_has_loop_struct = l1_bb->loop_father != outer_loop;
9132
9133       add_bb_to_loop (l2_bb, outer_loop);
9134
9135       /* We've added a new loop around the original loop.  Allocate the
9136          corresponding loop struct.  */
9137       struct loop *new_loop = alloc_loop ();
9138       new_loop->header = l0_bb;
9139       new_loop->latch = l2_bb;
9140       add_loop (new_loop, outer_loop);
9141
9142       /* Allocate a loop structure for the original loop unless we already
9143          had one.  */
9144       if (!orig_loop_has_loop_struct
9145           && !gimple_omp_for_combined_p (fd->for_stmt))
9146         {
9147           struct loop *orig_loop = alloc_loop ();
9148           orig_loop->header = l1_bb;
9149           /* The loop may have multiple latches.  */
9150           add_loop (orig_loop, new_loop);
9151         }
9152     }
9153 }
9154
9155
9156 /* A subroutine of expand_omp_for.  Generate code for a parallel
9157    loop with static schedule and no specified chunk size.  Given
9158    parameters:
9159
9160         for (V = N1; V cond N2; V += STEP) BODY;
9161
9162    where COND is "<" or ">", we generate pseudocode
9163
9164         if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
9165         if (cond is <)
9166           adj = STEP - 1;
9167         else
9168           adj = STEP + 1;
9169         if ((__typeof (V)) -1 > 0 && cond is >)
9170           n = -(adj + N2 - N1) / -STEP;
9171         else
9172           n = (adj + N2 - N1) / STEP;
9173         q = n / nthreads;
9174         tt = n % nthreads;
9175         if (threadid < tt) goto L3; else goto L4;
9176     L3:
9177         tt = 0;
9178         q = q + 1;
9179     L4:
9180         s0 = q * threadid + tt;
9181         e0 = s0 + q;
9182         V = s0 * STEP + N1;
9183         if (s0 >= e0) goto L2; else goto L0;
9184     L0:
9185         e = e0 * STEP + N1;
9186     L1:
9187         BODY;
9188         V += STEP;
9189         if (V cond e) goto L1;
9190     L2:
9191 */
9192
9193 static void
9194 expand_omp_for_static_nochunk (struct omp_region *region,
9195                                struct omp_for_data *fd,
9196                                gimple *inner_stmt)
9197 {
9198   tree n, q, s0, e0, e, t, tt, nthreads, threadid;
9199   tree type, itype, vmain, vback;
9200   basic_block entry_bb, second_bb, third_bb, exit_bb, seq_start_bb;
9201   basic_block body_bb, cont_bb, collapse_bb = NULL;
9202   basic_block fin_bb;
9203   gimple_stmt_iterator gsi;
9204   edge ep;
9205   bool broken_loop = region->cont == NULL;
9206   tree *counts = NULL;
9207   tree n1, n2, step;
9208
9209   itype = type = TREE_TYPE (fd->loop.v);
9210   if (POINTER_TYPE_P (type))
9211     itype = signed_type_for (type);
9212
9213   entry_bb = region->entry;
9214   cont_bb = region->cont;
9215   gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
9216   fin_bb = BRANCH_EDGE (entry_bb)->dest;
9217   gcc_assert (broken_loop
9218               || (fin_bb == FALLTHRU_EDGE (cont_bb)->dest));
9219   seq_start_bb = split_edge (FALLTHRU_EDGE (entry_bb));
9220   body_bb = single_succ (seq_start_bb);
9221   if (!broken_loop)
9222     {
9223       gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb
9224                   || single_succ (BRANCH_EDGE (cont_bb)->dest) == body_bb);
9225       gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
9226     }
9227   exit_bb = region->exit;
9228
9229   /* Iteration space partitioning goes in ENTRY_BB.  */
9230   gsi = gsi_last_bb (entry_bb);
9231   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
9232
9233   if (fd->collapse > 1)
9234     {
9235       int first_zero_iter = -1, dummy = -1;
9236       basic_block l2_dom_bb = NULL, dummy_bb = NULL;
9237
9238       counts = XALLOCAVEC (tree, fd->collapse);
9239       expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
9240                                   fin_bb, first_zero_iter,
9241                                   dummy_bb, dummy, l2_dom_bb);
9242       t = NULL_TREE;
9243     }
9244   else if (gimple_omp_for_combined_into_p (fd->for_stmt))
9245     t = integer_one_node;
9246   else
9247     t = fold_binary (fd->loop.cond_code, boolean_type_node,
9248                      fold_convert (type, fd->loop.n1),
9249                      fold_convert (type, fd->loop.n2));
9250   if (fd->collapse == 1
9251       && TYPE_UNSIGNED (type)
9252       && (t == NULL_TREE || !integer_onep (t)))
9253     {
9254       n1 = fold_convert (type, unshare_expr (fd->loop.n1));
9255       n1 = force_gimple_operand_gsi (&gsi, n1, true, NULL_TREE,
9256                                      true, GSI_SAME_STMT);
9257       n2 = fold_convert (type, unshare_expr (fd->loop.n2));
9258       n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE,
9259                                      true, GSI_SAME_STMT);
9260       gcond *cond_stmt = gimple_build_cond (fd->loop.cond_code, n1, n2,
9261                                                  NULL_TREE, NULL_TREE);
9262       gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
9263       if (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
9264                      expand_omp_regimplify_p, NULL, NULL)
9265           || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
9266                         expand_omp_regimplify_p, NULL, NULL))
9267         {
9268           gsi = gsi_for_stmt (cond_stmt);
9269           gimple_regimplify_operands (cond_stmt, &gsi);
9270         }
9271       ep = split_block (entry_bb, cond_stmt);
9272       ep->flags = EDGE_TRUE_VALUE;
9273       entry_bb = ep->dest;
9274       ep->probability = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1);
9275       ep = make_edge (ep->src, fin_bb, EDGE_FALSE_VALUE);
9276       ep->probability = REG_BR_PROB_BASE / 2000 - 1;
9277       if (gimple_in_ssa_p (cfun))
9278         {
9279           int dest_idx = find_edge (entry_bb, fin_bb)->dest_idx;
9280           for (gphi_iterator gpi = gsi_start_phis (fin_bb);
9281                !gsi_end_p (gpi); gsi_next (&gpi))
9282             {
9283               gphi *phi = gpi.phi ();
9284               add_phi_arg (phi, gimple_phi_arg_def (phi, dest_idx),
9285                            ep, UNKNOWN_LOCATION);
9286             }
9287         }
9288       gsi = gsi_last_bb (entry_bb);
9289     }
9290
9291   switch (gimple_omp_for_kind (fd->for_stmt))
9292     {
9293     case GF_OMP_FOR_KIND_FOR:
9294       nthreads = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
9295       threadid = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
9296       break;
9297     case GF_OMP_FOR_KIND_DISTRIBUTE:
9298       nthreads = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_TEAMS);
9299       threadid = builtin_decl_explicit (BUILT_IN_OMP_GET_TEAM_NUM);
9300       break;
9301     default:
9302       gcc_unreachable ();
9303     }
9304   nthreads = build_call_expr (nthreads, 0);
9305   nthreads = fold_convert (itype, nthreads);
9306   nthreads = force_gimple_operand_gsi (&gsi, nthreads, true, NULL_TREE,
9307                                        true, GSI_SAME_STMT);
9308   threadid = build_call_expr (threadid, 0);
9309   threadid = fold_convert (itype, threadid);
9310   threadid = force_gimple_operand_gsi (&gsi, threadid, true, NULL_TREE,
9311                                        true, GSI_SAME_STMT);
9312
9313   n1 = fd->loop.n1;
9314   n2 = fd->loop.n2;
9315   step = fd->loop.step;
9316   if (gimple_omp_for_combined_into_p (fd->for_stmt))
9317     {
9318       tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
9319                                      OMP_CLAUSE__LOOPTEMP_);
9320       gcc_assert (innerc);
9321       n1 = OMP_CLAUSE_DECL (innerc);
9322       innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
9323                                 OMP_CLAUSE__LOOPTEMP_);
9324       gcc_assert (innerc);
9325       n2 = OMP_CLAUSE_DECL (innerc);
9326     }
9327   n1 = force_gimple_operand_gsi (&gsi, fold_convert (type, n1),
9328                                  true, NULL_TREE, true, GSI_SAME_STMT);
9329   n2 = force_gimple_operand_gsi (&gsi, fold_convert (itype, n2),
9330                                  true, NULL_TREE, true, GSI_SAME_STMT);
9331   step = force_gimple_operand_gsi (&gsi, fold_convert (itype, step),
9332                                    true, NULL_TREE, true, GSI_SAME_STMT);
9333
9334   t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
9335   t = fold_build2 (PLUS_EXPR, itype, step, t);
9336   t = fold_build2 (PLUS_EXPR, itype, t, n2);
9337   t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, n1));
9338   if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
9339     t = fold_build2 (TRUNC_DIV_EXPR, itype,
9340                      fold_build1 (NEGATE_EXPR, itype, t),
9341                      fold_build1 (NEGATE_EXPR, itype, step));
9342   else
9343     t = fold_build2 (TRUNC_DIV_EXPR, itype, t, step);
9344   t = fold_convert (itype, t);
9345   n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
9346
9347   q = create_tmp_reg (itype, "q");
9348   t = fold_build2 (TRUNC_DIV_EXPR, itype, n, nthreads);
9349   t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
9350   gsi_insert_before (&gsi, gimple_build_assign (q, t), GSI_SAME_STMT);
9351
9352   tt = create_tmp_reg (itype, "tt");
9353   t = fold_build2 (TRUNC_MOD_EXPR, itype, n, nthreads);
9354   t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
9355   gsi_insert_before (&gsi, gimple_build_assign (tt, t), GSI_SAME_STMT);
9356
9357   t = build2 (LT_EXPR, boolean_type_node, threadid, tt);
9358   gcond *cond_stmt = gimple_build_cond_empty (t);
9359   gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
9360
9361   second_bb = split_block (entry_bb, cond_stmt)->dest;
9362   gsi = gsi_last_bb (second_bb);
9363   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
9364
9365   gsi_insert_before (&gsi, gimple_build_assign (tt, build_int_cst (itype, 0)),
9366                      GSI_SAME_STMT);
9367   gassign *assign_stmt
9368     = gimple_build_assign (q, PLUS_EXPR, q, build_int_cst (itype, 1));
9369   gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
9370
9371   third_bb = split_block (second_bb, assign_stmt)->dest;
9372   gsi = gsi_last_bb (third_bb);
9373   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
9374
9375   t = build2 (MULT_EXPR, itype, q, threadid);
9376   t = build2 (PLUS_EXPR, itype, t, tt);
9377   s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
9378
9379   t = fold_build2 (PLUS_EXPR, itype, s0, q);
9380   e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
9381
9382   t = build2 (GE_EXPR, boolean_type_node, s0, e0);
9383   gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
9384
9385   /* Remove the GIMPLE_OMP_FOR statement.  */
9386   gsi_remove (&gsi, true);
9387
9388   /* Setup code for sequential iteration goes in SEQ_START_BB.  */
9389   gsi = gsi_start_bb (seq_start_bb);
9390
9391   tree startvar = fd->loop.v;
9392   tree endvar = NULL_TREE;
9393
9394   if (gimple_omp_for_combined_p (fd->for_stmt))
9395     {
9396       tree clauses = gimple_code (inner_stmt) == GIMPLE_OMP_PARALLEL
9397                      ? gimple_omp_parallel_clauses (inner_stmt)
9398                      : gimple_omp_for_clauses (inner_stmt);
9399       tree innerc = find_omp_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
9400       gcc_assert (innerc);
9401       startvar = OMP_CLAUSE_DECL (innerc);
9402       innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
9403                                 OMP_CLAUSE__LOOPTEMP_);
9404       gcc_assert (innerc);
9405       endvar = OMP_CLAUSE_DECL (innerc);
9406       if (fd->collapse > 1 && TREE_CODE (fd->loop.n2) != INTEGER_CST
9407           && gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_DISTRIBUTE)
9408         {
9409           int i;
9410           for (i = 1; i < fd->collapse; i++)
9411             {
9412               innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
9413                                         OMP_CLAUSE__LOOPTEMP_);
9414               gcc_assert (innerc);
9415             }
9416           innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
9417                                     OMP_CLAUSE__LOOPTEMP_);
9418           if (innerc)
9419             {
9420               /* If needed (distribute parallel for with lastprivate),
9421                  propagate down the total number of iterations.  */
9422               tree t = fold_convert (TREE_TYPE (OMP_CLAUSE_DECL (innerc)),
9423                                      fd->loop.n2);
9424               t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, false,
9425                                             GSI_CONTINUE_LINKING);
9426               assign_stmt = gimple_build_assign (OMP_CLAUSE_DECL (innerc), t);
9427               gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
9428             }
9429         }
9430     }
9431   t = fold_convert (itype, s0);
9432   t = fold_build2 (MULT_EXPR, itype, t, step);
9433   if (POINTER_TYPE_P (type))
9434     t = fold_build_pointer_plus (n1, t);
9435   else
9436     t = fold_build2 (PLUS_EXPR, type, t, n1);
9437   t = fold_convert (TREE_TYPE (startvar), t);
9438   t = force_gimple_operand_gsi (&gsi, t,
9439                                 DECL_P (startvar)
9440                                 && TREE_ADDRESSABLE (startvar),
9441                                 NULL_TREE, false, GSI_CONTINUE_LINKING);
9442   assign_stmt = gimple_build_assign (startvar, t);
9443   gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
9444
9445   t = fold_convert (itype, e0);
9446   t = fold_build2 (MULT_EXPR, itype, t, step);
9447   if (POINTER_TYPE_P (type))
9448     t = fold_build_pointer_plus (n1, t);
9449   else
9450     t = fold_build2 (PLUS_EXPR, type, t, n1);
9451   t = fold_convert (TREE_TYPE (startvar), t);
9452   e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
9453                                 false, GSI_CONTINUE_LINKING);
9454   if (endvar)
9455     {
9456       assign_stmt = gimple_build_assign (endvar, e);
9457       gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
9458       if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
9459         assign_stmt = gimple_build_assign (fd->loop.v, e);
9460       else
9461         assign_stmt = gimple_build_assign (fd->loop.v, NOP_EXPR, e);
9462       gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
9463     }
9464   /* Handle linear clause adjustments.  */
9465   tree itercnt = NULL_TREE;
9466   if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_FOR)
9467     for (tree c = gimple_omp_for_clauses (fd->for_stmt);
9468          c; c = OMP_CLAUSE_CHAIN (c))
9469       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9470           && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9471         {
9472           tree d = OMP_CLAUSE_DECL (c);
9473           bool is_ref = is_reference (d);
9474           tree t = d, a, dest;
9475           if (is_ref)
9476             t = build_simple_mem_ref_loc (OMP_CLAUSE_LOCATION (c), t);
9477           if (itercnt == NULL_TREE)
9478             {
9479               if (gimple_omp_for_combined_into_p (fd->for_stmt))
9480                 {
9481                   itercnt = fold_build2 (MINUS_EXPR, itype,
9482                                          fold_convert (itype, n1),
9483                                          fold_convert (itype, fd->loop.n1));
9484                   itercnt = fold_build2 (EXACT_DIV_EXPR, itype, itercnt, step);
9485                   itercnt = fold_build2 (PLUS_EXPR, itype, itercnt, s0);
9486                   itercnt = force_gimple_operand_gsi (&gsi, itercnt, true,
9487                                                       NULL_TREE, false,
9488                                                       GSI_CONTINUE_LINKING);
9489                 }
9490               else
9491                 itercnt = s0;
9492             }
9493           tree type = TREE_TYPE (t);
9494           if (POINTER_TYPE_P (type))
9495             type = sizetype;
9496           a = fold_build2 (MULT_EXPR, type,
9497                            fold_convert (type, itercnt),
9498                            fold_convert (type, OMP_CLAUSE_LINEAR_STEP (c)));
9499           dest = unshare_expr (t);
9500           t = fold_build2 (type == TREE_TYPE (t) ? PLUS_EXPR
9501                            : POINTER_PLUS_EXPR, TREE_TYPE (t), t, a);
9502           t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
9503                                         false, GSI_CONTINUE_LINKING);
9504           assign_stmt = gimple_build_assign (dest, t);
9505           gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
9506         }
9507   if (fd->collapse > 1)
9508     expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
9509
9510   if (!broken_loop)
9511     {
9512       /* The code controlling the sequential loop replaces the
9513          GIMPLE_OMP_CONTINUE.  */
9514       gsi = gsi_last_bb (cont_bb);
9515       gomp_continue *cont_stmt = as_a <gomp_continue *> (gsi_stmt (gsi));
9516       gcc_assert (gimple_code (cont_stmt) == GIMPLE_OMP_CONTINUE);
9517       vmain = gimple_omp_continue_control_use (cont_stmt);
9518       vback = gimple_omp_continue_control_def (cont_stmt);
9519
9520       if (!gimple_omp_for_combined_p (fd->for_stmt))
9521         {
9522           if (POINTER_TYPE_P (type))
9523             t = fold_build_pointer_plus (vmain, step);
9524           else
9525             t = fold_build2 (PLUS_EXPR, type, vmain, step);
9526           t = force_gimple_operand_gsi (&gsi, t,
9527                                         DECL_P (vback)
9528                                         && TREE_ADDRESSABLE (vback),
9529                                         NULL_TREE, true, GSI_SAME_STMT);
9530           assign_stmt = gimple_build_assign (vback, t);
9531           gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
9532
9533           t = build2 (fd->loop.cond_code, boolean_type_node,
9534                       DECL_P (vback) && TREE_ADDRESSABLE (vback)
9535                       ? t : vback, e);
9536           gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
9537         }
9538
9539       /* Remove the GIMPLE_OMP_CONTINUE statement.  */
9540       gsi_remove (&gsi, true);
9541
9542       if (fd->collapse > 1 && !gimple_omp_for_combined_p (fd->for_stmt))
9543         collapse_bb = extract_omp_for_update_vars (fd, cont_bb, body_bb);
9544     }
9545
9546   /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing.  */
9547   gsi = gsi_last_bb (exit_bb);
9548   if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
9549     {
9550       t = gimple_omp_return_lhs (gsi_stmt (gsi));
9551       gsi_insert_after (&gsi, build_omp_barrier (t), GSI_SAME_STMT);
9552     }
9553   gsi_remove (&gsi, true);
9554
9555   /* Connect all the blocks.  */
9556   ep = make_edge (entry_bb, third_bb, EDGE_FALSE_VALUE);
9557   ep->probability = REG_BR_PROB_BASE / 4 * 3;
9558   ep = find_edge (entry_bb, second_bb);
9559   ep->flags = EDGE_TRUE_VALUE;
9560   ep->probability = REG_BR_PROB_BASE / 4;
9561   find_edge (third_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
9562   find_edge (third_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
9563
9564   if (!broken_loop)
9565     {
9566       ep = find_edge (cont_bb, body_bb);
9567       if (ep == NULL)
9568         {
9569           ep = BRANCH_EDGE (cont_bb);
9570           gcc_assert (single_succ (ep->dest) == body_bb);
9571         }
9572       if (gimple_omp_for_combined_p (fd->for_stmt))
9573         {
9574           remove_edge (ep);
9575           ep = NULL;
9576         }
9577       else if (fd->collapse > 1)
9578         {
9579           remove_edge (ep);
9580           ep = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
9581         }
9582       else
9583         ep->flags = EDGE_TRUE_VALUE;
9584       find_edge (cont_bb, fin_bb)->flags
9585         = ep ? EDGE_FALSE_VALUE : EDGE_FALLTHRU;
9586     }
9587
9588   set_immediate_dominator (CDI_DOMINATORS, second_bb, entry_bb);
9589   set_immediate_dominator (CDI_DOMINATORS, third_bb, entry_bb);
9590   set_immediate_dominator (CDI_DOMINATORS, seq_start_bb, third_bb);
9591
9592   set_immediate_dominator (CDI_DOMINATORS, body_bb,
9593                            recompute_dominator (CDI_DOMINATORS, body_bb));
9594   set_immediate_dominator (CDI_DOMINATORS, fin_bb,
9595                            recompute_dominator (CDI_DOMINATORS, fin_bb));
9596
9597   struct loop *loop = body_bb->loop_father;
9598   if (loop != entry_bb->loop_father)
9599     {
9600       gcc_assert (loop->header == body_bb);
9601       gcc_assert (broken_loop
9602                   || loop->latch == region->cont
9603                   || single_pred (loop->latch) == region->cont);
9604       return;
9605     }
9606
9607   if (!broken_loop && !gimple_omp_for_combined_p (fd->for_stmt))
9608     {
9609       loop = alloc_loop ();
9610       loop->header = body_bb;
9611       if (collapse_bb == NULL)
9612         loop->latch = cont_bb;
9613       add_loop (loop, body_bb->loop_father);
9614     }
9615 }
9616
9617 /* Return phi in E->DEST with ARG on edge E.  */
9618
9619 static gphi *
9620 find_phi_with_arg_on_edge (tree arg, edge e)
9621 {
9622   basic_block bb = e->dest;
9623
9624   for (gphi_iterator gpi = gsi_start_phis (bb);
9625        !gsi_end_p (gpi);
9626        gsi_next (&gpi))
9627     {
9628       gphi *phi = gpi.phi ();
9629       if (PHI_ARG_DEF_FROM_EDGE (phi, e) == arg)
9630         return phi;
9631     }
9632
9633   return NULL;
9634 }
9635
9636 /* A subroutine of expand_omp_for.  Generate code for a parallel
9637    loop with static schedule and a specified chunk size.  Given
9638    parameters:
9639
9640         for (V = N1; V cond N2; V += STEP) BODY;
9641
9642    where COND is "<" or ">", we generate pseudocode
9643
9644         if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
9645         if (cond is <)
9646           adj = STEP - 1;
9647         else
9648           adj = STEP + 1;
9649         if ((__typeof (V)) -1 > 0 && cond is >)
9650           n = -(adj + N2 - N1) / -STEP;
9651         else
9652           n = (adj + N2 - N1) / STEP;
9653         trip = 0;
9654         V = threadid * CHUNK * STEP + N1;  -- this extra definition of V is
9655                                               here so that V is defined
9656                                               if the loop is not entered
9657     L0:
9658         s0 = (trip * nthreads + threadid) * CHUNK;
9659         e0 = min(s0 + CHUNK, n);
9660         if (s0 < n) goto L1; else goto L4;
9661     L1:
9662         V = s0 * STEP + N1;
9663         e = e0 * STEP + N1;
9664     L2:
9665         BODY;
9666         V += STEP;
9667         if (V cond e) goto L2; else goto L3;
9668     L3:
9669         trip += 1;
9670         goto L0;
9671     L4:
9672 */
9673
9674 static void
9675 expand_omp_for_static_chunk (struct omp_region *region,
9676                              struct omp_for_data *fd, gimple *inner_stmt)
9677 {
9678   tree n, s0, e0, e, t;
9679   tree trip_var, trip_init, trip_main, trip_back, nthreads, threadid;
9680   tree type, itype, vmain, vback, vextra;
9681   basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
9682   basic_block trip_update_bb = NULL, cont_bb, collapse_bb = NULL, fin_bb;
9683   gimple_stmt_iterator gsi;
9684   edge se;
9685   bool broken_loop = region->cont == NULL;
9686   tree *counts = NULL;
9687   tree n1, n2, step;
9688
9689   itype = type = TREE_TYPE (fd->loop.v);
9690   if (POINTER_TYPE_P (type))
9691     itype = signed_type_for (type);
9692
9693   entry_bb = region->entry;
9694   se = split_block (entry_bb, last_stmt (entry_bb));
9695   entry_bb = se->src;
9696   iter_part_bb = se->dest;
9697   cont_bb = region->cont;
9698   gcc_assert (EDGE_COUNT (iter_part_bb->succs) == 2);
9699   fin_bb = BRANCH_EDGE (iter_part_bb)->dest;
9700   gcc_assert (broken_loop
9701               || fin_bb == FALLTHRU_EDGE (cont_bb)->dest);
9702   seq_start_bb = split_edge (FALLTHRU_EDGE (iter_part_bb));
9703   body_bb = single_succ (seq_start_bb);
9704   if (!broken_loop)
9705     {
9706       gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb
9707                   || single_succ (BRANCH_EDGE (cont_bb)->dest) == body_bb);
9708       gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
9709       trip_update_bb = split_edge (FALLTHRU_EDGE (cont_bb));
9710     }
9711   exit_bb = region->exit;
9712
9713   /* Trip and adjustment setup goes in ENTRY_BB.  */
9714   gsi = gsi_last_bb (entry_bb);
9715   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
9716
9717   if (fd->collapse > 1)
9718     {
9719       int first_zero_iter = -1, dummy = -1;
9720       basic_block l2_dom_bb = NULL, dummy_bb = NULL;
9721
9722       counts = XALLOCAVEC (tree, fd->collapse);
9723       expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
9724                                   fin_bb, first_zero_iter,
9725                                   dummy_bb, dummy, l2_dom_bb);
9726       t = NULL_TREE;
9727     }
9728   else if (gimple_omp_for_combined_into_p (fd->for_stmt))
9729     t = integer_one_node;
9730   else
9731     t = fold_binary (fd->loop.cond_code, boolean_type_node,
9732                      fold_convert (type, fd->loop.n1),
9733                      fold_convert (type, fd->loop.n2));
9734   if (fd->collapse == 1
9735       && TYPE_UNSIGNED (type)
9736       && (t == NULL_TREE || !integer_onep (t)))
9737     {
9738       n1 = fold_convert (type, unshare_expr (fd->loop.n1));
9739       n1 = force_gimple_operand_gsi (&gsi, n1, true, NULL_TREE,
9740                                      true, GSI_SAME_STMT);
9741       n2 = fold_convert (type, unshare_expr (fd->loop.n2));
9742       n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE,
9743                                      true, GSI_SAME_STMT);
9744       gcond *cond_stmt = gimple_build_cond (fd->loop.cond_code, n1, n2,
9745                                                  NULL_TREE, NULL_TREE);
9746       gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
9747       if (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
9748                      expand_omp_regimplify_p, NULL, NULL)
9749           || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
9750                         expand_omp_regimplify_p, NULL, NULL))
9751         {
9752           gsi = gsi_for_stmt (cond_stmt);
9753           gimple_regimplify_operands (cond_stmt, &gsi);
9754         }
9755       se = split_block (entry_bb, cond_stmt);
9756       se->flags = EDGE_TRUE_VALUE;
9757       entry_bb = se->dest;
9758       se->probability = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1);
9759       se = make_edge (se->src, fin_bb, EDGE_FALSE_VALUE);
9760       se->probability = REG_BR_PROB_BASE / 2000 - 1;
9761       if (gimple_in_ssa_p (cfun))
9762         {
9763           int dest_idx = find_edge (iter_part_bb, fin_bb)->dest_idx;
9764           for (gphi_iterator gpi = gsi_start_phis (fin_bb);
9765                !gsi_end_p (gpi); gsi_next (&gpi))
9766             {
9767               gphi *phi = gpi.phi ();
9768               add_phi_arg (phi, gimple_phi_arg_def (phi, dest_idx),
9769                            se, UNKNOWN_LOCATION);
9770             }
9771         }
9772       gsi = gsi_last_bb (entry_bb);
9773     }
9774
9775   switch (gimple_omp_for_kind (fd->for_stmt))
9776     {
9777     case GF_OMP_FOR_KIND_FOR:
9778       nthreads = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
9779       threadid = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
9780       break;
9781     case GF_OMP_FOR_KIND_DISTRIBUTE:
9782       nthreads = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_TEAMS);
9783       threadid = builtin_decl_explicit (BUILT_IN_OMP_GET_TEAM_NUM);
9784       break;
9785     default:
9786       gcc_unreachable ();
9787     }
9788   nthreads = build_call_expr (nthreads, 0);
9789   nthreads = fold_convert (itype, nthreads);
9790   nthreads = force_gimple_operand_gsi (&gsi, nthreads, true, NULL_TREE,
9791                                        true, GSI_SAME_STMT);
9792   threadid = build_call_expr (threadid, 0);
9793   threadid = fold_convert (itype, threadid);
9794   threadid = force_gimple_operand_gsi (&gsi, threadid, true, NULL_TREE,
9795                                        true, GSI_SAME_STMT);
9796
9797   n1 = fd->loop.n1;
9798   n2 = fd->loop.n2;
9799   step = fd->loop.step;
9800   if (gimple_omp_for_combined_into_p (fd->for_stmt))
9801     {
9802       tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
9803                                      OMP_CLAUSE__LOOPTEMP_);
9804       gcc_assert (innerc);
9805       n1 = OMP_CLAUSE_DECL (innerc);
9806       innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
9807                                 OMP_CLAUSE__LOOPTEMP_);
9808       gcc_assert (innerc);
9809       n2 = OMP_CLAUSE_DECL (innerc);
9810     }
9811   n1 = force_gimple_operand_gsi (&gsi, fold_convert (type, n1),
9812                                  true, NULL_TREE, true, GSI_SAME_STMT);
9813   n2 = force_gimple_operand_gsi (&gsi, fold_convert (itype, n2),
9814                                  true, NULL_TREE, true, GSI_SAME_STMT);
9815   step = force_gimple_operand_gsi (&gsi, fold_convert (itype, step),
9816                                    true, NULL_TREE, true, GSI_SAME_STMT);
9817   tree chunk_size = fold_convert (itype, fd->chunk_size);
9818   chunk_size = omp_adjust_chunk_size (chunk_size, fd->simd_schedule);
9819   chunk_size
9820     = force_gimple_operand_gsi (&gsi, chunk_size, true, NULL_TREE, true,
9821                                 GSI_SAME_STMT);
9822
9823   t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
9824   t = fold_build2 (PLUS_EXPR, itype, step, t);
9825   t = fold_build2 (PLUS_EXPR, itype, t, n2);
9826   t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, n1));
9827   if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
9828     t = fold_build2 (TRUNC_DIV_EXPR, itype,
9829                      fold_build1 (NEGATE_EXPR, itype, t),
9830                      fold_build1 (NEGATE_EXPR, itype, step));
9831   else
9832     t = fold_build2 (TRUNC_DIV_EXPR, itype, t, step);
9833   t = fold_convert (itype, t);
9834   n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
9835                                 true, GSI_SAME_STMT);
9836
9837   trip_var = create_tmp_reg (itype, ".trip");
9838   if (gimple_in_ssa_p (cfun))
9839     {
9840       trip_init = make_ssa_name (trip_var);
9841       trip_main = make_ssa_name (trip_var);
9842       trip_back = make_ssa_name (trip_var);
9843     }
9844   else
9845     {
9846       trip_init = trip_var;
9847       trip_main = trip_var;
9848       trip_back = trip_var;
9849     }
9850
9851   gassign *assign_stmt
9852     = gimple_build_assign (trip_init, build_int_cst (itype, 0));
9853   gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
9854
9855   t = fold_build2 (MULT_EXPR, itype, threadid, chunk_size);
9856   t = fold_build2 (MULT_EXPR, itype, t, step);
9857   if (POINTER_TYPE_P (type))
9858     t = fold_build_pointer_plus (n1, t);
9859   else
9860     t = fold_build2 (PLUS_EXPR, type, t, n1);
9861   vextra = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
9862                                      true, GSI_SAME_STMT);
9863
9864   /* Remove the GIMPLE_OMP_FOR.  */
9865   gsi_remove (&gsi, true);
9866
9867   gimple_stmt_iterator gsif = gsi;
9868
9869   /* Iteration space partitioning goes in ITER_PART_BB.  */
9870   gsi = gsi_last_bb (iter_part_bb);
9871
9872   t = fold_build2 (MULT_EXPR, itype, trip_main, nthreads);
9873   t = fold_build2 (PLUS_EXPR, itype, t, threadid);
9874   t = fold_build2 (MULT_EXPR, itype, t, chunk_size);
9875   s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
9876                                  false, GSI_CONTINUE_LINKING);
9877
9878   t = fold_build2 (PLUS_EXPR, itype, s0, chunk_size);
9879   t = fold_build2 (MIN_EXPR, itype, t, n);
9880   e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
9881                                  false, GSI_CONTINUE_LINKING);
9882
9883   t = build2 (LT_EXPR, boolean_type_node, s0, n);
9884   gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_CONTINUE_LINKING);
9885
9886   /* Setup code for sequential iteration goes in SEQ_START_BB.  */
9887   gsi = gsi_start_bb (seq_start_bb);
9888
9889   tree startvar = fd->loop.v;
9890   tree endvar = NULL_TREE;
9891
9892   if (gimple_omp_for_combined_p (fd->for_stmt))
9893     {
9894       tree clauses = gimple_code (inner_stmt) == GIMPLE_OMP_PARALLEL
9895                      ? gimple_omp_parallel_clauses (inner_stmt)
9896                      : gimple_omp_for_clauses (inner_stmt);
9897       tree innerc = find_omp_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
9898       gcc_assert (innerc);
9899       startvar = OMP_CLAUSE_DECL (innerc);
9900       innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
9901                                 OMP_CLAUSE__LOOPTEMP_);
9902       gcc_assert (innerc);
9903       endvar = OMP_CLAUSE_DECL (innerc);
9904       if (fd->collapse > 1 && TREE_CODE (fd->loop.n2) != INTEGER_CST
9905           && gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_DISTRIBUTE)
9906         {
9907           int i;
9908           for (i = 1; i < fd->collapse; i++)
9909             {
9910               innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
9911                                         OMP_CLAUSE__LOOPTEMP_);
9912               gcc_assert (innerc);
9913             }
9914           innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
9915                                     OMP_CLAUSE__LOOPTEMP_);
9916           if (innerc)
9917             {
9918               /* If needed (distribute parallel for with lastprivate),
9919                  propagate down the total number of iterations.  */
9920               tree t = fold_convert (TREE_TYPE (OMP_CLAUSE_DECL (innerc)),
9921                                      fd->loop.n2);
9922               t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, false,
9923                                             GSI_CONTINUE_LINKING);
9924               assign_stmt = gimple_build_assign (OMP_CLAUSE_DECL (innerc), t);
9925               gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
9926             }
9927         }
9928     }
9929
9930   t = fold_convert (itype, s0);
9931   t = fold_build2 (MULT_EXPR, itype, t, step);
9932   if (POINTER_TYPE_P (type))
9933     t = fold_build_pointer_plus (n1, t);
9934   else
9935     t = fold_build2 (PLUS_EXPR, type, t, n1);
9936   t = fold_convert (TREE_TYPE (startvar), t);
9937   t = force_gimple_operand_gsi (&gsi, t,
9938                                 DECL_P (startvar)
9939                                 && TREE_ADDRESSABLE (startvar),
9940                                 NULL_TREE, false, GSI_CONTINUE_LINKING);
9941   assign_stmt = gimple_build_assign (startvar, t);
9942   gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
9943
9944   t = fold_convert (itype, e0);
9945   t = fold_build2 (MULT_EXPR, itype, t, step);
9946   if (POINTER_TYPE_P (type))
9947     t = fold_build_pointer_plus (n1, t);
9948   else
9949     t = fold_build2 (PLUS_EXPR, type, t, n1);
9950   t = fold_convert (TREE_TYPE (startvar), t);
9951   e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
9952                                 false, GSI_CONTINUE_LINKING);
9953   if (endvar)
9954     {
9955       assign_stmt = gimple_build_assign (endvar, e);
9956       gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
9957       if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
9958         assign_stmt = gimple_build_assign (fd->loop.v, e);
9959       else
9960         assign_stmt = gimple_build_assign (fd->loop.v, NOP_EXPR, e);
9961       gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
9962     }
9963   /* Handle linear clause adjustments.  */
9964   tree itercnt = NULL_TREE, itercntbias = NULL_TREE;
9965   if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_FOR)
9966     for (tree c = gimple_omp_for_clauses (fd->for_stmt);
9967          c; c = OMP_CLAUSE_CHAIN (c))
9968       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9969           && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9970         {
9971           tree d = OMP_CLAUSE_DECL (c);
9972           bool is_ref = is_reference (d);
9973           tree t = d, a, dest;
9974           if (is_ref)
9975             t = build_simple_mem_ref_loc (OMP_CLAUSE_LOCATION (c), t);
9976           tree type = TREE_TYPE (t);
9977           if (POINTER_TYPE_P (type))
9978             type = sizetype;
9979           dest = unshare_expr (t);
9980           tree v = create_tmp_var (TREE_TYPE (t), NULL);
9981           expand_omp_build_assign (&gsif, v, t);
9982           if (itercnt == NULL_TREE)
9983             {
9984               if (gimple_omp_for_combined_into_p (fd->for_stmt))
9985                 {
9986                   itercntbias
9987                     = fold_build2 (MINUS_EXPR, itype, fold_convert (itype, n1),
9988                                    fold_convert (itype, fd->loop.n1));
9989                   itercntbias = fold_build2 (EXACT_DIV_EXPR, itype,
9990                                              itercntbias, step);
9991                   itercntbias
9992                     = force_gimple_operand_gsi (&gsif, itercntbias, true,
9993                                                 NULL_TREE, true,
9994                                                 GSI_SAME_STMT);
9995                   itercnt = fold_build2 (PLUS_EXPR, itype, itercntbias, s0);
9996                   itercnt = force_gimple_operand_gsi (&gsi, itercnt, true,
9997                                                       NULL_TREE, false,
9998                                                       GSI_CONTINUE_LINKING);
9999                 }
10000               else
10001                 itercnt = s0;
10002             }
10003           a = fold_build2 (MULT_EXPR, type,
10004                            fold_convert (type, itercnt),
10005                            fold_convert (type, OMP_CLAUSE_LINEAR_STEP (c)));
10006           t = fold_build2 (type == TREE_TYPE (t) ? PLUS_EXPR
10007                            : POINTER_PLUS_EXPR, TREE_TYPE (t), v, a);
10008           t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
10009                                         false, GSI_CONTINUE_LINKING);
10010           assign_stmt = gimple_build_assign (dest, t);
10011           gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
10012         }
10013   if (fd->collapse > 1)
10014     expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
10015
10016   if (!broken_loop)
10017     {
10018       /* The code controlling the sequential loop goes in CONT_BB,
10019          replacing the GIMPLE_OMP_CONTINUE.  */
10020       gsi = gsi_last_bb (cont_bb);
10021       gomp_continue *cont_stmt = as_a <gomp_continue *> (gsi_stmt (gsi));
10022       vmain = gimple_omp_continue_control_use (cont_stmt);
10023       vback = gimple_omp_continue_control_def (cont_stmt);
10024
10025       if (!gimple_omp_for_combined_p (fd->for_stmt))
10026         {
10027           if (POINTER_TYPE_P (type))
10028             t = fold_build_pointer_plus (vmain, step);
10029           else
10030             t = fold_build2 (PLUS_EXPR, type, vmain, step);
10031           if (DECL_P (vback) && TREE_ADDRESSABLE (vback))
10032             t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
10033                                           true, GSI_SAME_STMT);
10034           assign_stmt = gimple_build_assign (vback, t);
10035           gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
10036
10037           if (tree_int_cst_equal (fd->chunk_size, integer_one_node))
10038             t = build2 (EQ_EXPR, boolean_type_node,
10039                         build_int_cst (itype, 0),
10040                         build_int_cst (itype, 1));
10041           else
10042             t = build2 (fd->loop.cond_code, boolean_type_node,
10043                         DECL_P (vback) && TREE_ADDRESSABLE (vback)
10044                         ? t : vback, e);
10045           gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
10046         }
10047
10048       /* Remove GIMPLE_OMP_CONTINUE.  */
10049       gsi_remove (&gsi, true);
10050
10051       if (fd->collapse > 1 && !gimple_omp_for_combined_p (fd->for_stmt))
10052         collapse_bb = extract_omp_for_update_vars (fd, cont_bb, body_bb);
10053
10054       /* Trip update code goes into TRIP_UPDATE_BB.  */
10055       gsi = gsi_start_bb (trip_update_bb);
10056
10057       t = build_int_cst (itype, 1);
10058       t = build2 (PLUS_EXPR, itype, trip_main, t);
10059       assign_stmt = gimple_build_assign (trip_back, t);
10060       gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
10061     }
10062
10063   /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing.  */
10064   gsi = gsi_last_bb (exit_bb);
10065   if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
10066     {
10067       t = gimple_omp_return_lhs (gsi_stmt (gsi));
10068       gsi_insert_after (&gsi, build_omp_barrier (t), GSI_SAME_STMT);
10069     }
10070   gsi_remove (&gsi, true);
10071
10072   /* Connect the new blocks.  */
10073   find_edge (iter_part_bb, seq_start_bb)->flags = EDGE_TRUE_VALUE;
10074   find_edge (iter_part_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
10075
10076   if (!broken_loop)
10077     {
10078       se = find_edge (cont_bb, body_bb);
10079       if (se == NULL)
10080         {
10081           se = BRANCH_EDGE (cont_bb);
10082           gcc_assert (single_succ (se->dest) == body_bb);
10083         }
10084       if (gimple_omp_for_combined_p (fd->for_stmt))
10085         {
10086           remove_edge (se);
10087           se = NULL;
10088         }
10089       else if (fd->collapse > 1)
10090         {
10091           remove_edge (se);
10092           se = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
10093         }
10094       else
10095         se->flags = EDGE_TRUE_VALUE;
10096       find_edge (cont_bb, trip_update_bb)->flags
10097         = se ? EDGE_FALSE_VALUE : EDGE_FALLTHRU;
10098
10099       redirect_edge_and_branch (single_succ_edge (trip_update_bb), iter_part_bb);
10100     }
10101
10102   if (gimple_in_ssa_p (cfun))
10103     {
10104       gphi_iterator psi;
10105       gphi *phi;
10106       edge re, ene;
10107       edge_var_map *vm;
10108       size_t i;
10109
10110       gcc_assert (fd->collapse == 1 && !broken_loop);
10111
10112       /* When we redirect the edge from trip_update_bb to iter_part_bb, we
10113          remove arguments of the phi nodes in fin_bb.  We need to create
10114          appropriate phi nodes in iter_part_bb instead.  */
10115       se = find_edge (iter_part_bb, fin_bb);
10116       re = single_succ_edge (trip_update_bb);
10117       vec<edge_var_map> *head = redirect_edge_var_map_vector (re);
10118       ene = single_succ_edge (entry_bb);
10119
10120       psi = gsi_start_phis (fin_bb);
10121       for (i = 0; !gsi_end_p (psi) && head->iterate (i, &vm);
10122            gsi_next (&psi), ++i)
10123         {
10124           gphi *nphi;
10125           source_location locus;
10126
10127           phi = psi.phi ();
10128           t = gimple_phi_result (phi);
10129           gcc_assert (t == redirect_edge_var_map_result (vm));
10130
10131           if (!single_pred_p (fin_bb))
10132             t = copy_ssa_name (t, phi);
10133
10134           nphi = create_phi_node (t, iter_part_bb);
10135
10136           t = PHI_ARG_DEF_FROM_EDGE (phi, se);
10137           locus = gimple_phi_arg_location_from_edge (phi, se);
10138
10139           /* A special case -- fd->loop.v is not yet computed in
10140              iter_part_bb, we need to use vextra instead.  */
10141           if (t == fd->loop.v)
10142             t = vextra;
10143           add_phi_arg (nphi, t, ene, locus);
10144           locus = redirect_edge_var_map_location (vm);
10145           tree back_arg = redirect_edge_var_map_def (vm);
10146           add_phi_arg (nphi, back_arg, re, locus);
10147           edge ce = find_edge (cont_bb, body_bb);
10148           if (ce == NULL)
10149             {
10150               ce = BRANCH_EDGE (cont_bb);
10151               gcc_assert (single_succ (ce->dest) == body_bb);
10152               ce = single_succ_edge (ce->dest);
10153             }
10154           gphi *inner_loop_phi = find_phi_with_arg_on_edge (back_arg, ce);
10155           gcc_assert (inner_loop_phi != NULL);
10156           add_phi_arg (inner_loop_phi, gimple_phi_result (nphi),
10157                        find_edge (seq_start_bb, body_bb), locus);
10158
10159           if (!single_pred_p (fin_bb))
10160             add_phi_arg (phi, gimple_phi_result (nphi), se, locus);
10161         }
10162       gcc_assert (gsi_end_p (psi) && (head == NULL || i == head->length ()));
10163       redirect_edge_var_map_clear (re);
10164       if (single_pred_p (fin_bb))
10165         while (1)
10166           {
10167             psi = gsi_start_phis (fin_bb);
10168             if (gsi_end_p (psi))
10169               break;
10170             remove_phi_node (&psi, false);
10171           }
10172
10173       /* Make phi node for trip.  */
10174       phi = create_phi_node (trip_main, iter_part_bb);
10175       add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb),
10176                    UNKNOWN_LOCATION);
10177       add_phi_arg (phi, trip_init, single_succ_edge (entry_bb),
10178                    UNKNOWN_LOCATION);
10179     }
10180
10181   if (!broken_loop)
10182     set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
10183   set_immediate_dominator (CDI_DOMINATORS, iter_part_bb,
10184                            recompute_dominator (CDI_DOMINATORS, iter_part_bb));
10185   set_immediate_dominator (CDI_DOMINATORS, fin_bb,
10186                            recompute_dominator (CDI_DOMINATORS, fin_bb));
10187   set_immediate_dominator (CDI_DOMINATORS, seq_start_bb,
10188                            recompute_dominator (CDI_DOMINATORS, seq_start_bb));
10189   set_immediate_dominator (CDI_DOMINATORS, body_bb,
10190                            recompute_dominator (CDI_DOMINATORS, body_bb));
10191
10192   if (!broken_loop)
10193     {
10194       struct loop *loop = body_bb->loop_father;
10195       struct loop *trip_loop = alloc_loop ();
10196       trip_loop->header = iter_part_bb;
10197       trip_loop->latch = trip_update_bb;
10198       add_loop (trip_loop, iter_part_bb->loop_father);
10199
10200       if (loop != entry_bb->loop_father)
10201         {
10202           gcc_assert (loop->header == body_bb);
10203           gcc_assert (loop->latch == region->cont
10204                       || single_pred (loop->latch) == region->cont);
10205           trip_loop->inner = loop;
10206           return;
10207         }
10208
10209       if (!gimple_omp_for_combined_p (fd->for_stmt))
10210         {
10211           loop = alloc_loop ();
10212           loop->header = body_bb;
10213           if (collapse_bb == NULL)
10214             loop->latch = cont_bb;
10215           add_loop (loop, trip_loop);
10216         }
10217     }
10218 }
10219
10220 /* A subroutine of expand_omp_for.  Generate code for _Cilk_for loop.
10221    Given parameters:
10222    for (V = N1; V cond N2; V += STEP) BODY;
10223
10224    where COND is "<" or ">" or "!=", we generate pseudocode
10225
10226    for (ind_var = low; ind_var < high; ind_var++)
10227      {
10228        V = n1 + (ind_var * STEP)
10229
10230        <BODY>
10231      }
10232
10233    In the above pseudocode, low and high are function parameters of the
10234    child function.  In the function below, we are inserting a temp.
10235    variable that will be making a call to two OMP functions that will not be
10236    found in the body of _Cilk_for (since OMP_FOR cannot be mixed
10237    with _Cilk_for).  These functions are replaced with low and high
10238    by the function that handles taskreg.  */
10239
10240
10241 static void
10242 expand_cilk_for (struct omp_region *region, struct omp_for_data *fd)
10243 {
10244   bool broken_loop = region->cont == NULL;
10245   basic_block entry_bb = region->entry;
10246   basic_block cont_bb = region->cont;
10247
10248   gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
10249   gcc_assert (broken_loop
10250               || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
10251   basic_block l0_bb = FALLTHRU_EDGE (entry_bb)->dest;
10252   basic_block l1_bb, l2_bb;
10253
10254   if (!broken_loop)
10255     {
10256       gcc_assert (BRANCH_EDGE (cont_bb)->dest == l0_bb);
10257       gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
10258       l1_bb = split_block (cont_bb, last_stmt (cont_bb))->dest;
10259       l2_bb = BRANCH_EDGE (entry_bb)->dest;
10260     }
10261   else
10262     {
10263       BRANCH_EDGE (entry_bb)->flags &= ~EDGE_ABNORMAL;
10264       l1_bb = split_edge (BRANCH_EDGE (entry_bb));
10265       l2_bb = single_succ (l1_bb);
10266     }
10267   basic_block exit_bb = region->exit;
10268   basic_block l2_dom_bb = NULL;
10269
10270   gimple_stmt_iterator gsi = gsi_last_bb (entry_bb);
10271
10272   /* Below statements until the "tree high_val = ..." are pseudo statements
10273      used to pass information to be used by expand_omp_taskreg.
10274      low_val and high_val will be replaced by the __low and __high
10275      parameter from the child function.
10276
10277      The call_exprs part is a place-holder, it is mainly used
10278      to distinctly identify to the top-level part that this is
10279      where we should put low and high (reasoning given in header
10280      comment).  */
10281
10282   tree child_fndecl
10283     = gimple_omp_parallel_child_fn (
10284         as_a <gomp_parallel *> (last_stmt (region->outer->entry)));
10285   tree t, low_val = NULL_TREE, high_val = NULL_TREE;
10286   for (t = DECL_ARGUMENTS (child_fndecl); t; t = TREE_CHAIN (t))
10287     {
10288       if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__high"))
10289         high_val = t;
10290       else if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__low"))
10291         low_val = t;
10292     }
10293   gcc_assert (low_val && high_val);
10294
10295   tree type = TREE_TYPE (low_val);
10296   tree ind_var = create_tmp_reg (type, "__cilk_ind_var");
10297   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
10298
10299   /* Not needed in SSA form right now.  */
10300   gcc_assert (!gimple_in_ssa_p (cfun));
10301   if (l2_dom_bb == NULL)
10302     l2_dom_bb = l1_bb;
10303
10304   tree n1 = low_val;
10305   tree n2 = high_val;
10306
10307   gimple *stmt = gimple_build_assign (ind_var, n1);
10308
10309   /* Replace the GIMPLE_OMP_FOR statement.  */
10310   gsi_replace (&gsi, stmt, true);
10311
10312   if (!broken_loop)
10313     {
10314       /* Code to control the increment goes in the CONT_BB.  */
10315       gsi = gsi_last_bb (cont_bb);
10316       stmt = gsi_stmt (gsi);
10317       gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
10318       stmt = gimple_build_assign (ind_var, PLUS_EXPR, ind_var,
10319                                   build_one_cst (type));
10320
10321       /* Replace GIMPLE_OMP_CONTINUE.  */
10322       gsi_replace (&gsi, stmt, true);
10323     }
10324
10325   /* Emit the condition in L1_BB.  */
10326   gsi = gsi_after_labels (l1_bb);
10327   t = fold_build2 (MULT_EXPR, TREE_TYPE (fd->loop.step),
10328                    fold_convert (TREE_TYPE (fd->loop.step), ind_var),
10329                    fd->loop.step);
10330   if (POINTER_TYPE_P (TREE_TYPE (fd->loop.n1)))
10331     t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (fd->loop.n1),
10332                      fd->loop.n1, fold_convert (sizetype, t));
10333   else
10334     t = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->loop.n1),
10335                      fd->loop.n1, fold_convert (TREE_TYPE (fd->loop.n1), t));
10336   t = fold_convert (TREE_TYPE (fd->loop.v), t);
10337   expand_omp_build_assign (&gsi, fd->loop.v, t);
10338
10339   /* The condition is always '<' since the runtime will fill in the low
10340      and high values.  */
10341   stmt = gimple_build_cond (LT_EXPR, ind_var, n2, NULL_TREE, NULL_TREE);
10342   gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
10343
10344   /* Remove GIMPLE_OMP_RETURN.  */
10345   gsi = gsi_last_bb (exit_bb);
10346   gsi_remove (&gsi, true);
10347
10348   /* Connect the new blocks.  */
10349   remove_edge (FALLTHRU_EDGE (entry_bb));
10350
10351   edge e, ne;
10352   if (!broken_loop)
10353     {
10354       remove_edge (BRANCH_EDGE (entry_bb));
10355       make_edge (entry_bb, l1_bb, EDGE_FALLTHRU);
10356
10357       e = BRANCH_EDGE (l1_bb);
10358       ne = FALLTHRU_EDGE (l1_bb);
10359       e->flags = EDGE_TRUE_VALUE;
10360     }
10361   else
10362     {
10363       single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
10364
10365       ne = single_succ_edge (l1_bb);
10366       e = make_edge (l1_bb, l0_bb, EDGE_TRUE_VALUE);
10367
10368     }
10369   ne->flags = EDGE_FALSE_VALUE;
10370   e->probability = REG_BR_PROB_BASE * 7 / 8;
10371   ne->probability = REG_BR_PROB_BASE / 8;
10372
10373   set_immediate_dominator (CDI_DOMINATORS, l1_bb, entry_bb);
10374   set_immediate_dominator (CDI_DOMINATORS, l2_bb, l2_dom_bb);
10375   set_immediate_dominator (CDI_DOMINATORS, l0_bb, l1_bb);
10376
10377   if (!broken_loop)
10378     {
10379       struct loop *loop = alloc_loop ();
10380       loop->header = l1_bb;
10381       loop->latch = cont_bb;
10382       add_loop (loop, l1_bb->loop_father);
10383       loop->safelen = INT_MAX;
10384     }
10385
10386   /* Pick the correct library function based on the precision of the
10387      induction variable type.  */
10388   tree lib_fun = NULL_TREE;
10389   if (TYPE_PRECISION (type) == 32)
10390     lib_fun = cilk_for_32_fndecl;
10391   else if (TYPE_PRECISION (type) == 64)
10392     lib_fun = cilk_for_64_fndecl;
10393   else
10394     gcc_unreachable ();
10395
10396   gcc_assert (fd->sched_kind == OMP_CLAUSE_SCHEDULE_CILKFOR);
10397
10398   /* WS_ARGS contains the library function flavor to call:
10399      __libcilkrts_cilk_for_64 or __libcilkrts_cilk_for_32), and the
10400      user-defined grain value.  If the user does not define one, then zero
10401      is passed in by the parser.  */
10402   vec_alloc (region->ws_args, 2);
10403   region->ws_args->quick_push (lib_fun);
10404   region->ws_args->quick_push (fd->chunk_size);
10405 }
10406
10407 /* A subroutine of expand_omp_for.  Generate code for a simd non-worksharing
10408    loop.  Given parameters:
10409
10410         for (V = N1; V cond N2; V += STEP) BODY;
10411
10412    where COND is "<" or ">", we generate pseudocode
10413
10414         V = N1;
10415         goto L1;
10416     L0:
10417         BODY;
10418         V += STEP;
10419     L1:
10420         if (V cond N2) goto L0; else goto L2;
10421     L2:
10422
10423     For collapsed loops, given parameters:
10424       collapse(3)
10425       for (V1 = N11; V1 cond1 N12; V1 += STEP1)
10426         for (V2 = N21; V2 cond2 N22; V2 += STEP2)
10427           for (V3 = N31; V3 cond3 N32; V3 += STEP3)
10428             BODY;
10429
10430     we generate pseudocode
10431
10432         if (cond3 is <)
10433           adj = STEP3 - 1;
10434         else
10435           adj = STEP3 + 1;
10436         count3 = (adj + N32 - N31) / STEP3;
10437         if (cond2 is <)
10438           adj = STEP2 - 1;
10439         else
10440           adj = STEP2 + 1;
10441         count2 = (adj + N22 - N21) / STEP2;
10442         if (cond1 is <)
10443           adj = STEP1 - 1;
10444         else
10445           adj = STEP1 + 1;
10446         count1 = (adj + N12 - N11) / STEP1;
10447         count = count1 * count2 * count3;
10448         V = 0;
10449         V1 = N11;
10450         V2 = N21;
10451         V3 = N31;
10452         goto L1;
10453     L0:
10454         BODY;
10455         V += 1;
10456         V3 += STEP3;
10457         V2 += (V3 cond3 N32) ? 0 : STEP2;
10458         V3 = (V3 cond3 N32) ? V3 : N31;
10459         V1 += (V2 cond2 N22) ? 0 : STEP1;
10460         V2 = (V2 cond2 N22) ? V2 : N21;
10461     L1:
10462         if (V < count) goto L0; else goto L2;
10463     L2:
10464
10465       */
10466
10467 static void
10468 expand_omp_simd (struct omp_region *region, struct omp_for_data *fd)
10469 {
10470   tree type, t;
10471   basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, l2_bb, l2_dom_bb;
10472   gimple_stmt_iterator gsi;
10473   gimple *stmt;
10474   gcond *cond_stmt;
10475   bool broken_loop = region->cont == NULL;
10476   edge e, ne;
10477   tree *counts = NULL;
10478   int i;
10479   tree safelen = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
10480                                   OMP_CLAUSE_SAFELEN);
10481   tree simduid = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
10482                                   OMP_CLAUSE__SIMDUID_);
10483   tree n1, n2;
10484
10485   type = TREE_TYPE (fd->loop.v);
10486   entry_bb = region->entry;
10487   cont_bb = region->cont;
10488   gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
10489   gcc_assert (broken_loop
10490               || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
10491   l0_bb = FALLTHRU_EDGE (entry_bb)->dest;
10492   if (!broken_loop)
10493     {
10494       gcc_assert (BRANCH_EDGE (cont_bb)->dest == l0_bb);
10495       gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
10496       l1_bb = split_block (cont_bb, last_stmt (cont_bb))->dest;
10497       l2_bb = BRANCH_EDGE (entry_bb)->dest;
10498     }
10499   else
10500     {
10501       BRANCH_EDGE (entry_bb)->flags &= ~EDGE_ABNORMAL;
10502       l1_bb = split_edge (BRANCH_EDGE (entry_bb));
10503       l2_bb = single_succ (l1_bb);
10504     }
10505   exit_bb = region->exit;
10506   l2_dom_bb = NULL;
10507
10508   gsi = gsi_last_bb (entry_bb);
10509
10510   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
10511   /* Not needed in SSA form right now.  */
10512   gcc_assert (!gimple_in_ssa_p (cfun));
10513   if (fd->collapse > 1)
10514     {
10515       int first_zero_iter = -1, dummy = -1;
10516       basic_block zero_iter_bb = l2_bb, dummy_bb = NULL;
10517
10518       counts = XALLOCAVEC (tree, fd->collapse);
10519       expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
10520                                   zero_iter_bb, first_zero_iter,
10521                                   dummy_bb, dummy, l2_dom_bb);
10522     }
10523   if (l2_dom_bb == NULL)
10524     l2_dom_bb = l1_bb;
10525
10526   n1 = fd->loop.n1;
10527   n2 = fd->loop.n2;
10528   if (gimple_omp_for_combined_into_p (fd->for_stmt))
10529     {
10530       tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
10531                                      OMP_CLAUSE__LOOPTEMP_);
10532       gcc_assert (innerc);
10533       n1 = OMP_CLAUSE_DECL (innerc);
10534       innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
10535                                 OMP_CLAUSE__LOOPTEMP_);
10536       gcc_assert (innerc);
10537       n2 = OMP_CLAUSE_DECL (innerc);
10538       expand_omp_build_assign (&gsi, fd->loop.v,
10539                                fold_convert (type, n1));
10540       if (fd->collapse > 1)
10541         {
10542           gsi_prev (&gsi);
10543           expand_omp_for_init_vars (fd, &gsi, counts, NULL, n1);
10544           gsi_next (&gsi);
10545         }
10546     }
10547   else
10548     {
10549       expand_omp_build_assign (&gsi, fd->loop.v,
10550                                fold_convert (type, fd->loop.n1));
10551       if (fd->collapse > 1)
10552         for (i = 0; i < fd->collapse; i++)
10553           {
10554             tree itype = TREE_TYPE (fd->loops[i].v);
10555             if (POINTER_TYPE_P (itype))
10556               itype = signed_type_for (itype);
10557             t = fold_convert (TREE_TYPE (fd->loops[i].v), fd->loops[i].n1);
10558             expand_omp_build_assign (&gsi, fd->loops[i].v, t);
10559           }
10560       }
10561
10562   /* Remove the GIMPLE_OMP_FOR statement.  */
10563   gsi_remove (&gsi, true);
10564
10565   if (!broken_loop)
10566     {
10567       /* Code to control the increment goes in the CONT_BB.  */
10568       gsi = gsi_last_bb (cont_bb);
10569       stmt = gsi_stmt (gsi);
10570       gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
10571
10572       if (POINTER_TYPE_P (type))
10573         t = fold_build_pointer_plus (fd->loop.v, fd->loop.step);
10574       else
10575         t = fold_build2 (PLUS_EXPR, type, fd->loop.v, fd->loop.step);
10576       expand_omp_build_assign (&gsi, fd->loop.v, t);
10577
10578       if (fd->collapse > 1)
10579         {
10580           i = fd->collapse - 1;
10581           if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i].v)))
10582             {
10583               t = fold_convert (sizetype, fd->loops[i].step);
10584               t = fold_build_pointer_plus (fd->loops[i].v, t);
10585             }
10586           else
10587             {
10588               t = fold_convert (TREE_TYPE (fd->loops[i].v),
10589                                 fd->loops[i].step);
10590               t = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->loops[i].v),
10591                                fd->loops[i].v, t);
10592             }
10593           expand_omp_build_assign (&gsi, fd->loops[i].v, t);
10594
10595           for (i = fd->collapse - 1; i > 0; i--)
10596             {
10597               tree itype = TREE_TYPE (fd->loops[i].v);
10598               tree itype2 = TREE_TYPE (fd->loops[i - 1].v);
10599               if (POINTER_TYPE_P (itype2))
10600                 itype2 = signed_type_for (itype2);
10601               t = build3 (COND_EXPR, itype2,
10602                           build2 (fd->loops[i].cond_code, boolean_type_node,
10603                                   fd->loops[i].v,
10604                                   fold_convert (itype, fd->loops[i].n2)),
10605                           build_int_cst (itype2, 0),
10606                           fold_convert (itype2, fd->loops[i - 1].step));
10607               if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i - 1].v)))
10608                 t = fold_build_pointer_plus (fd->loops[i - 1].v, t);
10609               else
10610                 t = fold_build2 (PLUS_EXPR, itype2, fd->loops[i - 1].v, t);
10611               expand_omp_build_assign (&gsi, fd->loops[i - 1].v, t);
10612
10613               t = build3 (COND_EXPR, itype,
10614                           build2 (fd->loops[i].cond_code, boolean_type_node,
10615                                   fd->loops[i].v,
10616                                   fold_convert (itype, fd->loops[i].n2)),
10617                           fd->loops[i].v,
10618                           fold_convert (itype, fd->loops[i].n1));
10619               expand_omp_build_assign (&gsi, fd->loops[i].v, t);
10620             }
10621         }
10622
10623       /* Remove GIMPLE_OMP_CONTINUE.  */
10624       gsi_remove (&gsi, true);
10625     }
10626
10627   /* Emit the condition in L1_BB.  */
10628   gsi = gsi_start_bb (l1_bb);
10629
10630   t = fold_convert (type, n2);
10631   t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
10632                                 false, GSI_CONTINUE_LINKING);
10633   tree v = fd->loop.v;
10634   if (DECL_P (v) && TREE_ADDRESSABLE (v))
10635     v = force_gimple_operand_gsi (&gsi, v, true, NULL_TREE,
10636                                   false, GSI_CONTINUE_LINKING);
10637   t = build2 (fd->loop.cond_code, boolean_type_node, v, t);
10638   cond_stmt = gimple_build_cond_empty (t);
10639   gsi_insert_after (&gsi, cond_stmt, GSI_CONTINUE_LINKING);
10640   if (walk_tree (gimple_cond_lhs_ptr (cond_stmt), expand_omp_regimplify_p,
10641                  NULL, NULL)
10642       || walk_tree (gimple_cond_rhs_ptr (cond_stmt), expand_omp_regimplify_p,
10643                     NULL, NULL))
10644     {
10645       gsi = gsi_for_stmt (cond_stmt);
10646       gimple_regimplify_operands (cond_stmt, &gsi);
10647     }
10648
10649   /* Remove GIMPLE_OMP_RETURN.  */
10650   gsi = gsi_last_bb (exit_bb);
10651   gsi_remove (&gsi, true);
10652
10653   /* Connect the new blocks.  */
10654   remove_edge (FALLTHRU_EDGE (entry_bb));
10655
10656   if (!broken_loop)
10657     {
10658       remove_edge (BRANCH_EDGE (entry_bb));
10659       make_edge (entry_bb, l1_bb, EDGE_FALLTHRU);
10660
10661       e = BRANCH_EDGE (l1_bb);
10662       ne = FALLTHRU_EDGE (l1_bb);
10663       e->flags = EDGE_TRUE_VALUE;
10664     }
10665   else
10666     {
10667       single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
10668
10669       ne = single_succ_edge (l1_bb);
10670       e = make_edge (l1_bb, l0_bb, EDGE_TRUE_VALUE);
10671
10672     }
10673   ne->flags = EDGE_FALSE_VALUE;
10674   e->probability = REG_BR_PROB_BASE * 7 / 8;
10675   ne->probability = REG_BR_PROB_BASE / 8;
10676
10677   set_immediate_dominator (CDI_DOMINATORS, l1_bb, entry_bb);
10678   set_immediate_dominator (CDI_DOMINATORS, l2_bb, l2_dom_bb);
10679   set_immediate_dominator (CDI_DOMINATORS, l0_bb, l1_bb);
10680
10681   if (!broken_loop)
10682     {
10683       struct loop *loop = alloc_loop ();
10684       loop->header = l1_bb;
10685       loop->latch = cont_bb;
10686       add_loop (loop, l1_bb->loop_father);
10687       if (safelen == NULL_TREE)
10688         loop->safelen = INT_MAX;
10689       else
10690         {
10691           safelen = OMP_CLAUSE_SAFELEN_EXPR (safelen);
10692           if (TREE_CODE (safelen) != INTEGER_CST)
10693             loop->safelen = 0;
10694           else if (!tree_fits_uhwi_p (safelen)
10695                    || tree_to_uhwi (safelen) > INT_MAX)
10696             loop->safelen = INT_MAX;
10697           else
10698             loop->safelen = tree_to_uhwi (safelen);
10699           if (loop->safelen == 1)
10700             loop->safelen = 0;
10701         }
10702       if (simduid)
10703         {
10704           loop->simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
10705           cfun->has_simduid_loops = true;
10706         }
10707       /* If not -fno-tree-loop-vectorize, hint that we want to vectorize
10708          the loop.  */
10709       if ((flag_tree_loop_vectorize
10710            || (!global_options_set.x_flag_tree_loop_vectorize
10711                && !global_options_set.x_flag_tree_vectorize))
10712           && flag_tree_loop_optimize
10713           && loop->safelen > 1)
10714         {
10715           loop->force_vectorize = true;
10716           cfun->has_force_vectorize_loops = true;
10717         }
10718     }
10719   else if (simduid)
10720     cfun->has_simduid_loops = true;
10721 }
10722
10723 /* Taskloop construct is represented after gimplification with
10724    two GIMPLE_OMP_FOR constructs with GIMPLE_OMP_TASK sandwiched
10725    in between them.  This routine expands the outer GIMPLE_OMP_FOR,
10726    which should just compute all the needed loop temporaries
10727    for GIMPLE_OMP_TASK.  */
10728
10729 static void
10730 expand_omp_taskloop_for_outer (struct omp_region *region,
10731                                struct omp_for_data *fd,
10732                                gimple *inner_stmt)
10733 {
10734   tree type, bias = NULL_TREE;
10735   basic_block entry_bb, cont_bb, exit_bb;
10736   gimple_stmt_iterator gsi;
10737   gassign *assign_stmt;
10738   tree *counts = NULL;
10739   int i;
10740
10741   gcc_assert (inner_stmt);
10742   gcc_assert (region->cont);
10743   gcc_assert (gimple_code (inner_stmt) == GIMPLE_OMP_TASK
10744               && gimple_omp_task_taskloop_p (inner_stmt));
10745   type = TREE_TYPE (fd->loop.v);
10746
10747   /* See if we need to bias by LLONG_MIN.  */
10748   if (fd->iter_type == long_long_unsigned_type_node
10749       && TREE_CODE (type) == INTEGER_TYPE
10750       && !TYPE_UNSIGNED (type))
10751     {
10752       tree n1, n2;
10753
10754       if (fd->loop.cond_code == LT_EXPR)
10755         {
10756           n1 = fd->loop.n1;
10757           n2 = fold_build2 (PLUS_EXPR, type, fd->loop.n2, fd->loop.step);
10758         }
10759       else
10760         {
10761           n1 = fold_build2 (MINUS_EXPR, type, fd->loop.n2, fd->loop.step);
10762           n2 = fd->loop.n1;
10763         }
10764       if (TREE_CODE (n1) != INTEGER_CST
10765           || TREE_CODE (n2) != INTEGER_CST
10766           || ((tree_int_cst_sgn (n1) < 0) ^ (tree_int_cst_sgn (n2) < 0)))
10767         bias = fold_convert (fd->iter_type, TYPE_MIN_VALUE (type));
10768     }
10769
10770   entry_bb = region->entry;
10771   cont_bb = region->cont;
10772   gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
10773   gcc_assert (BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
10774   exit_bb = region->exit;
10775
10776   gsi = gsi_last_bb (entry_bb);
10777   gimple *for_stmt = gsi_stmt (gsi);
10778   gcc_assert (gimple_code (for_stmt) == GIMPLE_OMP_FOR);
10779   if (fd->collapse > 1)
10780     {
10781       int first_zero_iter = -1, dummy = -1;
10782       basic_block zero_iter_bb = NULL, dummy_bb = NULL, l2_dom_bb = NULL;
10783
10784       counts = XALLOCAVEC (tree, fd->collapse);
10785       expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
10786                                   zero_iter_bb, first_zero_iter,
10787                                   dummy_bb, dummy, l2_dom_bb);
10788
10789       if (zero_iter_bb)
10790         {
10791           /* Some counts[i] vars might be uninitialized if
10792              some loop has zero iterations.  But the body shouldn't
10793              be executed in that case, so just avoid uninit warnings.  */
10794           for (i = first_zero_iter; i < fd->collapse; i++)
10795             if (SSA_VAR_P (counts[i]))
10796               TREE_NO_WARNING (counts[i]) = 1;
10797           gsi_prev (&gsi);
10798           edge e = split_block (entry_bb, gsi_stmt (gsi));
10799           entry_bb = e->dest;
10800           make_edge (zero_iter_bb, entry_bb, EDGE_FALLTHRU);
10801           gsi = gsi_last_bb (entry_bb);
10802           set_immediate_dominator (CDI_DOMINATORS, entry_bb,
10803                                    get_immediate_dominator (CDI_DOMINATORS,
10804                                                             zero_iter_bb));
10805         }
10806     }
10807
10808   tree t0, t1;
10809   t1 = fd->loop.n2;
10810   t0 = fd->loop.n1;
10811   if (POINTER_TYPE_P (TREE_TYPE (t0))
10812       && TYPE_PRECISION (TREE_TYPE (t0))
10813          != TYPE_PRECISION (fd->iter_type))
10814     {
10815       /* Avoid casting pointers to integer of a different size.  */
10816       tree itype = signed_type_for (type);
10817       t1 = fold_convert (fd->iter_type, fold_convert (itype, t1));
10818       t0 = fold_convert (fd->iter_type, fold_convert (itype, t0));
10819     }
10820   else
10821     {
10822       t1 = fold_convert (fd->iter_type, t1);
10823       t0 = fold_convert (fd->iter_type, t0);
10824     }
10825   if (bias)
10826     {
10827       t1 = fold_build2 (PLUS_EXPR, fd->iter_type, t1, bias);
10828       t0 = fold_build2 (PLUS_EXPR, fd->iter_type, t0, bias);
10829     }
10830
10831   tree innerc = find_omp_clause (gimple_omp_task_clauses (inner_stmt),
10832                                  OMP_CLAUSE__LOOPTEMP_);
10833   gcc_assert (innerc);
10834   tree startvar = OMP_CLAUSE_DECL (innerc);
10835   innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc), OMP_CLAUSE__LOOPTEMP_);
10836   gcc_assert (innerc);
10837   tree endvar = OMP_CLAUSE_DECL (innerc);
10838   if (fd->collapse > 1 && TREE_CODE (fd->loop.n2) != INTEGER_CST)
10839     {
10840       gcc_assert (innerc);
10841       for (i = 1; i < fd->collapse; i++)
10842         {
10843           innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
10844                                     OMP_CLAUSE__LOOPTEMP_);
10845           gcc_assert (innerc);
10846         }
10847       innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
10848                                 OMP_CLAUSE__LOOPTEMP_);
10849       if (innerc)
10850         {
10851           /* If needed (inner taskloop has lastprivate clause), propagate
10852              down the total number of iterations.  */
10853           tree t = force_gimple_operand_gsi (&gsi, fd->loop.n2, false,
10854                                              NULL_TREE, false,
10855                                              GSI_CONTINUE_LINKING);
10856           assign_stmt = gimple_build_assign (OMP_CLAUSE_DECL (innerc), t);
10857           gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
10858         }
10859     }
10860
10861   t0 = force_gimple_operand_gsi (&gsi, t0, false, NULL_TREE, false,
10862                                  GSI_CONTINUE_LINKING);
10863   assign_stmt = gimple_build_assign (startvar, t0);
10864   gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
10865
10866   t1 = force_gimple_operand_gsi (&gsi, t1, false, NULL_TREE, false,
10867                                  GSI_CONTINUE_LINKING);
10868   assign_stmt = gimple_build_assign (endvar, t1);
10869   gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
10870   if (fd->collapse > 1)
10871     expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
10872
10873   /* Remove the GIMPLE_OMP_FOR statement.  */
10874   gsi = gsi_for_stmt (for_stmt);
10875   gsi_remove (&gsi, true);
10876
10877   gsi = gsi_last_bb (cont_bb);
10878   gsi_remove (&gsi, true);
10879
10880   gsi = gsi_last_bb (exit_bb);
10881   gsi_remove (&gsi, true);
10882
10883   FALLTHRU_EDGE (entry_bb)->probability = REG_BR_PROB_BASE;
10884   remove_edge (BRANCH_EDGE (entry_bb));
10885   FALLTHRU_EDGE (cont_bb)->probability = REG_BR_PROB_BASE;
10886   remove_edge (BRANCH_EDGE (cont_bb));
10887   set_immediate_dominator (CDI_DOMINATORS, exit_bb, cont_bb);
10888   set_immediate_dominator (CDI_DOMINATORS, region->entry,
10889                            recompute_dominator (CDI_DOMINATORS, region->entry));
10890 }
10891
10892 /* Taskloop construct is represented after gimplification with
10893    two GIMPLE_OMP_FOR constructs with GIMPLE_OMP_TASK sandwiched
10894    in between them.  This routine expands the inner GIMPLE_OMP_FOR.
10895    GOMP_taskloop{,_ull} function arranges for each task to be given just
10896    a single range of iterations.  */
10897
10898 static void
10899 expand_omp_taskloop_for_inner (struct omp_region *region,
10900                                struct omp_for_data *fd,
10901                                gimple *inner_stmt)
10902 {
10903   tree e, t, type, itype, vmain, vback, bias = NULL_TREE;
10904   basic_block entry_bb, exit_bb, body_bb, cont_bb, collapse_bb = NULL;
10905   basic_block fin_bb;
10906   gimple_stmt_iterator gsi;
10907   edge ep;
10908   bool broken_loop = region->cont == NULL;
10909   tree *counts = NULL;
10910   tree n1, n2, step;
10911
10912   itype = type = TREE_TYPE (fd->loop.v);
10913   if (POINTER_TYPE_P (type))
10914     itype = signed_type_for (type);
10915
10916   /* See if we need to bias by LLONG_MIN.  */
10917   if (fd->iter_type == long_long_unsigned_type_node
10918       && TREE_CODE (type) == INTEGER_TYPE
10919       && !TYPE_UNSIGNED (type))
10920     {
10921       tree n1, n2;
10922
10923       if (fd->loop.cond_code == LT_EXPR)
10924         {
10925           n1 = fd->loop.n1;
10926           n2 = fold_build2 (PLUS_EXPR, type, fd->loop.n2, fd->loop.step);
10927         }
10928       else
10929         {
10930           n1 = fold_build2 (MINUS_EXPR, type, fd->loop.n2, fd->loop.step);
10931           n2 = fd->loop.n1;
10932         }
10933       if (TREE_CODE (n1) != INTEGER_CST
10934           || TREE_CODE (n2) != INTEGER_CST
10935           || ((tree_int_cst_sgn (n1) < 0) ^ (tree_int_cst_sgn (n2) < 0)))
10936         bias = fold_convert (fd->iter_type, TYPE_MIN_VALUE (type));
10937     }
10938
10939   entry_bb = region->entry;
10940   cont_bb = region->cont;
10941   gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
10942   fin_bb = BRANCH_EDGE (entry_bb)->dest;
10943   gcc_assert (broken_loop
10944               || (fin_bb == FALLTHRU_EDGE (cont_bb)->dest));
10945   body_bb = FALLTHRU_EDGE (entry_bb)->dest;
10946   if (!broken_loop)
10947     {
10948       gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
10949       gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
10950     }
10951   exit_bb = region->exit;
10952
10953   /* Iteration space partitioning goes in ENTRY_BB.  */
10954   gsi = gsi_last_bb (entry_bb);
10955   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
10956
10957   if (fd->collapse > 1)
10958     {
10959       int first_zero_iter = -1, dummy = -1;
10960       basic_block l2_dom_bb = NULL, dummy_bb = NULL;
10961
10962       counts = XALLOCAVEC (tree, fd->collapse);
10963       expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
10964                                   fin_bb, first_zero_iter,
10965                                   dummy_bb, dummy, l2_dom_bb);
10966       t = NULL_TREE;
10967     }
10968   else
10969     t = integer_one_node;
10970
10971   step = fd->loop.step;
10972   tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
10973                                  OMP_CLAUSE__LOOPTEMP_);
10974   gcc_assert (innerc);
10975   n1 = OMP_CLAUSE_DECL (innerc);
10976   innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc), OMP_CLAUSE__LOOPTEMP_);
10977   gcc_assert (innerc);
10978   n2 = OMP_CLAUSE_DECL (innerc);
10979   if (bias)
10980     {
10981       n1 = fold_build2 (PLUS_EXPR, fd->iter_type, n1, bias);
10982       n2 = fold_build2 (PLUS_EXPR, fd->iter_type, n2, bias);
10983     }
10984   n1 = force_gimple_operand_gsi (&gsi, fold_convert (type, n1),
10985                                  true, NULL_TREE, true, GSI_SAME_STMT);
10986   n2 = force_gimple_operand_gsi (&gsi, fold_convert (itype, n2),
10987                                  true, NULL_TREE, true, GSI_SAME_STMT);
10988   step = force_gimple_operand_gsi (&gsi, fold_convert (itype, step),
10989                                    true, NULL_TREE, true, GSI_SAME_STMT);
10990
10991   tree startvar = fd->loop.v;
10992   tree endvar = NULL_TREE;
10993
10994   if (gimple_omp_for_combined_p (fd->for_stmt))
10995     {
10996       tree clauses = gimple_omp_for_clauses (inner_stmt);
10997       tree innerc = find_omp_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
10998       gcc_assert (innerc);
10999       startvar = OMP_CLAUSE_DECL (innerc);
11000       innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
11001                                 OMP_CLAUSE__LOOPTEMP_);
11002       gcc_assert (innerc);
11003       endvar = OMP_CLAUSE_DECL (innerc);
11004     }
11005   t = fold_convert (TREE_TYPE (startvar), n1);
11006   t = force_gimple_operand_gsi (&gsi, t,
11007                                 DECL_P (startvar)
11008                                 && TREE_ADDRESSABLE (startvar),
11009                                 NULL_TREE, false, GSI_CONTINUE_LINKING);
11010   gimple *assign_stmt = gimple_build_assign (startvar, t);
11011   gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
11012
11013   t = fold_convert (TREE_TYPE (startvar), n2);
11014   e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
11015                                 false, GSI_CONTINUE_LINKING);
11016   if (endvar)
11017     {
11018       assign_stmt = gimple_build_assign (endvar, e);
11019       gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
11020       if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
11021         assign_stmt = gimple_build_assign (fd->loop.v, e);
11022       else
11023         assign_stmt = gimple_build_assign (fd->loop.v, NOP_EXPR, e);
11024       gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
11025     }
11026   if (fd->collapse > 1)
11027     expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
11028
11029   if (!broken_loop)
11030     {
11031       /* The code controlling the sequential loop replaces the
11032          GIMPLE_OMP_CONTINUE.  */
11033       gsi = gsi_last_bb (cont_bb);
11034       gomp_continue *cont_stmt = as_a <gomp_continue *> (gsi_stmt (gsi));
11035       gcc_assert (gimple_code (cont_stmt) == GIMPLE_OMP_CONTINUE);
11036       vmain = gimple_omp_continue_control_use (cont_stmt);
11037       vback = gimple_omp_continue_control_def (cont_stmt);
11038
11039       if (!gimple_omp_for_combined_p (fd->for_stmt))
11040         {
11041           if (POINTER_TYPE_P (type))
11042             t = fold_build_pointer_plus (vmain, step);
11043           else
11044             t = fold_build2 (PLUS_EXPR, type, vmain, step);
11045           t = force_gimple_operand_gsi (&gsi, t,
11046                                         DECL_P (vback)
11047                                         && TREE_ADDRESSABLE (vback),
11048                                         NULL_TREE, true, GSI_SAME_STMT);
11049           assign_stmt = gimple_build_assign (vback, t);
11050           gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
11051
11052           t = build2 (fd->loop.cond_code, boolean_type_node,
11053                       DECL_P (vback) && TREE_ADDRESSABLE (vback)
11054                       ? t : vback, e);
11055           gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
11056         }
11057
11058       /* Remove the GIMPLE_OMP_CONTINUE statement.  */
11059       gsi_remove (&gsi, true);
11060
11061       if (fd->collapse > 1 && !gimple_omp_for_combined_p (fd->for_stmt))
11062         collapse_bb = extract_omp_for_update_vars (fd, cont_bb, body_bb);
11063     }
11064
11065   /* Remove the GIMPLE_OMP_FOR statement.  */
11066   gsi = gsi_for_stmt (fd->for_stmt);
11067   gsi_remove (&gsi, true);
11068
11069   /* Remove the GIMPLE_OMP_RETURN statement.  */
11070   gsi = gsi_last_bb (exit_bb);
11071   gsi_remove (&gsi, true);
11072
11073   FALLTHRU_EDGE (entry_bb)->probability = REG_BR_PROB_BASE;
11074   if (!broken_loop)
11075     remove_edge (BRANCH_EDGE (entry_bb));
11076   else
11077     {
11078       remove_edge_and_dominated_blocks (BRANCH_EDGE (entry_bb));
11079       region->outer->cont = NULL;
11080     }
11081
11082   /* Connect all the blocks.  */
11083   if (!broken_loop)
11084     {
11085       ep = find_edge (cont_bb, body_bb);
11086       if (gimple_omp_for_combined_p (fd->for_stmt))
11087         {
11088           remove_edge (ep);
11089           ep = NULL;
11090         }
11091       else if (fd->collapse > 1)
11092         {
11093           remove_edge (ep);
11094           ep = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
11095         }
11096       else
11097         ep->flags = EDGE_TRUE_VALUE;
11098       find_edge (cont_bb, fin_bb)->flags
11099         = ep ? EDGE_FALSE_VALUE : EDGE_FALLTHRU;
11100     }
11101
11102   set_immediate_dominator (CDI_DOMINATORS, body_bb,
11103                            recompute_dominator (CDI_DOMINATORS, body_bb));
11104   if (!broken_loop)
11105     set_immediate_dominator (CDI_DOMINATORS, fin_bb,
11106                              recompute_dominator (CDI_DOMINATORS, fin_bb));
11107
11108   if (!broken_loop && !gimple_omp_for_combined_p (fd->for_stmt))
11109     {
11110       struct loop *loop = alloc_loop ();
11111       loop->header = body_bb;
11112       if (collapse_bb == NULL)
11113         loop->latch = cont_bb;
11114       add_loop (loop, body_bb->loop_father);
11115     }
11116 }
11117
11118 /* A subroutine of expand_omp_for.  Generate code for an OpenACC
11119    partitioned loop.  The lowering here is abstracted, in that the
11120    loop parameters are passed through internal functions, which are
11121    further lowered by oacc_device_lower, once we get to the target
11122    compiler.  The loop is of the form:
11123
11124    for (V = B; V LTGT E; V += S) {BODY}
11125
11126    where LTGT is < or >.  We may have a specified chunking size, CHUNKING
11127    (constant 0 for no chunking) and we will have a GWV partitioning
11128    mask, specifying dimensions over which the loop is to be
11129    partitioned (see note below).  We generate code that looks like:
11130
11131    <entry_bb> [incoming FALL->body, BRANCH->exit]
11132      typedef signedintify (typeof (V)) T;  // underlying signed integral type
11133      T range = E - B;
11134      T chunk_no = 0;
11135      T DIR = LTGT == '<' ? +1 : -1;
11136      T chunk_max = GOACC_LOOP_CHUNK (dir, range, S, CHUNK_SIZE, GWV);
11137      T step = GOACC_LOOP_STEP (dir, range, S, CHUNK_SIZE, GWV);
11138
11139    <head_bb> [created by splitting end of entry_bb]
11140      T offset = GOACC_LOOP_OFFSET (dir, range, S, CHUNK_SIZE, GWV, chunk_no);
11141      T bound = GOACC_LOOP_BOUND (dir, range, S, CHUNK_SIZE, GWV, offset);
11142      if (!(offset LTGT bound)) goto bottom_bb;
11143
11144    <body_bb> [incoming]
11145      V = B + offset;
11146      {BODY}
11147
11148    <cont_bb> [incoming, may == body_bb FALL->exit_bb, BRANCH->body_bb]
11149      offset += step;
11150      if (offset LTGT bound) goto body_bb; [*]
11151
11152    <bottom_bb> [created by splitting start of exit_bb] insert BRANCH->head_bb
11153      chunk_no++;
11154      if (chunk < chunk_max) goto head_bb;
11155
11156    <exit_bb> [incoming]
11157      V = B + ((range -/+ 1) / S +/- 1) * S [*]
11158
11159    [*] Needed if V live at end of loop
11160
11161    Note: CHUNKING & GWV mask are specified explicitly here.  This is a
11162    transition, and will be specified by a more general mechanism shortly.
11163  */
11164
11165 static void
11166 expand_oacc_for (struct omp_region *region, struct omp_for_data *fd)
11167 {
11168   tree v = fd->loop.v;
11169   enum tree_code cond_code = fd->loop.cond_code;
11170   enum tree_code plus_code = PLUS_EXPR;
11171
11172   tree chunk_size = integer_minus_one_node;
11173   tree gwv = integer_zero_node;
11174   tree iter_type = TREE_TYPE (v);
11175   tree diff_type = iter_type;
11176   tree plus_type = iter_type;
11177   struct oacc_collapse *counts = NULL;
11178
11179   gcc_checking_assert (gimple_omp_for_kind (fd->for_stmt)
11180                        == GF_OMP_FOR_KIND_OACC_LOOP);
11181   gcc_assert (!gimple_omp_for_combined_into_p (fd->for_stmt));
11182   gcc_assert (cond_code == LT_EXPR || cond_code == GT_EXPR);
11183
11184   if (POINTER_TYPE_P (iter_type))
11185     {
11186       plus_code = POINTER_PLUS_EXPR;
11187       plus_type = sizetype;
11188     }
11189   if (POINTER_TYPE_P (diff_type) || TYPE_UNSIGNED (diff_type))
11190     diff_type = signed_type_for (diff_type);
11191
11192   basic_block entry_bb = region->entry; /* BB ending in OMP_FOR */
11193   basic_block exit_bb = region->exit; /* BB ending in OMP_RETURN */
11194   basic_block cont_bb = region->cont; /* BB ending in OMP_CONTINUE  */
11195   basic_block bottom_bb = NULL;
11196
11197   /* entry_bb has two sucessors; the branch edge is to the exit
11198      block,  fallthrough edge to body.  */
11199   gcc_assert (EDGE_COUNT (entry_bb->succs) == 2
11200               && BRANCH_EDGE (entry_bb)->dest == exit_bb);
11201
11202   /* If cont_bb non-NULL, it has 2 successors.  The branch successor is
11203      body_bb, or to a block whose only successor is the body_bb.  Its
11204      fallthrough successor is the final block (same as the branch
11205      successor of the entry_bb).  */
11206   if (cont_bb)
11207     {
11208       basic_block body_bb = FALLTHRU_EDGE (entry_bb)->dest;
11209       basic_block bed = BRANCH_EDGE (cont_bb)->dest;
11210
11211       gcc_assert (FALLTHRU_EDGE (cont_bb)->dest == exit_bb);
11212       gcc_assert (bed == body_bb || single_succ_edge (bed)->dest == body_bb);
11213     }
11214   else
11215     gcc_assert (!gimple_in_ssa_p (cfun));
11216
11217   /* The exit block only has entry_bb and cont_bb as predecessors.  */
11218   gcc_assert (EDGE_COUNT (exit_bb->preds) == 1 + (cont_bb != NULL));
11219
11220   tree chunk_no;
11221   tree chunk_max = NULL_TREE;
11222   tree bound, offset;
11223   tree step = create_tmp_var (diff_type, ".step");
11224   bool up = cond_code == LT_EXPR;
11225   tree dir = build_int_cst (diff_type, up ? +1 : -1);
11226   bool chunking = !gimple_in_ssa_p (cfun);;
11227   bool negating;
11228
11229   /* SSA instances.  */
11230   tree offset_incr = NULL_TREE;
11231   tree offset_init = NULL_TREE;
11232
11233   gimple_stmt_iterator gsi;
11234   gassign *ass;
11235   gcall *call;
11236   gimple *stmt;
11237   tree expr;
11238   location_t loc;
11239   edge split, be, fte;
11240
11241   /* Split the end of entry_bb to create head_bb.  */
11242   split = split_block (entry_bb, last_stmt (entry_bb));
11243   basic_block head_bb = split->dest;
11244   entry_bb = split->src;
11245
11246   /* Chunk setup goes at end of entry_bb, replacing the omp_for.  */
11247   gsi = gsi_last_bb (entry_bb);
11248   gomp_for *for_stmt = as_a <gomp_for *> (gsi_stmt (gsi));
11249   loc = gimple_location (for_stmt);
11250
11251   if (gimple_in_ssa_p (cfun))
11252     {
11253       offset_init = gimple_omp_for_index (for_stmt, 0);
11254       gcc_assert (integer_zerop (fd->loop.n1));
11255       /* The SSA parallelizer does gang parallelism.  */
11256       gwv = build_int_cst (integer_type_node, GOMP_DIM_MASK (GOMP_DIM_GANG));
11257     }
11258
11259   if (fd->collapse > 1)
11260     {
11261       counts = XALLOCAVEC (struct oacc_collapse, fd->collapse);
11262       tree total = expand_oacc_collapse_init (fd, &gsi, counts,
11263                                               TREE_TYPE (fd->loop.n2));
11264
11265       if (SSA_VAR_P (fd->loop.n2))
11266         {
11267           total = force_gimple_operand_gsi (&gsi, total, false, NULL_TREE,
11268                                             true, GSI_SAME_STMT);
11269           ass = gimple_build_assign (fd->loop.n2, total);
11270           gsi_insert_before (&gsi, ass, GSI_SAME_STMT);
11271         }
11272       
11273     }
11274
11275   tree b = fd->loop.n1;
11276   tree e = fd->loop.n2;
11277   tree s = fd->loop.step;
11278
11279   b = force_gimple_operand_gsi (&gsi, b, true, NULL_TREE, true, GSI_SAME_STMT);
11280   e = force_gimple_operand_gsi (&gsi, e, true, NULL_TREE, true, GSI_SAME_STMT);
11281
11282   /* Convert the step, avoiding possible unsigned->signed overflow. */
11283   negating = !up && TYPE_UNSIGNED (TREE_TYPE (s));
11284   if (negating)
11285     s = fold_build1 (NEGATE_EXPR, TREE_TYPE (s), s);
11286   s = fold_convert (diff_type, s);
11287   if (negating)
11288     s = fold_build1 (NEGATE_EXPR, diff_type, s);
11289   s = force_gimple_operand_gsi (&gsi, s, true, NULL_TREE, true, GSI_SAME_STMT);
11290
11291   if (!chunking)
11292     chunk_size = integer_zero_node;
11293   expr = fold_convert (diff_type, chunk_size);
11294   chunk_size = force_gimple_operand_gsi (&gsi, expr, true,
11295                                          NULL_TREE, true, GSI_SAME_STMT);
11296   /* Determine the range, avoiding possible unsigned->signed overflow. */
11297   negating = !up && TYPE_UNSIGNED (iter_type);
11298   expr = fold_build2 (MINUS_EXPR, plus_type,
11299                       fold_convert (plus_type, negating ? b : e),
11300                       fold_convert (plus_type, negating ? e : b));
11301   expr = fold_convert (diff_type, expr);
11302   if (negating)
11303     expr = fold_build1 (NEGATE_EXPR, diff_type, expr);
11304   tree range = force_gimple_operand_gsi (&gsi, expr, true,
11305                                          NULL_TREE, true, GSI_SAME_STMT);
11306
11307   chunk_no = build_int_cst (diff_type, 0);
11308   if (chunking)
11309     {
11310       gcc_assert (!gimple_in_ssa_p (cfun));
11311
11312       expr = chunk_no;
11313       chunk_max = create_tmp_var (diff_type, ".chunk_max");
11314       chunk_no = create_tmp_var (diff_type, ".chunk_no");
11315
11316       ass = gimple_build_assign (chunk_no, expr);
11317       gsi_insert_before (&gsi, ass, GSI_SAME_STMT);
11318
11319       call = gimple_build_call_internal (IFN_GOACC_LOOP, 6,
11320                                          build_int_cst (integer_type_node,
11321                                                         IFN_GOACC_LOOP_CHUNKS),
11322                                          dir, range, s, chunk_size, gwv);
11323       gimple_call_set_lhs (call, chunk_max);
11324       gimple_set_location (call, loc);
11325       gsi_insert_before (&gsi, call, GSI_SAME_STMT);
11326     }
11327   else
11328     chunk_size = chunk_no;
11329
11330   call = gimple_build_call_internal (IFN_GOACC_LOOP, 6,
11331                                      build_int_cst (integer_type_node,
11332                                                     IFN_GOACC_LOOP_STEP),
11333                                      dir, range, s, chunk_size, gwv);
11334   gimple_call_set_lhs (call, step);
11335   gimple_set_location (call, loc);
11336   gsi_insert_before (&gsi, call, GSI_SAME_STMT);
11337
11338   /* Remove the GIMPLE_OMP_FOR.  */
11339   gsi_remove (&gsi, true);
11340
11341   /* Fixup edges from head_bb */
11342   be = BRANCH_EDGE (head_bb);
11343   fte = FALLTHRU_EDGE (head_bb);
11344   be->flags |= EDGE_FALSE_VALUE;
11345   fte->flags ^= EDGE_FALLTHRU | EDGE_TRUE_VALUE;
11346
11347   basic_block body_bb = fte->dest;
11348
11349   if (gimple_in_ssa_p (cfun))
11350     {
11351       gsi = gsi_last_bb (cont_bb);
11352       gomp_continue *cont_stmt = as_a <gomp_continue *> (gsi_stmt (gsi));
11353
11354       offset = gimple_omp_continue_control_use (cont_stmt);
11355       offset_incr = gimple_omp_continue_control_def (cont_stmt);
11356     }
11357   else
11358     {
11359       offset = create_tmp_var (diff_type, ".offset");
11360       offset_init = offset_incr = offset;
11361     }
11362   bound = create_tmp_var (TREE_TYPE (offset), ".bound");
11363
11364   /* Loop offset & bound go into head_bb.  */
11365   gsi = gsi_start_bb (head_bb);
11366
11367   call = gimple_build_call_internal (IFN_GOACC_LOOP, 7,
11368                                      build_int_cst (integer_type_node,
11369                                                     IFN_GOACC_LOOP_OFFSET),
11370                                      dir, range, s,
11371                                      chunk_size, gwv, chunk_no);
11372   gimple_call_set_lhs (call, offset_init);
11373   gimple_set_location (call, loc);
11374   gsi_insert_after (&gsi, call, GSI_CONTINUE_LINKING);
11375
11376   call = gimple_build_call_internal (IFN_GOACC_LOOP, 7,
11377                                      build_int_cst (integer_type_node,
11378                                                     IFN_GOACC_LOOP_BOUND),
11379                                      dir, range, s,
11380                                      chunk_size, gwv, offset_init);
11381   gimple_call_set_lhs (call, bound);
11382   gimple_set_location (call, loc);
11383   gsi_insert_after (&gsi, call, GSI_CONTINUE_LINKING);
11384
11385   expr = build2 (cond_code, boolean_type_node, offset_init, bound);
11386   gsi_insert_after (&gsi, gimple_build_cond_empty (expr),
11387                     GSI_CONTINUE_LINKING);
11388
11389   /* V assignment goes into body_bb.  */
11390   if (!gimple_in_ssa_p (cfun))
11391     {
11392       gsi = gsi_start_bb (body_bb);
11393
11394       expr = build2 (plus_code, iter_type, b,
11395                      fold_convert (plus_type, offset));
11396       expr = force_gimple_operand_gsi (&gsi, expr, false, NULL_TREE,
11397                                        true, GSI_SAME_STMT);
11398       ass = gimple_build_assign (v, expr);
11399       gsi_insert_before (&gsi, ass, GSI_SAME_STMT);
11400       if (fd->collapse > 1)
11401         expand_oacc_collapse_vars (fd, &gsi, counts, v);
11402     }
11403
11404   /* Loop increment goes into cont_bb.  If this is not a loop, we
11405      will have spawned threads as if it was, and each one will
11406      execute one iteration.  The specification is not explicit about
11407      whether such constructs are ill-formed or not, and they can
11408      occur, especially when noreturn routines are involved.  */
11409   if (cont_bb)
11410     {
11411       gsi = gsi_last_bb (cont_bb);
11412       gomp_continue *cont_stmt = as_a <gomp_continue *> (gsi_stmt (gsi));
11413       loc = gimple_location (cont_stmt);
11414
11415       /* Increment offset.  */
11416       if (gimple_in_ssa_p (cfun))
11417         expr= build2 (plus_code, iter_type, offset,
11418                       fold_convert (plus_type, step));
11419       else
11420         expr = build2 (PLUS_EXPR, diff_type, offset, step);
11421       expr = force_gimple_operand_gsi (&gsi, expr, false, NULL_TREE,
11422                                        true, GSI_SAME_STMT);
11423       ass = gimple_build_assign (offset_incr, expr);
11424       gsi_insert_before (&gsi, ass, GSI_SAME_STMT);
11425       expr = build2 (cond_code, boolean_type_node, offset_incr, bound);
11426       gsi_insert_before (&gsi, gimple_build_cond_empty (expr), GSI_SAME_STMT);
11427
11428       /*  Remove the GIMPLE_OMP_CONTINUE.  */
11429       gsi_remove (&gsi, true);
11430
11431       /* Fixup edges from cont_bb */
11432       be = BRANCH_EDGE (cont_bb);
11433       fte = FALLTHRU_EDGE (cont_bb);
11434       be->flags |= EDGE_TRUE_VALUE;
11435       fte->flags ^= EDGE_FALLTHRU | EDGE_FALSE_VALUE;
11436
11437       if (chunking)
11438         {
11439           /* Split the beginning of exit_bb to make bottom_bb.  We
11440              need to insert a nop at the start, because splitting is
11441              after a stmt, not before.  */
11442           gsi = gsi_start_bb (exit_bb);
11443           stmt = gimple_build_nop ();
11444           gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
11445           split = split_block (exit_bb, stmt);
11446           bottom_bb = split->src;
11447           exit_bb = split->dest;
11448           gsi = gsi_last_bb (bottom_bb);
11449
11450           /* Chunk increment and test goes into bottom_bb.  */
11451           expr = build2 (PLUS_EXPR, diff_type, chunk_no,
11452                          build_int_cst (diff_type, 1));
11453           ass = gimple_build_assign (chunk_no, expr);
11454           gsi_insert_after (&gsi, ass, GSI_CONTINUE_LINKING);
11455
11456           /* Chunk test at end of bottom_bb.  */
11457           expr = build2 (LT_EXPR, boolean_type_node, chunk_no, chunk_max);
11458           gsi_insert_after (&gsi, gimple_build_cond_empty (expr),
11459                             GSI_CONTINUE_LINKING);
11460
11461           /* Fixup edges from bottom_bb. */
11462           split->flags ^= EDGE_FALLTHRU | EDGE_FALSE_VALUE;
11463           make_edge (bottom_bb, head_bb, EDGE_TRUE_VALUE);
11464         }
11465     }
11466
11467   gsi = gsi_last_bb (exit_bb);
11468   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
11469   loc = gimple_location (gsi_stmt (gsi));
11470
11471   if (!gimple_in_ssa_p (cfun))
11472     {
11473       /* Insert the final value of V, in case it is live.  This is the
11474          value for the only thread that survives past the join.  */
11475       expr = fold_build2 (MINUS_EXPR, diff_type, range, dir);
11476       expr = fold_build2 (PLUS_EXPR, diff_type, expr, s);
11477       expr = fold_build2 (TRUNC_DIV_EXPR, diff_type, expr, s);
11478       expr = fold_build2 (MULT_EXPR, diff_type, expr, s);
11479       expr = build2 (plus_code, iter_type, b, fold_convert (plus_type, expr));
11480       expr = force_gimple_operand_gsi (&gsi, expr, false, NULL_TREE,
11481                                        true, GSI_SAME_STMT);
11482       ass = gimple_build_assign (v, expr);
11483       gsi_insert_before (&gsi, ass, GSI_SAME_STMT);
11484     }
11485
11486   /* Remove the OMP_RETURN. */
11487   gsi_remove (&gsi, true);
11488
11489   if (cont_bb)
11490     {
11491       /* We now have one or two nested loops.  Update the loop
11492          structures.  */
11493       struct loop *parent = entry_bb->loop_father;
11494       struct loop *body = body_bb->loop_father;
11495       
11496       if (chunking)
11497         {
11498           struct loop *chunk_loop = alloc_loop ();
11499           chunk_loop->header = head_bb;
11500           chunk_loop->latch = bottom_bb;
11501           add_loop (chunk_loop, parent);
11502           parent = chunk_loop;
11503         }
11504       else if (parent != body)
11505         {
11506           gcc_assert (body->header == body_bb);
11507           gcc_assert (body->latch == cont_bb
11508                       || single_pred (body->latch) == cont_bb);
11509           parent = NULL;
11510         }
11511
11512       if (parent)
11513         {
11514           struct loop *body_loop = alloc_loop ();
11515           body_loop->header = body_bb;
11516           body_loop->latch = cont_bb;
11517           add_loop (body_loop, parent);
11518         }
11519     }
11520 }
11521
11522 /* Expand the OMP loop defined by REGION.  */
11523
11524 static void
11525 expand_omp_for (struct omp_region *region, gimple *inner_stmt)
11526 {
11527   struct omp_for_data fd;
11528   struct omp_for_data_loop *loops;
11529
11530   loops
11531     = (struct omp_for_data_loop *)
11532       alloca (gimple_omp_for_collapse (last_stmt (region->entry))
11533               * sizeof (struct omp_for_data_loop));
11534   extract_omp_for_data (as_a <gomp_for *> (last_stmt (region->entry)),
11535                         &fd, loops);
11536   region->sched_kind = fd.sched_kind;
11537   region->sched_modifiers = fd.sched_modifiers;
11538
11539   gcc_assert (EDGE_COUNT (region->entry->succs) == 2);
11540   BRANCH_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
11541   FALLTHRU_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
11542   if (region->cont)
11543     {
11544       gcc_assert (EDGE_COUNT (region->cont->succs) == 2);
11545       BRANCH_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
11546       FALLTHRU_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
11547     }
11548   else
11549     /* If there isn't a continue then this is a degerate case where
11550        the introduction of abnormal edges during lowering will prevent
11551        original loops from being detected.  Fix that up.  */
11552     loops_state_set (LOOPS_NEED_FIXUP);
11553
11554   if (gimple_omp_for_kind (fd.for_stmt) & GF_OMP_FOR_SIMD)
11555     expand_omp_simd (region, &fd);
11556   else if (gimple_omp_for_kind (fd.for_stmt) == GF_OMP_FOR_KIND_CILKFOR)
11557     expand_cilk_for (region, &fd);
11558   else if (gimple_omp_for_kind (fd.for_stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
11559     {
11560       gcc_assert (!inner_stmt);
11561       expand_oacc_for (region, &fd);
11562     }
11563   else if (gimple_omp_for_kind (fd.for_stmt) == GF_OMP_FOR_KIND_TASKLOOP)
11564     {
11565       if (gimple_omp_for_combined_into_p (fd.for_stmt))
11566         expand_omp_taskloop_for_inner (region, &fd, inner_stmt);
11567       else
11568         expand_omp_taskloop_for_outer (region, &fd, inner_stmt);
11569     }
11570   else if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
11571            && !fd.have_ordered)
11572     {
11573       if (fd.chunk_size == NULL)
11574         expand_omp_for_static_nochunk (region, &fd, inner_stmt);
11575       else
11576         expand_omp_for_static_chunk (region, &fd, inner_stmt);
11577     }
11578   else
11579     {
11580       int fn_index, start_ix, next_ix;
11581
11582       gcc_assert (gimple_omp_for_kind (fd.for_stmt)
11583                   == GF_OMP_FOR_KIND_FOR);
11584       if (fd.chunk_size == NULL
11585           && fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
11586         fd.chunk_size = integer_zero_node;
11587       gcc_assert (fd.sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
11588       switch (fd.sched_kind)
11589         {
11590         case OMP_CLAUSE_SCHEDULE_RUNTIME:
11591           fn_index = 3;
11592           break;
11593         case OMP_CLAUSE_SCHEDULE_DYNAMIC:
11594         case OMP_CLAUSE_SCHEDULE_GUIDED:
11595           if ((fd.sched_modifiers & OMP_CLAUSE_SCHEDULE_NONMONOTONIC)
11596               && !fd.ordered
11597               && !fd.have_ordered)
11598             {
11599               fn_index = 3 + fd.sched_kind;
11600               break;
11601             }
11602           /* FALLTHRU */
11603         default:
11604           fn_index = fd.sched_kind;
11605           break;
11606         }
11607       if (!fd.ordered)
11608         fn_index += fd.have_ordered * 6;
11609       if (fd.ordered)
11610         start_ix = ((int)BUILT_IN_GOMP_LOOP_DOACROSS_STATIC_START) + fn_index;
11611       else
11612         start_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_START) + fn_index;
11613       next_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_NEXT) + fn_index;
11614       if (fd.iter_type == long_long_unsigned_type_node)
11615         {
11616           start_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_START
11617                         - (int)BUILT_IN_GOMP_LOOP_STATIC_START);
11618           next_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT
11619                       - (int)BUILT_IN_GOMP_LOOP_STATIC_NEXT);
11620         }
11621       expand_omp_for_generic (region, &fd, (enum built_in_function) start_ix,
11622                               (enum built_in_function) next_ix, inner_stmt);
11623     }
11624
11625   if (gimple_in_ssa_p (cfun))
11626     update_ssa (TODO_update_ssa_only_virtuals);
11627 }
11628
11629
11630 /* Expand code for an OpenMP sections directive.  In pseudo code, we generate
11631
11632         v = GOMP_sections_start (n);
11633     L0:
11634         switch (v)
11635           {
11636           case 0:
11637             goto L2;
11638           case 1:
11639             section 1;
11640             goto L1;
11641           case 2:
11642             ...
11643           case n:
11644             ...
11645           default:
11646             abort ();
11647           }
11648     L1:
11649         v = GOMP_sections_next ();
11650         goto L0;
11651     L2:
11652         reduction;
11653
11654     If this is a combined parallel sections, replace the call to
11655     GOMP_sections_start with call to GOMP_sections_next.  */
11656
11657 static void
11658 expand_omp_sections (struct omp_region *region)
11659 {
11660   tree t, u, vin = NULL, vmain, vnext, l2;
11661   unsigned len;
11662   basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
11663   gimple_stmt_iterator si, switch_si;
11664   gomp_sections *sections_stmt;
11665   gimple *stmt;
11666   gomp_continue *cont;
11667   edge_iterator ei;
11668   edge e;
11669   struct omp_region *inner;
11670   unsigned i, casei;
11671   bool exit_reachable = region->cont != NULL;
11672
11673   gcc_assert (region->exit != NULL);
11674   entry_bb = region->entry;
11675   l0_bb = single_succ (entry_bb);
11676   l1_bb = region->cont;
11677   l2_bb = region->exit;
11678   if (single_pred_p (l2_bb) && single_pred (l2_bb) == l0_bb)
11679     l2 = gimple_block_label (l2_bb);
11680   else
11681     {
11682       /* This can happen if there are reductions.  */
11683       len = EDGE_COUNT (l0_bb->succs);
11684       gcc_assert (len > 0);
11685       e = EDGE_SUCC (l0_bb, len - 1);
11686       si = gsi_last_bb (e->dest);
11687       l2 = NULL_TREE;
11688       if (gsi_end_p (si)
11689           || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
11690         l2 = gimple_block_label (e->dest);
11691       else
11692         FOR_EACH_EDGE (e, ei, l0_bb->succs)
11693           {
11694             si = gsi_last_bb (e->dest);
11695             if (gsi_end_p (si)
11696                 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
11697               {
11698                 l2 = gimple_block_label (e->dest);
11699                 break;
11700               }
11701           }
11702     }
11703   if (exit_reachable)
11704     default_bb = create_empty_bb (l1_bb->prev_bb);
11705   else
11706     default_bb = create_empty_bb (l0_bb);
11707
11708   /* We will build a switch() with enough cases for all the
11709      GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
11710      and a default case to abort if something goes wrong.  */
11711   len = EDGE_COUNT (l0_bb->succs);
11712
11713   /* Use vec::quick_push on label_vec throughout, since we know the size
11714      in advance.  */
11715   auto_vec<tree> label_vec (len);
11716
11717   /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
11718      GIMPLE_OMP_SECTIONS statement.  */
11719   si = gsi_last_bb (entry_bb);
11720   sections_stmt = as_a <gomp_sections *> (gsi_stmt (si));
11721   gcc_assert (gimple_code (sections_stmt) == GIMPLE_OMP_SECTIONS);
11722   vin = gimple_omp_sections_control (sections_stmt);
11723   if (!is_combined_parallel (region))
11724     {
11725       /* If we are not inside a combined parallel+sections region,
11726          call GOMP_sections_start.  */
11727       t = build_int_cst (unsigned_type_node, len - 1);
11728       u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START);
11729       stmt = gimple_build_call (u, 1, t);
11730     }
11731   else
11732     {
11733       /* Otherwise, call GOMP_sections_next.  */
11734       u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
11735       stmt = gimple_build_call (u, 0);
11736     }
11737   gimple_call_set_lhs (stmt, vin);
11738   gsi_insert_after (&si, stmt, GSI_SAME_STMT);
11739   gsi_remove (&si, true);
11740
11741   /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
11742      L0_BB.  */
11743   switch_si = gsi_last_bb (l0_bb);
11744   gcc_assert (gimple_code (gsi_stmt (switch_si)) == GIMPLE_OMP_SECTIONS_SWITCH);
11745   if (exit_reachable)
11746     {
11747       cont = as_a <gomp_continue *> (last_stmt (l1_bb));
11748       gcc_assert (gimple_code (cont) == GIMPLE_OMP_CONTINUE);
11749       vmain = gimple_omp_continue_control_use (cont);
11750       vnext = gimple_omp_continue_control_def (cont);
11751     }
11752   else
11753     {
11754       vmain = vin;
11755       vnext = NULL_TREE;
11756     }
11757
11758   t = build_case_label (build_int_cst (unsigned_type_node, 0), NULL, l2);
11759   label_vec.quick_push (t);
11760   i = 1;
11761
11762   /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR.  */
11763   for (inner = region->inner, casei = 1;
11764        inner;
11765        inner = inner->next, i++, casei++)
11766     {
11767       basic_block s_entry_bb, s_exit_bb;
11768
11769       /* Skip optional reduction region.  */
11770       if (inner->type == GIMPLE_OMP_ATOMIC_LOAD)
11771         {
11772           --i;
11773           --casei;
11774           continue;
11775         }
11776
11777       s_entry_bb = inner->entry;
11778       s_exit_bb = inner->exit;
11779
11780       t = gimple_block_label (s_entry_bb);
11781       u = build_int_cst (unsigned_type_node, casei);
11782       u = build_case_label (u, NULL, t);
11783       label_vec.quick_push (u);
11784
11785       si = gsi_last_bb (s_entry_bb);
11786       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SECTION);
11787       gcc_assert (i < len || gimple_omp_section_last_p (gsi_stmt (si)));
11788       gsi_remove (&si, true);
11789       single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
11790
11791       if (s_exit_bb == NULL)
11792         continue;
11793
11794       si = gsi_last_bb (s_exit_bb);
11795       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
11796       gsi_remove (&si, true);
11797
11798       single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
11799     }
11800
11801   /* Error handling code goes in DEFAULT_BB.  */
11802   t = gimple_block_label (default_bb);
11803   u = build_case_label (NULL, NULL, t);
11804   make_edge (l0_bb, default_bb, 0);
11805   add_bb_to_loop (default_bb, current_loops->tree_root);
11806
11807   stmt = gimple_build_switch (vmain, u, label_vec);
11808   gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
11809   gsi_remove (&switch_si, true);
11810
11811   si = gsi_start_bb (default_bb);
11812   stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
11813   gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
11814
11815   if (exit_reachable)
11816     {
11817       tree bfn_decl;
11818
11819       /* Code to get the next section goes in L1_BB.  */
11820       si = gsi_last_bb (l1_bb);
11821       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CONTINUE);
11822
11823       bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
11824       stmt = gimple_build_call (bfn_decl, 0);
11825       gimple_call_set_lhs (stmt, vnext);
11826       gsi_insert_after (&si, stmt, GSI_SAME_STMT);
11827       gsi_remove (&si, true);
11828
11829       single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
11830     }
11831
11832   /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB.  */
11833   si = gsi_last_bb (l2_bb);
11834   if (gimple_omp_return_nowait_p (gsi_stmt (si)))
11835     t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT);
11836   else if (gimple_omp_return_lhs (gsi_stmt (si)))
11837     t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_CANCEL);
11838   else
11839     t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END);
11840   stmt = gimple_build_call (t, 0);
11841   if (gimple_omp_return_lhs (gsi_stmt (si)))
11842     gimple_call_set_lhs (stmt, gimple_omp_return_lhs (gsi_stmt (si)));
11843   gsi_insert_after (&si, stmt, GSI_SAME_STMT);
11844   gsi_remove (&si, true);
11845
11846   set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb);
11847 }
11848
11849
11850 /* Expand code for an OpenMP single directive.  We've already expanded
11851    much of the code, here we simply place the GOMP_barrier call.  */
11852
11853 static void
11854 expand_omp_single (struct omp_region *region)
11855 {
11856   basic_block entry_bb, exit_bb;
11857   gimple_stmt_iterator si;
11858
11859   entry_bb = region->entry;
11860   exit_bb = region->exit;
11861
11862   si = gsi_last_bb (entry_bb);
11863   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE);
11864   gsi_remove (&si, true);
11865   single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
11866
11867   si = gsi_last_bb (exit_bb);
11868   if (!gimple_omp_return_nowait_p (gsi_stmt (si)))
11869     {
11870       tree t = gimple_omp_return_lhs (gsi_stmt (si));
11871       gsi_insert_after (&si, build_omp_barrier (t), GSI_SAME_STMT);
11872     }
11873   gsi_remove (&si, true);
11874   single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
11875 }
11876
11877
11878 /* Generic expansion for OpenMP synchronization directives: master,
11879    ordered and critical.  All we need to do here is remove the entry
11880    and exit markers for REGION.  */
11881
11882 static void
11883 expand_omp_synch (struct omp_region *region)
11884 {
11885   basic_block entry_bb, exit_bb;
11886   gimple_stmt_iterator si;
11887
11888   entry_bb = region->entry;
11889   exit_bb = region->exit;
11890
11891   si = gsi_last_bb (entry_bb);
11892   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE
11893               || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASTER
11894               || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_TASKGROUP
11895               || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ORDERED
11896               || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CRITICAL
11897               || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_TEAMS);
11898   gsi_remove (&si, true);
11899   single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
11900
11901   if (exit_bb)
11902     {
11903       si = gsi_last_bb (exit_bb);
11904       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
11905       gsi_remove (&si, true);
11906       single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
11907     }
11908 }
11909
11910 /* A subroutine of expand_omp_atomic.  Attempt to implement the atomic
11911    operation as a normal volatile load.  */
11912
11913 static bool
11914 expand_omp_atomic_load (basic_block load_bb, tree addr,
11915                         tree loaded_val, int index)
11916 {
11917   enum built_in_function tmpbase;
11918   gimple_stmt_iterator gsi;
11919   basic_block store_bb;
11920   location_t loc;
11921   gimple *stmt;
11922   tree decl, call, type, itype;
11923
11924   gsi = gsi_last_bb (load_bb);
11925   stmt = gsi_stmt (gsi);
11926   gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
11927   loc = gimple_location (stmt);
11928
11929   /* ??? If the target does not implement atomic_load_optab[mode], and mode
11930      is smaller than word size, then expand_atomic_load assumes that the load
11931      is atomic.  We could avoid the builtin entirely in this case.  */
11932
11933   tmpbase = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
11934   decl = builtin_decl_explicit (tmpbase);
11935   if (decl == NULL_TREE)
11936     return false;
11937
11938   type = TREE_TYPE (loaded_val);
11939   itype = TREE_TYPE (TREE_TYPE (decl));
11940
11941   call = build_call_expr_loc (loc, decl, 2, addr,
11942                               build_int_cst (NULL,
11943                                              gimple_omp_atomic_seq_cst_p (stmt)
11944                                              ? MEMMODEL_SEQ_CST
11945                                              : MEMMODEL_RELAXED));
11946   if (!useless_type_conversion_p (type, itype))
11947     call = fold_build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
11948   call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
11949
11950   force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
11951   gsi_remove (&gsi, true);
11952
11953   store_bb = single_succ (load_bb);
11954   gsi = gsi_last_bb (store_bb);
11955   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
11956   gsi_remove (&gsi, true);
11957
11958   if (gimple_in_ssa_p (cfun))
11959     update_ssa (TODO_update_ssa_no_phi);
11960
11961   return true;
11962 }
11963
11964 /* A subroutine of expand_omp_atomic.  Attempt to implement the atomic
11965    operation as a normal volatile store.  */
11966
11967 static bool
11968 expand_omp_atomic_store (basic_block load_bb, tree addr,
11969                          tree loaded_val, tree stored_val, int index)
11970 {
11971   enum built_in_function tmpbase;
11972   gimple_stmt_iterator gsi;
11973   basic_block store_bb = single_succ (load_bb);
11974   location_t loc;
11975   gimple *stmt;
11976   tree decl, call, type, itype;
11977   machine_mode imode;
11978   bool exchange;
11979
11980   gsi = gsi_last_bb (load_bb);
11981   stmt = gsi_stmt (gsi);
11982   gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
11983
11984   /* If the load value is needed, then this isn't a store but an exchange.  */
11985   exchange = gimple_omp_atomic_need_value_p (stmt);
11986
11987   gsi = gsi_last_bb (store_bb);
11988   stmt = gsi_stmt (gsi);
11989   gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE);
11990   loc = gimple_location (stmt);
11991
11992   /* ??? If the target does not implement atomic_store_optab[mode], and mode
11993      is smaller than word size, then expand_atomic_store assumes that the store
11994      is atomic.  We could avoid the builtin entirely in this case.  */
11995
11996   tmpbase = (exchange ? BUILT_IN_ATOMIC_EXCHANGE_N : BUILT_IN_ATOMIC_STORE_N);
11997   tmpbase = (enum built_in_function) ((int) tmpbase + index + 1);
11998   decl = builtin_decl_explicit (tmpbase);
11999   if (decl == NULL_TREE)
12000     return false;
12001
12002   type = TREE_TYPE (stored_val);
12003
12004   /* Dig out the type of the function's second argument.  */
12005   itype = TREE_TYPE (decl);
12006   itype = TYPE_ARG_TYPES (itype);
12007   itype = TREE_CHAIN (itype);
12008   itype = TREE_VALUE (itype);
12009   imode = TYPE_MODE (itype);
12010
12011   if (exchange && !can_atomic_exchange_p (imode, true))
12012     return false;
12013
12014   if (!useless_type_conversion_p (itype, type))
12015     stored_val = fold_build1_loc (loc, VIEW_CONVERT_EXPR, itype, stored_val);
12016   call = build_call_expr_loc (loc, decl, 3, addr, stored_val,
12017                               build_int_cst (NULL,
12018                                              gimple_omp_atomic_seq_cst_p (stmt)
12019                                              ? MEMMODEL_SEQ_CST
12020                                              : MEMMODEL_RELAXED));
12021   if (exchange)
12022     {
12023       if (!useless_type_conversion_p (type, itype))
12024         call = build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
12025       call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
12026     }
12027
12028   force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
12029   gsi_remove (&gsi, true);
12030
12031   /* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above.  */
12032   gsi = gsi_last_bb (load_bb);
12033   gsi_remove (&gsi, true);
12034
12035   if (gimple_in_ssa_p (cfun))
12036     update_ssa (TODO_update_ssa_no_phi);
12037
12038   return true;
12039 }
12040
12041 /* A subroutine of expand_omp_atomic.  Attempt to implement the atomic
12042    operation as a __atomic_fetch_op builtin.  INDEX is log2 of the
12043    size of the data type, and thus usable to find the index of the builtin
12044    decl.  Returns false if the expression is not of the proper form.  */
12045
12046 static bool
12047 expand_omp_atomic_fetch_op (basic_block load_bb,
12048                             tree addr, tree loaded_val,
12049                             tree stored_val, int index)
12050 {
12051   enum built_in_function oldbase, newbase, tmpbase;
12052   tree decl, itype, call;
12053   tree lhs, rhs;
12054   basic_block store_bb = single_succ (load_bb);
12055   gimple_stmt_iterator gsi;
12056   gimple *stmt;
12057   location_t loc;
12058   enum tree_code code;
12059   bool need_old, need_new;
12060   machine_mode imode;
12061   bool seq_cst;
12062
12063   /* We expect to find the following sequences:
12064
12065    load_bb:
12066        GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
12067
12068    store_bb:
12069        val = tmp OP something; (or: something OP tmp)
12070        GIMPLE_OMP_STORE (val)
12071
12072   ???FIXME: Allow a more flexible sequence.
12073   Perhaps use data flow to pick the statements.
12074
12075   */
12076
12077   gsi = gsi_after_labels (store_bb);
12078   stmt = gsi_stmt (gsi);
12079   loc = gimple_location (stmt);
12080   if (!is_gimple_assign (stmt))
12081     return false;
12082   gsi_next (&gsi);
12083   if (gimple_code (gsi_stmt (gsi)) != GIMPLE_OMP_ATOMIC_STORE)
12084     return false;
12085   need_new = gimple_omp_atomic_need_value_p (gsi_stmt (gsi));
12086   need_old = gimple_omp_atomic_need_value_p (last_stmt (load_bb));
12087   seq_cst = gimple_omp_atomic_seq_cst_p (last_stmt (load_bb));
12088   gcc_checking_assert (!need_old || !need_new);
12089
12090   if (!operand_equal_p (gimple_assign_lhs (stmt), stored_val, 0))
12091     return false;
12092
12093   /* Check for one of the supported fetch-op operations.  */
12094   code = gimple_assign_rhs_code (stmt);
12095   switch (code)
12096     {
12097     case PLUS_EXPR:
12098     case POINTER_PLUS_EXPR:
12099       oldbase = BUILT_IN_ATOMIC_FETCH_ADD_N;
12100       newbase = BUILT_IN_ATOMIC_ADD_FETCH_N;
12101       break;
12102     case MINUS_EXPR:
12103       oldbase = BUILT_IN_ATOMIC_FETCH_SUB_N;
12104       newbase = BUILT_IN_ATOMIC_SUB_FETCH_N;
12105       break;
12106     case BIT_AND_EXPR:
12107       oldbase = BUILT_IN_ATOMIC_FETCH_AND_N;
12108       newbase = BUILT_IN_ATOMIC_AND_FETCH_N;
12109       break;
12110     case BIT_IOR_EXPR:
12111       oldbase = BUILT_IN_ATOMIC_FETCH_OR_N;
12112       newbase = BUILT_IN_ATOMIC_OR_FETCH_N;
12113       break;
12114     case BIT_XOR_EXPR:
12115       oldbase = BUILT_IN_ATOMIC_FETCH_XOR_N;
12116       newbase = BUILT_IN_ATOMIC_XOR_FETCH_N;
12117       break;
12118     default:
12119       return false;
12120     }
12121
12122   /* Make sure the expression is of the proper form.  */
12123   if (operand_equal_p (gimple_assign_rhs1 (stmt), loaded_val, 0))
12124     rhs = gimple_assign_rhs2 (stmt);
12125   else if (commutative_tree_code (gimple_assign_rhs_code (stmt))
12126            && operand_equal_p (gimple_assign_rhs2 (stmt), loaded_val, 0))
12127     rhs = gimple_assign_rhs1 (stmt);
12128   else
12129     return false;
12130
12131   tmpbase = ((enum built_in_function)
12132              ((need_new ? newbase : oldbase) + index + 1));
12133   decl = builtin_decl_explicit (tmpbase);
12134   if (decl == NULL_TREE)
12135     return false;
12136   itype = TREE_TYPE (TREE_TYPE (decl));
12137   imode = TYPE_MODE (itype);
12138
12139   /* We could test all of the various optabs involved, but the fact of the
12140      matter is that (with the exception of i486 vs i586 and xadd) all targets
12141      that support any atomic operaton optab also implements compare-and-swap.
12142      Let optabs.c take care of expanding any compare-and-swap loop.  */
12143   if (!can_compare_and_swap_p (imode, true))
12144     return false;
12145
12146   gsi = gsi_last_bb (load_bb);
12147   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_LOAD);
12148
12149   /* OpenMP does not imply any barrier-like semantics on its atomic ops.
12150      It only requires that the operation happen atomically.  Thus we can
12151      use the RELAXED memory model.  */
12152   call = build_call_expr_loc (loc, decl, 3, addr,
12153                               fold_convert_loc (loc, itype, rhs),
12154                               build_int_cst (NULL,
12155                                              seq_cst ? MEMMODEL_SEQ_CST
12156                                                      : MEMMODEL_RELAXED));
12157
12158   if (need_old || need_new)
12159     {
12160       lhs = need_old ? loaded_val : stored_val;
12161       call = fold_convert_loc (loc, TREE_TYPE (lhs), call);
12162       call = build2_loc (loc, MODIFY_EXPR, void_type_node, lhs, call);
12163     }
12164   else
12165     call = fold_convert_loc (loc, void_type_node, call);
12166   force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
12167   gsi_remove (&gsi, true);
12168
12169   gsi = gsi_last_bb (store_bb);
12170   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
12171   gsi_remove (&gsi, true);
12172   gsi = gsi_last_bb (store_bb);
12173   stmt = gsi_stmt (gsi);
12174   gsi_remove (&gsi, true);
12175
12176   if (gimple_in_ssa_p (cfun))
12177     {
12178       release_defs (stmt);
12179       update_ssa (TODO_update_ssa_no_phi);
12180     }
12181
12182   return true;
12183 }
12184
12185 /* A subroutine of expand_omp_atomic.  Implement the atomic operation as:
12186
12187       oldval = *addr;
12188       repeat:
12189         newval = rhs;    // with oldval replacing *addr in rhs
12190         oldval = __sync_val_compare_and_swap (addr, oldval, newval);
12191         if (oldval != newval)
12192           goto repeat;
12193
12194    INDEX is log2 of the size of the data type, and thus usable to find the
12195    index of the builtin decl.  */
12196
12197 static bool
12198 expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
12199                             tree addr, tree loaded_val, tree stored_val,
12200                             int index)
12201 {
12202   tree loadedi, storedi, initial, new_storedi, old_vali;
12203   tree type, itype, cmpxchg, iaddr;
12204   gimple_stmt_iterator si;
12205   basic_block loop_header = single_succ (load_bb);
12206   gimple *phi, *stmt;
12207   edge e;
12208   enum built_in_function fncode;
12209
12210   /* ??? We need a non-pointer interface to __atomic_compare_exchange in
12211      order to use the RELAXED memory model effectively.  */
12212   fncode = (enum built_in_function)((int)BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
12213                                     + index + 1);
12214   cmpxchg = builtin_decl_explicit (fncode);
12215   if (cmpxchg == NULL_TREE)
12216     return false;
12217   type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
12218   itype = TREE_TYPE (TREE_TYPE (cmpxchg));
12219
12220   if (!can_compare_and_swap_p (TYPE_MODE (itype), true))
12221     return false;
12222
12223   /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD.  */
12224   si = gsi_last_bb (load_bb);
12225   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
12226
12227   /* For floating-point values, we'll need to view-convert them to integers
12228      so that we can perform the atomic compare and swap.  Simplify the
12229      following code by always setting up the "i"ntegral variables.  */
12230   if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
12231     {
12232       tree iaddr_val;
12233
12234       iaddr = create_tmp_reg (build_pointer_type_for_mode (itype, ptr_mode,
12235                                                            true));
12236       iaddr_val
12237         = force_gimple_operand_gsi (&si,
12238                                     fold_convert (TREE_TYPE (iaddr), addr),
12239                                     false, NULL_TREE, true, GSI_SAME_STMT);
12240       stmt = gimple_build_assign (iaddr, iaddr_val);
12241       gsi_insert_before (&si, stmt, GSI_SAME_STMT);
12242       loadedi = create_tmp_var (itype);
12243       if (gimple_in_ssa_p (cfun))
12244         loadedi = make_ssa_name (loadedi);
12245     }
12246   else
12247     {
12248       iaddr = addr;
12249       loadedi = loaded_val;
12250     }
12251
12252   fncode = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
12253   tree loaddecl = builtin_decl_explicit (fncode);
12254   if (loaddecl)
12255     initial
12256       = fold_convert (TREE_TYPE (TREE_TYPE (iaddr)),
12257                       build_call_expr (loaddecl, 2, iaddr,
12258                                        build_int_cst (NULL_TREE,
12259                                                       MEMMODEL_RELAXED)));
12260   else
12261     initial = build2 (MEM_REF, TREE_TYPE (TREE_TYPE (iaddr)), iaddr,
12262                       build_int_cst (TREE_TYPE (iaddr), 0));
12263
12264   initial
12265     = force_gimple_operand_gsi (&si, initial, true, NULL_TREE, true,
12266                                 GSI_SAME_STMT);
12267
12268   /* Move the value to the LOADEDI temporary.  */
12269   if (gimple_in_ssa_p (cfun))
12270     {
12271       gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header)));
12272       phi = create_phi_node (loadedi, loop_header);
12273       SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (load_bb)),
12274                initial);
12275     }
12276   else
12277     gsi_insert_before (&si,
12278                        gimple_build_assign (loadedi, initial),
12279                        GSI_SAME_STMT);
12280   if (loadedi != loaded_val)
12281     {
12282       gimple_stmt_iterator gsi2;
12283       tree x;
12284
12285       x = build1 (VIEW_CONVERT_EXPR, type, loadedi);
12286       gsi2 = gsi_start_bb (loop_header);
12287       if (gimple_in_ssa_p (cfun))
12288         {
12289           gassign *stmt;
12290           x = force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
12291                                         true, GSI_SAME_STMT);
12292           stmt = gimple_build_assign (loaded_val, x);
12293           gsi_insert_before (&gsi2, stmt, GSI_SAME_STMT);
12294         }
12295       else
12296         {
12297           x = build2 (MODIFY_EXPR, TREE_TYPE (loaded_val), loaded_val, x);
12298           force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
12299                                     true, GSI_SAME_STMT);
12300         }
12301     }
12302   gsi_remove (&si, true);
12303
12304   si = gsi_last_bb (store_bb);
12305   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
12306
12307   if (iaddr == addr)
12308     storedi = stored_val;
12309   else
12310     storedi =
12311       force_gimple_operand_gsi (&si,
12312                                 build1 (VIEW_CONVERT_EXPR, itype,
12313                                         stored_val), true, NULL_TREE, true,
12314                                 GSI_SAME_STMT);
12315
12316   /* Build the compare&swap statement.  */
12317   new_storedi = build_call_expr (cmpxchg, 3, iaddr, loadedi, storedi);
12318   new_storedi = force_gimple_operand_gsi (&si,
12319                                           fold_convert (TREE_TYPE (loadedi),
12320                                                         new_storedi),
12321                                           true, NULL_TREE,
12322                                           true, GSI_SAME_STMT);
12323
12324   if (gimple_in_ssa_p (cfun))
12325     old_vali = loadedi;
12326   else
12327     {
12328       old_vali = create_tmp_var (TREE_TYPE (loadedi));
12329       stmt = gimple_build_assign (old_vali, loadedi);
12330       gsi_insert_before (&si, stmt, GSI_SAME_STMT);
12331
12332       stmt = gimple_build_assign (loadedi, new_storedi);
12333       gsi_insert_before (&si, stmt, GSI_SAME_STMT);
12334     }
12335
12336   /* Note that we always perform the comparison as an integer, even for
12337      floating point.  This allows the atomic operation to properly
12338      succeed even with NaNs and -0.0.  */
12339   stmt = gimple_build_cond_empty
12340            (build2 (NE_EXPR, boolean_type_node,
12341                     new_storedi, old_vali));
12342   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
12343
12344   /* Update cfg.  */
12345   e = single_succ_edge (store_bb);
12346   e->flags &= ~EDGE_FALLTHRU;
12347   e->flags |= EDGE_FALSE_VALUE;
12348
12349   e = make_edge (store_bb, loop_header, EDGE_TRUE_VALUE);
12350
12351   /* Copy the new value to loadedi (we already did that before the condition
12352      if we are not in SSA).  */
12353   if (gimple_in_ssa_p (cfun))
12354     {
12355       phi = gimple_seq_first_stmt (phi_nodes (loop_header));
12356       SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), new_storedi);
12357     }
12358
12359   /* Remove GIMPLE_OMP_ATOMIC_STORE.  */
12360   gsi_remove (&si, true);
12361
12362   struct loop *loop = alloc_loop ();
12363   loop->header = loop_header;
12364   loop->latch = store_bb;
12365   add_loop (loop, loop_header->loop_father);
12366
12367   if (gimple_in_ssa_p (cfun))
12368     update_ssa (TODO_update_ssa_no_phi);
12369
12370   return true;
12371 }
12372
12373 /* A subroutine of expand_omp_atomic.  Implement the atomic operation as:
12374
12375                                   GOMP_atomic_start ();
12376                                   *addr = rhs;
12377                                   GOMP_atomic_end ();
12378
12379    The result is not globally atomic, but works so long as all parallel
12380    references are within #pragma omp atomic directives.  According to
12381    responses received from omp@openmp.org, appears to be within spec.
12382    Which makes sense, since that's how several other compilers handle
12383    this situation as well.
12384    LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
12385    expanding.  STORED_VAL is the operand of the matching
12386    GIMPLE_OMP_ATOMIC_STORE.
12387
12388    We replace
12389    GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
12390    loaded_val = *addr;
12391
12392    and replace
12393    GIMPLE_OMP_ATOMIC_STORE (stored_val)  with
12394    *addr = stored_val;
12395 */
12396
12397 static bool
12398 expand_omp_atomic_mutex (basic_block load_bb, basic_block store_bb,
12399                          tree addr, tree loaded_val, tree stored_val)
12400 {
12401   gimple_stmt_iterator si;
12402   gassign *stmt;
12403   tree t;
12404
12405   si = gsi_last_bb (load_bb);
12406   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
12407
12408   t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
12409   t = build_call_expr (t, 0);
12410   force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
12411
12412   stmt = gimple_build_assign (loaded_val, build_simple_mem_ref (addr));
12413   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
12414   gsi_remove (&si, true);
12415
12416   si = gsi_last_bb (store_bb);
12417   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
12418
12419   stmt = gimple_build_assign (build_simple_mem_ref (unshare_expr (addr)),
12420                               stored_val);
12421   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
12422
12423   t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
12424   t = build_call_expr (t, 0);
12425   force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
12426   gsi_remove (&si, true);
12427
12428   if (gimple_in_ssa_p (cfun))
12429     update_ssa (TODO_update_ssa_no_phi);
12430   return true;
12431 }
12432
12433 /* Expand an GIMPLE_OMP_ATOMIC statement.  We try to expand
12434    using expand_omp_atomic_fetch_op. If it failed, we try to
12435    call expand_omp_atomic_pipeline, and if it fails too, the
12436    ultimate fallback is wrapping the operation in a mutex
12437    (expand_omp_atomic_mutex).  REGION is the atomic region built
12438    by build_omp_regions_1().  */
12439
12440 static void
12441 expand_omp_atomic (struct omp_region *region)
12442 {
12443   basic_block load_bb = region->entry, store_bb = region->exit;
12444   gomp_atomic_load *load = as_a <gomp_atomic_load *> (last_stmt (load_bb));
12445   gomp_atomic_store *store = as_a <gomp_atomic_store *> (last_stmt (store_bb));
12446   tree loaded_val = gimple_omp_atomic_load_lhs (load);
12447   tree addr = gimple_omp_atomic_load_rhs (load);
12448   tree stored_val = gimple_omp_atomic_store_val (store);
12449   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
12450   HOST_WIDE_INT index;
12451
12452   /* Make sure the type is one of the supported sizes.  */
12453   index = tree_to_uhwi (TYPE_SIZE_UNIT (type));
12454   index = exact_log2 (index);
12455   if (index >= 0 && index <= 4)
12456     {
12457       unsigned int align = TYPE_ALIGN_UNIT (type);
12458
12459       /* __sync builtins require strict data alignment.  */
12460       if (exact_log2 (align) >= index)
12461         {
12462           /* Atomic load.  */
12463           if (loaded_val == stored_val
12464               && (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
12465                   || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
12466               && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
12467               && expand_omp_atomic_load (load_bb, addr, loaded_val, index))
12468             return;
12469
12470           /* Atomic store.  */
12471           if ((GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
12472                || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
12473               && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
12474               && store_bb == single_succ (load_bb)
12475               && first_stmt (store_bb) == store
12476               && expand_omp_atomic_store (load_bb, addr, loaded_val,
12477                                           stored_val, index))
12478             return;
12479
12480           /* When possible, use specialized atomic update functions.  */
12481           if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
12482               && store_bb == single_succ (load_bb)
12483               && expand_omp_atomic_fetch_op (load_bb, addr,
12484                                              loaded_val, stored_val, index))
12485             return;
12486
12487           /* If we don't have specialized __sync builtins, try and implement
12488              as a compare and swap loop.  */
12489           if (expand_omp_atomic_pipeline (load_bb, store_bb, addr,
12490                                           loaded_val, stored_val, index))
12491             return;
12492         }
12493     }
12494
12495   /* The ultimate fallback is wrapping the operation in a mutex.  */
12496   expand_omp_atomic_mutex (load_bb, store_bb, addr, loaded_val, stored_val);
12497 }
12498
12499
12500 /* Encode an oacc launch argument.  This matches the GOMP_LAUNCH_PACK
12501    macro on gomp-constants.h.  We do not check for overflow.  */
12502
12503 static tree
12504 oacc_launch_pack (unsigned code, tree device, unsigned op)
12505 {
12506   tree res;
12507   
12508   res = build_int_cst (unsigned_type_node, GOMP_LAUNCH_PACK (code, 0, op));
12509   if (device)
12510     {
12511       device = fold_build2 (LSHIFT_EXPR, unsigned_type_node,
12512                             device, build_int_cst (unsigned_type_node,
12513                                                    GOMP_LAUNCH_DEVICE_SHIFT));
12514       res = fold_build2 (BIT_IOR_EXPR, unsigned_type_node, res, device);
12515     }
12516   return res;
12517 }
12518
12519 /* Look for compute grid dimension clauses and convert to an attribute
12520    attached to FN.  This permits the target-side code to (a) massage
12521    the dimensions, (b) emit that data and (c) optimize.  Non-constant
12522    dimensions are pushed onto ARGS.
12523
12524    The attribute value is a TREE_LIST.  A set of dimensions is
12525    represented as a list of INTEGER_CST.  Those that are runtime
12526    exprs are represented as an INTEGER_CST of zero.
12527
12528    TOOO. Normally the attribute will just contain a single such list.  If
12529    however it contains a list of lists, this will represent the use of
12530    device_type.  Each member of the outer list is an assoc list of
12531    dimensions, keyed by the device type.  The first entry will be the
12532    default.  Well, that's the plan.  */
12533
12534 #define OACC_FN_ATTRIB "oacc function"
12535
12536 /* Replace any existing oacc fn attribute with updated dimensions.  */
12537
12538 void
12539 replace_oacc_fn_attrib (tree fn, tree dims)
12540 {
12541   tree ident = get_identifier (OACC_FN_ATTRIB);
12542   tree attribs = DECL_ATTRIBUTES (fn);
12543
12544   /* If we happen to be present as the first attrib, drop it.  */
12545   if (attribs && TREE_PURPOSE (attribs) == ident)
12546     attribs = TREE_CHAIN (attribs);
12547   DECL_ATTRIBUTES (fn) = tree_cons (ident, dims, attribs);
12548 }
12549
12550 /* Scan CLAUSES for launch dimensions and attach them to the oacc
12551    function attribute.  Push any that are non-constant onto the ARGS
12552    list, along with an appropriate GOMP_LAUNCH_DIM tag.  IS_KERNEL is
12553    true, if these are for a kernels region offload function.  */
12554
12555 void
12556 set_oacc_fn_attrib (tree fn, tree clauses, bool is_kernel, vec<tree> *args)
12557 {
12558   /* Must match GOMP_DIM ordering.  */
12559   static const omp_clause_code ids[]
12560     = { OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS,
12561         OMP_CLAUSE_VECTOR_LENGTH };
12562   unsigned ix;
12563   tree dims[GOMP_DIM_MAX];
12564   tree attr = NULL_TREE;
12565   unsigned non_const = 0;
12566
12567   for (ix = GOMP_DIM_MAX; ix--;)
12568     {
12569       tree clause = find_omp_clause (clauses, ids[ix]);
12570       tree dim = NULL_TREE;
12571
12572       if (clause)
12573         dim = OMP_CLAUSE_EXPR (clause, ids[ix]);
12574       dims[ix] = dim;
12575       if (dim && TREE_CODE (dim) != INTEGER_CST)
12576         {
12577           dim = integer_zero_node;
12578           non_const |= GOMP_DIM_MASK (ix);
12579         }
12580       attr = tree_cons (NULL_TREE, dim, attr);
12581       /* Note kernelness with TREE_PUBLIC.  */
12582       if (is_kernel)
12583         TREE_PUBLIC (attr) = 1;
12584     }
12585
12586   replace_oacc_fn_attrib (fn, attr);
12587
12588   if (non_const)
12589     {
12590       /* Push a dynamic argument set.  */
12591       args->safe_push (oacc_launch_pack (GOMP_LAUNCH_DIM,
12592                                          NULL_TREE, non_const));
12593       for (unsigned ix = 0; ix != GOMP_DIM_MAX; ix++)
12594         if (non_const & GOMP_DIM_MASK (ix))
12595           args->safe_push (dims[ix]);
12596     }
12597 }
12598
12599 /*  Process the routine's dimension clauess to generate an attribute
12600     value.  Issue diagnostics as appropriate.  We default to SEQ
12601     (OpenACC 2.5 clarifies this). All dimensions have a size of zero
12602     (dynamic).  TREE_PURPOSE is set to indicate whether that dimension
12603     can have a loop partitioned on it.  non-zero indicates
12604     yes, zero indicates no.  By construction once a non-zero has been
12605     reached, further inner dimensions must also be non-zero.  We set
12606     TREE_VALUE to zero for the dimensions that may be partitioned and
12607     1 for the other ones -- if a loop is (erroneously) spawned at
12608     an outer level, we don't want to try and partition it.  */
12609
12610 tree
12611 build_oacc_routine_dims (tree clauses)
12612 {
12613   /* Must match GOMP_DIM ordering.  */
12614   static const omp_clause_code ids[] = 
12615     {OMP_CLAUSE_GANG, OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR, OMP_CLAUSE_SEQ};
12616   int ix;
12617   int level = -1;
12618
12619   for (; clauses; clauses = OMP_CLAUSE_CHAIN (clauses))
12620     for (ix = GOMP_DIM_MAX + 1; ix--;)
12621       if (OMP_CLAUSE_CODE (clauses) == ids[ix])
12622         {
12623           if (level >= 0)
12624             error_at (OMP_CLAUSE_LOCATION (clauses),
12625                       "multiple loop axes specified for routine");
12626           level = ix;
12627           break;
12628         }
12629
12630   /* Default to SEQ.  */
12631   if (level < 0)
12632     level = GOMP_DIM_MAX;
12633   
12634   tree dims = NULL_TREE;
12635
12636   for (ix = GOMP_DIM_MAX; ix--;)
12637     dims = tree_cons (build_int_cst (boolean_type_node, ix >= level),
12638                       build_int_cst (integer_type_node, ix < level), dims);
12639
12640   return dims;
12641 }
12642
12643 /* Retrieve the oacc function attrib and return it.  Non-oacc
12644    functions will return NULL.  */
12645
12646 tree
12647 get_oacc_fn_attrib (tree fn)
12648 {
12649   return lookup_attribute (OACC_FN_ATTRIB, DECL_ATTRIBUTES (fn));
12650 }
12651
12652 /* Return true if this oacc fn attrib is for a kernels offload
12653    region.  We use the TREE_PUBLIC flag of each dimension -- only
12654    need to check the first one.  */
12655
12656 bool
12657 oacc_fn_attrib_kernels_p (tree attr)
12658 {
12659   return TREE_PUBLIC (TREE_VALUE (attr));
12660 }
12661
12662 /* Return level at which oacc routine may spawn a partitioned loop, or
12663    -1 if it is not a routine (i.e. is an offload fn).  */
12664
12665 static int
12666 oacc_fn_attrib_level (tree attr)
12667 {
12668   tree pos = TREE_VALUE (attr);
12669
12670   if (!TREE_PURPOSE (pos))
12671     return -1;
12672   
12673   int ix = 0;
12674   for (ix = 0; ix != GOMP_DIM_MAX;
12675        ix++, pos = TREE_CHAIN (pos))
12676     if (!integer_zerop (TREE_PURPOSE (pos)))
12677       break;
12678
12679   return ix;
12680 }
12681
12682 /* Extract an oacc execution dimension from FN.  FN must be an
12683    offloaded function or routine that has already had its execution
12684    dimensions lowered to the target-specific values.  */
12685
12686 int
12687 get_oacc_fn_dim_size (tree fn, int axis)
12688 {
12689   tree attrs = get_oacc_fn_attrib (fn);
12690   
12691   gcc_assert (axis < GOMP_DIM_MAX);
12692
12693   tree dims = TREE_VALUE (attrs);
12694   while (axis--)
12695     dims = TREE_CHAIN (dims);
12696
12697   int size = TREE_INT_CST_LOW (TREE_VALUE (dims));
12698
12699   return size;
12700 }
12701
12702 /* Extract the dimension axis from an IFN_GOACC_DIM_POS or
12703    IFN_GOACC_DIM_SIZE call.  */
12704
12705 int
12706 get_oacc_ifn_dim_arg (const gimple *stmt)
12707 {
12708   gcc_checking_assert (gimple_call_internal_fn (stmt) == IFN_GOACC_DIM_SIZE
12709                        || gimple_call_internal_fn (stmt) == IFN_GOACC_DIM_POS);
12710   tree arg = gimple_call_arg (stmt, 0);
12711   HOST_WIDE_INT axis = TREE_INT_CST_LOW (arg);
12712
12713   gcc_checking_assert (axis >= 0 && axis < GOMP_DIM_MAX);
12714   return (int) axis;
12715 }
12716
12717 /* Mark the loops inside the kernels region starting at REGION_ENTRY and ending
12718    at REGION_EXIT.  */
12719
12720 static void
12721 mark_loops_in_oacc_kernels_region (basic_block region_entry,
12722                                    basic_block region_exit)
12723 {
12724   struct loop *outer = region_entry->loop_father;
12725   gcc_assert (region_exit == NULL || outer == region_exit->loop_father);
12726
12727   /* Don't parallelize the kernels region if it contains more than one outer
12728      loop.  */
12729   unsigned int nr_outer_loops = 0;
12730   struct loop *single_outer = NULL;
12731   for (struct loop *loop = outer->inner; loop != NULL; loop = loop->next)
12732     {
12733       gcc_assert (loop_outer (loop) == outer);
12734
12735       if (!dominated_by_p (CDI_DOMINATORS, loop->header, region_entry))
12736         continue;
12737
12738       if (region_exit != NULL
12739           && dominated_by_p (CDI_DOMINATORS, loop->header, region_exit))
12740         continue;
12741
12742       nr_outer_loops++;
12743       single_outer = loop;
12744     }
12745   if (nr_outer_loops != 1)
12746     return;
12747
12748   for (struct loop *loop = single_outer->inner; loop != NULL; loop = loop->inner)
12749     if (loop->next)
12750       return;
12751
12752   /* Mark the loops in the region.  */
12753   for (struct loop *loop = single_outer; loop != NULL; loop = loop->inner)
12754     loop->in_oacc_kernels_region = true;
12755 }
12756
12757 /* Types used to pass grid and wortkgroup sizes to kernel invocation.  */
12758
12759 struct GTY(()) grid_launch_attributes_trees
12760 {
12761   tree kernel_dim_array_type;
12762   tree kernel_lattrs_dimnum_decl;
12763   tree kernel_lattrs_grid_decl;
12764   tree kernel_lattrs_group_decl;
12765   tree kernel_launch_attributes_type;
12766 };
12767
12768 static GTY(()) struct grid_launch_attributes_trees *grid_attr_trees;
12769
12770 /* Create types used to pass kernel launch attributes to target.  */
12771
12772 static void
12773 grid_create_kernel_launch_attr_types (void)
12774 {
12775   if (grid_attr_trees)
12776     return;
12777   grid_attr_trees = ggc_alloc <grid_launch_attributes_trees> ();
12778
12779   tree dim_arr_index_type
12780     = build_index_type (build_int_cst (integer_type_node, 2));
12781   grid_attr_trees->kernel_dim_array_type
12782     = build_array_type (uint32_type_node, dim_arr_index_type);
12783
12784   grid_attr_trees->kernel_launch_attributes_type = make_node (RECORD_TYPE);
12785   grid_attr_trees->kernel_lattrs_dimnum_decl
12786     = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("ndim"),
12787                   uint32_type_node);
12788   DECL_CHAIN (grid_attr_trees->kernel_lattrs_dimnum_decl) = NULL_TREE;
12789
12790   grid_attr_trees->kernel_lattrs_grid_decl
12791     = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("grid_size"),
12792                   grid_attr_trees->kernel_dim_array_type);
12793   DECL_CHAIN (grid_attr_trees->kernel_lattrs_grid_decl)
12794     = grid_attr_trees->kernel_lattrs_dimnum_decl;
12795   grid_attr_trees->kernel_lattrs_group_decl
12796     = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("group_size"),
12797                   grid_attr_trees->kernel_dim_array_type);
12798   DECL_CHAIN (grid_attr_trees->kernel_lattrs_group_decl)
12799     = grid_attr_trees->kernel_lattrs_grid_decl;
12800   finish_builtin_struct (grid_attr_trees->kernel_launch_attributes_type,
12801                          "__gomp_kernel_launch_attributes",
12802                          grid_attr_trees->kernel_lattrs_group_decl, NULL_TREE);
12803 }
12804
12805 /* Insert before the current statement in GSI a store of VALUE to INDEX of
12806    array (of type kernel_dim_array_type) FLD_DECL of RANGE_VAR.  VALUE must be
12807    of type uint32_type_node.  */
12808
12809 static void
12810 grid_insert_store_range_dim (gimple_stmt_iterator *gsi, tree range_var,
12811                              tree fld_decl, int index, tree value)
12812 {
12813   tree ref = build4 (ARRAY_REF, uint32_type_node,
12814                      build3 (COMPONENT_REF,
12815                              grid_attr_trees->kernel_dim_array_type,
12816                              range_var, fld_decl, NULL_TREE),
12817                      build_int_cst (integer_type_node, index),
12818                      NULL_TREE, NULL_TREE);
12819   gsi_insert_before (gsi, gimple_build_assign (ref, value), GSI_SAME_STMT);
12820 }
12821
12822 /* Return a tree representation of a pointer to a structure with grid and
12823    work-group size information.  Statements filling that information will be
12824    inserted before GSI, TGT_STMT is the target statement which has the
12825    necessary information in it.  */
12826
12827 static tree
12828 grid_get_kernel_launch_attributes (gimple_stmt_iterator *gsi,
12829                                    gomp_target *tgt_stmt)
12830 {
12831   grid_create_kernel_launch_attr_types ();
12832   tree u32_one = build_one_cst (uint32_type_node);
12833   tree lattrs = create_tmp_var (grid_attr_trees->kernel_launch_attributes_type,
12834                                 "__kernel_launch_attrs");
12835
12836   unsigned max_dim = 0;
12837   for (tree clause = gimple_omp_target_clauses (tgt_stmt);
12838        clause;
12839        clause = OMP_CLAUSE_CHAIN (clause))
12840     {
12841       if (OMP_CLAUSE_CODE (clause) != OMP_CLAUSE__GRIDDIM_)
12842         continue;
12843
12844       unsigned dim = OMP_CLAUSE__GRIDDIM__DIMENSION (clause);
12845       max_dim = MAX (dim, max_dim);
12846
12847       grid_insert_store_range_dim (gsi, lattrs,
12848                                    grid_attr_trees->kernel_lattrs_grid_decl,
12849                                    dim, OMP_CLAUSE__GRIDDIM__SIZE (clause));
12850       grid_insert_store_range_dim (gsi, lattrs,
12851                                    grid_attr_trees->kernel_lattrs_group_decl,
12852                                    dim, OMP_CLAUSE__GRIDDIM__GROUP (clause));
12853     }
12854
12855   tree dimref = build3 (COMPONENT_REF, uint32_type_node, lattrs,
12856                         grid_attr_trees->kernel_lattrs_dimnum_decl, NULL_TREE);
12857   /* At this moment we cannot gridify a loop with a collapse clause.  */
12858   /* TODO: Adjust when we support bigger collapse.  */
12859   gcc_assert (max_dim == 0);
12860   gsi_insert_before (gsi, gimple_build_assign (dimref, u32_one), GSI_SAME_STMT);
12861   TREE_ADDRESSABLE (lattrs) = 1;
12862   return build_fold_addr_expr (lattrs);
12863 }
12864
12865 /* Build target argument identifier from the DEVICE identifier, value
12866    identifier ID and whether the element also has a SUBSEQUENT_PARAM.  */
12867
12868 static tree
12869 get_target_argument_identifier_1 (int device, bool subseqent_param, int id)
12870 {
12871   tree t = build_int_cst (integer_type_node, device);
12872   if (subseqent_param)
12873     t = fold_build2 (BIT_IOR_EXPR, integer_type_node, t,
12874                      build_int_cst (integer_type_node,
12875                                     GOMP_TARGET_ARG_SUBSEQUENT_PARAM));
12876   t = fold_build2 (BIT_IOR_EXPR, integer_type_node, t,
12877                    build_int_cst (integer_type_node, id));
12878   return t;
12879 }
12880
12881 /* Like above but return it in type that can be directly stored as an element
12882    of the argument array.  */
12883
12884 static tree
12885 get_target_argument_identifier (int device, bool subseqent_param, int id)
12886 {
12887   tree t = get_target_argument_identifier_1 (device, subseqent_param, id);
12888   return fold_convert (ptr_type_node, t);
12889 }
12890
12891 /* Return a target argument consisting of DEVICE identifier, value identifier
12892    ID, and the actual VALUE.  */
12893
12894 static tree
12895 get_target_argument_value (gimple_stmt_iterator *gsi, int device, int id,
12896                            tree value)
12897 {
12898   tree t = fold_build2 (LSHIFT_EXPR, integer_type_node,
12899                         fold_convert (integer_type_node, value),
12900                         build_int_cst (unsigned_type_node,
12901                                        GOMP_TARGET_ARG_VALUE_SHIFT));
12902   t = fold_build2 (BIT_IOR_EXPR, integer_type_node, t,
12903                    get_target_argument_identifier_1 (device, false, id));
12904   t = fold_convert (ptr_type_node, t);
12905   return force_gimple_operand_gsi (gsi, t, true, NULL, true, GSI_SAME_STMT);
12906 }
12907
12908 /* If VALUE is an integer constant greater than -2^15 and smaller than 2^15,
12909    push one argument to ARGS with both the DEVICE, ID and VALUE embedded in it,
12910    otherwise push an identifier (with DEVICE and ID) and the VALUE in two
12911    arguments.  */
12912
12913 static void
12914 push_target_argument_according_to_value (gimple_stmt_iterator *gsi, int device,
12915                                          int id, tree value, vec <tree> *args)
12916 {
12917   if (tree_fits_shwi_p (value)
12918       && tree_to_shwi (value) > -(1 << 15)
12919       && tree_to_shwi (value) < (1 << 15))
12920     args->quick_push (get_target_argument_value (gsi, device, id, value));
12921   else
12922     {
12923       args->quick_push (get_target_argument_identifier (device, true, id));
12924       value = fold_convert (ptr_type_node, value);
12925       value = force_gimple_operand_gsi (gsi, value, true, NULL, true,
12926                                         GSI_SAME_STMT);
12927       args->quick_push (value);
12928     }
12929 }
12930
12931 /* Create an array of arguments that is then passed to GOMP_target.   */
12932
12933 static tree
12934 get_target_arguments (gimple_stmt_iterator *gsi, gomp_target *tgt_stmt)
12935 {
12936   auto_vec <tree, 6> args;
12937   tree clauses = gimple_omp_target_clauses (tgt_stmt);
12938   tree t, c = find_omp_clause (clauses, OMP_CLAUSE_NUM_TEAMS);
12939   if (c)
12940     t = OMP_CLAUSE_NUM_TEAMS_EXPR (c);
12941   else
12942     t = integer_minus_one_node;
12943   push_target_argument_according_to_value (gsi, GOMP_TARGET_ARG_DEVICE_ALL,
12944                                            GOMP_TARGET_ARG_NUM_TEAMS, t, &args);
12945
12946   c = find_omp_clause (clauses, OMP_CLAUSE_THREAD_LIMIT);
12947   if (c)
12948     t = OMP_CLAUSE_THREAD_LIMIT_EXPR (c);
12949   else
12950     t = integer_minus_one_node;
12951   push_target_argument_according_to_value (gsi, GOMP_TARGET_ARG_DEVICE_ALL,
12952                                            GOMP_TARGET_ARG_THREAD_LIMIT, t,
12953                                            &args);
12954
12955   /* Add HSA-specific grid sizes, if available.  */
12956   if (find_omp_clause (gimple_omp_target_clauses (tgt_stmt),
12957                        OMP_CLAUSE__GRIDDIM_))
12958     {
12959       t = get_target_argument_identifier (GOMP_DEVICE_HSA, true,
12960                                           GOMP_TARGET_ARG_HSA_KERNEL_ATTRIBUTES);
12961       args.quick_push (t);
12962       args.quick_push (grid_get_kernel_launch_attributes (gsi, tgt_stmt));
12963     }
12964
12965   /* Produce more, perhaps device specific, arguments here.  */
12966
12967   tree argarray = create_tmp_var (build_array_type_nelts (ptr_type_node,
12968                                                           args.length () + 1),
12969                                   ".omp_target_args");
12970   for (unsigned i = 0; i < args.length (); i++)
12971     {
12972       tree ref = build4 (ARRAY_REF, ptr_type_node, argarray,
12973                          build_int_cst (integer_type_node, i),
12974                          NULL_TREE, NULL_TREE);
12975       gsi_insert_before (gsi, gimple_build_assign (ref, args[i]),
12976                          GSI_SAME_STMT);
12977     }
12978   tree ref = build4 (ARRAY_REF, ptr_type_node, argarray,
12979                      build_int_cst (integer_type_node, args.length ()),
12980                      NULL_TREE, NULL_TREE);
12981   gsi_insert_before (gsi, gimple_build_assign (ref, null_pointer_node),
12982                      GSI_SAME_STMT);
12983   TREE_ADDRESSABLE (argarray) = 1;
12984   return build_fold_addr_expr (argarray);
12985 }
12986
12987 /* Expand the GIMPLE_OMP_TARGET starting at REGION.  */
12988
12989 static void
12990 expand_omp_target (struct omp_region *region)
12991 {
12992   basic_block entry_bb, exit_bb, new_bb;
12993   struct function *child_cfun;
12994   tree child_fn, block, t;
12995   gimple_stmt_iterator gsi;
12996   gomp_target *entry_stmt;
12997   gimple *stmt;
12998   edge e;
12999   bool offloaded, data_region;
13000
13001   entry_stmt = as_a <gomp_target *> (last_stmt (region->entry));
13002   new_bb = region->entry;
13003
13004   offloaded = is_gimple_omp_offloaded (entry_stmt);
13005   switch (gimple_omp_target_kind (entry_stmt))
13006     {
13007     case GF_OMP_TARGET_KIND_REGION:
13008     case GF_OMP_TARGET_KIND_UPDATE:
13009     case GF_OMP_TARGET_KIND_ENTER_DATA:
13010     case GF_OMP_TARGET_KIND_EXIT_DATA:
13011     case GF_OMP_TARGET_KIND_OACC_PARALLEL:
13012     case GF_OMP_TARGET_KIND_OACC_KERNELS:
13013     case GF_OMP_TARGET_KIND_OACC_UPDATE:
13014     case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
13015     case GF_OMP_TARGET_KIND_OACC_DECLARE:
13016       data_region = false;
13017       break;
13018     case GF_OMP_TARGET_KIND_DATA:
13019     case GF_OMP_TARGET_KIND_OACC_DATA:
13020     case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
13021       data_region = true;
13022       break;
13023     default:
13024       gcc_unreachable ();
13025     }
13026
13027   child_fn = NULL_TREE;
13028   child_cfun = NULL;
13029   if (offloaded)
13030     {
13031       child_fn = gimple_omp_target_child_fn (entry_stmt);
13032       child_cfun = DECL_STRUCT_FUNCTION (child_fn);
13033     }
13034
13035   /* Supported by expand_omp_taskreg, but not here.  */
13036   if (child_cfun != NULL)
13037     gcc_checking_assert (!child_cfun->cfg);
13038   gcc_checking_assert (!gimple_in_ssa_p (cfun));
13039
13040   entry_bb = region->entry;
13041   exit_bb = region->exit;
13042
13043   if (gimple_omp_target_kind (entry_stmt) == GF_OMP_TARGET_KIND_OACC_KERNELS)
13044     mark_loops_in_oacc_kernels_region (region->entry, region->exit);
13045
13046   if (offloaded)
13047     {
13048       unsigned srcidx, dstidx, num;
13049
13050       /* If the offloading region needs data sent from the parent
13051          function, then the very first statement (except possible
13052          tree profile counter updates) of the offloading body
13053          is a copy assignment .OMP_DATA_I = &.OMP_DATA_O.  Since
13054          &.OMP_DATA_O is passed as an argument to the child function,
13055          we need to replace it with the argument as seen by the child
13056          function.
13057
13058          In most cases, this will end up being the identity assignment
13059          .OMP_DATA_I = .OMP_DATA_I.  However, if the offloading body had
13060          a function call that has been inlined, the original PARM_DECL
13061          .OMP_DATA_I may have been converted into a different local
13062          variable.  In which case, we need to keep the assignment.  */
13063       tree data_arg = gimple_omp_target_data_arg (entry_stmt);
13064       if (data_arg)
13065         {
13066           basic_block entry_succ_bb = single_succ (entry_bb);
13067           gimple_stmt_iterator gsi;
13068           tree arg;
13069           gimple *tgtcopy_stmt = NULL;
13070           tree sender = TREE_VEC_ELT (data_arg, 0);
13071
13072           for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
13073             {
13074               gcc_assert (!gsi_end_p (gsi));
13075               stmt = gsi_stmt (gsi);
13076               if (gimple_code (stmt) != GIMPLE_ASSIGN)
13077                 continue;
13078
13079               if (gimple_num_ops (stmt) == 2)
13080                 {
13081                   tree arg = gimple_assign_rhs1 (stmt);
13082
13083                   /* We're ignoring the subcode because we're
13084                      effectively doing a STRIP_NOPS.  */
13085
13086                   if (TREE_CODE (arg) == ADDR_EXPR
13087                       && TREE_OPERAND (arg, 0) == sender)
13088                     {
13089                       tgtcopy_stmt = stmt;
13090                       break;
13091                     }
13092                 }
13093             }
13094
13095           gcc_assert (tgtcopy_stmt != NULL);
13096           arg = DECL_ARGUMENTS (child_fn);
13097
13098           gcc_assert (gimple_assign_lhs (tgtcopy_stmt) == arg);
13099           gsi_remove (&gsi, true);
13100         }
13101
13102       /* Declare local variables needed in CHILD_CFUN.  */
13103       block = DECL_INITIAL (child_fn);
13104       BLOCK_VARS (block) = vec2chain (child_cfun->local_decls);
13105       /* The gimplifier could record temporaries in the offloading block
13106          rather than in containing function's local_decls chain,
13107          which would mean cgraph missed finalizing them.  Do it now.  */
13108       for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
13109         if (TREE_CODE (t) == VAR_DECL
13110             && TREE_STATIC (t)
13111             && !DECL_EXTERNAL (t))
13112           varpool_node::finalize_decl (t);
13113       DECL_SAVED_TREE (child_fn) = NULL;
13114       /* We'll create a CFG for child_fn, so no gimple body is needed.  */
13115       gimple_set_body (child_fn, NULL);
13116       TREE_USED (block) = 1;
13117
13118       /* Reset DECL_CONTEXT on function arguments.  */
13119       for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
13120         DECL_CONTEXT (t) = child_fn;
13121
13122       /* Split ENTRY_BB at GIMPLE_*,
13123          so that it can be moved to the child function.  */
13124       gsi = gsi_last_bb (entry_bb);
13125       stmt = gsi_stmt (gsi);
13126       gcc_assert (stmt
13127                   && gimple_code (stmt) == gimple_code (entry_stmt));
13128       e = split_block (entry_bb, stmt);
13129       gsi_remove (&gsi, true);
13130       entry_bb = e->dest;
13131       single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
13132
13133       /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR.  */
13134       if (exit_bb)
13135         {
13136           gsi = gsi_last_bb (exit_bb);
13137           gcc_assert (!gsi_end_p (gsi)
13138                       && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
13139           stmt = gimple_build_return (NULL);
13140           gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
13141           gsi_remove (&gsi, true);
13142         }
13143
13144       /* Move the offloading region into CHILD_CFUN.  */
13145
13146       block = gimple_block (entry_stmt);
13147
13148       new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
13149       if (exit_bb)
13150         single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
13151       /* When the OMP expansion process cannot guarantee an up-to-date
13152          loop tree arrange for the child function to fixup loops.  */
13153       if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
13154         child_cfun->x_current_loops->state |= LOOPS_NEED_FIXUP;
13155
13156       /* Remove non-local VAR_DECLs from child_cfun->local_decls list.  */
13157       num = vec_safe_length (child_cfun->local_decls);
13158       for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
13159         {
13160           t = (*child_cfun->local_decls)[srcidx];
13161           if (DECL_CONTEXT (t) == cfun->decl)
13162             continue;
13163           if (srcidx != dstidx)
13164             (*child_cfun->local_decls)[dstidx] = t;
13165           dstidx++;
13166         }
13167       if (dstidx != num)
13168         vec_safe_truncate (child_cfun->local_decls, dstidx);
13169
13170       /* Inform the callgraph about the new function.  */
13171       child_cfun->curr_properties = cfun->curr_properties;
13172       child_cfun->has_simduid_loops |= cfun->has_simduid_loops;
13173       child_cfun->has_force_vectorize_loops |= cfun->has_force_vectorize_loops;
13174       cgraph_node *node = cgraph_node::get_create (child_fn);
13175       node->parallelized_function = 1;
13176       cgraph_node::add_new_function (child_fn, true);
13177
13178       /* Add the new function to the offload table.  */
13179       if (ENABLE_OFFLOADING)
13180         vec_safe_push (offload_funcs, child_fn);
13181
13182       bool need_asm = DECL_ASSEMBLER_NAME_SET_P (current_function_decl)
13183                       && !DECL_ASSEMBLER_NAME_SET_P (child_fn);
13184
13185       /* Fix the callgraph edges for child_cfun.  Those for cfun will be
13186          fixed in a following pass.  */
13187       push_cfun (child_cfun);
13188       if (need_asm)
13189         assign_assembler_name_if_neeeded (child_fn);
13190       cgraph_edge::rebuild_edges ();
13191
13192       /* Some EH regions might become dead, see PR34608.  If
13193          pass_cleanup_cfg isn't the first pass to happen with the
13194          new child, these dead EH edges might cause problems.
13195          Clean them up now.  */
13196       if (flag_exceptions)
13197         {
13198           basic_block bb;
13199           bool changed = false;
13200
13201           FOR_EACH_BB_FN (bb, cfun)
13202             changed |= gimple_purge_dead_eh_edges (bb);
13203           if (changed)
13204             cleanup_tree_cfg ();
13205         }
13206       if (flag_checking && !loops_state_satisfies_p (LOOPS_NEED_FIXUP))
13207         verify_loop_structure ();
13208       pop_cfun ();
13209
13210       if (dump_file && !gimple_in_ssa_p (cfun))
13211         {
13212           omp_any_child_fn_dumped = true;
13213           dump_function_header (dump_file, child_fn, dump_flags);
13214           dump_function_to_file (child_fn, dump_file, dump_flags);
13215         }
13216     }
13217
13218   /* Emit a library call to launch the offloading region, or do data
13219      transfers.  */
13220   tree t1, t2, t3, t4, device, cond, depend, c, clauses;
13221   enum built_in_function start_ix;
13222   location_t clause_loc;
13223   unsigned int flags_i = 0;
13224   bool oacc_kernels_p = false;
13225
13226   switch (gimple_omp_target_kind (entry_stmt))
13227     {
13228     case GF_OMP_TARGET_KIND_REGION:
13229       start_ix = BUILT_IN_GOMP_TARGET;
13230       break;
13231     case GF_OMP_TARGET_KIND_DATA:
13232       start_ix = BUILT_IN_GOMP_TARGET_DATA;
13233       break;
13234     case GF_OMP_TARGET_KIND_UPDATE:
13235       start_ix = BUILT_IN_GOMP_TARGET_UPDATE;
13236       break;
13237     case GF_OMP_TARGET_KIND_ENTER_DATA:
13238       start_ix = BUILT_IN_GOMP_TARGET_ENTER_EXIT_DATA;
13239       break;
13240     case GF_OMP_TARGET_KIND_EXIT_DATA:
13241       start_ix = BUILT_IN_GOMP_TARGET_ENTER_EXIT_DATA;
13242       flags_i |= GOMP_TARGET_FLAG_EXIT_DATA;
13243       break;
13244     case GF_OMP_TARGET_KIND_OACC_KERNELS:
13245       oacc_kernels_p = true;
13246       /* FALLTHROUGH */
13247     case GF_OMP_TARGET_KIND_OACC_PARALLEL:
13248       start_ix = BUILT_IN_GOACC_PARALLEL;
13249       break;
13250     case GF_OMP_TARGET_KIND_OACC_DATA:
13251     case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
13252       start_ix = BUILT_IN_GOACC_DATA_START;
13253       break;
13254     case GF_OMP_TARGET_KIND_OACC_UPDATE:
13255       start_ix = BUILT_IN_GOACC_UPDATE;
13256       break;
13257     case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
13258       start_ix = BUILT_IN_GOACC_ENTER_EXIT_DATA;
13259       break;
13260     case GF_OMP_TARGET_KIND_OACC_DECLARE:
13261       start_ix = BUILT_IN_GOACC_DECLARE;
13262       break;
13263     default:
13264       gcc_unreachable ();
13265     }
13266
13267   clauses = gimple_omp_target_clauses (entry_stmt);
13268
13269   /* By default, the value of DEVICE is GOMP_DEVICE_ICV (let runtime
13270      library choose) and there is no conditional.  */
13271   cond = NULL_TREE;
13272   device = build_int_cst (integer_type_node, GOMP_DEVICE_ICV);
13273
13274   c = find_omp_clause (clauses, OMP_CLAUSE_IF);
13275   if (c)
13276     cond = OMP_CLAUSE_IF_EXPR (c);
13277
13278   c = find_omp_clause (clauses, OMP_CLAUSE_DEVICE);
13279   if (c)
13280     {
13281       /* Even if we pass it to all library function calls, it is currently only
13282          defined/used for the OpenMP target ones.  */
13283       gcc_checking_assert (start_ix == BUILT_IN_GOMP_TARGET
13284                            || start_ix == BUILT_IN_GOMP_TARGET_DATA
13285                            || start_ix == BUILT_IN_GOMP_TARGET_UPDATE
13286                            || start_ix == BUILT_IN_GOMP_TARGET_ENTER_EXIT_DATA);
13287
13288       device = OMP_CLAUSE_DEVICE_ID (c);
13289       clause_loc = OMP_CLAUSE_LOCATION (c);
13290     }
13291   else
13292     clause_loc = gimple_location (entry_stmt);
13293
13294   c = find_omp_clause (clauses, OMP_CLAUSE_NOWAIT);
13295   if (c)
13296     flags_i |= GOMP_TARGET_FLAG_NOWAIT;
13297
13298   /* Ensure 'device' is of the correct type.  */
13299   device = fold_convert_loc (clause_loc, integer_type_node, device);
13300
13301   /* If we found the clause 'if (cond)', build
13302      (cond ? device : GOMP_DEVICE_HOST_FALLBACK).  */
13303   if (cond)
13304     {
13305       cond = gimple_boolify (cond);
13306
13307       basic_block cond_bb, then_bb, else_bb;
13308       edge e;
13309       tree tmp_var;
13310
13311       tmp_var = create_tmp_var (TREE_TYPE (device));
13312       if (offloaded)
13313         e = split_block_after_labels (new_bb);
13314       else
13315         {
13316           gsi = gsi_last_bb (new_bb);
13317           gsi_prev (&gsi);
13318           e = split_block (new_bb, gsi_stmt (gsi));
13319         }
13320       cond_bb = e->src;
13321       new_bb = e->dest;
13322       remove_edge (e);
13323
13324       then_bb = create_empty_bb (cond_bb);
13325       else_bb = create_empty_bb (then_bb);
13326       set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
13327       set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
13328
13329       stmt = gimple_build_cond_empty (cond);
13330       gsi = gsi_last_bb (cond_bb);
13331       gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
13332
13333       gsi = gsi_start_bb (then_bb);
13334       stmt = gimple_build_assign (tmp_var, device);
13335       gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
13336
13337       gsi = gsi_start_bb (else_bb);
13338       stmt = gimple_build_assign (tmp_var,
13339                                   build_int_cst (integer_type_node,
13340                                                  GOMP_DEVICE_HOST_FALLBACK));
13341       gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
13342
13343       make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
13344       make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
13345       add_bb_to_loop (then_bb, cond_bb->loop_father);
13346       add_bb_to_loop (else_bb, cond_bb->loop_father);
13347       make_edge (then_bb, new_bb, EDGE_FALLTHRU);
13348       make_edge (else_bb, new_bb, EDGE_FALLTHRU);
13349
13350       device = tmp_var;
13351     }
13352
13353   gsi = gsi_last_bb (new_bb);
13354   t = gimple_omp_target_data_arg (entry_stmt);
13355   if (t == NULL)
13356     {
13357       t1 = size_zero_node;
13358       t2 = build_zero_cst (ptr_type_node);
13359       t3 = t2;
13360       t4 = t2;
13361     }
13362   else
13363     {
13364       t1 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (TREE_VEC_ELT (t, 1))));
13365       t1 = size_binop (PLUS_EXPR, t1, size_int (1));
13366       t2 = build_fold_addr_expr (TREE_VEC_ELT (t, 0));
13367       t3 = build_fold_addr_expr (TREE_VEC_ELT (t, 1));
13368       t4 = build_fold_addr_expr (TREE_VEC_ELT (t, 2));
13369     }
13370
13371   gimple *g;
13372   bool tagging = false;
13373   /* The maximum number used by any start_ix, without varargs.  */
13374   auto_vec<tree, 11> args;
13375   args.quick_push (device);
13376   if (offloaded)
13377     args.quick_push (build_fold_addr_expr (child_fn));
13378   args.quick_push (t1);
13379   args.quick_push (t2);
13380   args.quick_push (t3);
13381   args.quick_push (t4);
13382   switch (start_ix)
13383     {
13384     case BUILT_IN_GOACC_DATA_START:
13385     case BUILT_IN_GOACC_DECLARE:
13386     case BUILT_IN_GOMP_TARGET_DATA:
13387       break;
13388     case BUILT_IN_GOMP_TARGET:
13389     case BUILT_IN_GOMP_TARGET_UPDATE:
13390     case BUILT_IN_GOMP_TARGET_ENTER_EXIT_DATA:
13391       args.quick_push (build_int_cst (unsigned_type_node, flags_i));
13392       c = find_omp_clause (clauses, OMP_CLAUSE_DEPEND);
13393       if (c)
13394         depend = OMP_CLAUSE_DECL (c);
13395       else
13396         depend = build_int_cst (ptr_type_node, 0);
13397       args.quick_push (depend);
13398       if (start_ix == BUILT_IN_GOMP_TARGET)
13399         args.quick_push (get_target_arguments (&gsi, entry_stmt));
13400       break;
13401     case BUILT_IN_GOACC_PARALLEL:
13402       {
13403         set_oacc_fn_attrib (child_fn, clauses, oacc_kernels_p, &args);
13404         tagging = true;
13405       }
13406       /* FALLTHRU */
13407     case BUILT_IN_GOACC_ENTER_EXIT_DATA:
13408     case BUILT_IN_GOACC_UPDATE:
13409       {
13410         tree t_async = NULL_TREE;
13411
13412         /* If present, use the value specified by the respective
13413            clause, making sure that is of the correct type.  */
13414         c = find_omp_clause (clauses, OMP_CLAUSE_ASYNC);
13415         if (c)
13416           t_async = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
13417                                       integer_type_node,
13418                                       OMP_CLAUSE_ASYNC_EXPR (c));
13419         else if (!tagging)
13420           /* Default values for t_async.  */
13421           t_async = fold_convert_loc (gimple_location (entry_stmt),
13422                                       integer_type_node,
13423                                       build_int_cst (integer_type_node,
13424                                                      GOMP_ASYNC_SYNC));
13425         if (tagging && t_async)
13426           {
13427             unsigned HOST_WIDE_INT i_async = GOMP_LAUNCH_OP_MAX;
13428
13429             if (TREE_CODE (t_async) == INTEGER_CST)
13430               {
13431                 /* See if we can pack the async arg in to the tag's
13432                    operand.  */
13433                 i_async = TREE_INT_CST_LOW (t_async);
13434                 if (i_async < GOMP_LAUNCH_OP_MAX)
13435                   t_async = NULL_TREE;
13436                 else
13437                   i_async = GOMP_LAUNCH_OP_MAX;
13438               }
13439             args.safe_push (oacc_launch_pack (GOMP_LAUNCH_ASYNC, NULL_TREE,
13440                                               i_async));
13441           }
13442         if (t_async)
13443           args.safe_push (t_async);
13444
13445         /* Save the argument index, and ... */
13446         unsigned t_wait_idx = args.length ();
13447         unsigned num_waits = 0;
13448         c = find_omp_clause (clauses, OMP_CLAUSE_WAIT);
13449         if (!tagging || c)
13450           /* ... push a placeholder.  */
13451           args.safe_push (integer_zero_node);
13452
13453         for (; c; c = OMP_CLAUSE_CHAIN (c))
13454           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_WAIT)
13455             {
13456               args.safe_push (fold_convert_loc (OMP_CLAUSE_LOCATION (c),
13457                                                 integer_type_node,
13458                                                 OMP_CLAUSE_WAIT_EXPR (c)));
13459               num_waits++;
13460             }
13461
13462         if (!tagging || num_waits)
13463           {
13464             tree len;
13465
13466             /* Now that we know the number, update the placeholder.  */
13467             if (tagging)
13468               len = oacc_launch_pack (GOMP_LAUNCH_WAIT, NULL_TREE, num_waits);
13469             else
13470               len = build_int_cst (integer_type_node, num_waits);
13471             len = fold_convert_loc (gimple_location (entry_stmt),
13472                                     unsigned_type_node, len);
13473             args[t_wait_idx] = len;
13474           }
13475       }
13476       break;
13477     default:
13478       gcc_unreachable ();
13479     }
13480   if (tagging)
13481     /*  Push terminal marker - zero.  */
13482     args.safe_push (oacc_launch_pack (0, NULL_TREE, 0));
13483
13484   g = gimple_build_call_vec (builtin_decl_explicit (start_ix), args);
13485   gimple_set_location (g, gimple_location (entry_stmt));
13486   gsi_insert_before (&gsi, g, GSI_SAME_STMT);
13487   if (!offloaded)
13488     {
13489       g = gsi_stmt (gsi);
13490       gcc_assert (g && gimple_code (g) == GIMPLE_OMP_TARGET);
13491       gsi_remove (&gsi, true);
13492     }
13493   if (data_region && region->exit)
13494     {
13495       gsi = gsi_last_bb (region->exit);
13496       g = gsi_stmt (gsi);
13497       gcc_assert (g && gimple_code (g) == GIMPLE_OMP_RETURN);
13498       gsi_remove (&gsi, true);
13499     }
13500 }
13501
13502 /* Expand KFOR loop as a GPGPU kernel, i.e. as a body only with iteration
13503    variable derived from the thread number.  */
13504
13505 static void
13506 grid_expand_omp_for_loop (struct omp_region *kfor)
13507 {
13508   tree t, threadid;
13509   tree type, itype;
13510   gimple_stmt_iterator gsi;
13511   tree n1, step;
13512   struct omp_for_data fd;
13513
13514   gomp_for *for_stmt = as_a <gomp_for *> (last_stmt (kfor->entry));
13515   gcc_checking_assert (gimple_omp_for_kind (for_stmt)
13516                        == GF_OMP_FOR_KIND_GRID_LOOP);
13517   basic_block body_bb = FALLTHRU_EDGE (kfor->entry)->dest;
13518
13519   gcc_assert (gimple_omp_for_collapse (for_stmt) == 1);
13520   gcc_assert (kfor->cont);
13521   extract_omp_for_data (for_stmt, &fd, NULL);
13522
13523   itype = type = TREE_TYPE (fd.loop.v);
13524   if (POINTER_TYPE_P (type))
13525     itype = signed_type_for (type);
13526
13527   gsi = gsi_start_bb (body_bb);
13528
13529   n1 = fd.loop.n1;
13530   step = fd.loop.step;
13531   n1 = force_gimple_operand_gsi (&gsi, fold_convert (type, n1),
13532                                  true, NULL_TREE, true, GSI_SAME_STMT);
13533   step = force_gimple_operand_gsi (&gsi, fold_convert (itype, step),
13534                                    true, NULL_TREE, true, GSI_SAME_STMT);
13535   threadid = build_call_expr (builtin_decl_explicit
13536                               (BUILT_IN_OMP_GET_THREAD_NUM), 0);
13537   threadid = fold_convert (itype, threadid);
13538   threadid = force_gimple_operand_gsi (&gsi, threadid, true, NULL_TREE,
13539                                        true, GSI_SAME_STMT);
13540
13541   tree startvar = fd.loop.v;
13542   t = fold_build2 (MULT_EXPR, itype, threadid, step);
13543   if (POINTER_TYPE_P (type))
13544     t = fold_build_pointer_plus (n1, t);
13545   else
13546     t = fold_build2 (PLUS_EXPR, type, t, n1);
13547   t = fold_convert (type, t);
13548   t = force_gimple_operand_gsi (&gsi, t,
13549                                 DECL_P (startvar)
13550                                 && TREE_ADDRESSABLE (startvar),
13551                                 NULL_TREE, true, GSI_SAME_STMT);
13552   gassign *assign_stmt = gimple_build_assign (startvar, t);
13553   gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
13554
13555   /* Remove the omp for statement */
13556   gsi = gsi_last_bb (kfor->entry);
13557   gsi_remove (&gsi, true);
13558
13559   /* Remove the GIMPLE_OMP_CONTINUE statement.  */
13560   gsi = gsi_last_bb (kfor->cont);
13561   gcc_assert (!gsi_end_p (gsi)
13562               && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_CONTINUE);
13563   gsi_remove (&gsi, true);
13564
13565   /* Replace the GIMPLE_OMP_RETURN with a real return.  */
13566   gsi = gsi_last_bb (kfor->exit);
13567   gcc_assert (!gsi_end_p (gsi)
13568               && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
13569   gsi_remove (&gsi, true);
13570
13571   /* Fixup the much simpler CFG.  */
13572   remove_edge (find_edge (kfor->cont, body_bb));
13573
13574   if (kfor->cont != body_bb)
13575     set_immediate_dominator (CDI_DOMINATORS, kfor->cont, body_bb);
13576   set_immediate_dominator (CDI_DOMINATORS, kfor->exit, kfor->cont);
13577 }
13578
13579 /* Structure passed to grid_remap_kernel_arg_accesses so that it can remap
13580    argument_decls.  */
13581
13582 struct grid_arg_decl_map
13583 {
13584   tree old_arg;
13585   tree new_arg;
13586 };
13587
13588 /* Invoked through walk_gimple_op, will remap all PARM_DECLs to the ones
13589    pertaining to kernel function.  */
13590
13591 static tree
13592 grid_remap_kernel_arg_accesses (tree *tp, int *walk_subtrees, void *data)
13593 {
13594   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
13595   struct grid_arg_decl_map *adm = (struct grid_arg_decl_map *) wi->info;
13596   tree t = *tp;
13597
13598   if (t == adm->old_arg)
13599     *tp = adm->new_arg;
13600   *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
13601   return NULL_TREE;
13602 }
13603
13604 static void expand_omp (struct omp_region *region);
13605
13606 /* If TARGET region contains a kernel body for loop, remove its region from the
13607    TARGET and expand it in GPGPU kernel fashion. */
13608
13609 static void
13610 grid_expand_target_grid_body (struct omp_region *target)
13611 {
13612   if (!hsa_gen_requested_p ())
13613     return;
13614
13615   gomp_target *tgt_stmt = as_a <gomp_target *> (last_stmt (target->entry));
13616   struct omp_region **pp;
13617
13618   for (pp = &target->inner; *pp; pp = &(*pp)->next)
13619     if ((*pp)->type == GIMPLE_OMP_GRID_BODY)
13620       break;
13621
13622   struct omp_region *gpukernel = *pp;
13623
13624   tree orig_child_fndecl = gimple_omp_target_child_fn (tgt_stmt);
13625   if (!gpukernel)
13626     {
13627       /* HSA cannot handle OACC stuff.  */
13628       if (gimple_omp_target_kind (tgt_stmt) != GF_OMP_TARGET_KIND_REGION)
13629         return;
13630       gcc_checking_assert (orig_child_fndecl);
13631       gcc_assert (!find_omp_clause (gimple_omp_target_clauses (tgt_stmt),
13632                                     OMP_CLAUSE__GRIDDIM_));
13633       cgraph_node *n = cgraph_node::get (orig_child_fndecl);
13634
13635       hsa_register_kernel (n);
13636       return;
13637     }
13638
13639   gcc_assert (find_omp_clause (gimple_omp_target_clauses (tgt_stmt),
13640                                OMP_CLAUSE__GRIDDIM_));
13641   tree inside_block = gimple_block (first_stmt (single_succ (gpukernel->entry)));
13642   *pp = gpukernel->next;
13643   for (pp = &gpukernel->inner; *pp; pp = &(*pp)->next)
13644     if ((*pp)->type == GIMPLE_OMP_FOR)
13645       break;
13646
13647   struct omp_region *kfor = *pp;
13648   gcc_assert (kfor);
13649   gcc_assert (gimple_omp_for_kind (last_stmt ((kfor)->entry))
13650               == GF_OMP_FOR_KIND_GRID_LOOP);
13651   *pp = kfor->next;
13652   if (kfor->inner)
13653     expand_omp (kfor->inner);
13654   if (gpukernel->inner)
13655     expand_omp (gpukernel->inner);
13656
13657   tree kern_fndecl = copy_node (orig_child_fndecl);
13658   DECL_NAME (kern_fndecl) = clone_function_name (kern_fndecl, "kernel");
13659   SET_DECL_ASSEMBLER_NAME (kern_fndecl, DECL_NAME (kern_fndecl));
13660   tree tgtblock = gimple_block (tgt_stmt);
13661   tree fniniblock = make_node (BLOCK);
13662   BLOCK_ABSTRACT_ORIGIN (fniniblock) = tgtblock;
13663   BLOCK_SOURCE_LOCATION (fniniblock) = BLOCK_SOURCE_LOCATION (tgtblock);
13664   BLOCK_SOURCE_END_LOCATION (fniniblock) = BLOCK_SOURCE_END_LOCATION (tgtblock);
13665   DECL_INITIAL (kern_fndecl) = fniniblock;
13666   push_struct_function (kern_fndecl);
13667   cfun->function_end_locus = gimple_location (tgt_stmt);
13668   init_tree_ssa (cfun);
13669   pop_cfun ();
13670
13671   tree old_parm_decl = DECL_ARGUMENTS (kern_fndecl);
13672   gcc_assert (!DECL_CHAIN (old_parm_decl));
13673   tree new_parm_decl = copy_node (DECL_ARGUMENTS (kern_fndecl));
13674   DECL_CONTEXT (new_parm_decl) = kern_fndecl;
13675   DECL_ARGUMENTS (kern_fndecl) = new_parm_decl;
13676   gcc_assert (VOID_TYPE_P (TREE_TYPE (DECL_RESULT (kern_fndecl))));
13677   DECL_RESULT (kern_fndecl) = copy_node (DECL_RESULT (kern_fndecl));
13678   DECL_CONTEXT (DECL_RESULT (kern_fndecl)) = kern_fndecl;
13679   struct function *kern_cfun = DECL_STRUCT_FUNCTION (kern_fndecl);
13680   kern_cfun->curr_properties = cfun->curr_properties;
13681
13682   remove_edge (BRANCH_EDGE (kfor->entry));
13683   grid_expand_omp_for_loop (kfor);
13684
13685   /* Remove the omp for statement */
13686   gimple_stmt_iterator gsi = gsi_last_bb (gpukernel->entry);
13687   gsi_remove (&gsi, true);
13688   /* Replace the GIMPLE_OMP_RETURN at the end of the kernel region with a real
13689      return.  */
13690   gsi = gsi_last_bb (gpukernel->exit);
13691   gcc_assert (!gsi_end_p (gsi)
13692               && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
13693   gimple *ret_stmt = gimple_build_return (NULL);
13694   gsi_insert_after (&gsi, ret_stmt, GSI_SAME_STMT);
13695   gsi_remove (&gsi, true);
13696
13697   /* Statements in the first BB in the target construct have been produced by
13698      target lowering and must be copied inside the GPUKERNEL, with the two
13699      exceptions of the first OMP statement and the OMP_DATA assignment
13700      statement.  */
13701   gsi = gsi_start_bb (single_succ (gpukernel->entry));
13702   tree data_arg = gimple_omp_target_data_arg (tgt_stmt);
13703   tree sender = data_arg ? TREE_VEC_ELT (data_arg, 0) : NULL;
13704   for (gimple_stmt_iterator tsi = gsi_start_bb (single_succ (target->entry));
13705        !gsi_end_p (tsi); gsi_next (&tsi))
13706     {
13707       gimple *stmt = gsi_stmt (tsi);
13708       if (is_gimple_omp (stmt))
13709         break;
13710       if (sender
13711           && is_gimple_assign (stmt)
13712           && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR
13713           && TREE_OPERAND (gimple_assign_rhs1 (stmt), 0) == sender)
13714         continue;
13715       gimple *copy = gimple_copy (stmt);
13716       gsi_insert_before (&gsi, copy, GSI_SAME_STMT);
13717       gimple_set_block (copy, fniniblock);
13718     }
13719
13720   move_sese_region_to_fn (kern_cfun, single_succ (gpukernel->entry),
13721                           gpukernel->exit, inside_block);
13722
13723   cgraph_node *kcn = cgraph_node::get_create (kern_fndecl);
13724   kcn->mark_force_output ();
13725   cgraph_node *orig_child = cgraph_node::get (orig_child_fndecl);
13726
13727   hsa_register_kernel (kcn, orig_child);
13728
13729   cgraph_node::add_new_function (kern_fndecl, true);
13730   push_cfun (kern_cfun);
13731   cgraph_edge::rebuild_edges ();
13732
13733   /* Re-map any mention of the PARM_DECL of the original function to the
13734      PARM_DECL of the new one.
13735
13736      TODO: It would be great if lowering produced references into the GPU
13737      kernel decl straight away and we did not have to do this.  */
13738   struct grid_arg_decl_map adm;
13739   adm.old_arg = old_parm_decl;
13740   adm.new_arg = new_parm_decl;
13741   basic_block bb;
13742   FOR_EACH_BB_FN (bb, kern_cfun)
13743     {
13744       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
13745         {
13746           gimple *stmt = gsi_stmt (gsi);
13747           struct walk_stmt_info wi;
13748           memset (&wi, 0, sizeof (wi));
13749           wi.info = &adm;
13750           walk_gimple_op (stmt, grid_remap_kernel_arg_accesses, &wi);
13751         }
13752     }
13753   pop_cfun ();
13754
13755   return;
13756 }
13757
13758 /* Expand the parallel region tree rooted at REGION.  Expansion
13759    proceeds in depth-first order.  Innermost regions are expanded
13760    first.  This way, parallel regions that require a new function to
13761    be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
13762    internal dependencies in their body.  */
13763
13764 static void
13765 expand_omp (struct omp_region *region)
13766 {
13767   omp_any_child_fn_dumped = false;
13768   while (region)
13769     {
13770       location_t saved_location;
13771       gimple *inner_stmt = NULL;
13772
13773       /* First, determine whether this is a combined parallel+workshare
13774          region.  */
13775       if (region->type == GIMPLE_OMP_PARALLEL)
13776         determine_parallel_type (region);
13777       else if (region->type == GIMPLE_OMP_TARGET)
13778         grid_expand_target_grid_body (region);
13779
13780       if (region->type == GIMPLE_OMP_FOR
13781           && gimple_omp_for_combined_p (last_stmt (region->entry)))
13782         inner_stmt = last_stmt (region->inner->entry);
13783
13784       if (region->inner)
13785         expand_omp (region->inner);
13786
13787       saved_location = input_location;
13788       if (gimple_has_location (last_stmt (region->entry)))
13789         input_location = gimple_location (last_stmt (region->entry));
13790
13791       switch (region->type)
13792         {
13793         case GIMPLE_OMP_PARALLEL:
13794         case GIMPLE_OMP_TASK:
13795           expand_omp_taskreg (region);
13796           break;
13797
13798         case GIMPLE_OMP_FOR:
13799           expand_omp_for (region, inner_stmt);
13800           break;
13801
13802         case GIMPLE_OMP_SECTIONS:
13803           expand_omp_sections (region);
13804           break;
13805
13806         case GIMPLE_OMP_SECTION:
13807           /* Individual omp sections are handled together with their
13808              parent GIMPLE_OMP_SECTIONS region.  */
13809           break;
13810
13811         case GIMPLE_OMP_SINGLE:
13812           expand_omp_single (region);
13813           break;
13814
13815         case GIMPLE_OMP_ORDERED:
13816           {
13817             gomp_ordered *ord_stmt
13818               = as_a <gomp_ordered *> (last_stmt (region->entry));
13819             if (find_omp_clause (gimple_omp_ordered_clauses (ord_stmt),
13820                                  OMP_CLAUSE_DEPEND))
13821               {
13822                 /* We'll expand these when expanding corresponding
13823                    worksharing region with ordered(n) clause.  */
13824                 gcc_assert (region->outer
13825                             && region->outer->type == GIMPLE_OMP_FOR);
13826                 region->ord_stmt = ord_stmt;
13827                 break;
13828               }
13829           }
13830           /* FALLTHRU */
13831         case GIMPLE_OMP_MASTER:
13832         case GIMPLE_OMP_TASKGROUP:
13833         case GIMPLE_OMP_CRITICAL:
13834         case GIMPLE_OMP_TEAMS:
13835           expand_omp_synch (region);
13836           break;
13837
13838         case GIMPLE_OMP_ATOMIC_LOAD:
13839           expand_omp_atomic (region);
13840           break;
13841
13842         case GIMPLE_OMP_TARGET:
13843           expand_omp_target (region);
13844           break;
13845
13846         default:
13847           gcc_unreachable ();
13848         }
13849
13850       input_location = saved_location;
13851       region = region->next;
13852     }
13853   if (omp_any_child_fn_dumped)
13854     {
13855       if (dump_file)
13856         dump_function_header (dump_file, current_function_decl, dump_flags);
13857       omp_any_child_fn_dumped = false;
13858     }
13859 }
13860
13861
13862 /* Helper for build_omp_regions.  Scan the dominator tree starting at
13863    block BB.  PARENT is the region that contains BB.  If SINGLE_TREE is
13864    true, the function ends once a single tree is built (otherwise, whole
13865    forest of OMP constructs may be built).  */
13866
13867 static void
13868 build_omp_regions_1 (basic_block bb, struct omp_region *parent,
13869                      bool single_tree)
13870 {
13871   gimple_stmt_iterator gsi;
13872   gimple *stmt;
13873   basic_block son;
13874
13875   gsi = gsi_last_bb (bb);
13876   if (!gsi_end_p (gsi) && is_gimple_omp (gsi_stmt (gsi)))
13877     {
13878       struct omp_region *region;
13879       enum gimple_code code;
13880
13881       stmt = gsi_stmt (gsi);
13882       code = gimple_code (stmt);
13883       if (code == GIMPLE_OMP_RETURN)
13884         {
13885           /* STMT is the return point out of region PARENT.  Mark it
13886              as the exit point and make PARENT the immediately
13887              enclosing region.  */
13888           gcc_assert (parent);
13889           region = parent;
13890           region->exit = bb;
13891           parent = parent->outer;
13892         }
13893       else if (code == GIMPLE_OMP_ATOMIC_STORE)
13894         {
13895           /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
13896              GIMPLE_OMP_RETURN, but matches with
13897              GIMPLE_OMP_ATOMIC_LOAD.  */
13898           gcc_assert (parent);
13899           gcc_assert (parent->type == GIMPLE_OMP_ATOMIC_LOAD);
13900           region = parent;
13901           region->exit = bb;
13902           parent = parent->outer;
13903         }
13904       else if (code == GIMPLE_OMP_CONTINUE)
13905         {
13906           gcc_assert (parent);
13907           parent->cont = bb;
13908         }
13909       else if (code == GIMPLE_OMP_SECTIONS_SWITCH)
13910         {
13911           /* GIMPLE_OMP_SECTIONS_SWITCH is part of
13912              GIMPLE_OMP_SECTIONS, and we do nothing for it.  */
13913         }
13914       else
13915         {
13916           region = new_omp_region (bb, code, parent);
13917           /* Otherwise...  */
13918           if (code == GIMPLE_OMP_TARGET)
13919             {
13920               switch (gimple_omp_target_kind (stmt))
13921                 {
13922                 case GF_OMP_TARGET_KIND_REGION:
13923                 case GF_OMP_TARGET_KIND_DATA:
13924                 case GF_OMP_TARGET_KIND_OACC_PARALLEL:
13925                 case GF_OMP_TARGET_KIND_OACC_KERNELS:
13926                 case GF_OMP_TARGET_KIND_OACC_DATA:
13927                 case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
13928                   break;
13929                 case GF_OMP_TARGET_KIND_UPDATE:
13930                 case GF_OMP_TARGET_KIND_ENTER_DATA:
13931                 case GF_OMP_TARGET_KIND_EXIT_DATA:
13932                 case GF_OMP_TARGET_KIND_OACC_UPDATE:
13933                 case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
13934                 case GF_OMP_TARGET_KIND_OACC_DECLARE:
13935                   /* ..., other than for those stand-alone directives...  */
13936                   region = NULL;
13937                   break;
13938                 default:
13939                   gcc_unreachable ();
13940                 }
13941             }
13942           else if (code == GIMPLE_OMP_ORDERED
13943                    && find_omp_clause (gimple_omp_ordered_clauses
13944                                          (as_a <gomp_ordered *> (stmt)),
13945                                        OMP_CLAUSE_DEPEND))
13946             /* #pragma omp ordered depend is also just a stand-alone
13947                directive.  */
13948             region = NULL;
13949           /* ..., this directive becomes the parent for a new region.  */
13950           if (region)
13951             parent = region;
13952         }
13953     }
13954
13955   if (single_tree && !parent)
13956     return;
13957
13958   for (son = first_dom_son (CDI_DOMINATORS, bb);
13959        son;
13960        son = next_dom_son (CDI_DOMINATORS, son))
13961     build_omp_regions_1 (son, parent, single_tree);
13962 }
13963
13964 /* Builds the tree of OMP regions rooted at ROOT, storing it to
13965    root_omp_region.  */
13966
13967 static void
13968 build_omp_regions_root (basic_block root)
13969 {
13970   gcc_assert (root_omp_region == NULL);
13971   build_omp_regions_1 (root, NULL, true);
13972   gcc_assert (root_omp_region != NULL);
13973 }
13974
13975 /* Expands omp construct (and its subconstructs) starting in HEAD.  */
13976
13977 void
13978 omp_expand_local (basic_block head)
13979 {
13980   build_omp_regions_root (head);
13981   if (dump_file && (dump_flags & TDF_DETAILS))
13982     {
13983       fprintf (dump_file, "\nOMP region tree\n\n");
13984       dump_omp_region (dump_file, root_omp_region, 0);
13985       fprintf (dump_file, "\n");
13986     }
13987
13988   remove_exit_barriers (root_omp_region);
13989   expand_omp (root_omp_region);
13990
13991   free_omp_regions ();
13992 }
13993
13994 /* Scan the CFG and build a tree of OMP regions.  Return the root of
13995    the OMP region tree.  */
13996
13997 static void
13998 build_omp_regions (void)
13999 {
14000   gcc_assert (root_omp_region == NULL);
14001   calculate_dominance_info (CDI_DOMINATORS);
14002   build_omp_regions_1 (ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, false);
14003 }
14004
14005 /* Main entry point for expanding OMP-GIMPLE into runtime calls.  */
14006
14007 static unsigned int
14008 execute_expand_omp (void)
14009 {
14010   build_omp_regions ();
14011
14012   if (!root_omp_region)
14013     return 0;
14014
14015   if (dump_file)
14016     {
14017       fprintf (dump_file, "\nOMP region tree\n\n");
14018       dump_omp_region (dump_file, root_omp_region, 0);
14019       fprintf (dump_file, "\n");
14020     }
14021
14022   remove_exit_barriers (root_omp_region);
14023
14024   expand_omp (root_omp_region);
14025
14026   if (flag_checking && !loops_state_satisfies_p (LOOPS_NEED_FIXUP))
14027     verify_loop_structure ();
14028   cleanup_tree_cfg ();
14029
14030   free_omp_regions ();
14031
14032   return 0;
14033 }
14034
14035 /* OMP expansion -- the default pass, run before creation of SSA form.  */
14036
14037 namespace {
14038
14039 const pass_data pass_data_expand_omp =
14040 {
14041   GIMPLE_PASS, /* type */
14042   "ompexp", /* name */
14043   OPTGROUP_NONE, /* optinfo_flags */
14044   TV_NONE, /* tv_id */
14045   PROP_gimple_any, /* properties_required */
14046   PROP_gimple_eomp, /* properties_provided */
14047   0, /* properties_destroyed */
14048   0, /* todo_flags_start */
14049   0, /* todo_flags_finish */
14050 };
14051
14052 class pass_expand_omp : public gimple_opt_pass
14053 {
14054 public:
14055   pass_expand_omp (gcc::context *ctxt)
14056     : gimple_opt_pass (pass_data_expand_omp, ctxt)
14057   {}
14058
14059   /* opt_pass methods: */
14060   virtual unsigned int execute (function *)
14061     {
14062       bool gate = ((flag_cilkplus != 0 || flag_openacc != 0 || flag_openmp != 0
14063                     || flag_openmp_simd != 0)
14064                    && !seen_error ());
14065
14066       /* This pass always runs, to provide PROP_gimple_eomp.
14067          But often, there is nothing to do.  */
14068       if (!gate)
14069         return 0;
14070
14071       return execute_expand_omp ();
14072     }
14073
14074 }; // class pass_expand_omp
14075
14076 } // anon namespace
14077
14078 gimple_opt_pass *
14079 make_pass_expand_omp (gcc::context *ctxt)
14080 {
14081   return new pass_expand_omp (ctxt);
14082 }
14083
14084 namespace {
14085
14086 const pass_data pass_data_expand_omp_ssa =
14087 {
14088   GIMPLE_PASS, /* type */
14089   "ompexpssa", /* name */
14090   OPTGROUP_NONE, /* optinfo_flags */
14091   TV_NONE, /* tv_id */
14092   PROP_cfg | PROP_ssa, /* properties_required */
14093   PROP_gimple_eomp, /* properties_provided */
14094   0, /* properties_destroyed */
14095   0, /* todo_flags_start */
14096   TODO_cleanup_cfg | TODO_rebuild_alias, /* todo_flags_finish */
14097 };
14098
14099 class pass_expand_omp_ssa : public gimple_opt_pass
14100 {
14101 public:
14102   pass_expand_omp_ssa (gcc::context *ctxt)
14103     : gimple_opt_pass (pass_data_expand_omp_ssa, ctxt)
14104   {}
14105
14106   /* opt_pass methods: */
14107   virtual bool gate (function *fun)
14108     {
14109       return !(fun->curr_properties & PROP_gimple_eomp);
14110     }
14111   virtual unsigned int execute (function *) { return execute_expand_omp (); }
14112   opt_pass * clone () { return new pass_expand_omp_ssa (m_ctxt); }
14113
14114 }; // class pass_expand_omp_ssa
14115
14116 } // anon namespace
14117
14118 gimple_opt_pass *
14119 make_pass_expand_omp_ssa (gcc::context *ctxt)
14120 {
14121   return new pass_expand_omp_ssa (ctxt);
14122 }
14123 \f
14124 /* Routines to lower OMP directives into OMP-GIMPLE.  */
14125
14126 /* If ctx is a worksharing context inside of a cancellable parallel
14127    region and it isn't nowait, add lhs to its GIMPLE_OMP_RETURN
14128    and conditional branch to parallel's cancel_label to handle
14129    cancellation in the implicit barrier.  */
14130
14131 static void
14132 maybe_add_implicit_barrier_cancel (omp_context *ctx, gimple_seq *body)
14133 {
14134   gimple *omp_return = gimple_seq_last_stmt (*body);
14135   gcc_assert (gimple_code (omp_return) == GIMPLE_OMP_RETURN);
14136   if (gimple_omp_return_nowait_p (omp_return))
14137     return;
14138   if (ctx->outer
14139       && gimple_code (ctx->outer->stmt) == GIMPLE_OMP_PARALLEL
14140       && ctx->outer->cancellable)
14141     {
14142       tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
14143       tree c_bool_type = TREE_TYPE (TREE_TYPE (fndecl));
14144       tree lhs = create_tmp_var (c_bool_type);
14145       gimple_omp_return_set_lhs (omp_return, lhs);
14146       tree fallthru_label = create_artificial_label (UNKNOWN_LOCATION);
14147       gimple *g = gimple_build_cond (NE_EXPR, lhs,
14148                                     fold_convert (c_bool_type,
14149                                                   boolean_false_node),
14150                                     ctx->outer->cancel_label, fallthru_label);
14151       gimple_seq_add_stmt (body, g);
14152       gimple_seq_add_stmt (body, gimple_build_label (fallthru_label));
14153     }
14154 }
14155
14156 /* Lower the OpenMP sections directive in the current statement in GSI_P.
14157    CTX is the enclosing OMP context for the current statement.  */
14158
14159 static void
14160 lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
14161 {
14162   tree block, control;
14163   gimple_stmt_iterator tgsi;
14164   gomp_sections *stmt;
14165   gimple *t;
14166   gbind *new_stmt, *bind;
14167   gimple_seq ilist, dlist, olist, new_body;
14168
14169   stmt = as_a <gomp_sections *> (gsi_stmt (*gsi_p));
14170
14171   push_gimplify_context ();
14172
14173   dlist = NULL;
14174   ilist = NULL;
14175   lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
14176                            &ilist, &dlist, ctx, NULL);
14177
14178   new_body = gimple_omp_body (stmt);
14179   gimple_omp_set_body (stmt, NULL);
14180   tgsi = gsi_start (new_body);
14181   for (; !gsi_end_p (tgsi); gsi_next (&tgsi))
14182     {
14183       omp_context *sctx;
14184       gimple *sec_start;
14185
14186       sec_start = gsi_stmt (tgsi);
14187       sctx = maybe_lookup_ctx (sec_start);
14188       gcc_assert (sctx);
14189
14190       lower_omp (gimple_omp_body_ptr (sec_start), sctx);
14191       gsi_insert_seq_after (&tgsi, gimple_omp_body (sec_start),
14192                             GSI_CONTINUE_LINKING);
14193       gimple_omp_set_body (sec_start, NULL);
14194
14195       if (gsi_one_before_end_p (tgsi))
14196         {
14197           gimple_seq l = NULL;
14198           lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
14199                                      &l, ctx);
14200           gsi_insert_seq_after (&tgsi, l, GSI_CONTINUE_LINKING);
14201           gimple_omp_section_set_last (sec_start);
14202         }
14203
14204       gsi_insert_after (&tgsi, gimple_build_omp_return (false),
14205                         GSI_CONTINUE_LINKING);
14206     }
14207
14208   block = make_node (BLOCK);
14209   bind = gimple_build_bind (NULL, new_body, block);
14210
14211   olist = NULL;
14212   lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
14213
14214   block = make_node (BLOCK);
14215   new_stmt = gimple_build_bind (NULL, NULL, block);
14216   gsi_replace (gsi_p, new_stmt, true);
14217
14218   pop_gimplify_context (new_stmt);
14219   gimple_bind_append_vars (new_stmt, ctx->block_vars);
14220   BLOCK_VARS (block) = gimple_bind_vars (bind);
14221   if (BLOCK_VARS (block))
14222     TREE_USED (block) = 1;
14223
14224   new_body = NULL;
14225   gimple_seq_add_seq (&new_body, ilist);
14226   gimple_seq_add_stmt (&new_body, stmt);
14227   gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
14228   gimple_seq_add_stmt (&new_body, bind);
14229
14230   control = create_tmp_var (unsigned_type_node, ".section");
14231   t = gimple_build_omp_continue (control, control);
14232   gimple_omp_sections_set_control (stmt, control);
14233   gimple_seq_add_stmt (&new_body, t);
14234
14235   gimple_seq_add_seq (&new_body, olist);
14236   if (ctx->cancellable)
14237     gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
14238   gimple_seq_add_seq (&new_body, dlist);
14239
14240   new_body = maybe_catch_exception (new_body);
14241
14242   t = gimple_build_omp_return
14243         (!!find_omp_clause (gimple_omp_sections_clauses (stmt),
14244                             OMP_CLAUSE_NOWAIT));
14245   gimple_seq_add_stmt (&new_body, t);
14246   maybe_add_implicit_barrier_cancel (ctx, &new_body);
14247
14248   gimple_bind_set_body (new_stmt, new_body);
14249 }
14250
14251
14252 /* A subroutine of lower_omp_single.  Expand the simple form of
14253    a GIMPLE_OMP_SINGLE, without a copyprivate clause:
14254
14255         if (GOMP_single_start ())
14256           BODY;
14257         [ GOMP_barrier (); ]    -> unless 'nowait' is present.
14258
14259   FIXME.  It may be better to delay expanding the logic of this until
14260   pass_expand_omp.  The expanded logic may make the job more difficult
14261   to a synchronization analysis pass.  */
14262
14263 static void
14264 lower_omp_single_simple (gomp_single *single_stmt, gimple_seq *pre_p)
14265 {
14266   location_t loc = gimple_location (single_stmt);
14267   tree tlabel = create_artificial_label (loc);
14268   tree flabel = create_artificial_label (loc);
14269   gimple *call, *cond;
14270   tree lhs, decl;
14271
14272   decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START);
14273   lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)));
14274   call = gimple_build_call (decl, 0);
14275   gimple_call_set_lhs (call, lhs);
14276   gimple_seq_add_stmt (pre_p, call);
14277
14278   cond = gimple_build_cond (EQ_EXPR, lhs,
14279                             fold_convert_loc (loc, TREE_TYPE (lhs),
14280                                               boolean_true_node),
14281                             tlabel, flabel);
14282   gimple_seq_add_stmt (pre_p, cond);
14283   gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
14284   gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
14285   gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
14286 }
14287
14288
14289 /* A subroutine of lower_omp_single.  Expand the simple form of
14290    a GIMPLE_OMP_SINGLE, with a copyprivate clause:
14291
14292         #pragma omp single copyprivate (a, b, c)
14293
14294    Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
14295
14296       {
14297         if ((copyout_p = GOMP_single_copy_start ()) == NULL)
14298           {
14299             BODY;
14300             copyout.a = a;
14301             copyout.b = b;
14302             copyout.c = c;
14303             GOMP_single_copy_end (&copyout);
14304           }
14305         else
14306           {
14307             a = copyout_p->a;
14308             b = copyout_p->b;
14309             c = copyout_p->c;
14310           }
14311         GOMP_barrier ();
14312       }
14313
14314   FIXME.  It may be better to delay expanding the logic of this until
14315   pass_expand_omp.  The expanded logic may make the job more difficult
14316   to a synchronization analysis pass.  */
14317
14318 static void
14319 lower_omp_single_copy (gomp_single *single_stmt, gimple_seq *pre_p,
14320                        omp_context *ctx)
14321 {
14322   tree ptr_type, t, l0, l1, l2, bfn_decl;
14323   gimple_seq copyin_seq;
14324   location_t loc = gimple_location (single_stmt);
14325
14326   ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
14327
14328   ptr_type = build_pointer_type (ctx->record_type);
14329   ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
14330
14331   l0 = create_artificial_label (loc);
14332   l1 = create_artificial_label (loc);
14333   l2 = create_artificial_label (loc);
14334
14335   bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START);
14336   t = build_call_expr_loc (loc, bfn_decl, 0);
14337   t = fold_convert_loc (loc, ptr_type, t);
14338   gimplify_assign (ctx->receiver_decl, t, pre_p);
14339
14340   t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
14341               build_int_cst (ptr_type, 0));
14342   t = build3 (COND_EXPR, void_type_node, t,
14343               build_and_jump (&l0), build_and_jump (&l1));
14344   gimplify_and_add (t, pre_p);
14345
14346   gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
14347
14348   gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
14349
14350   copyin_seq = NULL;
14351   lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
14352                               &copyin_seq, ctx);
14353
14354   t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
14355   bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END);
14356   t = build_call_expr_loc (loc, bfn_decl, 1, t);
14357   gimplify_and_add (t, pre_p);
14358
14359   t = build_and_jump (&l2);
14360   gimplify_and_add (t, pre_p);
14361
14362   gimple_seq_add_stmt (pre_p, gimple_build_label (l1));
14363
14364   gimple_seq_add_seq (pre_p, copyin_seq);
14365
14366   gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
14367 }
14368
14369
14370 /* Expand code for an OpenMP single directive.  */
14371
14372 static void
14373 lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
14374 {
14375   tree block;
14376   gimple *t;
14377   gomp_single *single_stmt = as_a <gomp_single *> (gsi_stmt (*gsi_p));
14378   gbind *bind;
14379   gimple_seq bind_body, bind_body_tail = NULL, dlist;
14380
14381   push_gimplify_context ();
14382
14383   block = make_node (BLOCK);
14384   bind = gimple_build_bind (NULL, NULL, block);
14385   gsi_replace (gsi_p, bind, true);
14386   bind_body = NULL;
14387   dlist = NULL;
14388   lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
14389                            &bind_body, &dlist, ctx, NULL);
14390   lower_omp (gimple_omp_body_ptr (single_stmt), ctx);
14391
14392   gimple_seq_add_stmt (&bind_body, single_stmt);
14393
14394   if (ctx->record_type)
14395     lower_omp_single_copy (single_stmt, &bind_body, ctx);
14396   else
14397     lower_omp_single_simple (single_stmt, &bind_body);
14398
14399   gimple_omp_set_body (single_stmt, NULL);
14400
14401   gimple_seq_add_seq (&bind_body, dlist);
14402
14403   bind_body = maybe_catch_exception (bind_body);
14404
14405   t = gimple_build_omp_return
14406         (!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
14407                             OMP_CLAUSE_NOWAIT));
14408   gimple_seq_add_stmt (&bind_body_tail, t);
14409   maybe_add_implicit_barrier_cancel (ctx, &bind_body_tail);
14410   if (ctx->record_type)
14411     {
14412       gimple_stmt_iterator gsi = gsi_start (bind_body_tail);
14413       tree clobber = build_constructor (ctx->record_type, NULL);
14414       TREE_THIS_VOLATILE (clobber) = 1;
14415       gsi_insert_after (&gsi, gimple_build_assign (ctx->sender_decl,
14416                                                    clobber), GSI_SAME_STMT);
14417     }
14418   gimple_seq_add_seq (&bind_body, bind_body_tail);
14419   gimple_bind_set_body (bind, bind_body);
14420
14421   pop_gimplify_context (bind);
14422
14423   gimple_bind_append_vars (bind, ctx->block_vars);
14424   BLOCK_VARS (block) = ctx->block_vars;
14425   if (BLOCK_VARS (block))
14426     TREE_USED (block) = 1;
14427 }
14428
14429
14430 /* Expand code for an OpenMP master directive.  */
14431
14432 static void
14433 lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
14434 {
14435   tree block, lab = NULL, x, bfn_decl;
14436   gimple *stmt = gsi_stmt (*gsi_p);
14437   gbind *bind;
14438   location_t loc = gimple_location (stmt);
14439   gimple_seq tseq;
14440
14441   push_gimplify_context ();
14442
14443   block = make_node (BLOCK);
14444   bind = gimple_build_bind (NULL, NULL, block);
14445   gsi_replace (gsi_p, bind, true);
14446   gimple_bind_add_stmt (bind, stmt);
14447
14448   bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
14449   x = build_call_expr_loc (loc, bfn_decl, 0);
14450   x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
14451   x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
14452   tseq = NULL;
14453   gimplify_and_add (x, &tseq);
14454   gimple_bind_add_seq (bind, tseq);
14455
14456   lower_omp (gimple_omp_body_ptr (stmt), ctx);
14457   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
14458   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
14459   gimple_omp_set_body (stmt, NULL);
14460
14461   gimple_bind_add_stmt (bind, gimple_build_label (lab));
14462
14463   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
14464
14465   pop_gimplify_context (bind);
14466
14467   gimple_bind_append_vars (bind, ctx->block_vars);
14468   BLOCK_VARS (block) = ctx->block_vars;
14469 }
14470
14471
14472 /* Expand code for an OpenMP taskgroup directive.  */
14473
14474 static void
14475 lower_omp_taskgroup (gimple_stmt_iterator *gsi_p, omp_context *ctx)
14476 {
14477   gimple *stmt = gsi_stmt (*gsi_p);
14478   gcall *x;
14479   gbind *bind;
14480   tree block = make_node (BLOCK);
14481
14482   bind = gimple_build_bind (NULL, NULL, block);
14483   gsi_replace (gsi_p, bind, true);
14484   gimple_bind_add_stmt (bind, stmt);
14485
14486   x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_START),
14487                          0);
14488   gimple_bind_add_stmt (bind, x);
14489
14490   lower_omp (gimple_omp_body_ptr (stmt), ctx);
14491   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
14492   gimple_omp_set_body (stmt, NULL);
14493
14494   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
14495
14496   gimple_bind_append_vars (bind, ctx->block_vars);
14497   BLOCK_VARS (block) = ctx->block_vars;
14498 }
14499
14500
14501 /* Fold the OMP_ORDERED_CLAUSES for the OMP_ORDERED in STMT if possible.  */
14502
14503 static void
14504 lower_omp_ordered_clauses (gimple_stmt_iterator *gsi_p, gomp_ordered *ord_stmt,
14505                            omp_context *ctx)
14506 {
14507   struct omp_for_data fd;
14508   if (!ctx->outer || gimple_code (ctx->outer->stmt) != GIMPLE_OMP_FOR)
14509     return;
14510
14511   unsigned int len = gimple_omp_for_collapse (ctx->outer->stmt);
14512   struct omp_for_data_loop *loops = XALLOCAVEC (struct omp_for_data_loop, len);
14513   extract_omp_for_data (as_a <gomp_for *> (ctx->outer->stmt), &fd, loops);
14514   if (!fd.ordered)
14515     return;
14516
14517   tree *list_p = gimple_omp_ordered_clauses_ptr (ord_stmt);
14518   tree c = gimple_omp_ordered_clauses (ord_stmt);
14519   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14520       && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
14521     {
14522       /* Merge depend clauses from multiple adjacent
14523          #pragma omp ordered depend(sink:...) constructs
14524          into one #pragma omp ordered depend(sink:...), so that
14525          we can optimize them together.  */
14526       gimple_stmt_iterator gsi = *gsi_p;
14527       gsi_next (&gsi);
14528       while (!gsi_end_p (gsi))
14529         {
14530           gimple *stmt = gsi_stmt (gsi);
14531           if (is_gimple_debug (stmt)
14532               || gimple_code (stmt) == GIMPLE_NOP)
14533             {
14534               gsi_next (&gsi);
14535               continue;
14536             }
14537           if (gimple_code (stmt) != GIMPLE_OMP_ORDERED)
14538             break;
14539           gomp_ordered *ord_stmt2 = as_a <gomp_ordered *> (stmt);
14540           c = gimple_omp_ordered_clauses (ord_stmt2);
14541           if (c == NULL_TREE
14542               || OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
14543               || OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_SINK)
14544             break;
14545           while (*list_p)
14546             list_p = &OMP_CLAUSE_CHAIN (*list_p);
14547           *list_p = c;
14548           gsi_remove (&gsi, true);
14549         }
14550     }
14551
14552   /* Canonicalize sink dependence clauses into one folded clause if
14553      possible.
14554
14555      The basic algorithm is to create a sink vector whose first
14556      element is the GCD of all the first elements, and whose remaining
14557      elements are the minimum of the subsequent columns.
14558
14559      We ignore dependence vectors whose first element is zero because
14560      such dependencies are known to be executed by the same thread.
14561
14562      We take into account the direction of the loop, so a minimum
14563      becomes a maximum if the loop is iterating forwards.  We also
14564      ignore sink clauses where the loop direction is unknown, or where
14565      the offsets are clearly invalid because they are not a multiple
14566      of the loop increment.
14567
14568      For example:
14569
14570         #pragma omp for ordered(2)
14571         for (i=0; i < N; ++i)
14572           for (j=0; j < M; ++j)
14573             {
14574               #pragma omp ordered \
14575                 depend(sink:i-8,j-2) \
14576                 depend(sink:i,j-1) \    // Completely ignored because i+0.
14577                 depend(sink:i-4,j-3) \
14578                 depend(sink:i-6,j-4)
14579               #pragma omp ordered depend(source)
14580             }
14581
14582      Folded clause is:
14583
14584         depend(sink:-gcd(8,4,6),-min(2,3,4))
14585           -or-
14586         depend(sink:-2,-2)
14587   */
14588
14589   /* FIXME: Computing GCD's where the first element is zero is
14590      non-trivial in the presence of collapsed loops.  Do this later.  */
14591   if (fd.collapse > 1)
14592     return;
14593
14594   wide_int *folded_deps = XALLOCAVEC (wide_int, 2 * len - 1);
14595   memset (folded_deps, 0, sizeof (*folded_deps) * (2 * len - 1));
14596   tree folded_dep = NULL_TREE;
14597   /* TRUE if the first dimension's offset is negative.  */
14598   bool neg_offset_p = false;
14599
14600   list_p = gimple_omp_ordered_clauses_ptr (ord_stmt);
14601   unsigned int i;
14602   while ((c = *list_p) != NULL)
14603     {
14604       bool remove = false;
14605
14606       gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND);
14607       if (OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_SINK)
14608         goto next_ordered_clause;
14609
14610       tree vec;
14611       for (vec = OMP_CLAUSE_DECL (c), i = 0;
14612            vec && TREE_CODE (vec) == TREE_LIST;
14613            vec = TREE_CHAIN (vec), ++i)
14614         {
14615           gcc_assert (i < len);
14616
14617           /* extract_omp_for_data has canonicalized the condition.  */
14618           gcc_assert (fd.loops[i].cond_code == LT_EXPR
14619                       || fd.loops[i].cond_code == GT_EXPR);
14620           bool forward = fd.loops[i].cond_code == LT_EXPR;
14621           bool maybe_lexically_later = true;
14622
14623           /* While the committee makes up its mind, bail if we have any
14624              non-constant steps.  */
14625           if (TREE_CODE (fd.loops[i].step) != INTEGER_CST)
14626             goto lower_omp_ordered_ret;
14627
14628           tree itype = TREE_TYPE (TREE_VALUE (vec));
14629           if (POINTER_TYPE_P (itype))
14630             itype = sizetype;
14631           wide_int offset = wide_int::from (TREE_PURPOSE (vec),
14632                                             TYPE_PRECISION (itype),
14633                                             TYPE_SIGN (itype));
14634
14635           /* Ignore invalid offsets that are not multiples of the step.  */
14636           if (!wi::multiple_of_p
14637               (wi::abs (offset), wi::abs ((wide_int) fd.loops[i].step),
14638                UNSIGNED))
14639             {
14640               warning_at (OMP_CLAUSE_LOCATION (c), 0,
14641                           "ignoring sink clause with offset that is not "
14642                           "a multiple of the loop step");
14643               remove = true;
14644               goto next_ordered_clause;
14645             }
14646
14647           /* Calculate the first dimension.  The first dimension of
14648              the folded dependency vector is the GCD of the first
14649              elements, while ignoring any first elements whose offset
14650              is 0.  */
14651           if (i == 0)
14652             {
14653               /* Ignore dependence vectors whose first dimension is 0.  */
14654               if (offset == 0)
14655                 {
14656                   remove = true;
14657                   goto next_ordered_clause;
14658                 }
14659               else
14660                 {
14661                   if (!TYPE_UNSIGNED (itype) && (forward ^ wi::neg_p (offset)))
14662                     {
14663                       error_at (OMP_CLAUSE_LOCATION (c),
14664                                 "first offset must be in opposite direction "
14665                                 "of loop iterations");
14666                       goto lower_omp_ordered_ret;
14667                     }
14668                   if (forward)
14669                     offset = -offset;
14670                   neg_offset_p = forward;
14671                   /* Initialize the first time around.  */
14672                   if (folded_dep == NULL_TREE)
14673                     {
14674                       folded_dep = c;
14675                       folded_deps[0] = offset;
14676                     }
14677                   else
14678                     folded_deps[0] = wi::gcd (folded_deps[0],
14679                                               offset, UNSIGNED);
14680                 }
14681             }
14682           /* Calculate minimum for the remaining dimensions.  */
14683           else
14684             {
14685               folded_deps[len + i - 1] = offset;
14686               if (folded_dep == c)
14687                 folded_deps[i] = offset;
14688               else if (maybe_lexically_later
14689                        && !wi::eq_p (folded_deps[i], offset))
14690                 {
14691                   if (forward ^ wi::gts_p (folded_deps[i], offset))
14692                     {
14693                       unsigned int j;
14694                       folded_dep = c;
14695                       for (j = 1; j <= i; j++)
14696                         folded_deps[j] = folded_deps[len + j - 1];
14697                     }
14698                   else
14699                     maybe_lexically_later = false;
14700                 }
14701             }
14702         }
14703       gcc_assert (i == len);
14704
14705       remove = true;
14706
14707     next_ordered_clause:
14708       if (remove)
14709         *list_p = OMP_CLAUSE_CHAIN (c);
14710       else
14711         list_p = &OMP_CLAUSE_CHAIN (c);
14712     }
14713
14714   if (folded_dep)
14715     {
14716       if (neg_offset_p)
14717         folded_deps[0] = -folded_deps[0];
14718
14719       tree itype = TREE_TYPE (TREE_VALUE (OMP_CLAUSE_DECL (folded_dep)));
14720       if (POINTER_TYPE_P (itype))
14721         itype = sizetype;
14722
14723       TREE_PURPOSE (OMP_CLAUSE_DECL (folded_dep))
14724         = wide_int_to_tree (itype, folded_deps[0]);
14725       OMP_CLAUSE_CHAIN (folded_dep) = gimple_omp_ordered_clauses (ord_stmt);
14726       *gimple_omp_ordered_clauses_ptr (ord_stmt) = folded_dep;
14727     }
14728
14729  lower_omp_ordered_ret:
14730
14731   /* Ordered without clauses is #pragma omp threads, while we want
14732      a nop instead if we remove all clauses.  */
14733   if (gimple_omp_ordered_clauses (ord_stmt) == NULL_TREE)
14734     gsi_replace (gsi_p, gimple_build_nop (), true);
14735 }
14736
14737
14738 /* Expand code for an OpenMP ordered directive.  */
14739
14740 static void
14741 lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
14742 {
14743   tree block;
14744   gimple *stmt = gsi_stmt (*gsi_p);
14745   gomp_ordered *ord_stmt = as_a <gomp_ordered *> (stmt);
14746   gcall *x;
14747   gbind *bind;
14748   bool simd = find_omp_clause (gimple_omp_ordered_clauses (ord_stmt),
14749                                OMP_CLAUSE_SIMD);
14750   bool threads = find_omp_clause (gimple_omp_ordered_clauses (ord_stmt),
14751                                   OMP_CLAUSE_THREADS);
14752
14753   if (find_omp_clause (gimple_omp_ordered_clauses (ord_stmt),
14754                        OMP_CLAUSE_DEPEND))
14755     {
14756       /* FIXME: This is needs to be moved to the expansion to verify various
14757          conditions only testable on cfg with dominators computed, and also
14758          all the depend clauses to be merged still might need to be available
14759          for the runtime checks.  */
14760       if (0)
14761         lower_omp_ordered_clauses (gsi_p, ord_stmt, ctx);
14762       return;
14763     }
14764
14765   push_gimplify_context ();
14766
14767   block = make_node (BLOCK);
14768   bind = gimple_build_bind (NULL, NULL, block);
14769   gsi_replace (gsi_p, bind, true);
14770   gimple_bind_add_stmt (bind, stmt);
14771
14772   if (simd)
14773     {
14774       x = gimple_build_call_internal (IFN_GOMP_SIMD_ORDERED_START, 1,
14775                                       build_int_cst (NULL_TREE, threads));
14776       cfun->has_simduid_loops = true;
14777     }
14778   else
14779     x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
14780                            0);
14781   gimple_bind_add_stmt (bind, x);
14782
14783   lower_omp (gimple_omp_body_ptr (stmt), ctx);
14784   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
14785   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
14786   gimple_omp_set_body (stmt, NULL);
14787
14788   if (simd)
14789     x = gimple_build_call_internal (IFN_GOMP_SIMD_ORDERED_END, 1,
14790                                     build_int_cst (NULL_TREE, threads));
14791   else
14792     x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END),
14793                            0);
14794   gimple_bind_add_stmt (bind, x);
14795
14796   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
14797
14798   pop_gimplify_context (bind);
14799
14800   gimple_bind_append_vars (bind, ctx->block_vars);
14801   BLOCK_VARS (block) = gimple_bind_vars (bind);
14802 }
14803
14804
14805 /* Gimplify a GIMPLE_OMP_CRITICAL statement.  This is a relatively simple
14806    substitution of a couple of function calls.  But in the NAMED case,
14807    requires that languages coordinate a symbol name.  It is therefore
14808    best put here in common code.  */
14809
14810 static GTY(()) hash_map<tree, tree> *critical_name_mutexes;
14811
14812 static void
14813 lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
14814 {
14815   tree block;
14816   tree name, lock, unlock;
14817   gomp_critical *stmt = as_a <gomp_critical *> (gsi_stmt (*gsi_p));
14818   gbind *bind;
14819   location_t loc = gimple_location (stmt);
14820   gimple_seq tbody;
14821
14822   name = gimple_omp_critical_name (stmt);
14823   if (name)
14824     {
14825       tree decl;
14826
14827       if (!critical_name_mutexes)
14828         critical_name_mutexes = hash_map<tree, tree>::create_ggc (10);
14829
14830       tree *n = critical_name_mutexes->get (name);
14831       if (n == NULL)
14832         {
14833           char *new_str;
14834
14835           decl = create_tmp_var_raw (ptr_type_node);
14836
14837           new_str = ACONCAT ((".gomp_critical_user_",
14838                               IDENTIFIER_POINTER (name), NULL));
14839           DECL_NAME (decl) = get_identifier (new_str);
14840           TREE_PUBLIC (decl) = 1;
14841           TREE_STATIC (decl) = 1;
14842           DECL_COMMON (decl) = 1;
14843           DECL_ARTIFICIAL (decl) = 1;
14844           DECL_IGNORED_P (decl) = 1;
14845
14846           varpool_node::finalize_decl (decl);
14847
14848           critical_name_mutexes->put (name, decl);
14849         }
14850       else
14851         decl = *n;
14852
14853       /* If '#pragma omp critical' is inside offloaded region or
14854          inside function marked as offloadable, the symbol must be
14855          marked as offloadable too.  */
14856       omp_context *octx;
14857       if (cgraph_node::get (current_function_decl)->offloadable)
14858         varpool_node::get_create (decl)->offloadable = 1;
14859       else
14860         for (octx = ctx->outer; octx; octx = octx->outer)
14861           if (is_gimple_omp_offloaded (octx->stmt))
14862             {
14863               varpool_node::get_create (decl)->offloadable = 1;
14864               break;
14865             }
14866
14867       lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START);
14868       lock = build_call_expr_loc (loc, lock, 1, build_fold_addr_expr_loc (loc, decl));
14869
14870       unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END);
14871       unlock = build_call_expr_loc (loc, unlock, 1,
14872                                 build_fold_addr_expr_loc (loc, decl));
14873     }
14874   else
14875     {
14876       lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START);
14877       lock = build_call_expr_loc (loc, lock, 0);
14878
14879       unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END);
14880       unlock = build_call_expr_loc (loc, unlock, 0);
14881     }
14882
14883   push_gimplify_context ();
14884
14885   block = make_node (BLOCK);
14886   bind = gimple_build_bind (NULL, NULL, block);
14887   gsi_replace (gsi_p, bind, true);
14888   gimple_bind_add_stmt (bind, stmt);
14889
14890   tbody = gimple_bind_body (bind);
14891   gimplify_and_add (lock, &tbody);
14892   gimple_bind_set_body (bind, tbody);
14893
14894   lower_omp (gimple_omp_body_ptr (stmt), ctx);
14895   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
14896   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
14897   gimple_omp_set_body (stmt, NULL);
14898
14899   tbody = gimple_bind_body (bind);
14900   gimplify_and_add (unlock, &tbody);
14901   gimple_bind_set_body (bind, tbody);
14902
14903   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
14904
14905   pop_gimplify_context (bind);
14906   gimple_bind_append_vars (bind, ctx->block_vars);
14907   BLOCK_VARS (block) = gimple_bind_vars (bind);
14908 }
14909
14910
14911 /* A subroutine of lower_omp_for.  Generate code to emit the predicate
14912    for a lastprivate clause.  Given a loop control predicate of (V
14913    cond N2), we gate the clause on (!(V cond N2)).  The lowered form
14914    is appended to *DLIST, iterator initialization is appended to
14915    *BODY_P.  */
14916
14917 static void
14918 lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
14919                            gimple_seq *dlist, struct omp_context *ctx)
14920 {
14921   tree clauses, cond, vinit;
14922   enum tree_code cond_code;
14923   gimple_seq stmts;
14924
14925   cond_code = fd->loop.cond_code;
14926   cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
14927
14928   /* When possible, use a strict equality expression.  This can let VRP
14929      type optimizations deduce the value and remove a copy.  */
14930   if (tree_fits_shwi_p (fd->loop.step))
14931     {
14932       HOST_WIDE_INT step = tree_to_shwi (fd->loop.step);
14933       if (step == 1 || step == -1)
14934         cond_code = EQ_EXPR;
14935     }
14936
14937   tree n2 = fd->loop.n2;
14938   if (fd->collapse > 1
14939       && TREE_CODE (n2) != INTEGER_CST
14940       && gimple_omp_for_combined_into_p (fd->for_stmt))
14941     {
14942       struct omp_context *taskreg_ctx = NULL;
14943       if (gimple_code (ctx->outer->stmt) == GIMPLE_OMP_FOR)
14944         {
14945           gomp_for *gfor = as_a <gomp_for *> (ctx->outer->stmt);
14946           if (gimple_omp_for_kind (gfor) == GF_OMP_FOR_KIND_FOR
14947               || gimple_omp_for_kind (gfor) == GF_OMP_FOR_KIND_DISTRIBUTE)
14948             {
14949               if (gimple_omp_for_combined_into_p (gfor))
14950                 {
14951                   gcc_assert (ctx->outer->outer
14952                               && is_parallel_ctx (ctx->outer->outer));
14953                   taskreg_ctx = ctx->outer->outer;
14954                 }
14955               else
14956                 {
14957                   struct omp_for_data outer_fd;
14958                   extract_omp_for_data (gfor, &outer_fd, NULL);
14959                   n2 = fold_convert (TREE_TYPE (n2), outer_fd.loop.n2);
14960                 }
14961             }
14962           else if (gimple_omp_for_kind (gfor) == GF_OMP_FOR_KIND_TASKLOOP)
14963             taskreg_ctx = ctx->outer->outer;
14964         }
14965       else if (is_taskreg_ctx (ctx->outer))
14966         taskreg_ctx = ctx->outer;
14967       if (taskreg_ctx)
14968         {
14969           int i;
14970           tree innerc
14971             = find_omp_clause (gimple_omp_taskreg_clauses (taskreg_ctx->stmt),
14972                                OMP_CLAUSE__LOOPTEMP_);
14973           gcc_assert (innerc);
14974           for (i = 0; i < fd->collapse; i++)
14975             {
14976               innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
14977                                         OMP_CLAUSE__LOOPTEMP_);
14978               gcc_assert (innerc);
14979             }
14980           innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
14981                                     OMP_CLAUSE__LOOPTEMP_);
14982           if (innerc)
14983             n2 = fold_convert (TREE_TYPE (n2),
14984                                lookup_decl (OMP_CLAUSE_DECL (innerc),
14985                                             taskreg_ctx));
14986         }
14987     }
14988   cond = build2 (cond_code, boolean_type_node, fd->loop.v, n2);
14989
14990   clauses = gimple_omp_for_clauses (fd->for_stmt);
14991   stmts = NULL;
14992   lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
14993   if (!gimple_seq_empty_p (stmts))
14994     {
14995       gimple_seq_add_seq (&stmts, *dlist);
14996       *dlist = stmts;
14997
14998       /* Optimize: v = 0; is usually cheaper than v = some_other_constant.  */
14999       vinit = fd->loop.n1;
15000       if (cond_code == EQ_EXPR
15001           && tree_fits_shwi_p (fd->loop.n2)
15002           && ! integer_zerop (fd->loop.n2))
15003         vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
15004       else
15005         vinit = unshare_expr (vinit);
15006
15007       /* Initialize the iterator variable, so that threads that don't execute
15008          any iterations don't execute the lastprivate clauses by accident.  */
15009       gimplify_assign (fd->loop.v, vinit, body_p);
15010     }
15011 }
15012
15013
15014 /* Lower code for an OMP loop directive.  */
15015
15016 static void
15017 lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
15018 {
15019   tree *rhs_p, block;
15020   struct omp_for_data fd, *fdp = NULL;
15021   gomp_for *stmt = as_a <gomp_for *> (gsi_stmt (*gsi_p));
15022   gbind *new_stmt;
15023   gimple_seq omp_for_body, body, dlist;
15024   gimple_seq oacc_head = NULL, oacc_tail = NULL;
15025   size_t i;
15026
15027   push_gimplify_context ();
15028
15029   lower_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
15030
15031   block = make_node (BLOCK);
15032   new_stmt = gimple_build_bind (NULL, NULL, block);
15033   /* Replace at gsi right away, so that 'stmt' is no member
15034      of a sequence anymore as we're going to add to a different
15035      one below.  */
15036   gsi_replace (gsi_p, new_stmt, true);
15037
15038   /* Move declaration of temporaries in the loop body before we make
15039      it go away.  */
15040   omp_for_body = gimple_omp_body (stmt);
15041   if (!gimple_seq_empty_p (omp_for_body)
15042       && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
15043     {
15044       gbind *inner_bind
15045         = as_a <gbind *> (gimple_seq_first_stmt (omp_for_body));
15046       tree vars = gimple_bind_vars (inner_bind);
15047       gimple_bind_append_vars (new_stmt, vars);
15048       /* bind_vars/BLOCK_VARS are being moved to new_stmt/block, don't
15049          keep them on the inner_bind and it's block.  */
15050       gimple_bind_set_vars (inner_bind, NULL_TREE);
15051       if (gimple_bind_block (inner_bind))
15052         BLOCK_VARS (gimple_bind_block (inner_bind)) = NULL_TREE;
15053     }
15054
15055   if (gimple_omp_for_combined_into_p (stmt))
15056     {
15057       extract_omp_for_data (stmt, &fd, NULL);
15058       fdp = &fd;
15059
15060       /* We need two temporaries with fd.loop.v type (istart/iend)
15061          and then (fd.collapse - 1) temporaries with the same
15062          type for count2 ... countN-1 vars if not constant.  */
15063       size_t count = 2;
15064       tree type = fd.iter_type;
15065       if (fd.collapse > 1
15066           && TREE_CODE (fd.loop.n2) != INTEGER_CST)
15067         count += fd.collapse - 1;
15068       bool taskreg_for
15069         = (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR
15070            || gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_TASKLOOP);
15071       tree outerc = NULL, *pc = gimple_omp_for_clauses_ptr (stmt);
15072       tree clauses = *pc;
15073       if (taskreg_for)
15074         outerc
15075           = find_omp_clause (gimple_omp_taskreg_clauses (ctx->outer->stmt),
15076                              OMP_CLAUSE__LOOPTEMP_);
15077       for (i = 0; i < count; i++)
15078         {
15079           tree temp;
15080           if (taskreg_for)
15081             {
15082               gcc_assert (outerc);
15083               temp = lookup_decl (OMP_CLAUSE_DECL (outerc), ctx->outer);
15084               outerc = find_omp_clause (OMP_CLAUSE_CHAIN (outerc),
15085                                         OMP_CLAUSE__LOOPTEMP_);
15086             }
15087           else
15088             {
15089               temp = create_tmp_var (type);
15090               insert_decl_map (&ctx->outer->cb, temp, temp);
15091             }
15092           *pc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__LOOPTEMP_);
15093           OMP_CLAUSE_DECL (*pc) = temp;
15094           pc = &OMP_CLAUSE_CHAIN (*pc);
15095         }
15096       *pc = clauses;
15097     }
15098
15099   /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR.  */
15100   dlist = NULL;
15101   body = NULL;
15102   lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx,
15103                            fdp);
15104   gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
15105
15106   lower_omp (gimple_omp_body_ptr (stmt), ctx);
15107
15108   /* Lower the header expressions.  At this point, we can assume that
15109      the header is of the form:
15110
15111         #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
15112
15113      We just need to make sure that VAL1, VAL2 and VAL3 are lowered
15114      using the .omp_data_s mapping, if needed.  */
15115   for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
15116     {
15117       rhs_p = gimple_omp_for_initial_ptr (stmt, i);
15118       if (!is_gimple_min_invariant (*rhs_p))
15119         *rhs_p = get_formal_tmp_var (*rhs_p, &body);
15120
15121       rhs_p = gimple_omp_for_final_ptr (stmt, i);
15122       if (!is_gimple_min_invariant (*rhs_p))
15123         *rhs_p = get_formal_tmp_var (*rhs_p, &body);
15124
15125       rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
15126       if (!is_gimple_min_invariant (*rhs_p))
15127         *rhs_p = get_formal_tmp_var (*rhs_p, &body);
15128     }
15129
15130   /* Once lowered, extract the bounds and clauses.  */
15131   extract_omp_for_data (stmt, &fd, NULL);
15132
15133   if (is_gimple_omp_oacc (ctx->stmt)
15134       && !ctx_in_oacc_kernels_region (ctx))
15135     lower_oacc_head_tail (gimple_location (stmt),
15136                           gimple_omp_for_clauses (stmt),
15137                           &oacc_head, &oacc_tail, ctx);
15138
15139   /* Add OpenACC partitioning and reduction markers just before the loop  */
15140   if (oacc_head)
15141     gimple_seq_add_seq (&body, oacc_head);
15142   
15143   lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
15144
15145   if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR)
15146     for (tree c = gimple_omp_for_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
15147       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
15148           && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
15149         {
15150           OMP_CLAUSE_DECL (c) = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
15151           if (DECL_P (OMP_CLAUSE_LINEAR_STEP (c)))
15152             OMP_CLAUSE_LINEAR_STEP (c)
15153               = maybe_lookup_decl_in_outer_ctx (OMP_CLAUSE_LINEAR_STEP (c),
15154                                                 ctx);
15155         }
15156
15157   if (!gimple_omp_for_grid_phony (stmt))
15158     gimple_seq_add_stmt (&body, stmt);
15159   gimple_seq_add_seq (&body, gimple_omp_body (stmt));
15160
15161   if (!gimple_omp_for_grid_phony (stmt))
15162     gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
15163                                                            fd.loop.v));
15164
15165   /* After the loop, add exit clauses.  */
15166   lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, ctx);
15167
15168   if (ctx->cancellable)
15169     gimple_seq_add_stmt (&body, gimple_build_label (ctx->cancel_label));
15170
15171   gimple_seq_add_seq (&body, dlist);
15172
15173   body = maybe_catch_exception (body);
15174
15175   if (!gimple_omp_for_grid_phony (stmt))
15176     {
15177       /* Region exit marker goes at the end of the loop body.  */
15178       gimple_seq_add_stmt (&body, gimple_build_omp_return (fd.have_nowait));
15179       maybe_add_implicit_barrier_cancel (ctx, &body);
15180     }
15181
15182   /* Add OpenACC joining and reduction markers just after the loop.  */
15183   if (oacc_tail)
15184     gimple_seq_add_seq (&body, oacc_tail);
15185
15186   pop_gimplify_context (new_stmt);
15187
15188   gimple_bind_append_vars (new_stmt, ctx->block_vars);
15189   BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
15190   if (BLOCK_VARS (block))
15191     TREE_USED (block) = 1;
15192
15193   gimple_bind_set_body (new_stmt, body);
15194   gimple_omp_set_body (stmt, NULL);
15195   gimple_omp_for_set_pre_body (stmt, NULL);
15196 }
15197
15198 /* Callback for walk_stmts.  Check if the current statement only contains
15199    GIMPLE_OMP_FOR or GIMPLE_OMP_SECTIONS.  */
15200
15201 static tree
15202 check_combined_parallel (gimple_stmt_iterator *gsi_p,
15203                          bool *handled_ops_p,
15204                          struct walk_stmt_info *wi)
15205 {
15206   int *info = (int *) wi->info;
15207   gimple *stmt = gsi_stmt (*gsi_p);
15208
15209   *handled_ops_p = true;
15210   switch (gimple_code (stmt))
15211     {
15212     WALK_SUBSTMTS;
15213
15214     case GIMPLE_OMP_FOR:
15215     case GIMPLE_OMP_SECTIONS:
15216       *info = *info == 0 ? 1 : -1;
15217       break;
15218     default:
15219       *info = -1;
15220       break;
15221     }
15222   return NULL;
15223 }
15224
15225 struct omp_taskcopy_context
15226 {
15227   /* This field must be at the beginning, as we do "inheritance": Some
15228      callback functions for tree-inline.c (e.g., omp_copy_decl)
15229      receive a copy_body_data pointer that is up-casted to an
15230      omp_context pointer.  */
15231   copy_body_data cb;
15232   omp_context *ctx;
15233 };
15234
15235 static tree
15236 task_copyfn_copy_decl (tree var, copy_body_data *cb)
15237 {
15238   struct omp_taskcopy_context *tcctx = (struct omp_taskcopy_context *) cb;
15239
15240   if (splay_tree_lookup (tcctx->ctx->sfield_map, (splay_tree_key) var))
15241     return create_tmp_var (TREE_TYPE (var));
15242
15243   return var;
15244 }
15245
15246 static tree
15247 task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
15248 {
15249   tree name, new_fields = NULL, type, f;
15250
15251   type = lang_hooks.types.make_type (RECORD_TYPE);
15252   name = DECL_NAME (TYPE_NAME (orig_type));
15253   name = build_decl (gimple_location (tcctx->ctx->stmt),
15254                      TYPE_DECL, name, type);
15255   TYPE_NAME (type) = name;
15256
15257   for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
15258     {
15259       tree new_f = copy_node (f);
15260       DECL_CONTEXT (new_f) = type;
15261       TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
15262       TREE_CHAIN (new_f) = new_fields;
15263       walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
15264       walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
15265       walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
15266                  &tcctx->cb, NULL);
15267       new_fields = new_f;
15268       tcctx->cb.decl_map->put (f, new_f);
15269     }
15270   TYPE_FIELDS (type) = nreverse (new_fields);
15271   layout_type (type);
15272   return type;
15273 }
15274
15275 /* Create task copyfn.  */
15276
15277 static void
15278 create_task_copyfn (gomp_task *task_stmt, omp_context *ctx)
15279 {
15280   struct function *child_cfun;
15281   tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
15282   tree record_type, srecord_type, bind, list;
15283   bool record_needs_remap = false, srecord_needs_remap = false;
15284   splay_tree_node n;
15285   struct omp_taskcopy_context tcctx;
15286   location_t loc = gimple_location (task_stmt);
15287
15288   child_fn = gimple_omp_task_copy_fn (task_stmt);
15289   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
15290   gcc_assert (child_cfun->cfg == NULL);
15291   DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();
15292
15293   /* Reset DECL_CONTEXT on function arguments.  */
15294   for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
15295     DECL_CONTEXT (t) = child_fn;
15296
15297   /* Populate the function.  */
15298   push_gimplify_context ();
15299   push_cfun (child_cfun);
15300
15301   bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
15302   TREE_SIDE_EFFECTS (bind) = 1;
15303   list = NULL;
15304   DECL_SAVED_TREE (child_fn) = bind;
15305   DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);
15306
15307   /* Remap src and dst argument types if needed.  */
15308   record_type = ctx->record_type;
15309   srecord_type = ctx->srecord_type;
15310   for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
15311     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
15312       {
15313         record_needs_remap = true;
15314         break;
15315       }
15316   for (f = TYPE_FIELDS (srecord_type); f ; f = DECL_CHAIN (f))
15317     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
15318       {
15319         srecord_needs_remap = true;
15320         break;
15321       }
15322
15323   if (record_needs_remap || srecord_needs_remap)
15324     {
15325       memset (&tcctx, '\0', sizeof (tcctx));
15326       tcctx.cb.src_fn = ctx->cb.src_fn;
15327       tcctx.cb.dst_fn = child_fn;
15328       tcctx.cb.src_node = cgraph_node::get (tcctx.cb.src_fn);
15329       gcc_checking_assert (tcctx.cb.src_node);
15330       tcctx.cb.dst_node = tcctx.cb.src_node;
15331       tcctx.cb.src_cfun = ctx->cb.src_cfun;
15332       tcctx.cb.copy_decl = task_copyfn_copy_decl;
15333       tcctx.cb.eh_lp_nr = 0;
15334       tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
15335       tcctx.cb.decl_map = new hash_map<tree, tree>;
15336       tcctx.ctx = ctx;
15337
15338       if (record_needs_remap)
15339         record_type = task_copyfn_remap_type (&tcctx, record_type);
15340       if (srecord_needs_remap)
15341         srecord_type = task_copyfn_remap_type (&tcctx, srecord_type);
15342     }
15343   else
15344     tcctx.cb.decl_map = NULL;
15345
15346   arg = DECL_ARGUMENTS (child_fn);
15347   TREE_TYPE (arg) = build_pointer_type (record_type);
15348   sarg = DECL_CHAIN (arg);
15349   TREE_TYPE (sarg) = build_pointer_type (srecord_type);
15350
15351   /* First pass: initialize temporaries used in record_type and srecord_type
15352      sizes and field offsets.  */
15353   if (tcctx.cb.decl_map)
15354     for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
15355       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
15356         {
15357           tree *p;
15358
15359           decl = OMP_CLAUSE_DECL (c);
15360           p = tcctx.cb.decl_map->get (decl);
15361           if (p == NULL)
15362             continue;
15363           n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
15364           sf = (tree) n->value;
15365           sf = *tcctx.cb.decl_map->get (sf);
15366           src = build_simple_mem_ref_loc (loc, sarg);
15367           src = omp_build_component_ref (src, sf);
15368           t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
15369           append_to_statement_list (t, &list);
15370         }
15371
15372   /* Second pass: copy shared var pointers and copy construct non-VLA
15373      firstprivate vars.  */
15374   for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
15375     switch (OMP_CLAUSE_CODE (c))
15376       {
15377         splay_tree_key key;
15378       case OMP_CLAUSE_SHARED:
15379         decl = OMP_CLAUSE_DECL (c);
15380         key = (splay_tree_key) decl;
15381         if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c))
15382           key = (splay_tree_key) &DECL_UID (decl);
15383         n = splay_tree_lookup (ctx->field_map, key);
15384         if (n == NULL)
15385           break;
15386         f = (tree) n->value;
15387         if (tcctx.cb.decl_map)
15388           f = *tcctx.cb.decl_map->get (f);
15389         n = splay_tree_lookup (ctx->sfield_map, key);
15390         sf = (tree) n->value;
15391         if (tcctx.cb.decl_map)
15392           sf = *tcctx.cb.decl_map->get (sf);
15393         src = build_simple_mem_ref_loc (loc, sarg);
15394         src = omp_build_component_ref (src, sf);
15395         dst = build_simple_mem_ref_loc (loc, arg);
15396         dst = omp_build_component_ref (dst, f);
15397         t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
15398         append_to_statement_list (t, &list);
15399         break;
15400       case OMP_CLAUSE_FIRSTPRIVATE:
15401         decl = OMP_CLAUSE_DECL (c);
15402         if (is_variable_sized (decl))
15403           break;
15404         n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
15405         if (n == NULL)
15406           break;
15407         f = (tree) n->value;
15408         if (tcctx.cb.decl_map)
15409           f = *tcctx.cb.decl_map->get (f);
15410         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
15411         if (n != NULL)
15412           {
15413             sf = (tree) n->value;
15414             if (tcctx.cb.decl_map)
15415               sf = *tcctx.cb.decl_map->get (sf);
15416             src = build_simple_mem_ref_loc (loc, sarg);
15417             src = omp_build_component_ref (src, sf);
15418             if (use_pointer_for_field (decl, NULL) || is_reference (decl))
15419               src = build_simple_mem_ref_loc (loc, src);
15420           }
15421         else
15422           src = decl;
15423         dst = build_simple_mem_ref_loc (loc, arg);
15424         dst = omp_build_component_ref (dst, f);
15425         t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
15426         append_to_statement_list (t, &list);
15427         break;
15428       case OMP_CLAUSE_PRIVATE:
15429         if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c))
15430           break;
15431         decl = OMP_CLAUSE_DECL (c);
15432         n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
15433         f = (tree) n->value;
15434         if (tcctx.cb.decl_map)
15435           f = *tcctx.cb.decl_map->get (f);
15436         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
15437         if (n != NULL)
15438           {
15439             sf = (tree) n->value;
15440             if (tcctx.cb.decl_map)
15441               sf = *tcctx.cb.decl_map->get (sf);
15442             src = build_simple_mem_ref_loc (loc, sarg);
15443             src = omp_build_component_ref (src, sf);
15444             if (use_pointer_for_field (decl, NULL))
15445               src = build_simple_mem_ref_loc (loc, src);
15446           }
15447         else
15448           src = decl;
15449         dst = build_simple_mem_ref_loc (loc, arg);
15450         dst = omp_build_component_ref (dst, f);
15451         t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
15452         append_to_statement_list (t, &list);
15453         break;
15454       default:
15455         break;
15456       }
15457
15458   /* Last pass: handle VLA firstprivates.  */
15459   if (tcctx.cb.decl_map)
15460     for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
15461       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
15462         {
15463           tree ind, ptr, df;
15464
15465           decl = OMP_CLAUSE_DECL (c);
15466           if (!is_variable_sized (decl))
15467             continue;
15468           n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
15469           if (n == NULL)
15470             continue;
15471           f = (tree) n->value;
15472           f = *tcctx.cb.decl_map->get (f);
15473           gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
15474           ind = DECL_VALUE_EXPR (decl);
15475           gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
15476           gcc_assert (DECL_P (TREE_OPERAND (ind, 0)));
15477           n = splay_tree_lookup (ctx->sfield_map,
15478                                  (splay_tree_key) TREE_OPERAND (ind, 0));
15479           sf = (tree) n->value;
15480           sf = *tcctx.cb.decl_map->get (sf);
15481           src = build_simple_mem_ref_loc (loc, sarg);
15482           src = omp_build_component_ref (src, sf);
15483           src = build_simple_mem_ref_loc (loc, src);
15484           dst = build_simple_mem_ref_loc (loc, arg);
15485           dst = omp_build_component_ref (dst, f);
15486           t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
15487           append_to_statement_list (t, &list);
15488           n = splay_tree_lookup (ctx->field_map,
15489                                  (splay_tree_key) TREE_OPERAND (ind, 0));
15490           df = (tree) n->value;
15491           df = *tcctx.cb.decl_map->get (df);
15492           ptr = build_simple_mem_ref_loc (loc, arg);
15493           ptr = omp_build_component_ref (ptr, df);
15494           t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
15495                       build_fold_addr_expr_loc (loc, dst));
15496           append_to_statement_list (t, &list);
15497         }
15498
15499   t = build1 (RETURN_EXPR, void_type_node, NULL);
15500   append_to_statement_list (t, &list);
15501
15502   if (tcctx.cb.decl_map)
15503     delete tcctx.cb.decl_map;
15504   pop_gimplify_context (NULL);
15505   BIND_EXPR_BODY (bind) = list;
15506   pop_cfun ();
15507 }
15508
15509 static void
15510 lower_depend_clauses (tree *pclauses, gimple_seq *iseq, gimple_seq *oseq)
15511 {
15512   tree c, clauses;
15513   gimple *g;
15514   size_t n_in = 0, n_out = 0, idx = 2, i;
15515
15516   clauses = find_omp_clause (*pclauses, OMP_CLAUSE_DEPEND);
15517   gcc_assert (clauses);
15518   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
15519     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
15520       switch (OMP_CLAUSE_DEPEND_KIND (c))
15521         {
15522         case OMP_CLAUSE_DEPEND_IN:
15523           n_in++;
15524           break;
15525         case OMP_CLAUSE_DEPEND_OUT:
15526         case OMP_CLAUSE_DEPEND_INOUT:
15527           n_out++;
15528           break;
15529         case OMP_CLAUSE_DEPEND_SOURCE:
15530         case OMP_CLAUSE_DEPEND_SINK:
15531           /* FALLTHRU */
15532         default:
15533           gcc_unreachable ();
15534         }
15535   tree type = build_array_type_nelts (ptr_type_node, n_in + n_out + 2);
15536   tree array = create_tmp_var (type);
15537   TREE_ADDRESSABLE (array) = 1;
15538   tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
15539                    NULL_TREE);
15540   g = gimple_build_assign (r, build_int_cst (ptr_type_node, n_in + n_out));
15541   gimple_seq_add_stmt (iseq, g);
15542   r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
15543               NULL_TREE);
15544   g = gimple_build_assign (r, build_int_cst (ptr_type_node, n_out));
15545   gimple_seq_add_stmt (iseq, g);
15546   for (i = 0; i < 2; i++)
15547     {
15548       if ((i ? n_in : n_out) == 0)
15549         continue;
15550       for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
15551         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
15552             && ((OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_IN) ^ i))
15553           {
15554             tree t = OMP_CLAUSE_DECL (c);
15555             t = fold_convert (ptr_type_node, t);
15556             gimplify_expr (&t, iseq, NULL, is_gimple_val, fb_rvalue);
15557             r = build4 (ARRAY_REF, ptr_type_node, array, size_int (idx++),
15558                         NULL_TREE, NULL_TREE);
15559             g = gimple_build_assign (r, t);
15560             gimple_seq_add_stmt (iseq, g);
15561           }
15562     }
15563   c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
15564   OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
15565   OMP_CLAUSE_CHAIN (c) = *pclauses;
15566   *pclauses = c;
15567   tree clobber = build_constructor (type, NULL);
15568   TREE_THIS_VOLATILE (clobber) = 1;
15569   g = gimple_build_assign (array, clobber);
15570   gimple_seq_add_stmt (oseq, g);
15571 }
15572
15573 /* Lower the OpenMP parallel or task directive in the current statement
15574    in GSI_P.  CTX holds context information for the directive.  */
15575
15576 static void
15577 lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
15578 {
15579   tree clauses;
15580   tree child_fn, t;
15581   gimple *stmt = gsi_stmt (*gsi_p);
15582   gbind *par_bind, *bind, *dep_bind = NULL;
15583   gimple_seq par_body, olist, ilist, par_olist, par_rlist, par_ilist, new_body;
15584   location_t loc = gimple_location (stmt);
15585
15586   clauses = gimple_omp_taskreg_clauses (stmt);
15587   par_bind
15588     = as_a <gbind *> (gimple_seq_first_stmt (gimple_omp_body (stmt)));
15589   par_body = gimple_bind_body (par_bind);
15590   child_fn = ctx->cb.dst_fn;
15591   if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
15592       && !gimple_omp_parallel_combined_p (stmt))
15593     {
15594       struct walk_stmt_info wi;
15595       int ws_num = 0;
15596
15597       memset (&wi, 0, sizeof (wi));
15598       wi.info = &ws_num;
15599       wi.val_only = true;
15600       walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
15601       if (ws_num == 1)
15602         gimple_omp_parallel_set_combined_p (stmt, true);
15603     }
15604   gimple_seq dep_ilist = NULL;
15605   gimple_seq dep_olist = NULL;
15606   if (gimple_code (stmt) == GIMPLE_OMP_TASK
15607       && find_omp_clause (clauses, OMP_CLAUSE_DEPEND))
15608     {
15609       push_gimplify_context ();
15610       dep_bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
15611       lower_depend_clauses (gimple_omp_task_clauses_ptr (stmt),
15612                             &dep_ilist, &dep_olist);
15613     }
15614
15615   if (ctx->srecord_type)
15616     create_task_copyfn (as_a <gomp_task *> (stmt), ctx);
15617
15618   push_gimplify_context ();
15619
15620   par_olist = NULL;
15621   par_ilist = NULL;
15622   par_rlist = NULL;
15623   bool phony_construct = gimple_code (stmt) == GIMPLE_OMP_PARALLEL
15624     && gimple_omp_parallel_grid_phony (as_a <gomp_parallel *> (stmt));
15625   if (phony_construct && ctx->record_type)
15626     {
15627       gcc_checking_assert (!ctx->receiver_decl);
15628       ctx->receiver_decl = create_tmp_var
15629         (build_reference_type (ctx->record_type), ".omp_rec");
15630     }
15631   lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx, NULL);
15632   lower_omp (&par_body, ctx);
15633   if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
15634     lower_reduction_clauses (clauses, &par_rlist, ctx);
15635
15636   /* Declare all the variables created by mapping and the variables
15637      declared in the scope of the parallel body.  */
15638   record_vars_into (ctx->block_vars, child_fn);
15639   record_vars_into (gimple_bind_vars (par_bind), child_fn);
15640
15641   if (ctx->record_type)
15642     {
15643       ctx->sender_decl
15644         = create_tmp_var (ctx->srecord_type ? ctx->srecord_type
15645                           : ctx->record_type, ".omp_data_o");
15646       DECL_NAMELESS (ctx->sender_decl) = 1;
15647       TREE_ADDRESSABLE (ctx->sender_decl) = 1;
15648       gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
15649     }
15650
15651   olist = NULL;
15652   ilist = NULL;
15653   lower_send_clauses (clauses, &ilist, &olist, ctx);
15654   lower_send_shared_vars (&ilist, &olist, ctx);
15655
15656   if (ctx->record_type)
15657     {
15658       tree clobber = build_constructor (TREE_TYPE (ctx->sender_decl), NULL);
15659       TREE_THIS_VOLATILE (clobber) = 1;
15660       gimple_seq_add_stmt (&olist, gimple_build_assign (ctx->sender_decl,
15661                                                         clobber));
15662     }
15663
15664   /* Once all the expansions are done, sequence all the different
15665      fragments inside gimple_omp_body.  */
15666
15667   new_body = NULL;
15668
15669   if (ctx->record_type)
15670     {
15671       t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
15672       /* fixup_child_record_type might have changed receiver_decl's type.  */
15673       t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
15674       gimple_seq_add_stmt (&new_body,
15675                            gimple_build_assign (ctx->receiver_decl, t));
15676     }
15677
15678   gimple_seq_add_seq (&new_body, par_ilist);
15679   gimple_seq_add_seq (&new_body, par_body);
15680   gimple_seq_add_seq (&new_body, par_rlist);
15681   if (ctx->cancellable)
15682     gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
15683   gimple_seq_add_seq (&new_body, par_olist);
15684   new_body = maybe_catch_exception (new_body);
15685   if (gimple_code (stmt) == GIMPLE_OMP_TASK)
15686     gimple_seq_add_stmt (&new_body,
15687                          gimple_build_omp_continue (integer_zero_node,
15688                                                     integer_zero_node));
15689   if (!phony_construct)
15690     {
15691       gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
15692       gimple_omp_set_body (stmt, new_body);
15693     }
15694
15695   bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
15696   gsi_replace (gsi_p, dep_bind ? dep_bind : bind, true);
15697   gimple_bind_add_seq (bind, ilist);
15698   if (!phony_construct)
15699     gimple_bind_add_stmt (bind, stmt);
15700   else
15701     gimple_bind_add_seq (bind, new_body);
15702   gimple_bind_add_seq (bind, olist);
15703
15704   pop_gimplify_context (NULL);
15705
15706   if (dep_bind)
15707     {
15708       gimple_bind_add_seq (dep_bind, dep_ilist);
15709       gimple_bind_add_stmt (dep_bind, bind);
15710       gimple_bind_add_seq (dep_bind, dep_olist);
15711       pop_gimplify_context (dep_bind);
15712     }
15713 }
15714
15715 /* Lower the GIMPLE_OMP_TARGET in the current statement
15716    in GSI_P.  CTX holds context information for the directive.  */
15717
15718 static void
15719 lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
15720 {
15721   tree clauses;
15722   tree child_fn, t, c;
15723   gomp_target *stmt = as_a <gomp_target *> (gsi_stmt (*gsi_p));
15724   gbind *tgt_bind, *bind, *dep_bind = NULL;
15725   gimple_seq tgt_body, olist, ilist, fplist, new_body;
15726   location_t loc = gimple_location (stmt);
15727   bool offloaded, data_region;
15728   unsigned int map_cnt = 0;
15729
15730   offloaded = is_gimple_omp_offloaded (stmt);
15731   switch (gimple_omp_target_kind (stmt))
15732     {
15733     case GF_OMP_TARGET_KIND_REGION:
15734     case GF_OMP_TARGET_KIND_UPDATE:
15735     case GF_OMP_TARGET_KIND_ENTER_DATA:
15736     case GF_OMP_TARGET_KIND_EXIT_DATA:
15737     case GF_OMP_TARGET_KIND_OACC_PARALLEL:
15738     case GF_OMP_TARGET_KIND_OACC_KERNELS:
15739     case GF_OMP_TARGET_KIND_OACC_UPDATE:
15740     case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
15741     case GF_OMP_TARGET_KIND_OACC_DECLARE:
15742       data_region = false;
15743       break;
15744     case GF_OMP_TARGET_KIND_DATA:
15745     case GF_OMP_TARGET_KIND_OACC_DATA:
15746     case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
15747       data_region = true;
15748       break;
15749     default:
15750       gcc_unreachable ();
15751     }
15752
15753   clauses = gimple_omp_target_clauses (stmt);
15754
15755   gimple_seq dep_ilist = NULL;
15756   gimple_seq dep_olist = NULL;
15757   if (find_omp_clause (clauses, OMP_CLAUSE_DEPEND))
15758     {
15759       push_gimplify_context ();
15760       dep_bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
15761       lower_depend_clauses (gimple_omp_target_clauses_ptr (stmt),
15762                             &dep_ilist, &dep_olist);
15763     }
15764
15765   tgt_bind = NULL;
15766   tgt_body = NULL;
15767   if (offloaded)
15768     {
15769       tgt_bind = gimple_seq_first_stmt_as_a_bind (gimple_omp_body (stmt));
15770       tgt_body = gimple_bind_body (tgt_bind);
15771     }
15772   else if (data_region)
15773     tgt_body = gimple_omp_body (stmt);
15774   child_fn = ctx->cb.dst_fn;
15775
15776   push_gimplify_context ();
15777   fplist = NULL;
15778
15779   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
15780     switch (OMP_CLAUSE_CODE (c))
15781       {
15782         tree var, x;
15783
15784       default:
15785         break;
15786       case OMP_CLAUSE_MAP:
15787 #if CHECKING_P
15788         /* First check what we're prepared to handle in the following.  */
15789         switch (OMP_CLAUSE_MAP_KIND (c))
15790           {
15791           case GOMP_MAP_ALLOC:
15792           case GOMP_MAP_TO:
15793           case GOMP_MAP_FROM:
15794           case GOMP_MAP_TOFROM:
15795           case GOMP_MAP_POINTER:
15796           case GOMP_MAP_TO_PSET:
15797           case GOMP_MAP_DELETE:
15798           case GOMP_MAP_RELEASE:
15799           case GOMP_MAP_ALWAYS_TO:
15800           case GOMP_MAP_ALWAYS_FROM:
15801           case GOMP_MAP_ALWAYS_TOFROM:
15802           case GOMP_MAP_FIRSTPRIVATE_POINTER:
15803           case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
15804           case GOMP_MAP_STRUCT:
15805           case GOMP_MAP_ALWAYS_POINTER:
15806             break;
15807           case GOMP_MAP_FORCE_ALLOC:
15808           case GOMP_MAP_FORCE_TO:
15809           case GOMP_MAP_FORCE_FROM:
15810           case GOMP_MAP_FORCE_TOFROM:
15811           case GOMP_MAP_FORCE_PRESENT:
15812           case GOMP_MAP_FORCE_DEVICEPTR:
15813           case GOMP_MAP_DEVICE_RESIDENT:
15814           case GOMP_MAP_LINK:
15815             gcc_assert (is_gimple_omp_oacc (stmt));
15816             break;
15817           default:
15818             gcc_unreachable ();
15819           }
15820 #endif
15821           /* FALLTHRU */
15822       case OMP_CLAUSE_TO:
15823       case OMP_CLAUSE_FROM:
15824       oacc_firstprivate:
15825         var = OMP_CLAUSE_DECL (c);
15826         if (!DECL_P (var))
15827           {
15828             if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
15829                 || (!OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
15830                     && (OMP_CLAUSE_MAP_KIND (c)
15831                         != GOMP_MAP_FIRSTPRIVATE_POINTER)))
15832               map_cnt++;
15833             continue;
15834           }
15835
15836         if (DECL_SIZE (var)
15837             && TREE_CODE (DECL_SIZE (var)) != INTEGER_CST)
15838           {
15839             tree var2 = DECL_VALUE_EXPR (var);
15840             gcc_assert (TREE_CODE (var2) == INDIRECT_REF);
15841             var2 = TREE_OPERAND (var2, 0);
15842             gcc_assert (DECL_P (var2));
15843             var = var2;
15844           }
15845
15846         if (offloaded
15847             && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
15848             && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
15849                 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
15850           {
15851             if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
15852               {
15853                 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx))
15854                     && varpool_node::get_create (var)->offloadable)
15855                   continue;
15856
15857                 tree type = build_pointer_type (TREE_TYPE (var));
15858                 tree new_var = lookup_decl (var, ctx);
15859                 x = create_tmp_var_raw (type, get_name (new_var));
15860                 gimple_add_tmp_var (x);
15861                 x = build_simple_mem_ref (x);
15862                 SET_DECL_VALUE_EXPR (new_var, x);
15863                 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
15864               }
15865             continue;
15866           }
15867
15868         if (!maybe_lookup_field (var, ctx))
15869           continue;
15870
15871         /* Don't remap oacc parallel reduction variables, because the
15872            intermediate result must be local to each gang.  */
15873         if (offloaded && !(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
15874                            && OMP_CLAUSE_MAP_IN_REDUCTION (c)))
15875           {
15876             x = build_receiver_ref (var, true, ctx);
15877             tree new_var = lookup_decl (var, ctx);
15878
15879             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
15880                 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
15881                 && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
15882                 && TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
15883               x = build_simple_mem_ref (x);
15884             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
15885               {
15886                 gcc_assert (is_gimple_omp_oacc (ctx->stmt));
15887                 if (is_reference (new_var))
15888                   {
15889                     /* Create a local object to hold the instance
15890                        value.  */
15891                     tree type = TREE_TYPE (TREE_TYPE (new_var));
15892                     const char *id = IDENTIFIER_POINTER (DECL_NAME (new_var));
15893                     tree inst = create_tmp_var (type, id);
15894                     gimplify_assign (inst, fold_indirect_ref (x), &fplist);
15895                     x = build_fold_addr_expr (inst);
15896                   }
15897                 gimplify_assign (new_var, x, &fplist);
15898               }
15899             else if (DECL_P (new_var))
15900               {
15901                 SET_DECL_VALUE_EXPR (new_var, x);
15902                 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
15903               }
15904             else
15905               gcc_unreachable ();
15906           }
15907         map_cnt++;
15908         break;
15909
15910       case OMP_CLAUSE_FIRSTPRIVATE:
15911         if (is_oacc_parallel (ctx))
15912           goto oacc_firstprivate;
15913         map_cnt++;
15914         var = OMP_CLAUSE_DECL (c);
15915         if (!is_reference (var)
15916             && !is_gimple_reg_type (TREE_TYPE (var)))
15917           {
15918             tree new_var = lookup_decl (var, ctx);
15919             if (is_variable_sized (var))
15920               {
15921                 tree pvar = DECL_VALUE_EXPR (var);
15922                 gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
15923                 pvar = TREE_OPERAND (pvar, 0);
15924                 gcc_assert (DECL_P (pvar));
15925                 tree new_pvar = lookup_decl (pvar, ctx);
15926                 x = build_fold_indirect_ref (new_pvar);
15927                 TREE_THIS_NOTRAP (x) = 1;
15928               }
15929             else
15930               x = build_receiver_ref (var, true, ctx);
15931             SET_DECL_VALUE_EXPR (new_var, x);
15932             DECL_HAS_VALUE_EXPR_P (new_var) = 1;
15933           }
15934         break;
15935
15936       case OMP_CLAUSE_PRIVATE:
15937         if (is_gimple_omp_oacc (ctx->stmt))
15938           break;
15939         var = OMP_CLAUSE_DECL (c);
15940         if (is_variable_sized (var))
15941           {
15942             tree new_var = lookup_decl (var, ctx);
15943             tree pvar = DECL_VALUE_EXPR (var);
15944             gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
15945             pvar = TREE_OPERAND (pvar, 0);
15946             gcc_assert (DECL_P (pvar));
15947             tree new_pvar = lookup_decl (pvar, ctx);
15948             x = build_fold_indirect_ref (new_pvar);
15949             TREE_THIS_NOTRAP (x) = 1;
15950             SET_DECL_VALUE_EXPR (new_var, x);
15951             DECL_HAS_VALUE_EXPR_P (new_var) = 1;
15952           }
15953         break;
15954
15955       case OMP_CLAUSE_USE_DEVICE_PTR:
15956       case OMP_CLAUSE_IS_DEVICE_PTR:
15957         var = OMP_CLAUSE_DECL (c);
15958         map_cnt++;
15959         if (is_variable_sized (var))
15960           {
15961             tree new_var = lookup_decl (var, ctx);
15962             tree pvar = DECL_VALUE_EXPR (var);
15963             gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
15964             pvar = TREE_OPERAND (pvar, 0);
15965             gcc_assert (DECL_P (pvar));
15966             tree new_pvar = lookup_decl (pvar, ctx);
15967             x = build_fold_indirect_ref (new_pvar);
15968             TREE_THIS_NOTRAP (x) = 1;
15969             SET_DECL_VALUE_EXPR (new_var, x);
15970             DECL_HAS_VALUE_EXPR_P (new_var) = 1;
15971           }
15972         else if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
15973           {
15974             tree new_var = lookup_decl (var, ctx);
15975             tree type = build_pointer_type (TREE_TYPE (var));
15976             x = create_tmp_var_raw (type, get_name (new_var));
15977             gimple_add_tmp_var (x);
15978             x = build_simple_mem_ref (x);
15979             SET_DECL_VALUE_EXPR (new_var, x);
15980             DECL_HAS_VALUE_EXPR_P (new_var) = 1;
15981           }
15982         else
15983           {
15984             tree new_var = lookup_decl (var, ctx);
15985             x = create_tmp_var_raw (TREE_TYPE (new_var), get_name (new_var));
15986             gimple_add_tmp_var (x);
15987             SET_DECL_VALUE_EXPR (new_var, x);
15988             DECL_HAS_VALUE_EXPR_P (new_var) = 1;
15989           }
15990         break;
15991       }
15992
15993   if (offloaded)
15994     {
15995       target_nesting_level++;
15996       lower_omp (&tgt_body, ctx);
15997       target_nesting_level--;
15998     }
15999   else if (data_region)
16000     lower_omp (&tgt_body, ctx);
16001
16002   if (offloaded)
16003     {
16004       /* Declare all the variables created by mapping and the variables
16005          declared in the scope of the target body.  */
16006       record_vars_into (ctx->block_vars, child_fn);
16007       record_vars_into (gimple_bind_vars (tgt_bind), child_fn);
16008     }
16009
16010   olist = NULL;
16011   ilist = NULL;
16012   if (ctx->record_type)
16013     {
16014       ctx->sender_decl
16015         = create_tmp_var (ctx->record_type, ".omp_data_arr");
16016       DECL_NAMELESS (ctx->sender_decl) = 1;
16017       TREE_ADDRESSABLE (ctx->sender_decl) = 1;
16018       t = make_tree_vec (3);
16019       TREE_VEC_ELT (t, 0) = ctx->sender_decl;
16020       TREE_VEC_ELT (t, 1)
16021         = create_tmp_var (build_array_type_nelts (size_type_node, map_cnt),
16022                           ".omp_data_sizes");
16023       DECL_NAMELESS (TREE_VEC_ELT (t, 1)) = 1;
16024       TREE_ADDRESSABLE (TREE_VEC_ELT (t, 1)) = 1;
16025       TREE_STATIC (TREE_VEC_ELT (t, 1)) = 1;
16026       tree tkind_type = short_unsigned_type_node;
16027       int talign_shift = 8;
16028       TREE_VEC_ELT (t, 2)
16029         = create_tmp_var (build_array_type_nelts (tkind_type, map_cnt),
16030                           ".omp_data_kinds");
16031       DECL_NAMELESS (TREE_VEC_ELT (t, 2)) = 1;
16032       TREE_ADDRESSABLE (TREE_VEC_ELT (t, 2)) = 1;
16033       TREE_STATIC (TREE_VEC_ELT (t, 2)) = 1;
16034       gimple_omp_target_set_data_arg (stmt, t);
16035
16036       vec<constructor_elt, va_gc> *vsize;
16037       vec<constructor_elt, va_gc> *vkind;
16038       vec_alloc (vsize, map_cnt);
16039       vec_alloc (vkind, map_cnt);
16040       unsigned int map_idx = 0;
16041
16042       for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
16043         switch (OMP_CLAUSE_CODE (c))
16044           {
16045             tree ovar, nc, s, purpose, var, x, type;
16046             unsigned int talign;
16047
16048           default:
16049             break;
16050
16051           case OMP_CLAUSE_MAP:
16052           case OMP_CLAUSE_TO:
16053           case OMP_CLAUSE_FROM:
16054           oacc_firstprivate_map:
16055             nc = c;
16056             ovar = OMP_CLAUSE_DECL (c);
16057             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
16058                 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
16059                     || (OMP_CLAUSE_MAP_KIND (c)
16060                         == GOMP_MAP_FIRSTPRIVATE_REFERENCE)))
16061               break;
16062             if (!DECL_P (ovar))
16063               {
16064                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
16065                     && OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
16066                   {
16067                     gcc_checking_assert (OMP_CLAUSE_DECL (OMP_CLAUSE_CHAIN (c))
16068                                          == get_base_address (ovar));
16069                     nc = OMP_CLAUSE_CHAIN (c);
16070                     ovar = OMP_CLAUSE_DECL (nc);
16071                   }
16072                 else
16073                   {
16074                     tree x = build_sender_ref (ovar, ctx);
16075                     tree v
16076                       = build_fold_addr_expr_with_type (ovar, ptr_type_node);
16077                     gimplify_assign (x, v, &ilist);
16078                     nc = NULL_TREE;
16079                   }
16080               }
16081             else
16082               {
16083                 if (DECL_SIZE (ovar)
16084                     && TREE_CODE (DECL_SIZE (ovar)) != INTEGER_CST)
16085                   {
16086                     tree ovar2 = DECL_VALUE_EXPR (ovar);
16087                     gcc_assert (TREE_CODE (ovar2) == INDIRECT_REF);
16088                     ovar2 = TREE_OPERAND (ovar2, 0);
16089                     gcc_assert (DECL_P (ovar2));
16090                     ovar = ovar2;
16091                   }
16092                 if (!maybe_lookup_field (ovar, ctx))
16093                   continue;
16094               }
16095
16096             talign = TYPE_ALIGN_UNIT (TREE_TYPE (ovar));
16097             if (DECL_P (ovar) && DECL_ALIGN_UNIT (ovar) > talign)
16098               talign = DECL_ALIGN_UNIT (ovar);
16099             if (nc)
16100               {
16101                 var = lookup_decl_in_outer_ctx (ovar, ctx);
16102                 x = build_sender_ref (ovar, ctx);
16103
16104                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
16105                     && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
16106                     && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
16107                     && TREE_CODE (TREE_TYPE (ovar)) == ARRAY_TYPE)
16108                   {
16109                     gcc_assert (offloaded);
16110                     tree avar
16111                       = create_tmp_var (TREE_TYPE (TREE_TYPE (x)));
16112                     mark_addressable (avar);
16113                     gimplify_assign (avar, build_fold_addr_expr (var), &ilist);
16114                     talign = DECL_ALIGN_UNIT (avar);
16115                     avar = build_fold_addr_expr (avar);
16116                     gimplify_assign (x, avar, &ilist);
16117                   }
16118                 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
16119                   {
16120                     gcc_assert (is_gimple_omp_oacc (ctx->stmt));
16121                     if (!is_reference (var))
16122                       {
16123                         if (is_gimple_reg (var)
16124                             && OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
16125                           TREE_NO_WARNING (var) = 1;
16126                         var = build_fold_addr_expr (var);
16127                       }
16128                     else
16129                       talign = TYPE_ALIGN_UNIT (TREE_TYPE (TREE_TYPE (ovar)));
16130                     gimplify_assign (x, var, &ilist);
16131                   }
16132                 else if (is_gimple_reg (var))
16133                   {
16134                     gcc_assert (offloaded);
16135                     tree avar = create_tmp_var (TREE_TYPE (var));
16136                     mark_addressable (avar);
16137                     enum gomp_map_kind map_kind = OMP_CLAUSE_MAP_KIND (c);
16138                     if (GOMP_MAP_COPY_TO_P (map_kind)
16139                         || map_kind == GOMP_MAP_POINTER
16140                         || map_kind == GOMP_MAP_TO_PSET
16141                         || map_kind == GOMP_MAP_FORCE_DEVICEPTR)
16142                       {
16143                         /* If we need to initialize a temporary
16144                            with VAR because it is not addressable, and
16145                            the variable hasn't been initialized yet, then
16146                            we'll get a warning for the store to avar.
16147                            Don't warn in that case, the mapping might
16148                            be implicit.  */
16149                         TREE_NO_WARNING (var) = 1;
16150                         gimplify_assign (avar, var, &ilist);
16151                       }
16152                     avar = build_fold_addr_expr (avar);
16153                     gimplify_assign (x, avar, &ilist);
16154                     if ((GOMP_MAP_COPY_FROM_P (map_kind)
16155                          || map_kind == GOMP_MAP_FORCE_DEVICEPTR)
16156                         && !TYPE_READONLY (TREE_TYPE (var)))
16157                       {
16158                         x = unshare_expr (x);
16159                         x = build_simple_mem_ref (x);
16160                         gimplify_assign (var, x, &olist);
16161                       }
16162                   }
16163                 else
16164                   {
16165                     var = build_fold_addr_expr (var);
16166                     gimplify_assign (x, var, &ilist);
16167                   }
16168               }
16169             s = NULL_TREE;
16170             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
16171               {
16172                 gcc_checking_assert (is_gimple_omp_oacc (ctx->stmt));
16173                 s = TREE_TYPE (ovar);
16174                 if (TREE_CODE (s) == REFERENCE_TYPE)
16175                   s = TREE_TYPE (s);
16176                 s = TYPE_SIZE_UNIT (s);
16177               }
16178             else
16179               s = OMP_CLAUSE_SIZE (c);
16180             if (s == NULL_TREE)
16181               s = TYPE_SIZE_UNIT (TREE_TYPE (ovar));
16182             s = fold_convert (size_type_node, s);
16183             purpose = size_int (map_idx++);
16184             CONSTRUCTOR_APPEND_ELT (vsize, purpose, s);
16185             if (TREE_CODE (s) != INTEGER_CST)
16186               TREE_STATIC (TREE_VEC_ELT (t, 1)) = 0;
16187
16188             unsigned HOST_WIDE_INT tkind, tkind_zero;
16189             switch (OMP_CLAUSE_CODE (c))
16190               {
16191               case OMP_CLAUSE_MAP:
16192                 tkind = OMP_CLAUSE_MAP_KIND (c);
16193                 tkind_zero = tkind;
16194                 if (OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c))
16195                   switch (tkind)
16196                     {
16197                     case GOMP_MAP_ALLOC:
16198                     case GOMP_MAP_TO:
16199                     case GOMP_MAP_FROM:
16200                     case GOMP_MAP_TOFROM:
16201                     case GOMP_MAP_ALWAYS_TO:
16202                     case GOMP_MAP_ALWAYS_FROM:
16203                     case GOMP_MAP_ALWAYS_TOFROM:
16204                     case GOMP_MAP_RELEASE:
16205                       tkind_zero = GOMP_MAP_ZERO_LEN_ARRAY_SECTION;
16206                       break;
16207                     case GOMP_MAP_DELETE:
16208                       tkind_zero = GOMP_MAP_DELETE_ZERO_LEN_ARRAY_SECTION;
16209                     default:
16210                       break;
16211                     }
16212                 if (tkind_zero != tkind)
16213                   {
16214                     if (integer_zerop (s))
16215                       tkind = tkind_zero;
16216                     else if (integer_nonzerop (s))
16217                       tkind_zero = tkind;
16218                   }
16219                 break;
16220               case OMP_CLAUSE_FIRSTPRIVATE:
16221                 gcc_checking_assert (is_gimple_omp_oacc (ctx->stmt));
16222                 tkind = GOMP_MAP_TO;
16223                 tkind_zero = tkind;
16224                 break;
16225               case OMP_CLAUSE_TO:
16226                 tkind = GOMP_MAP_TO;
16227                 tkind_zero = tkind;
16228                 break;
16229               case OMP_CLAUSE_FROM:
16230                 tkind = GOMP_MAP_FROM;
16231                 tkind_zero = tkind;
16232                 break;
16233               default:
16234                 gcc_unreachable ();
16235               }
16236             gcc_checking_assert (tkind
16237                                  < (HOST_WIDE_INT_C (1U) << talign_shift));
16238             gcc_checking_assert (tkind_zero
16239                                  < (HOST_WIDE_INT_C (1U) << talign_shift));
16240             talign = ceil_log2 (talign);
16241             tkind |= talign << talign_shift;
16242             tkind_zero |= talign << talign_shift;
16243             gcc_checking_assert (tkind
16244                                  <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
16245             gcc_checking_assert (tkind_zero
16246                                  <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
16247             if (tkind == tkind_zero)
16248               x = build_int_cstu (tkind_type, tkind);
16249             else
16250               {
16251                 TREE_STATIC (TREE_VEC_ELT (t, 2)) = 0;
16252                 x = build3 (COND_EXPR, tkind_type,
16253                             fold_build2 (EQ_EXPR, boolean_type_node,
16254                                          unshare_expr (s), size_zero_node),
16255                             build_int_cstu (tkind_type, tkind_zero),
16256                             build_int_cstu (tkind_type, tkind));
16257               }
16258             CONSTRUCTOR_APPEND_ELT (vkind, purpose, x);
16259             if (nc && nc != c)
16260               c = nc;
16261             break;
16262
16263           case OMP_CLAUSE_FIRSTPRIVATE:
16264             if (is_oacc_parallel (ctx))
16265               goto oacc_firstprivate_map;
16266             ovar = OMP_CLAUSE_DECL (c);
16267             if (is_reference (ovar))
16268               talign = TYPE_ALIGN_UNIT (TREE_TYPE (TREE_TYPE (ovar)));
16269             else
16270               talign = DECL_ALIGN_UNIT (ovar);
16271             var = lookup_decl_in_outer_ctx (ovar, ctx);
16272             x = build_sender_ref (ovar, ctx);
16273             tkind = GOMP_MAP_FIRSTPRIVATE;
16274             type = TREE_TYPE (ovar);
16275             if (is_reference (ovar))
16276               type = TREE_TYPE (type);
16277             if ((INTEGRAL_TYPE_P (type)
16278                  && TYPE_PRECISION (type) <= POINTER_SIZE)
16279                 || TREE_CODE (type) == POINTER_TYPE)
16280               {
16281                 tkind = GOMP_MAP_FIRSTPRIVATE_INT;
16282                 tree t = var;
16283                 if (is_reference (var))
16284                   t = build_simple_mem_ref (var);
16285                 else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
16286                   TREE_NO_WARNING (var) = 1;
16287                 if (TREE_CODE (type) != POINTER_TYPE)
16288                   t = fold_convert (pointer_sized_int_node, t);
16289                 t = fold_convert (TREE_TYPE (x), t);
16290                 gimplify_assign (x, t, &ilist);
16291               }
16292             else if (is_reference (var))
16293               gimplify_assign (x, var, &ilist);
16294             else if (is_gimple_reg (var))
16295               {
16296                 tree avar = create_tmp_var (TREE_TYPE (var));
16297                 mark_addressable (avar);
16298                 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
16299                   TREE_NO_WARNING (var) = 1;
16300                 gimplify_assign (avar, var, &ilist);
16301                 avar = build_fold_addr_expr (avar);
16302                 gimplify_assign (x, avar, &ilist);
16303               }
16304             else
16305               {
16306                 var = build_fold_addr_expr (var);
16307                 gimplify_assign (x, var, &ilist);
16308               }
16309             if (tkind == GOMP_MAP_FIRSTPRIVATE_INT)
16310               s = size_int (0);
16311             else if (is_reference (var))
16312               s = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ovar)));
16313             else
16314               s = TYPE_SIZE_UNIT (TREE_TYPE (ovar));
16315             s = fold_convert (size_type_node, s);
16316             purpose = size_int (map_idx++);
16317             CONSTRUCTOR_APPEND_ELT (vsize, purpose, s);
16318             if (TREE_CODE (s) != INTEGER_CST)
16319               TREE_STATIC (TREE_VEC_ELT (t, 1)) = 0;
16320
16321             gcc_checking_assert (tkind
16322                                  < (HOST_WIDE_INT_C (1U) << talign_shift));
16323             talign = ceil_log2 (talign);
16324             tkind |= talign << talign_shift;
16325             gcc_checking_assert (tkind
16326                                  <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
16327             CONSTRUCTOR_APPEND_ELT (vkind, purpose,
16328                                     build_int_cstu (tkind_type, tkind));
16329             break;
16330
16331           case OMP_CLAUSE_USE_DEVICE_PTR:
16332           case OMP_CLAUSE_IS_DEVICE_PTR:
16333             ovar = OMP_CLAUSE_DECL (c);
16334             var = lookup_decl_in_outer_ctx (ovar, ctx);
16335             x = build_sender_ref (ovar, ctx);
16336             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
16337               tkind = GOMP_MAP_USE_DEVICE_PTR;
16338             else
16339               tkind = GOMP_MAP_FIRSTPRIVATE_INT;
16340             type = TREE_TYPE (ovar);
16341             if (TREE_CODE (type) == ARRAY_TYPE)
16342               var = build_fold_addr_expr (var);
16343             else
16344               {
16345                 if (is_reference (ovar))
16346                   {
16347                     type = TREE_TYPE (type);
16348                     if (TREE_CODE (type) != ARRAY_TYPE)
16349                       var = build_simple_mem_ref (var);
16350                     var = fold_convert (TREE_TYPE (x), var);
16351                   }
16352               }
16353             gimplify_assign (x, var, &ilist);
16354             s = size_int (0);
16355             purpose = size_int (map_idx++);
16356             CONSTRUCTOR_APPEND_ELT (vsize, purpose, s);
16357             gcc_checking_assert (tkind
16358                                  < (HOST_WIDE_INT_C (1U) << talign_shift));
16359             gcc_checking_assert (tkind
16360                                  <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
16361             CONSTRUCTOR_APPEND_ELT (vkind, purpose,
16362                                     build_int_cstu (tkind_type, tkind));
16363             break;
16364           }
16365
16366       gcc_assert (map_idx == map_cnt);
16367
16368       DECL_INITIAL (TREE_VEC_ELT (t, 1))
16369         = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 1)), vsize);
16370       DECL_INITIAL (TREE_VEC_ELT (t, 2))
16371         = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 2)), vkind);
16372       for (int i = 1; i <= 2; i++)
16373         if (!TREE_STATIC (TREE_VEC_ELT (t, i)))
16374           {
16375             gimple_seq initlist = NULL;
16376             force_gimple_operand (build1 (DECL_EXPR, void_type_node,
16377                                           TREE_VEC_ELT (t, i)),
16378                                   &initlist, true, NULL_TREE);
16379             gimple_seq_add_seq (&ilist, initlist);
16380
16381             tree clobber = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, i)),
16382                                               NULL);
16383             TREE_THIS_VOLATILE (clobber) = 1;
16384             gimple_seq_add_stmt (&olist,
16385                                  gimple_build_assign (TREE_VEC_ELT (t, i),
16386                                                       clobber));
16387           }
16388
16389       tree clobber = build_constructor (ctx->record_type, NULL);
16390       TREE_THIS_VOLATILE (clobber) = 1;
16391       gimple_seq_add_stmt (&olist, gimple_build_assign (ctx->sender_decl,
16392                                                         clobber));
16393     }
16394
16395   /* Once all the expansions are done, sequence all the different
16396      fragments inside gimple_omp_body.  */
16397
16398   new_body = NULL;
16399
16400   if (offloaded
16401       && ctx->record_type)
16402     {
16403       t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
16404       /* fixup_child_record_type might have changed receiver_decl's type.  */
16405       t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
16406       gimple_seq_add_stmt (&new_body,
16407                            gimple_build_assign (ctx->receiver_decl, t));
16408     }
16409   gimple_seq_add_seq (&new_body, fplist);
16410
16411   if (offloaded || data_region)
16412     {
16413       tree prev = NULL_TREE;
16414       for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
16415         switch (OMP_CLAUSE_CODE (c))
16416           {
16417             tree var, x;
16418           default:
16419             break;
16420           case OMP_CLAUSE_FIRSTPRIVATE:
16421             if (is_gimple_omp_oacc (ctx->stmt))
16422               break;
16423             var = OMP_CLAUSE_DECL (c);
16424             if (is_reference (var)
16425                 || is_gimple_reg_type (TREE_TYPE (var)))
16426               {
16427                 tree new_var = lookup_decl (var, ctx);
16428                 tree type;
16429                 type = TREE_TYPE (var);
16430                 if (is_reference (var))
16431                   type = TREE_TYPE (type);
16432                 if ((INTEGRAL_TYPE_P (type)
16433                      && TYPE_PRECISION (type) <= POINTER_SIZE)
16434                     || TREE_CODE (type) == POINTER_TYPE)
16435                   {
16436                     x = build_receiver_ref (var, false, ctx);
16437                     if (TREE_CODE (type) != POINTER_TYPE)
16438                       x = fold_convert (pointer_sized_int_node, x);
16439                     x = fold_convert (type, x);
16440                     gimplify_expr (&x, &new_body, NULL, is_gimple_val,
16441                                    fb_rvalue);
16442                     if (is_reference (var))
16443                       {
16444                         tree v = create_tmp_var_raw (type, get_name (var));
16445                         gimple_add_tmp_var (v);
16446                         TREE_ADDRESSABLE (v) = 1;
16447                         gimple_seq_add_stmt (&new_body,
16448                                              gimple_build_assign (v, x));
16449                         x = build_fold_addr_expr (v);
16450                       }
16451                     gimple_seq_add_stmt (&new_body,
16452                                          gimple_build_assign (new_var, x));
16453                   }
16454                 else
16455                   {
16456                     x = build_receiver_ref (var, !is_reference (var), ctx);
16457                     gimplify_expr (&x, &new_body, NULL, is_gimple_val,
16458                                    fb_rvalue);
16459                     gimple_seq_add_stmt (&new_body,
16460                                          gimple_build_assign (new_var, x));
16461                   }
16462               }
16463             else if (is_variable_sized (var))
16464               {
16465                 tree pvar = DECL_VALUE_EXPR (var);
16466                 gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
16467                 pvar = TREE_OPERAND (pvar, 0);
16468                 gcc_assert (DECL_P (pvar));
16469                 tree new_var = lookup_decl (pvar, ctx);
16470                 x = build_receiver_ref (var, false, ctx);
16471                 gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
16472                 gimple_seq_add_stmt (&new_body,
16473                                      gimple_build_assign (new_var, x));
16474               }
16475             break;
16476           case OMP_CLAUSE_PRIVATE:
16477             if (is_gimple_omp_oacc (ctx->stmt))
16478               break;
16479             var = OMP_CLAUSE_DECL (c);
16480             if (is_reference (var))
16481               {
16482                 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
16483                 tree new_var = lookup_decl (var, ctx);
16484                 x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
16485                 if (TREE_CONSTANT (x))
16486                   {
16487                     x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
16488                                             get_name (var));
16489                     gimple_add_tmp_var (x);
16490                     TREE_ADDRESSABLE (x) = 1;
16491                     x = build_fold_addr_expr_loc (clause_loc, x);
16492                   }
16493                 else
16494                   break;
16495
16496                 x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
16497                 gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
16498                 gimple_seq_add_stmt (&new_body,
16499                                      gimple_build_assign (new_var, x));
16500               }
16501             break;
16502           case OMP_CLAUSE_USE_DEVICE_PTR:
16503           case OMP_CLAUSE_IS_DEVICE_PTR:
16504             var = OMP_CLAUSE_DECL (c);
16505             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
16506               x = build_sender_ref (var, ctx);
16507             else
16508               x = build_receiver_ref (var, false, ctx);
16509             if (is_variable_sized (var))
16510               {
16511                 tree pvar = DECL_VALUE_EXPR (var);
16512                 gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
16513                 pvar = TREE_OPERAND (pvar, 0);
16514                 gcc_assert (DECL_P (pvar));
16515                 tree new_var = lookup_decl (pvar, ctx);
16516                 gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
16517                 gimple_seq_add_stmt (&new_body,
16518                                      gimple_build_assign (new_var, x));
16519               }
16520             else if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
16521               {
16522                 tree new_var = lookup_decl (var, ctx);
16523                 new_var = DECL_VALUE_EXPR (new_var);
16524                 gcc_assert (TREE_CODE (new_var) == MEM_REF);
16525                 new_var = TREE_OPERAND (new_var, 0);
16526                 gcc_assert (DECL_P (new_var));
16527                 gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
16528                 gimple_seq_add_stmt (&new_body,
16529                                      gimple_build_assign (new_var, x));
16530               }
16531             else
16532               {
16533                 tree type = TREE_TYPE (var);
16534                 tree new_var = lookup_decl (var, ctx);
16535                 if (is_reference (var))
16536                   {
16537                     type = TREE_TYPE (type);
16538                     if (TREE_CODE (type) != ARRAY_TYPE)
16539                       {
16540                         tree v = create_tmp_var_raw (type, get_name (var));
16541                         gimple_add_tmp_var (v);
16542                         TREE_ADDRESSABLE (v) = 1;
16543                         x = fold_convert (type, x);
16544                         gimplify_expr (&x, &new_body, NULL, is_gimple_val,
16545                                        fb_rvalue);
16546                         gimple_seq_add_stmt (&new_body,
16547                                              gimple_build_assign (v, x));
16548                         x = build_fold_addr_expr (v);
16549                       }
16550                   }
16551                 new_var = DECL_VALUE_EXPR (new_var);
16552                 x = fold_convert (TREE_TYPE (new_var), x);
16553                 gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
16554                 gimple_seq_add_stmt (&new_body,
16555                                      gimple_build_assign (new_var, x));
16556               }
16557             break;
16558           }
16559       /* Handle GOMP_MAP_FIRSTPRIVATE_{POINTER,REFERENCE} in second pass,
16560          so that firstprivate vars holding OMP_CLAUSE_SIZE if needed
16561          are already handled.  Similarly OMP_CLAUSE_PRIVATE for VLAs
16562          or references to VLAs.  */
16563       for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
16564         switch (OMP_CLAUSE_CODE (c))
16565           {
16566             tree var;
16567           default:
16568             break;
16569           case OMP_CLAUSE_MAP:
16570             if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
16571                 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
16572               {
16573                 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
16574                 HOST_WIDE_INT offset = 0;
16575                 gcc_assert (prev);
16576                 var = OMP_CLAUSE_DECL (c);
16577                 if (DECL_P (var)
16578                     && TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE
16579                     && is_global_var (maybe_lookup_decl_in_outer_ctx (var,
16580                                                                       ctx))
16581                     && varpool_node::get_create (var)->offloadable)
16582                   break;
16583                 if (TREE_CODE (var) == INDIRECT_REF
16584                     && TREE_CODE (TREE_OPERAND (var, 0)) == COMPONENT_REF)
16585                   var = TREE_OPERAND (var, 0);
16586                 if (TREE_CODE (var) == COMPONENT_REF)
16587                   {
16588                     var = get_addr_base_and_unit_offset (var, &offset);
16589                     gcc_assert (var != NULL_TREE && DECL_P (var));
16590                   }
16591                 else if (DECL_SIZE (var)
16592                          && TREE_CODE (DECL_SIZE (var)) != INTEGER_CST)
16593                   {
16594                     tree var2 = DECL_VALUE_EXPR (var);
16595                     gcc_assert (TREE_CODE (var2) == INDIRECT_REF);
16596                     var2 = TREE_OPERAND (var2, 0);
16597                     gcc_assert (DECL_P (var2));
16598                     var = var2;
16599                   }
16600                 tree new_var = lookup_decl (var, ctx), x;
16601                 tree type = TREE_TYPE (new_var);
16602                 bool is_ref;
16603                 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == INDIRECT_REF
16604                     && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
16605                         == COMPONENT_REF))
16606                   {
16607                     type = TREE_TYPE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0));
16608                     is_ref = true;
16609                     new_var = build2 (MEM_REF, type,
16610                                       build_fold_addr_expr (new_var),
16611                                       build_int_cst (build_pointer_type (type),
16612                                                      offset));
16613                   }
16614                 else if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPONENT_REF)
16615                   {
16616                     type = TREE_TYPE (OMP_CLAUSE_DECL (c));
16617                     is_ref = TREE_CODE (type) == REFERENCE_TYPE;
16618                     new_var = build2 (MEM_REF, type,
16619                                       build_fold_addr_expr (new_var),
16620                                       build_int_cst (build_pointer_type (type),
16621                                                      offset));
16622                   }
16623                 else
16624                   is_ref = is_reference (var);
16625                 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
16626                   is_ref = false;
16627                 bool ref_to_array = false;
16628                 if (is_ref)
16629                   {
16630                     type = TREE_TYPE (type);
16631                     if (TREE_CODE (type) == ARRAY_TYPE)
16632                       {
16633                         type = build_pointer_type (type);
16634                         ref_to_array = true;
16635                       }
16636                   }
16637                 else if (TREE_CODE (type) == ARRAY_TYPE)
16638                   {
16639                     tree decl2 = DECL_VALUE_EXPR (new_var);
16640                     gcc_assert (TREE_CODE (decl2) == MEM_REF);
16641                     decl2 = TREE_OPERAND (decl2, 0);
16642                     gcc_assert (DECL_P (decl2));
16643                     new_var = decl2;
16644                     type = TREE_TYPE (new_var);
16645                   }
16646                 x = build_receiver_ref (OMP_CLAUSE_DECL (prev), false, ctx);
16647                 x = fold_convert_loc (clause_loc, type, x);
16648                 if (!integer_zerop (OMP_CLAUSE_SIZE (c)))
16649                   {
16650                     tree bias = OMP_CLAUSE_SIZE (c);
16651                     if (DECL_P (bias))
16652                       bias = lookup_decl (bias, ctx);
16653                     bias = fold_convert_loc (clause_loc, sizetype, bias);
16654                     bias = fold_build1_loc (clause_loc, NEGATE_EXPR, sizetype,
16655                                             bias);
16656                     x = fold_build2_loc (clause_loc, POINTER_PLUS_EXPR,
16657                                          TREE_TYPE (x), x, bias);
16658                   }
16659                 if (ref_to_array)
16660                   x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
16661                 gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
16662                 if (is_ref && !ref_to_array)
16663                   {
16664                     tree t = create_tmp_var_raw (type, get_name (var));
16665                     gimple_add_tmp_var (t);
16666                     TREE_ADDRESSABLE (t) = 1;
16667                     gimple_seq_add_stmt (&new_body,
16668                                          gimple_build_assign (t, x));
16669                     x = build_fold_addr_expr_loc (clause_loc, t);
16670                   }
16671                 gimple_seq_add_stmt (&new_body,
16672                                      gimple_build_assign (new_var, x));
16673                 prev = NULL_TREE;
16674               }
16675             else if (OMP_CLAUSE_CHAIN (c)
16676                      && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c))
16677                         == OMP_CLAUSE_MAP
16678                      && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
16679                          == GOMP_MAP_FIRSTPRIVATE_POINTER
16680                          || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
16681                              == GOMP_MAP_FIRSTPRIVATE_REFERENCE)))
16682               prev = c;
16683             break;
16684           case OMP_CLAUSE_PRIVATE:
16685             var = OMP_CLAUSE_DECL (c);
16686             if (is_variable_sized (var))
16687               {
16688                 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
16689                 tree new_var = lookup_decl (var, ctx);
16690                 tree pvar = DECL_VALUE_EXPR (var);
16691                 gcc_assert (TREE_CODE (pvar) == INDIRECT_REF);
16692                 pvar = TREE_OPERAND (pvar, 0);
16693                 gcc_assert (DECL_P (pvar));
16694                 tree new_pvar = lookup_decl (pvar, ctx);
16695                 tree atmp = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
16696                 tree al = size_int (DECL_ALIGN (var));
16697                 tree x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
16698                 x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
16699                 x = fold_convert_loc (clause_loc, TREE_TYPE (new_pvar), x);
16700                 gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
16701                 gimple_seq_add_stmt (&new_body,
16702                                      gimple_build_assign (new_pvar, x));
16703               }
16704             else if (is_reference (var) && !is_gimple_omp_oacc (ctx->stmt))
16705               {
16706                 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
16707                 tree new_var = lookup_decl (var, ctx);
16708                 tree x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
16709                 if (TREE_CONSTANT (x))
16710                   break;
16711                 else
16712                   {
16713                     tree atmp
16714                       = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
16715                     tree rtype = TREE_TYPE (TREE_TYPE (new_var));
16716                     tree al = size_int (TYPE_ALIGN (rtype));
16717                     x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
16718                   }
16719
16720                 x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
16721                 gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
16722                 gimple_seq_add_stmt (&new_body,
16723                                      gimple_build_assign (new_var, x));
16724               }
16725             break;
16726           }
16727
16728       gimple_seq fork_seq = NULL;
16729       gimple_seq join_seq = NULL;
16730
16731       if (is_oacc_parallel (ctx))
16732         {
16733           /* If there are reductions on the offloaded region itself, treat
16734              them as a dummy GANG loop.  */
16735           tree level = build_int_cst (integer_type_node, GOMP_DIM_GANG);
16736
16737           lower_oacc_reductions (gimple_location (ctx->stmt), clauses, level,
16738                                  false, NULL, NULL, &fork_seq, &join_seq, ctx);
16739         }
16740
16741       gimple_seq_add_seq (&new_body, fork_seq);
16742       gimple_seq_add_seq (&new_body, tgt_body);
16743       gimple_seq_add_seq (&new_body, join_seq);
16744
16745       if (offloaded)
16746         new_body = maybe_catch_exception (new_body);
16747
16748       gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
16749       gimple_omp_set_body (stmt, new_body);
16750     }
16751
16752   bind = gimple_build_bind (NULL, NULL,
16753                             tgt_bind ? gimple_bind_block (tgt_bind)
16754                                      : NULL_TREE);
16755   gsi_replace (gsi_p, dep_bind ? dep_bind : bind, true);
16756   gimple_bind_add_seq (bind, ilist);
16757   gimple_bind_add_stmt (bind, stmt);
16758   gimple_bind_add_seq (bind, olist);
16759
16760   pop_gimplify_context (NULL);
16761
16762   if (dep_bind)
16763     {
16764       gimple_bind_add_seq (dep_bind, dep_ilist);
16765       gimple_bind_add_stmt (dep_bind, bind);
16766       gimple_bind_add_seq (dep_bind, dep_olist);
16767       pop_gimplify_context (dep_bind);
16768     }
16769 }
16770
16771 /* Expand code for an OpenMP teams directive.  */
16772
16773 static void
16774 lower_omp_teams (gimple_stmt_iterator *gsi_p, omp_context *ctx)
16775 {
16776   gomp_teams *teams_stmt = as_a <gomp_teams *> (gsi_stmt (*gsi_p));
16777   push_gimplify_context ();
16778
16779   tree block = make_node (BLOCK);
16780   gbind *bind = gimple_build_bind (NULL, NULL, block);
16781   gsi_replace (gsi_p, bind, true);
16782   gimple_seq bind_body = NULL;
16783   gimple_seq dlist = NULL;
16784   gimple_seq olist = NULL;
16785
16786   tree num_teams = find_omp_clause (gimple_omp_teams_clauses (teams_stmt),
16787                                     OMP_CLAUSE_NUM_TEAMS);
16788   if (num_teams == NULL_TREE)
16789     num_teams = build_int_cst (unsigned_type_node, 0);
16790   else
16791     {
16792       num_teams = OMP_CLAUSE_NUM_TEAMS_EXPR (num_teams);
16793       num_teams = fold_convert (unsigned_type_node, num_teams);
16794       gimplify_expr (&num_teams, &bind_body, NULL, is_gimple_val, fb_rvalue);
16795     }
16796   tree thread_limit = find_omp_clause (gimple_omp_teams_clauses (teams_stmt),
16797                                        OMP_CLAUSE_THREAD_LIMIT);
16798   if (thread_limit == NULL_TREE)
16799     thread_limit = build_int_cst (unsigned_type_node, 0);
16800   else
16801     {
16802       thread_limit = OMP_CLAUSE_THREAD_LIMIT_EXPR (thread_limit);
16803       thread_limit = fold_convert (unsigned_type_node, thread_limit);
16804       gimplify_expr (&thread_limit, &bind_body, NULL, is_gimple_val,
16805                      fb_rvalue);
16806     }
16807
16808   lower_rec_input_clauses (gimple_omp_teams_clauses (teams_stmt),
16809                            &bind_body, &dlist, ctx, NULL);
16810   lower_omp (gimple_omp_body_ptr (teams_stmt), ctx);
16811   lower_reduction_clauses (gimple_omp_teams_clauses (teams_stmt), &olist, ctx);
16812   if (!gimple_omp_teams_grid_phony (teams_stmt))
16813     {
16814       gimple_seq_add_stmt (&bind_body, teams_stmt);
16815       location_t loc = gimple_location (teams_stmt);
16816       tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TEAMS);
16817       gimple *call = gimple_build_call (decl, 2, num_teams, thread_limit);
16818       gimple_set_location (call, loc);
16819       gimple_seq_add_stmt (&bind_body, call);
16820     }
16821
16822   gimple_seq_add_seq (&bind_body, gimple_omp_body (teams_stmt));
16823   gimple_omp_set_body (teams_stmt, NULL);
16824   gimple_seq_add_seq (&bind_body, olist);
16825   gimple_seq_add_seq (&bind_body, dlist);
16826   if (!gimple_omp_teams_grid_phony (teams_stmt))
16827     gimple_seq_add_stmt (&bind_body, gimple_build_omp_return (true));
16828   gimple_bind_set_body (bind, bind_body);
16829
16830   pop_gimplify_context (bind);
16831
16832   gimple_bind_append_vars (bind, ctx->block_vars);
16833   BLOCK_VARS (block) = ctx->block_vars;
16834   if (BLOCK_VARS (block))
16835     TREE_USED (block) = 1;
16836 }
16837
16838 /* Expand code within an artificial GIMPLE_OMP_GRID_BODY OMP construct.  */
16839
16840 static void
16841 lower_omp_grid_body (gimple_stmt_iterator *gsi_p, omp_context *ctx)
16842 {
16843   gimple *stmt = gsi_stmt (*gsi_p);
16844   lower_omp (gimple_omp_body_ptr (stmt), ctx);
16845   gimple_seq_add_stmt (gimple_omp_body_ptr (stmt),
16846                        gimple_build_omp_return (false));
16847 }
16848
16849
16850 /* Callback for lower_omp_1.  Return non-NULL if *tp needs to be
16851    regimplified.  If DATA is non-NULL, lower_omp_1 is outside
16852    of OMP context, but with task_shared_vars set.  */
16853
16854 static tree
16855 lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
16856                         void *data)
16857 {
16858   tree t = *tp;
16859
16860   /* Any variable with DECL_VALUE_EXPR needs to be regimplified.  */
16861   if (TREE_CODE (t) == VAR_DECL && data == NULL && DECL_HAS_VALUE_EXPR_P (t))
16862     return t;
16863
16864   if (task_shared_vars
16865       && DECL_P (t)
16866       && bitmap_bit_p (task_shared_vars, DECL_UID (t)))
16867     return t;
16868
16869   /* If a global variable has been privatized, TREE_CONSTANT on
16870      ADDR_EXPR might be wrong.  */
16871   if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
16872     recompute_tree_invariant_for_addr_expr (t);
16873
16874   *walk_subtrees = !IS_TYPE_OR_DECL_P (t);
16875   return NULL_TREE;
16876 }
16877
16878 /* Data to be communicated between lower_omp_regimplify_operands and
16879    lower_omp_regimplify_operands_p.  */
16880
16881 struct lower_omp_regimplify_operands_data
16882 {
16883   omp_context *ctx;
16884   vec<tree> *decls;
16885 };
16886
16887 /* Helper function for lower_omp_regimplify_operands.  Find
16888    omp_member_access_dummy_var vars and adjust temporarily their
16889    DECL_VALUE_EXPRs if needed.  */
16890
16891 static tree
16892 lower_omp_regimplify_operands_p (tree *tp, int *walk_subtrees,
16893                                  void *data)
16894 {
16895   tree t = omp_member_access_dummy_var (*tp);
16896   if (t)
16897     {
16898       struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
16899       lower_omp_regimplify_operands_data *ldata
16900         = (lower_omp_regimplify_operands_data *) wi->info;
16901       tree o = maybe_lookup_decl (t, ldata->ctx);
16902       if (o != t)
16903         {
16904           ldata->decls->safe_push (DECL_VALUE_EXPR (*tp));
16905           ldata->decls->safe_push (*tp);
16906           tree v = unshare_and_remap (DECL_VALUE_EXPR (*tp), t, o);
16907           SET_DECL_VALUE_EXPR (*tp, v);
16908         }
16909     }
16910   *walk_subtrees = !IS_TYPE_OR_DECL_P (*tp);
16911   return NULL_TREE;
16912 }
16913
16914 /* Wrapper around gimple_regimplify_operands that adjusts DECL_VALUE_EXPRs
16915    of omp_member_access_dummy_var vars during regimplification.  */
16916
16917 static void
16918 lower_omp_regimplify_operands (omp_context *ctx, gimple *stmt,
16919                                gimple_stmt_iterator *gsi_p)
16920 {
16921   auto_vec<tree, 10> decls;
16922   if (ctx)
16923     {
16924       struct walk_stmt_info wi;
16925       memset (&wi, '\0', sizeof (wi));
16926       struct lower_omp_regimplify_operands_data data;
16927       data.ctx = ctx;
16928       data.decls = &decls;
16929       wi.info = &data;
16930       walk_gimple_op (stmt, lower_omp_regimplify_operands_p, &wi);
16931     }
16932   gimple_regimplify_operands (stmt, gsi_p);
16933   while (!decls.is_empty ())
16934     {
16935       tree t = decls.pop ();
16936       tree v = decls.pop ();
16937       SET_DECL_VALUE_EXPR (t, v);
16938     }
16939 }
16940
16941 static void
16942 lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
16943 {
16944   gimple *stmt = gsi_stmt (*gsi_p);
16945   struct walk_stmt_info wi;
16946   gcall *call_stmt;
16947
16948   if (gimple_has_location (stmt))
16949     input_location = gimple_location (stmt);
16950
16951   if (task_shared_vars)
16952     memset (&wi, '\0', sizeof (wi));
16953
16954   /* If we have issued syntax errors, avoid doing any heavy lifting.
16955      Just replace the OMP directives with a NOP to avoid
16956      confusing RTL expansion.  */
16957   if (seen_error () && is_gimple_omp (stmt))
16958     {
16959       gsi_replace (gsi_p, gimple_build_nop (), true);
16960       return;
16961     }
16962
16963   switch (gimple_code (stmt))
16964     {
16965     case GIMPLE_COND:
16966       {
16967         gcond *cond_stmt = as_a <gcond *> (stmt);
16968         if ((ctx || task_shared_vars)
16969             && (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
16970                            lower_omp_regimplify_p,
16971                            ctx ? NULL : &wi, NULL)
16972                 || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
16973                               lower_omp_regimplify_p,
16974                               ctx ? NULL : &wi, NULL)))
16975           lower_omp_regimplify_operands (ctx, cond_stmt, gsi_p);
16976       }
16977       break;
16978     case GIMPLE_CATCH:
16979       lower_omp (gimple_catch_handler_ptr (as_a <gcatch *> (stmt)), ctx);
16980       break;
16981     case GIMPLE_EH_FILTER:
16982       lower_omp (gimple_eh_filter_failure_ptr (stmt), ctx);
16983       break;
16984     case GIMPLE_TRY:
16985       lower_omp (gimple_try_eval_ptr (stmt), ctx);
16986       lower_omp (gimple_try_cleanup_ptr (stmt), ctx);
16987       break;
16988     case GIMPLE_TRANSACTION:
16989       lower_omp (gimple_transaction_body_ptr (
16990                    as_a <gtransaction *> (stmt)),
16991                  ctx);
16992       break;
16993     case GIMPLE_BIND:
16994       lower_omp (gimple_bind_body_ptr (as_a <gbind *> (stmt)), ctx);
16995       break;
16996     case GIMPLE_OMP_PARALLEL:
16997     case GIMPLE_OMP_TASK:
16998       ctx = maybe_lookup_ctx (stmt);
16999       gcc_assert (ctx);
17000       if (ctx->cancellable)
17001         ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
17002       lower_omp_taskreg (gsi_p, ctx);
17003       break;
17004     case GIMPLE_OMP_FOR:
17005       ctx = maybe_lookup_ctx (stmt);
17006       gcc_assert (ctx);
17007       if (ctx->cancellable)
17008         ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
17009       lower_omp_for (gsi_p, ctx);
17010       break;
17011     case GIMPLE_OMP_SECTIONS:
17012       ctx = maybe_lookup_ctx (stmt);
17013       gcc_assert (ctx);
17014       if (ctx->cancellable)
17015         ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
17016       lower_omp_sections (gsi_p, ctx);
17017       break;
17018     case GIMPLE_OMP_SINGLE:
17019       ctx = maybe_lookup_ctx (stmt);
17020       gcc_assert (ctx);
17021       lower_omp_single (gsi_p, ctx);
17022       break;
17023     case GIMPLE_OMP_MASTER:
17024       ctx = maybe_lookup_ctx (stmt);
17025       gcc_assert (ctx);
17026       lower_omp_master (gsi_p, ctx);
17027       break;
17028     case GIMPLE_OMP_TASKGROUP:
17029       ctx = maybe_lookup_ctx (stmt);
17030       gcc_assert (ctx);
17031       lower_omp_taskgroup (gsi_p, ctx);
17032       break;
17033     case GIMPLE_OMP_ORDERED:
17034       ctx = maybe_lookup_ctx (stmt);
17035       gcc_assert (ctx);
17036       lower_omp_ordered (gsi_p, ctx);
17037       break;
17038     case GIMPLE_OMP_CRITICAL:
17039       ctx = maybe_lookup_ctx (stmt);
17040       gcc_assert (ctx);
17041       lower_omp_critical (gsi_p, ctx);
17042       break;
17043     case GIMPLE_OMP_ATOMIC_LOAD:
17044       if ((ctx || task_shared_vars)
17045           && walk_tree (gimple_omp_atomic_load_rhs_ptr (
17046                           as_a <gomp_atomic_load *> (stmt)),
17047                         lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
17048         lower_omp_regimplify_operands (ctx, stmt, gsi_p);
17049       break;
17050     case GIMPLE_OMP_TARGET:
17051       ctx = maybe_lookup_ctx (stmt);
17052       gcc_assert (ctx);
17053       lower_omp_target (gsi_p, ctx);
17054       break;
17055     case GIMPLE_OMP_TEAMS:
17056       ctx = maybe_lookup_ctx (stmt);
17057       gcc_assert (ctx);
17058       lower_omp_teams (gsi_p, ctx);
17059       break;
17060     case GIMPLE_OMP_GRID_BODY:
17061       ctx = maybe_lookup_ctx (stmt);
17062       gcc_assert (ctx);
17063       lower_omp_grid_body (gsi_p, ctx);
17064       break;
17065     case GIMPLE_CALL:
17066       tree fndecl;
17067       call_stmt = as_a <gcall *> (stmt);
17068       fndecl = gimple_call_fndecl (call_stmt);
17069       if (fndecl
17070           && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
17071         switch (DECL_FUNCTION_CODE (fndecl))
17072           {
17073           case BUILT_IN_GOMP_BARRIER:
17074             if (ctx == NULL)
17075               break;
17076             /* FALLTHRU */
17077           case BUILT_IN_GOMP_CANCEL:
17078           case BUILT_IN_GOMP_CANCELLATION_POINT:
17079             omp_context *cctx;
17080             cctx = ctx;
17081             if (gimple_code (cctx->stmt) == GIMPLE_OMP_SECTION)
17082               cctx = cctx->outer;
17083             gcc_assert (gimple_call_lhs (call_stmt) == NULL_TREE);
17084             if (!cctx->cancellable)
17085               {
17086                 if (DECL_FUNCTION_CODE (fndecl)
17087                     == BUILT_IN_GOMP_CANCELLATION_POINT)
17088                   {
17089                     stmt = gimple_build_nop ();
17090                     gsi_replace (gsi_p, stmt, false);
17091                   }
17092                 break;
17093               }
17094             if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER)
17095               {
17096                 fndecl = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER_CANCEL);
17097                 gimple_call_set_fndecl (call_stmt, fndecl);
17098                 gimple_call_set_fntype (call_stmt, TREE_TYPE (fndecl));
17099               }
17100             tree lhs;
17101             lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (fndecl)));
17102             gimple_call_set_lhs (call_stmt, lhs);
17103             tree fallthru_label;
17104             fallthru_label = create_artificial_label (UNKNOWN_LOCATION);
17105             gimple *g;
17106             g = gimple_build_label (fallthru_label);
17107             gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
17108             g = gimple_build_cond (NE_EXPR, lhs,
17109                                    fold_convert (TREE_TYPE (lhs),
17110                                                  boolean_false_node),
17111                                    cctx->cancel_label, fallthru_label);
17112             gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
17113             break;
17114           default:
17115             break;
17116           }
17117       /* FALLTHRU */
17118     default:
17119       if ((ctx || task_shared_vars)
17120           && walk_gimple_op (stmt, lower_omp_regimplify_p,
17121                              ctx ? NULL : &wi))
17122         {
17123           /* Just remove clobbers, this should happen only if we have
17124              "privatized" local addressable variables in SIMD regions,
17125              the clobber isn't needed in that case and gimplifying address
17126              of the ARRAY_REF into a pointer and creating MEM_REF based
17127              clobber would create worse code than we get with the clobber
17128              dropped.  */
17129           if (gimple_clobber_p (stmt))
17130             {
17131               gsi_replace (gsi_p, gimple_build_nop (), true);
17132               break;
17133             }
17134           lower_omp_regimplify_operands (ctx, stmt, gsi_p);
17135         }
17136       break;
17137     }
17138 }
17139
17140 static void
17141 lower_omp (gimple_seq *body, omp_context *ctx)
17142 {
17143   location_t saved_location = input_location;
17144   gimple_stmt_iterator gsi;
17145   for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
17146     lower_omp_1 (&gsi, ctx);
17147   /* During gimplification, we haven't folded statments inside offloading
17148      or taskreg regions (gimplify.c:maybe_fold_stmt); do that now.  */
17149   if (target_nesting_level || taskreg_nesting_level)
17150     for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
17151       fold_stmt (&gsi);
17152   input_location = saved_location;
17153 }
17154
17155 /* Returen true if STMT is an assignment of a register-type into a local
17156    VAR_DECL.  */
17157
17158 static bool
17159 grid_reg_assignment_to_local_var_p (gimple *stmt)
17160 {
17161   gassign *assign = dyn_cast <gassign *> (stmt);
17162   if (!assign)
17163     return false;
17164   tree lhs = gimple_assign_lhs (assign);
17165   if (TREE_CODE (lhs) != VAR_DECL
17166       || !is_gimple_reg_type (TREE_TYPE (lhs))
17167       || is_global_var (lhs))
17168     return false;
17169   return true;
17170 }
17171
17172 /* Return true if all statements in SEQ are assignments to local register-type
17173    variables.  */
17174
17175 static bool
17176 grid_seq_only_contains_local_assignments (gimple_seq seq)
17177 {
17178   if (!seq)
17179     return true;
17180
17181   gimple_stmt_iterator gsi;
17182   for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
17183     if (!grid_reg_assignment_to_local_var_p (gsi_stmt (gsi)))
17184       return false;
17185   return true;
17186 }
17187
17188 /* Scan statements in SEQ and call itself recursively on any bind.  If during
17189    whole search only assignments to register-type local variables and one
17190    single OMP statement is encountered, return true, otherwise return false.
17191    RET is where we store any OMP statement encountered.  TARGET_LOC and NAME
17192    are used for dumping a note about a failure.  */
17193
17194 static bool
17195 grid_find_single_omp_among_assignments_1 (gimple_seq seq, location_t target_loc,
17196                                      const char *name, gimple **ret)
17197 {
17198   gimple_stmt_iterator gsi;
17199   for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
17200     {
17201       gimple *stmt = gsi_stmt (gsi);
17202
17203       if (grid_reg_assignment_to_local_var_p (stmt))
17204         continue;
17205       if (gbind *bind = dyn_cast <gbind *> (stmt))
17206         {
17207           if (!grid_find_single_omp_among_assignments_1 (gimple_bind_body (bind),
17208                                                          target_loc, name, ret))
17209               return false;
17210         }
17211       else if (is_gimple_omp (stmt))
17212         {
17213           if (*ret)
17214             {
17215               if (dump_enabled_p ())
17216                 dump_printf_loc (MSG_NOTE, target_loc,
17217                                  "Will not turn target construct into a simple "
17218                                  "GPGPU kernel because %s construct contains "
17219                                  "multiple OpenMP constructs\n", name);
17220               return false;
17221             }
17222           *ret = stmt;
17223         }
17224       else
17225         {
17226           if (dump_enabled_p ())
17227             dump_printf_loc (MSG_NOTE, target_loc,
17228                              "Will not turn target construct into a simple "
17229                              "GPGPU kernel because %s construct contains "
17230                              "a complex statement\n", name);
17231           return false;
17232         }
17233     }
17234   return true;
17235 }
17236
17237 /* Scan statements in SEQ and make sure that it and any binds in it contain
17238    only assignments to local register-type variables and one OMP construct.  If
17239    so, return that construct, otherwise return NULL.  If dumping is enabled and
17240    function fails, use TARGET_LOC and NAME to dump a note with the reason for
17241    failure.  */
17242
17243 static gimple *
17244 grid_find_single_omp_among_assignments (gimple_seq seq, location_t target_loc,
17245                                         const char *name)
17246 {
17247   if (!seq)
17248     {
17249       if (dump_enabled_p ())
17250         dump_printf_loc (MSG_NOTE, target_loc,
17251                          "Will not turn target construct into a simple "
17252                          "GPGPU kernel because %s construct has empty "
17253                          "body\n",
17254                          name);
17255       return NULL;
17256     }
17257
17258   gimple *ret = NULL;
17259   if (grid_find_single_omp_among_assignments_1 (seq, target_loc, name, &ret))
17260     {
17261       if (!ret && dump_enabled_p ())
17262         dump_printf_loc (MSG_NOTE, target_loc,
17263                          "Will not turn target construct into a simple "
17264                          "GPGPU kernel because %s construct does not contain"
17265                          "any other OpenMP construct\n", name);
17266       return ret;
17267     }
17268   else
17269     return NULL;
17270 }
17271
17272 /* Walker function looking for statements there is no point gridifying (and for
17273    noreturn function calls which we cannot do).  Return non-NULL if such a
17274    function is found.  */
17275
17276 static tree
17277 grid_find_ungridifiable_statement (gimple_stmt_iterator *gsi,
17278                                    bool *handled_ops_p,
17279                                    struct walk_stmt_info *wi)
17280 {
17281   *handled_ops_p = false;
17282   gimple *stmt = gsi_stmt (*gsi);
17283   switch (gimple_code (stmt))
17284     {
17285     case GIMPLE_CALL:
17286       if (gimple_call_noreturn_p (as_a <gcall *> (stmt)))
17287         {
17288           *handled_ops_p = true;
17289           wi->info = stmt;
17290           return error_mark_node;
17291         }
17292       break;
17293
17294     /* We may reduce the following list if we find a way to implement the
17295        clauses, but now there is no point trying further.  */
17296     case GIMPLE_OMP_CRITICAL:
17297     case GIMPLE_OMP_TASKGROUP:
17298     case GIMPLE_OMP_TASK:
17299     case GIMPLE_OMP_SECTION:
17300     case GIMPLE_OMP_SECTIONS:
17301     case GIMPLE_OMP_SECTIONS_SWITCH:
17302     case GIMPLE_OMP_TARGET:
17303     case GIMPLE_OMP_ORDERED:
17304       *handled_ops_p = true;
17305       wi->info = stmt;
17306       return error_mark_node;
17307
17308     case GIMPLE_OMP_FOR:
17309       if ((gimple_omp_for_kind (stmt) & GF_OMP_FOR_SIMD)
17310           && gimple_omp_for_combined_into_p (stmt))
17311         {
17312           *handled_ops_p = true;
17313           wi->info = stmt;
17314           return error_mark_node;
17315         }
17316       break;
17317
17318     default:
17319       break;
17320     }
17321   return NULL;
17322 }
17323
17324
17325 /* If TARGET follows a pattern that can be turned into a gridified GPGPU
17326    kernel, return true, otherwise return false.  In the case of success, also
17327    fill in GROUP_SIZE_P with the requested group size or NULL if there is
17328    none.  */
17329
17330 static bool
17331 grid_target_follows_gridifiable_pattern (gomp_target *target, tree *group_size_p)
17332 {
17333   if (gimple_omp_target_kind (target) != GF_OMP_TARGET_KIND_REGION)
17334     return false;
17335
17336   location_t tloc = gimple_location (target);
17337   gimple *stmt
17338     = grid_find_single_omp_among_assignments (gimple_omp_body (target),
17339                                               tloc, "target");
17340   if (!stmt)
17341     return false;
17342   gomp_teams *teams = dyn_cast <gomp_teams *> (stmt);
17343   tree group_size = NULL;
17344   if (!teams)
17345     {
17346       dump_printf_loc (MSG_NOTE, tloc,
17347                        "Will not turn target construct into a simple "
17348                        "GPGPU kernel because it does not have a sole teams "
17349                        "construct in it.\n");
17350       return false;
17351     }
17352
17353   tree clauses = gimple_omp_teams_clauses (teams);
17354   while (clauses)
17355     {
17356       switch (OMP_CLAUSE_CODE (clauses))
17357         {
17358         case OMP_CLAUSE_NUM_TEAMS:
17359           if (dump_enabled_p ())
17360             dump_printf_loc (MSG_NOTE, tloc,
17361                              "Will not turn target construct into a "
17362                              "gridified GPGPU kernel because we cannot "
17363                              "handle num_teams clause of teams "
17364                              "construct\n ");
17365           return false;
17366
17367         case OMP_CLAUSE_REDUCTION:
17368           if (dump_enabled_p ())
17369             dump_printf_loc (MSG_NOTE, tloc,
17370                              "Will not turn target construct into a "
17371                              "gridified GPGPU kernel because a reduction "
17372                              "clause is present\n ");
17373           return false;
17374
17375         case OMP_CLAUSE_LASTPRIVATE:
17376           if (dump_enabled_p ())
17377             dump_printf_loc (MSG_NOTE, tloc,
17378                              "Will not turn target construct into a "
17379                              "gridified GPGPU kernel because a lastprivate "
17380                              "clause is present\n ");
17381           return false;
17382
17383         case OMP_CLAUSE_THREAD_LIMIT:
17384           group_size = OMP_CLAUSE_OPERAND (clauses, 0);
17385           break;
17386
17387         default:
17388           break;
17389         }
17390       clauses = OMP_CLAUSE_CHAIN (clauses);
17391     }
17392
17393   stmt = grid_find_single_omp_among_assignments (gimple_omp_body (teams), tloc,
17394                                                  "teams");
17395   if (!stmt)
17396     return false;
17397   gomp_for *dist = dyn_cast <gomp_for *> (stmt);
17398   if (!dist)
17399     {
17400       dump_printf_loc (MSG_NOTE, tloc,
17401                        "Will not turn target construct into a simple "
17402                        "GPGPU kernel because the teams construct  does not have "
17403                        "a sole distribute construct in it.\n");
17404       return false;
17405     }
17406
17407   gcc_assert (gimple_omp_for_kind (dist) == GF_OMP_FOR_KIND_DISTRIBUTE);
17408   if (!gimple_omp_for_combined_p (dist))
17409     {
17410       if (dump_enabled_p ())
17411         dump_printf_loc (MSG_NOTE, tloc,
17412                          "Will not turn target construct into a gridified GPGPU "
17413                          "kernel because we cannot handle a standalone "
17414                          "distribute construct\n ");
17415       return false;
17416     }
17417   if (dist->collapse > 1)
17418     {
17419       if (dump_enabled_p ())
17420         dump_printf_loc (MSG_NOTE, tloc,
17421                          "Will not turn target construct into a gridified GPGPU "
17422                          "kernel because the distribute construct contains "
17423                          "collapse clause\n");
17424       return false;
17425     }
17426   struct omp_for_data fd;
17427   extract_omp_for_data (dist, &fd, NULL);
17428   if (fd.chunk_size)
17429     {
17430       if (group_size && !operand_equal_p (group_size, fd.chunk_size, 0))
17431         {
17432           if (dump_enabled_p ())
17433             dump_printf_loc (MSG_NOTE, tloc,
17434                              "Will not turn target construct into a "
17435                              "gridified GPGPU kernel because the teams "
17436                              "thread limit is different from distribute "
17437                              "schedule chunk\n");
17438           return false;
17439         }
17440       group_size = fd.chunk_size;
17441     }
17442   stmt = grid_find_single_omp_among_assignments (gimple_omp_body (dist), tloc,
17443                                                  "distribute");
17444   gomp_parallel *par;
17445   if (!stmt || !(par = dyn_cast <gomp_parallel *> (stmt)))
17446     return false;
17447
17448   clauses = gimple_omp_parallel_clauses (par);
17449   while (clauses)
17450     {
17451       switch (OMP_CLAUSE_CODE (clauses))
17452         {
17453         case OMP_CLAUSE_NUM_THREADS:
17454           if (dump_enabled_p ())
17455             dump_printf_loc (MSG_NOTE, tloc,
17456                              "Will not turn target construct into a gridified"
17457                              "GPGPU kernel because there is a num_threads "
17458                              "clause of the parallel construct\n");
17459           return false;
17460
17461         case OMP_CLAUSE_REDUCTION:
17462           if (dump_enabled_p ())
17463             dump_printf_loc (MSG_NOTE, tloc,
17464                              "Will not turn target construct into a "
17465                              "gridified GPGPU kernel because a reduction "
17466                              "clause is present\n ");
17467           return false;
17468
17469         case OMP_CLAUSE_LASTPRIVATE:
17470           if (dump_enabled_p ())
17471             dump_printf_loc (MSG_NOTE, tloc,
17472                              "Will not turn target construct into a "
17473                              "gridified GPGPU kernel because a lastprivate "
17474                              "clause is present\n ");
17475           return false;
17476
17477         default:
17478           break;
17479         }
17480       clauses = OMP_CLAUSE_CHAIN (clauses);
17481     }
17482
17483   stmt = grid_find_single_omp_among_assignments (gimple_omp_body (par), tloc,
17484                                                  "parallel");
17485   gomp_for *gfor;
17486   if (!stmt || !(gfor = dyn_cast <gomp_for *> (stmt)))
17487     return false;
17488
17489   if (gimple_omp_for_kind (gfor) != GF_OMP_FOR_KIND_FOR)
17490     {
17491       if (dump_enabled_p ())
17492         dump_printf_loc (MSG_NOTE, tloc,
17493                          "Will not turn target construct into a gridified GPGPU "
17494                          "kernel because the inner loop is not a simple for "
17495                          "loop\n");
17496       return false;
17497     }
17498   if (gfor->collapse > 1)
17499     {
17500       if (dump_enabled_p ())
17501         dump_printf_loc (MSG_NOTE, tloc,
17502                          "Will not turn target construct into a gridified GPGPU "
17503                          "kernel because the inner loop contains collapse "
17504                          "clause\n");
17505       return false;
17506     }
17507
17508   if (!grid_seq_only_contains_local_assignments (gimple_omp_for_pre_body (gfor)))
17509     {
17510       if (dump_enabled_p ())
17511         dump_printf_loc (MSG_NOTE, tloc,
17512                          "Will not turn target construct into a gridified GPGPU "
17513                          "kernel because the inner loop pre_body contains"
17514                          "a complex instruction\n");
17515       return false;
17516     }
17517
17518   clauses = gimple_omp_for_clauses (gfor);
17519   while (clauses)
17520     {
17521       switch (OMP_CLAUSE_CODE (clauses))
17522         {
17523         case OMP_CLAUSE_SCHEDULE:
17524           if (OMP_CLAUSE_SCHEDULE_KIND (clauses) != OMP_CLAUSE_SCHEDULE_AUTO)
17525             {
17526               if (dump_enabled_p ())
17527                 dump_printf_loc (MSG_NOTE, tloc,
17528                                  "Will not turn target construct into a "
17529                                  "gridified GPGPU kernel because the inner "
17530                                  "loop has a non-automatic scheduling clause\n");
17531               return false;
17532             }
17533           break;
17534
17535         case OMP_CLAUSE_REDUCTION:
17536           if (dump_enabled_p ())
17537             dump_printf_loc (MSG_NOTE, tloc,
17538                              "Will not turn target construct into a "
17539                              "gridified GPGPU kernel because a reduction "
17540                              "clause is present\n ");
17541           return false;
17542
17543         case OMP_CLAUSE_LASTPRIVATE:
17544           if (dump_enabled_p ())
17545             dump_printf_loc (MSG_NOTE, tloc,
17546                              "Will not turn target construct into a "
17547                              "gridified GPGPU kernel because a lastprivate "
17548                              "clause is present\n ");
17549           return false;
17550
17551         default:
17552           break;
17553         }
17554       clauses = OMP_CLAUSE_CHAIN (clauses);
17555     }
17556
17557   struct walk_stmt_info wi;
17558   memset (&wi, 0, sizeof (wi));
17559   if (walk_gimple_seq (gimple_omp_body (gfor),
17560                        grid_find_ungridifiable_statement,
17561                        NULL, &wi))
17562     {
17563       gimple *bad = (gimple *) wi.info;
17564       if (dump_enabled_p ())
17565         {
17566           if (is_gimple_call (bad))
17567             dump_printf_loc (MSG_NOTE, tloc,
17568                              "Will not turn target construct into a gridified "
17569                              " GPGPU kernel because the inner loop contains "
17570                              "call to a noreturn function\n");
17571           if (gimple_code (bad) == GIMPLE_OMP_FOR)
17572             dump_printf_loc (MSG_NOTE, tloc,
17573                              "Will not turn target construct into a gridified "
17574                              " GPGPU kernel because the inner loop contains "
17575                              "a simd construct\n");
17576           else
17577             dump_printf_loc (MSG_NOTE, tloc,
17578                              "Will not turn target construct into a gridified "
17579                              "GPGPU kernel because the inner loop contains "
17580                              "statement %s which cannot be transformed\n",
17581                              gimple_code_name[(int) gimple_code (bad)]);
17582         }
17583       return false;
17584     }
17585
17586   *group_size_p = group_size;
17587   return true;
17588 }
17589
17590 /* Operand walker, used to remap pre-body declarations according to a hash map
17591    provided in DATA.  */
17592
17593 static tree
17594 grid_remap_prebody_decls (tree *tp, int *walk_subtrees, void *data)
17595 {
17596   tree t = *tp;
17597
17598   if (DECL_P (t) || TYPE_P (t))
17599     *walk_subtrees = 0;
17600   else
17601     *walk_subtrees = 1;
17602
17603   if (TREE_CODE (t) == VAR_DECL)
17604     {
17605       struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
17606       hash_map<tree, tree> *declmap = (hash_map<tree, tree> *) wi->info;
17607       tree *repl = declmap->get (t);
17608       if (repl)
17609         *tp = *repl;
17610     }
17611   return NULL_TREE;
17612 }
17613
17614 /* Copy leading register-type assignments to local variables in SRC to just
17615    before DST, Creating temporaries, adjusting mapping of operands in WI and
17616    remapping operands as necessary.  Add any new temporaries to TGT_BIND.
17617    Return the first statement that does not conform to
17618    grid_reg_assignment_to_local_var_p or NULL.  */
17619
17620 static gimple *
17621 grid_copy_leading_local_assignments (gimple_seq src, gimple_stmt_iterator *dst,
17622                                 gbind *tgt_bind, struct walk_stmt_info *wi)
17623 {
17624   hash_map<tree, tree> *declmap = (hash_map<tree, tree> *) wi->info;
17625   gimple_stmt_iterator gsi;
17626   for (gsi = gsi_start (src); !gsi_end_p (gsi); gsi_next (&gsi))
17627     {
17628       gimple *stmt = gsi_stmt (gsi);
17629       if (gbind *bind = dyn_cast <gbind *> (stmt))
17630         {
17631           gimple *r = grid_copy_leading_local_assignments
17632             (gimple_bind_body (bind), dst, tgt_bind, wi);
17633           if (r)
17634             return r;
17635           else
17636             continue;
17637         }
17638       if (!grid_reg_assignment_to_local_var_p (stmt))
17639         return stmt;
17640       tree lhs = gimple_assign_lhs (as_a <gassign *> (stmt));
17641       tree repl = copy_var_decl (lhs, create_tmp_var_name (NULL),
17642                                  TREE_TYPE (lhs));
17643       DECL_CONTEXT (repl) = current_function_decl;
17644       gimple_bind_append_vars (tgt_bind, repl);
17645
17646       declmap->put (lhs, repl);
17647       gassign *copy = as_a <gassign *> (gimple_copy (stmt));
17648       walk_gimple_op (copy, grid_remap_prebody_decls, wi);
17649       gsi_insert_before (dst, copy, GSI_SAME_STMT);
17650     }
17651   return NULL;
17652 }
17653
17654 /* Given freshly copied top level kernel SEQ, identify the individual OMP
17655    components, mark them as part of kernel and return the inner loop, and copy
17656    assignment leading to them just before DST, remapping them using WI and
17657    adding new temporaries to TGT_BIND.  */
17658
17659 static gomp_for *
17660 grid_process_kernel_body_copy (gimple_seq seq, gimple_stmt_iterator *dst,
17661                                gbind *tgt_bind, struct walk_stmt_info *wi)
17662 {
17663   gimple *stmt = grid_copy_leading_local_assignments (seq, dst, tgt_bind, wi);
17664   gomp_teams *teams = dyn_cast <gomp_teams *> (stmt);
17665   gcc_assert (teams);
17666   gimple_omp_teams_set_grid_phony (teams, true);
17667   stmt = grid_copy_leading_local_assignments (gimple_omp_body (teams), dst,
17668                                          tgt_bind, wi);
17669   gcc_checking_assert (stmt);
17670   gomp_for *dist = dyn_cast <gomp_for *> (stmt);
17671   gcc_assert (dist);
17672   gimple_seq prebody = gimple_omp_for_pre_body (dist);
17673   if (prebody)
17674     grid_copy_leading_local_assignments (prebody, dst, tgt_bind, wi);
17675   gimple_omp_for_set_grid_phony (dist, true);
17676   stmt = grid_copy_leading_local_assignments (gimple_omp_body (dist), dst,
17677                                          tgt_bind, wi);
17678   gcc_checking_assert (stmt);
17679
17680   gomp_parallel *parallel = as_a <gomp_parallel *> (stmt);
17681   gimple_omp_parallel_set_grid_phony (parallel, true);
17682   stmt = grid_copy_leading_local_assignments (gimple_omp_body (parallel), dst,
17683                                          tgt_bind, wi);
17684   gomp_for *inner_loop = as_a <gomp_for *> (stmt);
17685   gimple_omp_for_set_kind (inner_loop, GF_OMP_FOR_KIND_GRID_LOOP);
17686   prebody = gimple_omp_for_pre_body (inner_loop);
17687   if (prebody)
17688     grid_copy_leading_local_assignments (prebody, dst, tgt_bind, wi);
17689
17690   return inner_loop;
17691 }
17692
17693 /* If TARGET points to a GOMP_TARGET which follows a gridifiable pattern,
17694    create a GPU kernel for it.  GSI must point to the same statement, TGT_BIND
17695    is the bind into which temporaries inserted before TARGET should be
17696    added.  */
17697
17698 static void
17699 grid_attempt_target_gridification (gomp_target *target,
17700                                    gimple_stmt_iterator *gsi,
17701                                    gbind *tgt_bind)
17702 {
17703   tree group_size;
17704   if (!target || !grid_target_follows_gridifiable_pattern (target, &group_size))
17705     return;
17706
17707   location_t loc = gimple_location (target);
17708   if (dump_enabled_p ())
17709     dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
17710                      "Target construct will be turned into a gridified GPGPU "
17711                      "kernel\n");
17712
17713   /* Copy target body to a GPUKERNEL construct:  */
17714   gimple_seq kernel_seq = copy_gimple_seq_and_replace_locals
17715     (gimple_omp_body (target));
17716
17717   hash_map<tree, tree> *declmap = new hash_map<tree, tree>;
17718   struct walk_stmt_info wi;
17719   memset (&wi, 0, sizeof (struct walk_stmt_info));
17720   wi.info = declmap;
17721
17722   /* Copy assignments in between OMP statements before target, mark OMP
17723      statements within copy appropriatly.  */
17724   gomp_for *inner_loop = grid_process_kernel_body_copy (kernel_seq, gsi,
17725                                                         tgt_bind, &wi);
17726
17727   gbind *old_bind = as_a <gbind *> (gimple_seq_first (gimple_omp_body (target)));
17728   gbind *new_bind = as_a <gbind *> (gimple_seq_first (kernel_seq));
17729   tree new_block = gimple_bind_block (new_bind);
17730   tree enc_block = BLOCK_SUPERCONTEXT (gimple_bind_block (old_bind));
17731   BLOCK_CHAIN (new_block) = BLOCK_SUBBLOCKS (enc_block);
17732   BLOCK_SUBBLOCKS (enc_block) = new_block;
17733   BLOCK_SUPERCONTEXT (new_block) = enc_block;
17734   gimple *gpukernel = gimple_build_omp_grid_body (kernel_seq);
17735   gimple_seq_add_stmt
17736     (gimple_bind_body_ptr (as_a <gbind *> (gimple_omp_body (target))),
17737      gpukernel);
17738
17739   walk_tree (&group_size, grid_remap_prebody_decls, &wi, NULL);
17740   push_gimplify_context ();
17741   size_t collapse = gimple_omp_for_collapse (inner_loop);
17742   for (size_t i = 0; i < collapse; i++)
17743     {
17744       tree itype, type = TREE_TYPE (gimple_omp_for_index (inner_loop, i));
17745       if (POINTER_TYPE_P (type))
17746         itype = signed_type_for (type);
17747       else
17748         itype = type;
17749
17750       enum tree_code cond_code = gimple_omp_for_cond (inner_loop, i);
17751       tree n1 = unshare_expr (gimple_omp_for_initial (inner_loop, i));
17752       walk_tree (&n1, grid_remap_prebody_decls, &wi, NULL);
17753       tree n2 = unshare_expr (gimple_omp_for_final (inner_loop, i));
17754       walk_tree (&n2, grid_remap_prebody_decls, &wi, NULL);
17755       adjust_for_condition (loc, &cond_code, &n2);
17756       tree step;
17757       step = get_omp_for_step_from_incr (loc,
17758                                          gimple_omp_for_incr (inner_loop, i));
17759       gimple_seq tmpseq = NULL;
17760       n1 = fold_convert (itype, n1);
17761       n2 = fold_convert (itype, n2);
17762       tree t = build_int_cst (itype, (cond_code == LT_EXPR ? -1 : 1));
17763       t = fold_build2 (PLUS_EXPR, itype, step, t);
17764       t = fold_build2 (PLUS_EXPR, itype, t, n2);
17765       t = fold_build2 (MINUS_EXPR, itype, t, n1);
17766       if (TYPE_UNSIGNED (itype) && cond_code == GT_EXPR)
17767         t = fold_build2 (TRUNC_DIV_EXPR, itype,
17768                          fold_build1 (NEGATE_EXPR, itype, t),
17769                          fold_build1 (NEGATE_EXPR, itype, step));
17770       else
17771         t = fold_build2 (TRUNC_DIV_EXPR, itype, t, step);
17772       tree gs = fold_convert (uint32_type_node, t);
17773       gimplify_expr (&gs, &tmpseq, NULL, is_gimple_val, fb_rvalue);
17774       if (!gimple_seq_empty_p (tmpseq))
17775         gsi_insert_seq_before (gsi, tmpseq, GSI_SAME_STMT);
17776
17777       tree ws;
17778       if (i == 0 && group_size)
17779         {
17780           ws = fold_convert (uint32_type_node, group_size);
17781           tmpseq = NULL;
17782           gimplify_expr (&ws, &tmpseq, NULL, is_gimple_val, fb_rvalue);
17783           if (!gimple_seq_empty_p (tmpseq))
17784             gsi_insert_seq_before (gsi, tmpseq, GSI_SAME_STMT);
17785         }
17786       else
17787         ws = build_zero_cst (uint32_type_node);
17788
17789       tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__GRIDDIM_);
17790       OMP_CLAUSE__GRIDDIM__DIMENSION (c) = i;
17791       OMP_CLAUSE__GRIDDIM__SIZE (c) = gs;
17792       OMP_CLAUSE__GRIDDIM__GROUP (c) = ws;
17793       OMP_CLAUSE_CHAIN (c) = gimple_omp_target_clauses (target);
17794       gimple_omp_target_set_clauses (target, c);
17795     }
17796   pop_gimplify_context (tgt_bind);
17797   delete declmap;
17798   return;
17799 }
17800
17801 /* Walker function doing all the work for create_target_kernels. */
17802
17803 static tree
17804 grid_gridify_all_targets_stmt (gimple_stmt_iterator *gsi,
17805                                    bool *handled_ops_p,
17806                                    struct walk_stmt_info *incoming)
17807 {
17808   *handled_ops_p = false;
17809
17810   gimple *stmt = gsi_stmt (*gsi);
17811   gomp_target *target = dyn_cast <gomp_target *> (stmt);
17812   if (target)
17813     {
17814       gbind *tgt_bind = (gbind *) incoming->info;
17815       gcc_checking_assert (tgt_bind);
17816       grid_attempt_target_gridification (target, gsi, tgt_bind);
17817       return NULL_TREE;
17818     }
17819   gbind *bind = dyn_cast <gbind *> (stmt);
17820   if (bind)
17821     {
17822       *handled_ops_p = true;
17823       struct walk_stmt_info wi;
17824       memset (&wi, 0, sizeof (wi));
17825       wi.info = bind;
17826       walk_gimple_seq_mod (gimple_bind_body_ptr (bind),
17827                            grid_gridify_all_targets_stmt, NULL, &wi);
17828     }
17829   return NULL_TREE;
17830 }
17831
17832 /* Attempt to gridify all target constructs in BODY_P.  All such targets will
17833    have their bodies duplicated, with the new copy being put into a
17834    gimple_omp_grid_body statement.  All kernel-related construct within the
17835    grid_body will be marked with phony flags or kernel kinds.  Moreover, some
17836    re-structuring is often needed, such as copying pre-bodies before the target
17837    construct so that kernel grid sizes can be computed.  */
17838
17839 static void
17840 grid_gridify_all_targets (gimple_seq *body_p)
17841 {
17842   struct walk_stmt_info wi;
17843   memset (&wi, 0, sizeof (wi));
17844   walk_gimple_seq_mod (body_p, grid_gridify_all_targets_stmt, NULL, &wi);
17845 }
17846 \f
17847
17848 /* Main entry point.  */
17849
17850 static unsigned int
17851 execute_lower_omp (void)
17852 {
17853   gimple_seq body;
17854   int i;
17855   omp_context *ctx;
17856
17857   /* This pass always runs, to provide PROP_gimple_lomp.
17858      But often, there is nothing to do.  */
17859   if (flag_cilkplus == 0 && flag_openacc == 0 && flag_openmp == 0
17860       && flag_openmp_simd == 0)
17861     return 0;
17862
17863   all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
17864                                  delete_omp_context);
17865
17866   body = gimple_body (current_function_decl);
17867
17868   if (hsa_gen_requested_p ())
17869     grid_gridify_all_targets (&body);
17870
17871   scan_omp (&body, NULL);
17872   gcc_assert (taskreg_nesting_level == 0);
17873   FOR_EACH_VEC_ELT (taskreg_contexts, i, ctx)
17874     finish_taskreg_scan (ctx);
17875   taskreg_contexts.release ();
17876
17877   if (all_contexts->root)
17878     {
17879       if (task_shared_vars)
17880         push_gimplify_context ();
17881       lower_omp (&body, NULL);
17882       if (task_shared_vars)
17883         pop_gimplify_context (NULL);
17884     }
17885
17886   if (all_contexts)
17887     {
17888       splay_tree_delete (all_contexts);
17889       all_contexts = NULL;
17890     }
17891   BITMAP_FREE (task_shared_vars);
17892   return 0;
17893 }
17894
17895 namespace {
17896
17897 const pass_data pass_data_lower_omp =
17898 {
17899   GIMPLE_PASS, /* type */
17900   "omplower", /* name */
17901   OPTGROUP_NONE, /* optinfo_flags */
17902   TV_NONE, /* tv_id */
17903   PROP_gimple_any, /* properties_required */
17904   PROP_gimple_lomp, /* properties_provided */
17905   0, /* properties_destroyed */
17906   0, /* todo_flags_start */
17907   0, /* todo_flags_finish */
17908 };
17909
17910 class pass_lower_omp : public gimple_opt_pass
17911 {
17912 public:
17913   pass_lower_omp (gcc::context *ctxt)
17914     : gimple_opt_pass (pass_data_lower_omp, ctxt)
17915   {}
17916
17917   /* opt_pass methods: */
17918   virtual unsigned int execute (function *) { return execute_lower_omp (); }
17919
17920 }; // class pass_lower_omp
17921
17922 } // anon namespace
17923
17924 gimple_opt_pass *
17925 make_pass_lower_omp (gcc::context *ctxt)
17926 {
17927   return new pass_lower_omp (ctxt);
17928 }
17929 \f
17930 /* The following is a utility to diagnose structured block violations.
17931    It is not part of the "omplower" pass, as that's invoked too late.  It
17932    should be invoked by the respective front ends after gimplification.  */
17933
17934 static splay_tree all_labels;
17935
17936 /* Check for mismatched contexts and generate an error if needed.  Return
17937    true if an error is detected.  */
17938
17939 static bool
17940 diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
17941                gimple *branch_ctx, gimple *label_ctx)
17942 {
17943   gcc_checking_assert (!branch_ctx || is_gimple_omp (branch_ctx));
17944   gcc_checking_assert (!label_ctx || is_gimple_omp (label_ctx));
17945
17946   if (label_ctx == branch_ctx)
17947     return false;
17948
17949   const char* kind = NULL;
17950
17951   if (flag_cilkplus)
17952     {
17953       if ((branch_ctx
17954            && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
17955            && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
17956           || (label_ctx
17957               && gimple_code (label_ctx) == GIMPLE_OMP_FOR
17958               && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
17959         kind = "Cilk Plus";
17960     }
17961   if (flag_openacc)
17962     {
17963       if ((branch_ctx && is_gimple_omp_oacc (branch_ctx))
17964           || (label_ctx && is_gimple_omp_oacc (label_ctx)))
17965         {
17966           gcc_checking_assert (kind == NULL);
17967           kind = "OpenACC";
17968         }
17969     }
17970   if (kind == NULL)
17971     {
17972       gcc_checking_assert (flag_openmp);
17973       kind = "OpenMP";
17974     }
17975
17976   /*
17977      Previously we kept track of the label's entire context in diagnose_sb_[12]
17978      so we could traverse it and issue a correct "exit" or "enter" error
17979      message upon a structured block violation.
17980
17981      We built the context by building a list with tree_cons'ing, but there is
17982      no easy counterpart in gimple tuples.  It seems like far too much work
17983      for issuing exit/enter error messages.  If someone really misses the
17984      distinct error message... patches welcome.
17985    */
17986
17987 #if 0
17988   /* Try to avoid confusing the user by producing and error message
17989      with correct "exit" or "enter" verbiage.  We prefer "exit"
17990      unless we can show that LABEL_CTX is nested within BRANCH_CTX.  */
17991   if (branch_ctx == NULL)
17992     exit_p = false;
17993   else
17994     {
17995       while (label_ctx)
17996         {
17997           if (TREE_VALUE (label_ctx) == branch_ctx)
17998             {
17999               exit_p = false;
18000               break;
18001             }
18002           label_ctx = TREE_CHAIN (label_ctx);
18003         }
18004     }
18005
18006   if (exit_p)
18007     error ("invalid exit from %s structured block", kind);
18008   else
18009     error ("invalid entry to %s structured block", kind);
18010 #endif
18011
18012   /* If it's obvious we have an invalid entry, be specific about the error.  */
18013   if (branch_ctx == NULL)
18014     error ("invalid entry to %s structured block", kind);
18015   else
18016     {
18017       /* Otherwise, be vague and lazy, but efficient.  */
18018       error ("invalid branch to/from %s structured block", kind);
18019     }
18020
18021   gsi_replace (gsi_p, gimple_build_nop (), false);
18022   return true;
18023 }
18024
18025 /* Pass 1: Create a minimal tree of structured blocks, and record
18026    where each label is found.  */
18027
18028 static tree
18029 diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
18030                struct walk_stmt_info *wi)
18031 {
18032   gimple *context = (gimple *) wi->info;
18033   gimple *inner_context;
18034   gimple *stmt = gsi_stmt (*gsi_p);
18035
18036   *handled_ops_p = true;
18037
18038   switch (gimple_code (stmt))
18039     {
18040     WALK_SUBSTMTS;
18041
18042     case GIMPLE_OMP_PARALLEL:
18043     case GIMPLE_OMP_TASK:
18044     case GIMPLE_OMP_SECTIONS:
18045     case GIMPLE_OMP_SINGLE:
18046     case GIMPLE_OMP_SECTION:
18047     case GIMPLE_OMP_MASTER:
18048     case GIMPLE_OMP_ORDERED:
18049     case GIMPLE_OMP_CRITICAL:
18050     case GIMPLE_OMP_TARGET:
18051     case GIMPLE_OMP_TEAMS:
18052     case GIMPLE_OMP_TASKGROUP:
18053       /* The minimal context here is just the current OMP construct.  */
18054       inner_context = stmt;
18055       wi->info = inner_context;
18056       walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
18057       wi->info = context;
18058       break;
18059
18060     case GIMPLE_OMP_FOR:
18061       inner_context = stmt;
18062       wi->info = inner_context;
18063       /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
18064          walk them.  */
18065       walk_gimple_seq (gimple_omp_for_pre_body (stmt),
18066                        diagnose_sb_1, NULL, wi);
18067       walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
18068       wi->info = context;
18069       break;
18070
18071     case GIMPLE_LABEL:
18072       splay_tree_insert (all_labels,
18073                          (splay_tree_key) gimple_label_label (
18074                                             as_a <glabel *> (stmt)),
18075                          (splay_tree_value) context);
18076       break;
18077
18078     default:
18079       break;
18080     }
18081
18082   return NULL_TREE;
18083 }
18084
18085 /* Pass 2: Check each branch and see if its context differs from that of
18086    the destination label's context.  */
18087
18088 static tree
18089 diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
18090                struct walk_stmt_info *wi)
18091 {
18092   gimple *context = (gimple *) wi->info;
18093   splay_tree_node n;
18094   gimple *stmt = gsi_stmt (*gsi_p);
18095
18096   *handled_ops_p = true;
18097
18098   switch (gimple_code (stmt))
18099     {
18100     WALK_SUBSTMTS;
18101
18102     case GIMPLE_OMP_PARALLEL:
18103     case GIMPLE_OMP_TASK:
18104     case GIMPLE_OMP_SECTIONS:
18105     case GIMPLE_OMP_SINGLE:
18106     case GIMPLE_OMP_SECTION:
18107     case GIMPLE_OMP_MASTER:
18108     case GIMPLE_OMP_ORDERED:
18109     case GIMPLE_OMP_CRITICAL:
18110     case GIMPLE_OMP_TARGET:
18111     case GIMPLE_OMP_TEAMS:
18112     case GIMPLE_OMP_TASKGROUP:
18113       wi->info = stmt;
18114       walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
18115       wi->info = context;
18116       break;
18117
18118     case GIMPLE_OMP_FOR:
18119       wi->info = stmt;
18120       /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
18121          walk them.  */
18122       walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt),
18123                            diagnose_sb_2, NULL, wi);
18124       walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
18125       wi->info = context;
18126       break;
18127
18128     case GIMPLE_COND:
18129         {
18130           gcond *cond_stmt = as_a <gcond *> (stmt);
18131           tree lab = gimple_cond_true_label (cond_stmt);
18132           if (lab)
18133             {
18134               n = splay_tree_lookup (all_labels,
18135                                      (splay_tree_key) lab);
18136               diagnose_sb_0 (gsi_p, context,
18137                              n ? (gimple *) n->value : NULL);
18138             }
18139           lab = gimple_cond_false_label (cond_stmt);
18140           if (lab)
18141             {
18142               n = splay_tree_lookup (all_labels,
18143                                      (splay_tree_key) lab);
18144               diagnose_sb_0 (gsi_p, context,
18145                              n ? (gimple *) n->value : NULL);
18146             }
18147         }
18148       break;
18149
18150     case GIMPLE_GOTO:
18151       {
18152         tree lab = gimple_goto_dest (stmt);
18153         if (TREE_CODE (lab) != LABEL_DECL)
18154           break;
18155
18156         n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
18157         diagnose_sb_0 (gsi_p, context, n ? (gimple *) n->value : NULL);
18158       }
18159       break;
18160
18161     case GIMPLE_SWITCH:
18162       {
18163         gswitch *switch_stmt = as_a <gswitch *> (stmt);
18164         unsigned int i;
18165         for (i = 0; i < gimple_switch_num_labels (switch_stmt); ++i)
18166           {
18167             tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i));
18168             n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
18169             if (n && diagnose_sb_0 (gsi_p, context, (gimple *) n->value))
18170               break;
18171           }
18172       }
18173       break;
18174
18175     case GIMPLE_RETURN:
18176       diagnose_sb_0 (gsi_p, context, NULL);
18177       break;
18178
18179     default:
18180       break;
18181     }
18182
18183   return NULL_TREE;
18184 }
18185
18186 /* Called from tree-cfg.c::make_edges to create cfg edges for all relevant
18187    GIMPLE_* codes.  */
18188 bool
18189 make_gimple_omp_edges (basic_block bb, struct omp_region **region,
18190                        int *region_idx)
18191 {
18192   gimple *last = last_stmt (bb);
18193   enum gimple_code code = gimple_code (last);
18194   struct omp_region *cur_region = *region;
18195   bool fallthru = false;
18196
18197   switch (code)
18198     {
18199     case GIMPLE_OMP_PARALLEL:
18200     case GIMPLE_OMP_TASK:
18201     case GIMPLE_OMP_FOR:
18202     case GIMPLE_OMP_SINGLE:
18203     case GIMPLE_OMP_TEAMS:
18204     case GIMPLE_OMP_MASTER:
18205     case GIMPLE_OMP_TASKGROUP:
18206     case GIMPLE_OMP_CRITICAL:
18207     case GIMPLE_OMP_SECTION:
18208     case GIMPLE_OMP_GRID_BODY:
18209       cur_region = new_omp_region (bb, code, cur_region);
18210       fallthru = true;
18211       break;
18212
18213     case GIMPLE_OMP_ORDERED:
18214       cur_region = new_omp_region (bb, code, cur_region);
18215       fallthru = true;
18216       if (find_omp_clause (gimple_omp_ordered_clauses
18217                              (as_a <gomp_ordered *> (last)),
18218                            OMP_CLAUSE_DEPEND))
18219         cur_region = cur_region->outer;
18220       break;
18221
18222     case GIMPLE_OMP_TARGET:
18223       cur_region = new_omp_region (bb, code, cur_region);
18224       fallthru = true;
18225       switch (gimple_omp_target_kind (last))
18226         {
18227         case GF_OMP_TARGET_KIND_REGION:
18228         case GF_OMP_TARGET_KIND_DATA:
18229         case GF_OMP_TARGET_KIND_OACC_PARALLEL:
18230         case GF_OMP_TARGET_KIND_OACC_KERNELS:
18231         case GF_OMP_TARGET_KIND_OACC_DATA:
18232         case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
18233           break;
18234         case GF_OMP_TARGET_KIND_UPDATE:
18235         case GF_OMP_TARGET_KIND_ENTER_DATA:
18236         case GF_OMP_TARGET_KIND_EXIT_DATA:
18237         case GF_OMP_TARGET_KIND_OACC_UPDATE:
18238         case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
18239         case GF_OMP_TARGET_KIND_OACC_DECLARE:
18240           cur_region = cur_region->outer;
18241           break;
18242         default:
18243           gcc_unreachable ();
18244         }
18245       break;
18246
18247     case GIMPLE_OMP_SECTIONS:
18248       cur_region = new_omp_region (bb, code, cur_region);
18249       fallthru = true;
18250       break;
18251
18252     case GIMPLE_OMP_SECTIONS_SWITCH:
18253       fallthru = false;
18254       break;
18255
18256     case GIMPLE_OMP_ATOMIC_LOAD:
18257     case GIMPLE_OMP_ATOMIC_STORE:
18258        fallthru = true;
18259        break;
18260
18261     case GIMPLE_OMP_RETURN:
18262       /* In the case of a GIMPLE_OMP_SECTION, the edge will go
18263          somewhere other than the next block.  This will be
18264          created later.  */
18265       cur_region->exit = bb;
18266       if (cur_region->type == GIMPLE_OMP_TASK)
18267         /* Add an edge corresponding to not scheduling the task
18268            immediately.  */
18269         make_edge (cur_region->entry, bb, EDGE_ABNORMAL);
18270       fallthru = cur_region->type != GIMPLE_OMP_SECTION;
18271       cur_region = cur_region->outer;
18272       break;
18273
18274     case GIMPLE_OMP_CONTINUE:
18275       cur_region->cont = bb;
18276       switch (cur_region->type)
18277         {
18278         case GIMPLE_OMP_FOR:
18279           /* Mark all GIMPLE_OMP_FOR and GIMPLE_OMP_CONTINUE
18280              succs edges as abnormal to prevent splitting
18281              them.  */
18282           single_succ_edge (cur_region->entry)->flags |= EDGE_ABNORMAL;
18283           /* Make the loopback edge.  */
18284           make_edge (bb, single_succ (cur_region->entry),
18285                      EDGE_ABNORMAL);
18286
18287           /* Create an edge from GIMPLE_OMP_FOR to exit, which
18288              corresponds to the case that the body of the loop
18289              is not executed at all.  */
18290           make_edge (cur_region->entry, bb->next_bb, EDGE_ABNORMAL);
18291           make_edge (bb, bb->next_bb, EDGE_FALLTHRU | EDGE_ABNORMAL);
18292           fallthru = false;
18293           break;
18294
18295         case GIMPLE_OMP_SECTIONS:
18296           /* Wire up the edges into and out of the nested sections.  */
18297           {
18298             basic_block switch_bb = single_succ (cur_region->entry);
18299
18300             struct omp_region *i;
18301             for (i = cur_region->inner; i ; i = i->next)
18302               {
18303                 gcc_assert (i->type == GIMPLE_OMP_SECTION);
18304                 make_edge (switch_bb, i->entry, 0);
18305                 make_edge (i->exit, bb, EDGE_FALLTHRU);
18306               }
18307
18308             /* Make the loopback edge to the block with
18309                GIMPLE_OMP_SECTIONS_SWITCH.  */
18310             make_edge (bb, switch_bb, 0);
18311
18312             /* Make the edge from the switch to exit.  */
18313             make_edge (switch_bb, bb->next_bb, 0);
18314             fallthru = false;
18315           }
18316           break;
18317
18318         case GIMPLE_OMP_TASK:
18319           fallthru = true;
18320           break;
18321
18322         default:
18323           gcc_unreachable ();
18324         }
18325       break;
18326
18327     default:
18328       gcc_unreachable ();
18329     }
18330
18331   if (*region != cur_region)
18332     {
18333       *region = cur_region;
18334       if (cur_region)
18335         *region_idx = cur_region->entry->index;
18336       else
18337         *region_idx = 0;
18338     }
18339
18340   return fallthru;
18341 }
18342
18343 static unsigned int
18344 diagnose_omp_structured_block_errors (void)
18345 {
18346   struct walk_stmt_info wi;
18347   gimple_seq body = gimple_body (current_function_decl);
18348
18349   all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
18350
18351   memset (&wi, 0, sizeof (wi));
18352   walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);
18353
18354   memset (&wi, 0, sizeof (wi));
18355   wi.want_locations = true;
18356   walk_gimple_seq_mod (&body, diagnose_sb_2, NULL, &wi);
18357
18358   gimple_set_body (current_function_decl, body);
18359
18360   splay_tree_delete (all_labels);
18361   all_labels = NULL;
18362
18363   return 0;
18364 }
18365
18366 namespace {
18367
18368 const pass_data pass_data_diagnose_omp_blocks =
18369 {
18370   GIMPLE_PASS, /* type */
18371   "*diagnose_omp_blocks", /* name */
18372   OPTGROUP_NONE, /* optinfo_flags */
18373   TV_NONE, /* tv_id */
18374   PROP_gimple_any, /* properties_required */
18375   0, /* properties_provided */
18376   0, /* properties_destroyed */
18377   0, /* todo_flags_start */
18378   0, /* todo_flags_finish */
18379 };
18380
18381 class pass_diagnose_omp_blocks : public gimple_opt_pass
18382 {
18383 public:
18384   pass_diagnose_omp_blocks (gcc::context *ctxt)
18385     : gimple_opt_pass (pass_data_diagnose_omp_blocks, ctxt)
18386   {}
18387
18388   /* opt_pass methods: */
18389   virtual bool gate (function *)
18390   {
18391     return flag_cilkplus || flag_openacc || flag_openmp;
18392   }
18393   virtual unsigned int execute (function *)
18394     {
18395       return diagnose_omp_structured_block_errors ();
18396     }
18397
18398 }; // class pass_diagnose_omp_blocks
18399
18400 } // anon namespace
18401
18402 gimple_opt_pass *
18403 make_pass_diagnose_omp_blocks (gcc::context *ctxt)
18404 {
18405   return new pass_diagnose_omp_blocks (ctxt);
18406 }
18407 \f
18408 /* Helper function for omp_finish_file routine.  Takes decls from V_DECLS and
18409    adds their addresses and sizes to constructor-vector V_CTOR.  */
18410 static void
18411 add_decls_addresses_to_decl_constructor (vec<tree, va_gc> *v_decls,
18412                                          vec<constructor_elt, va_gc> *v_ctor)
18413 {
18414   unsigned len = vec_safe_length (v_decls);
18415   for (unsigned i = 0; i < len; i++)
18416     {
18417       tree it = (*v_decls)[i];
18418       bool is_var = TREE_CODE (it) == VAR_DECL;
18419       bool is_link_var
18420         = is_var
18421 #ifdef ACCEL_COMPILER
18422           && DECL_HAS_VALUE_EXPR_P (it)
18423 #endif
18424           && lookup_attribute ("omp declare target link", DECL_ATTRIBUTES (it));
18425
18426       tree size = NULL_TREE;
18427       if (is_var)
18428         size = fold_convert (const_ptr_type_node, DECL_SIZE_UNIT (it));
18429
18430       tree addr;
18431       if (!is_link_var)
18432         addr = build_fold_addr_expr (it);
18433       else
18434         {
18435 #ifdef ACCEL_COMPILER
18436           /* For "omp declare target link" vars add address of the pointer to
18437              the target table, instead of address of the var.  */
18438           tree value_expr = DECL_VALUE_EXPR (it);
18439           tree link_ptr_decl = TREE_OPERAND (value_expr, 0);
18440           varpool_node::finalize_decl (link_ptr_decl);
18441           addr = build_fold_addr_expr (link_ptr_decl);
18442 #else
18443           addr = build_fold_addr_expr (it);
18444 #endif
18445
18446           /* Most significant bit of the size marks "omp declare target link"
18447              vars in host and target tables.  */
18448           unsigned HOST_WIDE_INT isize = tree_to_uhwi (size);
18449           isize |= 1ULL << (int_size_in_bytes (const_ptr_type_node)
18450                             * BITS_PER_UNIT - 1);
18451           size = wide_int_to_tree (const_ptr_type_node, isize);
18452         }
18453
18454       CONSTRUCTOR_APPEND_ELT (v_ctor, NULL_TREE, addr);
18455       if (is_var)
18456         CONSTRUCTOR_APPEND_ELT (v_ctor, NULL_TREE, size);
18457     }
18458 }
18459
18460 /* Create new symbols containing (address, size) pairs for global variables,
18461    marked with "omp declare target" attribute, as well as addresses for the
18462    functions, which are outlined offloading regions.  */
18463 void
18464 omp_finish_file (void)
18465 {
18466   unsigned num_funcs = vec_safe_length (offload_funcs);
18467   unsigned num_vars = vec_safe_length (offload_vars);
18468
18469   if (num_funcs == 0 && num_vars == 0)
18470     return;
18471
18472   if (targetm_common.have_named_sections)
18473     {
18474       vec<constructor_elt, va_gc> *v_f, *v_v;
18475       vec_alloc (v_f, num_funcs);
18476       vec_alloc (v_v, num_vars * 2);
18477
18478       add_decls_addresses_to_decl_constructor (offload_funcs, v_f);
18479       add_decls_addresses_to_decl_constructor (offload_vars, v_v);
18480
18481       tree vars_decl_type = build_array_type_nelts (pointer_sized_int_node,
18482                                                     num_vars * 2);
18483       tree funcs_decl_type = build_array_type_nelts (pointer_sized_int_node,
18484                                                      num_funcs);
18485       SET_TYPE_ALIGN (vars_decl_type, TYPE_ALIGN (pointer_sized_int_node));
18486       SET_TYPE_ALIGN (funcs_decl_type, TYPE_ALIGN (pointer_sized_int_node));
18487       tree ctor_v = build_constructor (vars_decl_type, v_v);
18488       tree ctor_f = build_constructor (funcs_decl_type, v_f);
18489       TREE_CONSTANT (ctor_v) = TREE_CONSTANT (ctor_f) = 1;
18490       TREE_STATIC (ctor_v) = TREE_STATIC (ctor_f) = 1;
18491       tree funcs_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
18492                                     get_identifier (".offload_func_table"),
18493                                     funcs_decl_type);
18494       tree vars_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
18495                                    get_identifier (".offload_var_table"),
18496                                    vars_decl_type);
18497       TREE_STATIC (funcs_decl) = TREE_STATIC (vars_decl) = 1;
18498       /* Do not align tables more than TYPE_ALIGN (pointer_sized_int_node),
18499          otherwise a joint table in a binary will contain padding between
18500          tables from multiple object files.  */
18501       DECL_USER_ALIGN (funcs_decl) = DECL_USER_ALIGN (vars_decl) = 1;
18502       SET_DECL_ALIGN (funcs_decl, TYPE_ALIGN (funcs_decl_type));
18503       SET_DECL_ALIGN (vars_decl, TYPE_ALIGN (vars_decl_type));
18504       DECL_INITIAL (funcs_decl) = ctor_f;
18505       DECL_INITIAL (vars_decl) = ctor_v;
18506       set_decl_section_name (funcs_decl, OFFLOAD_FUNC_TABLE_SECTION_NAME);
18507       set_decl_section_name (vars_decl, OFFLOAD_VAR_TABLE_SECTION_NAME);
18508
18509       varpool_node::finalize_decl (vars_decl);
18510       varpool_node::finalize_decl (funcs_decl);
18511     }
18512   else
18513     {
18514       for (unsigned i = 0; i < num_funcs; i++)
18515         {
18516           tree it = (*offload_funcs)[i];
18517           targetm.record_offload_symbol (it);
18518         }
18519       for (unsigned i = 0; i < num_vars; i++)
18520         {
18521           tree it = (*offload_vars)[i];
18522           targetm.record_offload_symbol (it);
18523         }
18524     }
18525 }
18526
18527 /* Find the number of threads (POS = false), or thread number (POS =
18528    true) for an OpenACC region partitioned as MASK.  Setup code
18529    required for the calculation is added to SEQ.  */
18530
18531 static tree
18532 oacc_thread_numbers (bool pos, int mask, gimple_seq *seq)
18533 {
18534   tree res = pos ? NULL_TREE : build_int_cst (unsigned_type_node, 1);
18535   unsigned ix;
18536
18537   /* Start at gang level, and examine relevant dimension indices.  */
18538   for (ix = GOMP_DIM_GANG; ix != GOMP_DIM_MAX; ix++)
18539     if (GOMP_DIM_MASK (ix) & mask)
18540       {
18541         tree arg = build_int_cst (unsigned_type_node, ix);
18542
18543         if (res)
18544           {
18545             /* We had an outer index, so scale that by the size of
18546                this dimension.  */
18547             tree n = create_tmp_var (integer_type_node);
18548             gimple *call
18549               = gimple_build_call_internal (IFN_GOACC_DIM_SIZE, 1, arg);
18550             
18551             gimple_call_set_lhs (call, n);
18552             gimple_seq_add_stmt (seq, call);
18553             res = fold_build2 (MULT_EXPR, integer_type_node, res, n);
18554           }
18555         if (pos)
18556           {
18557             /* Determine index in this dimension.  */
18558             tree id = create_tmp_var (integer_type_node);
18559             gimple *call = gimple_build_call_internal
18560               (IFN_GOACC_DIM_POS, 1, arg);
18561
18562             gimple_call_set_lhs (call, id);
18563             gimple_seq_add_stmt (seq, call);
18564             if (res)
18565               res = fold_build2 (PLUS_EXPR, integer_type_node, res, id);
18566             else
18567               res = id;
18568           }
18569       }
18570
18571   if (res == NULL_TREE)
18572     res = integer_zero_node;
18573
18574   return res;
18575 }
18576
18577 /* Transform IFN_GOACC_LOOP calls to actual code.  See
18578    expand_oacc_for for where these are generated.  At the vector
18579    level, we stride loops, such that each member of a warp will
18580    operate on adjacent iterations.  At the worker and gang level,
18581    each gang/warp executes a set of contiguous iterations.  Chunking
18582    can override this such that each iteration engine executes a
18583    contiguous chunk, and then moves on to stride to the next chunk.   */
18584
18585 static void
18586 oacc_xform_loop (gcall *call)
18587 {
18588   gimple_stmt_iterator gsi = gsi_for_stmt (call);
18589   enum ifn_goacc_loop_kind code
18590     = (enum ifn_goacc_loop_kind) TREE_INT_CST_LOW (gimple_call_arg (call, 0));
18591   tree dir = gimple_call_arg (call, 1);
18592   tree range = gimple_call_arg (call, 2);
18593   tree step = gimple_call_arg (call, 3);
18594   tree chunk_size = NULL_TREE;
18595   unsigned mask = (unsigned) TREE_INT_CST_LOW (gimple_call_arg (call, 5));
18596   tree lhs = gimple_call_lhs (call);
18597   tree type = TREE_TYPE (lhs);
18598   tree diff_type = TREE_TYPE (range);
18599   tree r = NULL_TREE;
18600   gimple_seq seq = NULL;
18601   bool chunking = false, striding = true;
18602   unsigned outer_mask = mask & (~mask + 1); // Outermost partitioning
18603   unsigned inner_mask = mask & ~outer_mask; // Inner partitioning (if any)
18604
18605 #ifdef ACCEL_COMPILER
18606   chunk_size = gimple_call_arg (call, 4);
18607   if (integer_minus_onep (chunk_size)  /* Force static allocation.  */
18608       || integer_zerop (chunk_size))   /* Default (also static).  */
18609     {
18610       /* If we're at the gang level, we want each to execute a
18611          contiguous run of iterations.  Otherwise we want each element
18612          to stride.  */
18613       striding = !(outer_mask & GOMP_DIM_MASK (GOMP_DIM_GANG));
18614       chunking = false;
18615     }
18616   else
18617     {
18618       /* Chunk of size 1 is striding.  */
18619       striding = integer_onep (chunk_size);
18620       chunking = !striding;
18621     }
18622 #endif
18623
18624   /* striding=true, chunking=true
18625        -> invalid.
18626      striding=true, chunking=false
18627        -> chunks=1
18628      striding=false,chunking=true
18629        -> chunks=ceil (range/(chunksize*threads*step))
18630      striding=false,chunking=false
18631        -> chunk_size=ceil(range/(threads*step)),chunks=1  */
18632   push_gimplify_context (true);
18633
18634   switch (code)
18635     {
18636     default: gcc_unreachable ();
18637
18638     case IFN_GOACC_LOOP_CHUNKS:
18639       if (!chunking)
18640         r = build_int_cst (type, 1);
18641       else
18642         {
18643           /* chunk_max
18644              = (range - dir) / (chunks * step * num_threads) + dir  */
18645           tree per = oacc_thread_numbers (false, mask, &seq);
18646           per = fold_convert (type, per);
18647           chunk_size = fold_convert (type, chunk_size);
18648           per = fold_build2 (MULT_EXPR, type, per, chunk_size);
18649           per = fold_build2 (MULT_EXPR, type, per, step);
18650           r = build2 (MINUS_EXPR, type, range, dir);
18651           r = build2 (PLUS_EXPR, type, r, per);
18652           r = build2 (TRUNC_DIV_EXPR, type, r, per);
18653         }
18654       break;
18655
18656     case IFN_GOACC_LOOP_STEP:
18657       {
18658         /* If striding, step by the entire compute volume, otherwise
18659            step by the inner volume.  */
18660         unsigned volume = striding ? mask : inner_mask;
18661
18662         r = oacc_thread_numbers (false, volume, &seq);
18663         r = build2 (MULT_EXPR, type, fold_convert (type, r), step);
18664       }
18665       break;
18666
18667     case IFN_GOACC_LOOP_OFFSET:
18668       if (striding)
18669         {
18670           r = oacc_thread_numbers (true, mask, &seq);
18671           r = fold_convert (diff_type, r);
18672         }
18673       else
18674         {
18675           tree inner_size = oacc_thread_numbers (false, inner_mask, &seq);
18676           tree outer_size = oacc_thread_numbers (false, outer_mask, &seq);
18677           tree volume = fold_build2 (MULT_EXPR, TREE_TYPE (inner_size),
18678                                      inner_size, outer_size);
18679
18680           volume = fold_convert (diff_type, volume);
18681           if (chunking)
18682             chunk_size = fold_convert (diff_type, chunk_size);
18683           else
18684             {
18685               tree per = fold_build2 (MULT_EXPR, diff_type, volume, step);
18686
18687               chunk_size = build2 (MINUS_EXPR, diff_type, range, dir);
18688               chunk_size = build2 (PLUS_EXPR, diff_type, chunk_size, per);
18689               chunk_size = build2 (TRUNC_DIV_EXPR, diff_type, chunk_size, per);
18690             }
18691
18692           tree span = build2 (MULT_EXPR, diff_type, chunk_size,
18693                               fold_convert (diff_type, inner_size));
18694           r = oacc_thread_numbers (true, outer_mask, &seq);
18695           r = fold_convert (diff_type, r);
18696           r = build2 (MULT_EXPR, diff_type, r, span);
18697
18698           tree inner = oacc_thread_numbers (true, inner_mask, &seq);
18699           inner = fold_convert (diff_type, inner);
18700           r = fold_build2 (PLUS_EXPR, diff_type, r, inner);
18701
18702           if (chunking)
18703             {
18704               tree chunk = fold_convert (diff_type, gimple_call_arg (call, 6));
18705               tree per
18706                 = fold_build2 (MULT_EXPR, diff_type, volume, chunk_size);
18707               per = build2 (MULT_EXPR, diff_type, per, chunk);
18708
18709               r = build2 (PLUS_EXPR, diff_type, r, per);
18710             }
18711         }
18712       r = fold_build2 (MULT_EXPR, diff_type, r, step);
18713       if (type != diff_type)
18714         r = fold_convert (type, r);
18715       break;
18716
18717     case IFN_GOACC_LOOP_BOUND:
18718       if (striding)
18719         r = range;
18720       else
18721         {
18722           tree inner_size = oacc_thread_numbers (false, inner_mask, &seq);
18723           tree outer_size = oacc_thread_numbers (false, outer_mask, &seq);
18724           tree volume = fold_build2 (MULT_EXPR, TREE_TYPE (inner_size),
18725                                      inner_size, outer_size);
18726
18727           volume = fold_convert (diff_type, volume);
18728           if (chunking)
18729             chunk_size = fold_convert (diff_type, chunk_size);
18730           else
18731             {
18732               tree per = fold_build2 (MULT_EXPR, diff_type, volume, step);
18733
18734               chunk_size = build2 (MINUS_EXPR, diff_type, range, dir);
18735               chunk_size = build2 (PLUS_EXPR, diff_type, chunk_size, per);
18736               chunk_size = build2 (TRUNC_DIV_EXPR, diff_type, chunk_size, per);
18737             }
18738
18739           tree span = build2 (MULT_EXPR, diff_type, chunk_size,
18740                               fold_convert (diff_type, inner_size));
18741
18742           r = fold_build2 (MULT_EXPR, diff_type, span, step);
18743
18744           tree offset = gimple_call_arg (call, 6);
18745           r = build2 (PLUS_EXPR, diff_type, r,
18746                       fold_convert (diff_type, offset));
18747           r = build2 (integer_onep (dir) ? MIN_EXPR : MAX_EXPR,
18748                       diff_type, r, range);
18749         }
18750       if (diff_type != type)
18751         r = fold_convert (type, r);
18752       break;
18753     }
18754
18755   gimplify_assign (lhs, r, &seq);
18756
18757   pop_gimplify_context (NULL);
18758
18759   gsi_replace_with_seq (&gsi, seq, true);
18760 }
18761
18762 /* Default partitioned and minimum partitioned dimensions.  */
18763
18764 static int oacc_default_dims[GOMP_DIM_MAX];
18765 static int oacc_min_dims[GOMP_DIM_MAX];
18766
18767 /* Parse the default dimension parameter.  This is a set of
18768    :-separated optional compute dimensions.  Each specified dimension
18769    is a positive integer.  When device type support is added, it is
18770    planned to be a comma separated list of such compute dimensions,
18771    with all but the first prefixed by the colon-terminated device
18772    type.  */
18773
18774 static void
18775 oacc_parse_default_dims (const char *dims)
18776 {
18777   int ix;
18778
18779   for (ix = GOMP_DIM_MAX; ix--;)
18780     {
18781       oacc_default_dims[ix] = -1;
18782       oacc_min_dims[ix] = 1;
18783     }
18784
18785 #ifndef ACCEL_COMPILER
18786   /* Cannot be overridden on the host.  */
18787   dims = NULL;
18788 #endif
18789   if (dims)
18790     {
18791       const char *pos = dims;
18792
18793       for (ix = 0; *pos && ix != GOMP_DIM_MAX; ix++)
18794         {
18795           if (ix)
18796             {
18797               if (*pos != ':')
18798                 goto malformed;
18799               pos++;
18800             }
18801
18802           if (*pos != ':')
18803             {
18804               long val;
18805               const char *eptr;
18806
18807               errno = 0;
18808               val = strtol (pos, CONST_CAST (char **, &eptr), 10);
18809               if (errno || val <= 0 || (int) val != val)
18810                 goto malformed;
18811               pos = eptr;
18812               oacc_default_dims[ix] = (int) val;
18813             }
18814         }
18815       if (*pos)
18816         {
18817         malformed:
18818           error_at (UNKNOWN_LOCATION,
18819                     "-fopenacc-dim operand is malformed at '%s'", pos);
18820         }
18821     }
18822
18823   /* Allow the backend to validate the dimensions.  */
18824   targetm.goacc.validate_dims (NULL_TREE, oacc_default_dims, -1);
18825   targetm.goacc.validate_dims (NULL_TREE, oacc_min_dims, -2);
18826 }
18827
18828 /* Validate and update the dimensions for offloaded FN.  ATTRS is the
18829    raw attribute.  DIMS is an array of dimensions, which is filled in.
18830    LEVEL is the partitioning level of a routine, or -1 for an offload
18831    region itself. USED is the mask of partitioned execution in the
18832    function.  */
18833
18834 static void
18835 oacc_validate_dims (tree fn, tree attrs, int *dims, int level, unsigned used)
18836 {
18837   tree purpose[GOMP_DIM_MAX];
18838   unsigned ix;
18839   tree pos = TREE_VALUE (attrs);
18840   bool is_kernel = oacc_fn_attrib_kernels_p (attrs);
18841
18842   /* Make sure the attribute creator attached the dimension
18843      information.  */
18844   gcc_assert (pos);
18845
18846   for (ix = 0; ix != GOMP_DIM_MAX; ix++)
18847     {
18848       purpose[ix] = TREE_PURPOSE (pos);
18849       tree val = TREE_VALUE (pos);
18850       dims[ix] = val ? TREE_INT_CST_LOW (val) : -1;
18851       pos = TREE_CHAIN (pos);
18852     }
18853
18854   bool changed = targetm.goacc.validate_dims (fn, dims, level);
18855
18856   /* Default anything left to 1 or a partitioned default.  */
18857   for (ix = 0; ix != GOMP_DIM_MAX; ix++)
18858     if (dims[ix] < 0)
18859       {
18860         /* The OpenACC spec says 'If the [num_gangs] clause is not
18861            specified, an implementation-defined default will be used;
18862            the default may depend on the code within the construct.' 
18863            (2.5.6).  Thus an implementation is free to choose
18864            non-unity default for a parallel region that doesn't have
18865            any gang-partitioned loops.  However, it appears that there
18866            is a sufficient body of user code that expects non-gang
18867            partitioned regions to not execute in gang-redundant mode.
18868            So we (a) don't warn about the non-portability and (b) pick
18869            the minimum permissible dimension size when there is no
18870            partitioned execution.  Otherwise we pick the global
18871            default for the dimension, which the user can control.  The
18872            same wording and logic applies to num_workers and
18873            vector_length, however the worker- or vector- single
18874            execution doesn't have the same impact as gang-redundant
18875            execution.  (If the minimum gang-level partioning is not 1,
18876            the target is probably too confusing.)  */
18877         dims[ix] = (used & GOMP_DIM_MASK (ix)
18878                     ? oacc_default_dims[ix] : oacc_min_dims[ix]);
18879         changed = true;
18880       }
18881
18882   if (changed)
18883     {
18884       /* Replace the attribute with new values.  */
18885       pos = NULL_TREE;
18886       for (ix = GOMP_DIM_MAX; ix--;)
18887         {
18888           pos = tree_cons (purpose[ix],
18889                            build_int_cst (integer_type_node, dims[ix]),
18890                            pos);
18891           if (is_kernel)
18892             TREE_PUBLIC (pos) = 1;
18893         }
18894       replace_oacc_fn_attrib (fn, pos);
18895     }
18896 }
18897
18898 /* Create an empty OpenACC loop structure at LOC.  */
18899
18900 static oacc_loop *
18901 new_oacc_loop_raw (oacc_loop *parent, location_t loc)
18902 {
18903   oacc_loop *loop = XCNEW (oacc_loop);
18904
18905   loop->parent = parent;
18906   loop->child = loop->sibling = NULL;
18907
18908   if (parent)
18909     {
18910       loop->sibling = parent->child;
18911       parent->child = loop;
18912     }
18913
18914   loop->loc = loc;
18915   loop->marker = NULL;
18916   memset (loop->heads, 0, sizeof (loop->heads));
18917   memset (loop->tails, 0, sizeof (loop->tails));
18918   loop->routine = NULL_TREE;
18919
18920   loop->mask = loop->flags = loop->inner = 0;
18921   loop->ifns = 0;
18922   loop->chunk_size = 0;
18923   loop->head_end = NULL;
18924
18925   return loop;
18926 }
18927
18928 /* Create an outermost, dummy OpenACC loop for offloaded function
18929    DECL.  */
18930
18931 static oacc_loop *
18932 new_oacc_loop_outer (tree decl)
18933 {
18934   return new_oacc_loop_raw (NULL, DECL_SOURCE_LOCATION (decl));
18935 }
18936
18937 /* Start a new OpenACC loop  structure beginning at head marker HEAD.
18938    Link into PARENT loop.  Return the new loop.  */
18939
18940 static oacc_loop *
18941 new_oacc_loop (oacc_loop *parent, gcall *marker)
18942 {
18943   oacc_loop *loop = new_oacc_loop_raw (parent, gimple_location (marker));
18944
18945   loop->marker = marker;
18946   
18947   /* TODO: This is where device_type flattening would occur for the loop
18948      flags.   */
18949
18950   loop->flags = TREE_INT_CST_LOW (gimple_call_arg (marker, 3));
18951
18952   tree chunk_size = integer_zero_node;
18953   if (loop->flags & OLF_GANG_STATIC)
18954     chunk_size = gimple_call_arg (marker, 4);
18955   loop->chunk_size = chunk_size;
18956
18957   return loop;
18958 }
18959
18960 /* Create a dummy loop encompassing a call to a openACC routine.
18961    Extract the routine's partitioning requirements.  */
18962
18963 static void
18964 new_oacc_loop_routine (oacc_loop *parent, gcall *call, tree decl, tree attrs)
18965 {
18966   oacc_loop *loop = new_oacc_loop_raw (parent, gimple_location (call));
18967   int level = oacc_fn_attrib_level (attrs);
18968
18969   gcc_assert (level >= 0);
18970
18971   loop->marker = call;
18972   loop->routine = decl;
18973   loop->mask = ((GOMP_DIM_MASK (GOMP_DIM_MAX) - 1)
18974                 ^ (GOMP_DIM_MASK (level) - 1));
18975 }
18976
18977 /* Finish off the current OpenACC loop ending at tail marker TAIL.
18978    Return the parent loop.  */
18979
18980 static oacc_loop *
18981 finish_oacc_loop (oacc_loop *loop)
18982 {
18983   /* If the loop has been collapsed, don't partition it.  */
18984   if (!loop->ifns)
18985     loop->mask = loop->flags = 0;
18986   return loop->parent;
18987 }
18988
18989 /* Free all OpenACC loop structures within LOOP (inclusive).  */
18990
18991 static void
18992 free_oacc_loop (oacc_loop *loop)
18993 {
18994   if (loop->sibling)
18995     free_oacc_loop (loop->sibling);
18996   if (loop->child)
18997     free_oacc_loop (loop->child);
18998
18999   free (loop);
19000 }
19001
19002 /* Dump out the OpenACC loop head or tail beginning at FROM.  */
19003
19004 static void
19005 dump_oacc_loop_part (FILE *file, gcall *from, int depth,
19006                      const char *title, int level)
19007 {
19008   enum ifn_unique_kind kind
19009     = (enum ifn_unique_kind) TREE_INT_CST_LOW (gimple_call_arg (from, 0));
19010
19011   fprintf (file, "%*s%s-%d:\n", depth * 2, "", title, level);
19012   for (gimple_stmt_iterator gsi = gsi_for_stmt (from);;)
19013     {
19014       gimple *stmt = gsi_stmt (gsi);
19015
19016       if (is_gimple_call (stmt)
19017           && gimple_call_internal_p (stmt)
19018           && gimple_call_internal_fn (stmt) == IFN_UNIQUE)
19019         {
19020           enum ifn_unique_kind k
19021             = ((enum ifn_unique_kind) TREE_INT_CST_LOW
19022                (gimple_call_arg (stmt, 0)));
19023
19024           if (k == kind && stmt != from)
19025             break;
19026         }
19027       print_gimple_stmt (file, stmt, depth * 2 + 2, 0);
19028
19029       gsi_next (&gsi);
19030       while (gsi_end_p (gsi))
19031         gsi = gsi_start_bb (single_succ (gsi_bb (gsi)));
19032     }
19033 }
19034
19035 /* Dump OpenACC loops LOOP, its siblings and its children.  */
19036
19037 static void
19038 dump_oacc_loop (FILE *file, oacc_loop *loop, int depth)
19039 {
19040   int ix;
19041   
19042   fprintf (file, "%*sLoop %x(%x) %s:%u\n", depth * 2, "",
19043            loop->flags, loop->mask,
19044            LOCATION_FILE (loop->loc), LOCATION_LINE (loop->loc));
19045
19046   if (loop->marker)
19047     print_gimple_stmt (file, loop->marker, depth * 2, 0);
19048
19049   if (loop->routine)
19050     fprintf (file, "%*sRoutine %s:%u:%s\n",
19051              depth * 2, "", DECL_SOURCE_FILE (loop->routine),
19052              DECL_SOURCE_LINE (loop->routine),
19053              IDENTIFIER_POINTER (DECL_NAME (loop->routine)));
19054
19055   for (ix = GOMP_DIM_GANG; ix != GOMP_DIM_MAX; ix++)
19056     if (loop->heads[ix])
19057       dump_oacc_loop_part (file, loop->heads[ix], depth, "Head", ix);
19058   for (ix = GOMP_DIM_MAX; ix--;)
19059     if (loop->tails[ix])
19060       dump_oacc_loop_part (file, loop->tails[ix], depth, "Tail", ix);
19061
19062   if (loop->child)
19063     dump_oacc_loop (file, loop->child, depth + 1);
19064   if (loop->sibling)
19065     dump_oacc_loop (file, loop->sibling, depth);
19066 }
19067
19068 void debug_oacc_loop (oacc_loop *);
19069
19070 /* Dump loops to stderr.  */
19071
19072 DEBUG_FUNCTION void
19073 debug_oacc_loop (oacc_loop *loop)
19074 {
19075   dump_oacc_loop (stderr, loop, 0);
19076 }
19077
19078 /* DFS walk of basic blocks BB onwards, creating OpenACC loop
19079    structures as we go.  By construction these loops are properly
19080    nested.  */
19081
19082 static void
19083 oacc_loop_discover_walk (oacc_loop *loop, basic_block bb)
19084 {
19085   int marker = 0;
19086   int remaining = 0;
19087
19088   if (bb->flags & BB_VISITED)
19089     return;
19090
19091  follow:
19092   bb->flags |= BB_VISITED;
19093
19094   /* Scan for loop markers.  */
19095   for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
19096        gsi_next (&gsi))
19097     {
19098       gimple *stmt = gsi_stmt (gsi);
19099
19100       if (!is_gimple_call (stmt))
19101         continue;
19102
19103       gcall *call = as_a <gcall *> (stmt);
19104       
19105       /* If this is a routine, make a dummy loop for it.  */
19106       if (tree decl = gimple_call_fndecl (call))
19107         if (tree attrs = get_oacc_fn_attrib (decl))
19108           {
19109             gcc_assert (!marker);
19110             new_oacc_loop_routine (loop, call, decl, attrs);
19111           }
19112
19113       if (!gimple_call_internal_p (call))
19114         continue;
19115
19116       switch (gimple_call_internal_fn (call))
19117         {
19118         default:
19119           break;
19120
19121         case IFN_GOACC_LOOP:
19122           /* Count the goacc loop abstraction fns, to determine if the
19123              loop was collapsed already.  */
19124           loop->ifns++;
19125           break;
19126
19127         case IFN_UNIQUE:
19128           enum ifn_unique_kind kind
19129             = (enum ifn_unique_kind) (TREE_INT_CST_LOW
19130                                       (gimple_call_arg (call, 0)));
19131           if (kind == IFN_UNIQUE_OACC_HEAD_MARK
19132               || kind == IFN_UNIQUE_OACC_TAIL_MARK)
19133             {
19134               if (gimple_call_num_args (call) == 2)
19135                 {
19136                   gcc_assert (marker && !remaining);
19137                   marker = 0;
19138                   if (kind == IFN_UNIQUE_OACC_TAIL_MARK)
19139                     loop = finish_oacc_loop (loop);
19140                   else
19141                     loop->head_end = call;
19142                 }
19143               else
19144                 {
19145                   int count = TREE_INT_CST_LOW (gimple_call_arg (call, 2));
19146
19147                   if (!marker)
19148                     {
19149                       if (kind == IFN_UNIQUE_OACC_HEAD_MARK)
19150                         loop = new_oacc_loop (loop, call);
19151                       remaining = count;
19152                     }
19153                   gcc_assert (count == remaining);
19154                   if (remaining)
19155                     {
19156                       remaining--;
19157                       if (kind == IFN_UNIQUE_OACC_HEAD_MARK)
19158                         loop->heads[marker] = call;
19159                       else
19160                         loop->tails[remaining] = call;
19161                     }
19162                   marker++;
19163                 }
19164             }
19165         }
19166     }
19167   if (remaining || marker)
19168     {
19169       bb = single_succ (bb);
19170       gcc_assert (single_pred_p (bb) && !(bb->flags & BB_VISITED));
19171       goto follow;
19172     }
19173
19174   /* Walk successor blocks.  */
19175   edge e;
19176   edge_iterator ei;
19177
19178   FOR_EACH_EDGE (e, ei, bb->succs)
19179     oacc_loop_discover_walk (loop, e->dest);
19180 }
19181
19182 /* LOOP is the first sibling.  Reverse the order in place and return
19183    the new first sibling.  Recurse to child loops.  */
19184
19185 static oacc_loop *
19186 oacc_loop_sibling_nreverse (oacc_loop *loop)
19187 {
19188   oacc_loop *last = NULL;
19189   do
19190     {
19191       if (loop->child)
19192         loop->child = oacc_loop_sibling_nreverse  (loop->child);
19193
19194       oacc_loop *next = loop->sibling;
19195       loop->sibling = last;
19196       last = loop;
19197       loop = next;
19198     }
19199   while (loop);
19200
19201   return last;
19202 }
19203
19204 /* Discover the OpenACC loops marked up by HEAD and TAIL markers for
19205    the current function.  */
19206
19207 static oacc_loop *
19208 oacc_loop_discovery ()
19209 {
19210   basic_block bb;
19211   
19212   oacc_loop *top = new_oacc_loop_outer (current_function_decl);
19213   oacc_loop_discover_walk (top, ENTRY_BLOCK_PTR_FOR_FN (cfun));
19214
19215   /* The siblings were constructed in reverse order, reverse them so
19216      that diagnostics come out in an unsurprising order.  */
19217   top = oacc_loop_sibling_nreverse (top);
19218
19219   /* Reset the visited flags.  */
19220   FOR_ALL_BB_FN (bb, cfun)
19221     bb->flags &= ~BB_VISITED;
19222
19223   return top;
19224 }
19225
19226 /* Transform the abstract internal function markers starting at FROM
19227    to be for partitioning level LEVEL.  Stop when we meet another HEAD
19228    or TAIL  marker.  */
19229
19230 static void
19231 oacc_loop_xform_head_tail (gcall *from, int level)
19232 {
19233   enum ifn_unique_kind kind
19234     = (enum ifn_unique_kind) TREE_INT_CST_LOW (gimple_call_arg (from, 0));
19235   tree replacement = build_int_cst (unsigned_type_node, level);
19236
19237   for (gimple_stmt_iterator gsi = gsi_for_stmt (from);;)
19238     {
19239       gimple *stmt = gsi_stmt (gsi);
19240       
19241       if (is_gimple_call (stmt)
19242           && gimple_call_internal_p (stmt)
19243           && gimple_call_internal_fn (stmt) == IFN_UNIQUE)
19244         {
19245           enum ifn_unique_kind k
19246             = ((enum ifn_unique_kind)
19247                TREE_INT_CST_LOW (gimple_call_arg (stmt, 0)));
19248
19249           if (k == IFN_UNIQUE_OACC_FORK || k == IFN_UNIQUE_OACC_JOIN)
19250             *gimple_call_arg_ptr (stmt, 2) = replacement;
19251           else if (k == kind && stmt != from)
19252             break;
19253         }
19254       else if (is_gimple_call (stmt)
19255                && gimple_call_internal_p (stmt)
19256                && gimple_call_internal_fn (stmt) == IFN_GOACC_REDUCTION)
19257         *gimple_call_arg_ptr (stmt, 3) = replacement;
19258
19259       gsi_next (&gsi);
19260       while (gsi_end_p (gsi))
19261         gsi = gsi_start_bb (single_succ (gsi_bb (gsi)));
19262     }
19263 }
19264
19265 /* Transform the IFN_GOACC_LOOP internal functions by providing the
19266    determined partitioning mask and chunking argument.  END_MARKER
19267    points at the end IFN_HEAD_TAIL call intgroducing the loop.  IFNS
19268    is the number of IFN_GOACC_LOOP calls for the loop.  MASK_ARG is
19269    the replacement partitioning mask and CHUNK_ARG is the replacement
19270    chunking arg.  */
19271
19272 static void
19273 oacc_loop_xform_loop (gcall *end_marker, unsigned ifns,
19274                       tree mask_arg, tree chunk_arg)
19275 {
19276   gimple_stmt_iterator gsi = gsi_for_stmt (end_marker);
19277   
19278   gcc_checking_assert (ifns);
19279   for (;;)
19280     {
19281       for (; !gsi_end_p (gsi); gsi_next (&gsi))
19282         {
19283           gimple *stmt = gsi_stmt (gsi);
19284
19285           if (!is_gimple_call (stmt))
19286             continue;
19287
19288           gcall *call = as_a <gcall *> (stmt);
19289       
19290           if (!gimple_call_internal_p (call))
19291             continue;
19292
19293           if (gimple_call_internal_fn (call) != IFN_GOACC_LOOP)
19294             continue;
19295
19296           *gimple_call_arg_ptr (call, 5) = mask_arg;
19297           *gimple_call_arg_ptr (call, 4) = chunk_arg;
19298           ifns--;
19299           if (!ifns)
19300             return;
19301         }
19302
19303       /* The LOOP_BOUND ifn could be in the single successor
19304          block.  */
19305       basic_block bb = single_succ (gsi_bb (gsi));
19306       gsi = gsi_start_bb (bb);
19307     }
19308 }
19309
19310 /* Process the discovered OpenACC loops, setting the correct
19311    partitioning level etc.  */
19312
19313 static void
19314 oacc_loop_process (oacc_loop *loop)
19315 {
19316   if (loop->child)
19317     oacc_loop_process (loop->child);
19318
19319   if (loop->mask && !loop->routine)
19320     {
19321       int ix;
19322       unsigned mask = loop->mask;
19323       unsigned dim = GOMP_DIM_GANG;
19324       tree mask_arg = build_int_cst (unsigned_type_node, mask);
19325       tree chunk_arg = loop->chunk_size;
19326
19327       oacc_loop_xform_loop (loop->head_end, loop->ifns, mask_arg, chunk_arg);
19328
19329       for (ix = 0; ix != GOMP_DIM_MAX && mask; ix++)
19330         {
19331           while (!(GOMP_DIM_MASK (dim) & mask))
19332             dim++;
19333
19334           oacc_loop_xform_head_tail (loop->heads[ix], dim);
19335           oacc_loop_xform_head_tail (loop->tails[ix], dim);
19336
19337           mask ^= GOMP_DIM_MASK (dim);
19338         }
19339     }
19340
19341   if (loop->sibling)
19342     oacc_loop_process (loop->sibling);
19343 }
19344
19345 /* Walk the OpenACC loop heirarchy checking and assigning the
19346    programmer-specified partitionings.  OUTER_MASK is the partitioning
19347    this loop is contained within.  Return mask of partitioning
19348    encountered.  If any auto loops are discovered, set GOMP_DIM_MAX
19349    bit.  */
19350
19351 static unsigned
19352 oacc_loop_fixed_partitions (oacc_loop *loop, unsigned outer_mask)
19353 {
19354   unsigned this_mask = loop->mask;
19355   unsigned mask_all = 0;
19356   bool noisy = true;
19357
19358 #ifdef ACCEL_COMPILER
19359   /* When device_type is supported, we want the device compiler to be
19360      noisy, if the loop parameters are device_type-specific.  */
19361   noisy = false;
19362 #endif
19363
19364   if (!loop->routine)
19365     {
19366       bool auto_par = (loop->flags & OLF_AUTO) != 0;
19367       bool seq_par = (loop->flags & OLF_SEQ) != 0;
19368
19369       this_mask = ((loop->flags >> OLF_DIM_BASE)
19370                    & (GOMP_DIM_MASK (GOMP_DIM_MAX) - 1));
19371
19372       if ((this_mask != 0) + auto_par + seq_par > 1)
19373         {
19374           if (noisy)
19375             error_at (loop->loc,
19376                       seq_par
19377                       ? "%<seq%> overrides other OpenACC loop specifiers"
19378                       : "%<auto%> conflicts with other OpenACC loop specifiers");
19379           auto_par = false;
19380           loop->flags &= ~OLF_AUTO;
19381           if (seq_par)
19382             {
19383               loop->flags &=
19384                 ~((GOMP_DIM_MASK (GOMP_DIM_MAX) - 1) << OLF_DIM_BASE);
19385               this_mask = 0;
19386             }
19387         }
19388       if (auto_par && (loop->flags & OLF_INDEPENDENT))
19389         mask_all |= GOMP_DIM_MASK (GOMP_DIM_MAX);
19390     }
19391
19392   if (this_mask & outer_mask)
19393     {
19394       const oacc_loop *outer;
19395       for (outer = loop->parent; outer; outer = outer->parent)
19396         if (outer->mask & this_mask)
19397           break;
19398
19399       if (noisy)
19400         {
19401           if (outer)
19402             {
19403               error_at (loop->loc,
19404                         "%s uses same OpenACC parallelism as containing loop",
19405                         loop->routine ? "routine call" : "inner loop");
19406               inform (outer->loc, "containing loop here");
19407             }
19408           else
19409             error_at (loop->loc,
19410                       "%s uses OpenACC parallelism disallowed by containing routine",
19411                       loop->routine ? "routine call" : "loop");
19412       
19413           if (loop->routine)
19414             inform (DECL_SOURCE_LOCATION (loop->routine),
19415                     "routine %qD declared here", loop->routine);
19416         }
19417       this_mask &= ~outer_mask;
19418     }
19419   else
19420     {
19421       unsigned outermost = this_mask & -this_mask;
19422
19423       if (outermost && outermost <= outer_mask)
19424         {
19425           if (noisy)
19426             {
19427               error_at (loop->loc,
19428                         "incorrectly nested OpenACC loop parallelism");
19429
19430               const oacc_loop *outer;
19431               for (outer = loop->parent;
19432                    outer->flags && outer->flags < outermost;
19433                    outer = outer->parent)
19434                 continue;
19435               inform (outer->loc, "containing loop here");
19436             }
19437
19438           this_mask &= ~outermost;
19439         }
19440     }
19441
19442   loop->mask = this_mask;
19443   mask_all |= this_mask;
19444   
19445   if (loop->child)
19446     {
19447       loop->inner = oacc_loop_fixed_partitions (loop->child,
19448                                                 outer_mask | this_mask); 
19449       mask_all |= loop->inner;
19450     }
19451
19452   if (loop->sibling)
19453     mask_all |= oacc_loop_fixed_partitions (loop->sibling, outer_mask);
19454
19455   return mask_all;
19456 }
19457
19458 /* Walk the OpenACC loop heirarchy to assign auto-partitioned loops.
19459    OUTER_MASK is the partitioning this loop is contained within.
19460    Return the cumulative partitioning used by this loop, siblings and
19461    children.  */
19462
19463 static unsigned
19464 oacc_loop_auto_partitions (oacc_loop *loop, unsigned outer_mask)
19465 {
19466   bool assign = (loop->flags & OLF_AUTO) && (loop->flags & OLF_INDEPENDENT);
19467   bool noisy = true;
19468
19469 #ifdef ACCEL_COMPILER
19470   /* When device_type is supported, we want the device compiler to be
19471      noisy, if the loop parameters are device_type-specific.  */
19472   noisy = false;
19473 #endif
19474
19475   if (assign && outer_mask < GOMP_DIM_MASK (GOMP_DIM_MAX - 1))
19476     {
19477       /* Allocate the outermost loop at the outermost available
19478          level.  */
19479       unsigned this_mask = outer_mask + 1;
19480
19481       if (!(this_mask & loop->inner))
19482         loop->mask = this_mask;
19483     }
19484
19485   if (loop->child)
19486     {
19487       unsigned child_mask = outer_mask | loop->mask;
19488
19489       if (loop->mask || assign)
19490         child_mask |= GOMP_DIM_MASK (GOMP_DIM_MAX);
19491
19492       loop->inner = oacc_loop_auto_partitions (loop->child, child_mask);
19493     }
19494
19495   if (assign && !loop->mask)
19496     {
19497       /* Allocate the loop at the innermost available level.  */
19498       unsigned this_mask = 0;
19499       
19500       /* Determine the outermost partitioning used within this loop. */
19501       this_mask = loop->inner | GOMP_DIM_MASK (GOMP_DIM_MAX);
19502       this_mask = (this_mask & -this_mask);
19503
19504       /* Pick the partitioning just inside that one.  */
19505       this_mask >>= 1;
19506
19507       /* And avoid picking one use by an outer loop. */
19508       this_mask &= ~outer_mask;
19509
19510       if (!this_mask && noisy)
19511         warning_at (loop->loc, 0,
19512                     "insufficient partitioning available to parallelize loop");
19513
19514       loop->mask = this_mask;
19515     }
19516
19517   if (assign && dump_file)
19518     fprintf (dump_file, "Auto loop %s:%d assigned %d\n",
19519              LOCATION_FILE (loop->loc), LOCATION_LINE (loop->loc),
19520              loop->mask);
19521
19522   unsigned inner_mask = 0;
19523   
19524   if (loop->sibling)
19525     inner_mask |= oacc_loop_auto_partitions (loop->sibling, outer_mask);
19526   
19527   inner_mask |= loop->inner | loop->mask;
19528
19529   return inner_mask;
19530 }
19531
19532 /* Walk the OpenACC loop heirarchy to check and assign partitioning
19533    axes.  Return mask of partitioning.  */
19534
19535 static unsigned
19536 oacc_loop_partition (oacc_loop *loop, unsigned outer_mask)
19537 {
19538   unsigned mask_all = oacc_loop_fixed_partitions (loop, outer_mask);
19539
19540   if (mask_all & GOMP_DIM_MASK (GOMP_DIM_MAX))
19541     {
19542       mask_all ^= GOMP_DIM_MASK (GOMP_DIM_MAX);
19543       mask_all |= oacc_loop_auto_partitions (loop, outer_mask);
19544     }
19545   return mask_all;
19546 }
19547
19548 /* Default fork/join early expander.  Delete the function calls if
19549    there is no RTL expander.  */
19550
19551 bool
19552 default_goacc_fork_join (gcall *ARG_UNUSED (call),
19553                          const int *ARG_UNUSED (dims), bool is_fork)
19554 {
19555   if (is_fork)
19556     return targetm.have_oacc_fork ();
19557   else
19558     return targetm.have_oacc_join ();
19559 }
19560
19561 /* Default goacc.reduction early expander.
19562
19563    LHS-opt = IFN_REDUCTION (KIND, RES_PTR, VAR, LEVEL, OP, OFFSET)
19564    If RES_PTR is not integer-zerop:
19565        SETUP - emit 'LHS = *RES_PTR', LHS = NULL
19566        TEARDOWN - emit '*RES_PTR = VAR'
19567    If LHS is not NULL
19568        emit 'LHS = VAR'   */
19569
19570 void
19571 default_goacc_reduction (gcall *call)
19572 {
19573   unsigned code = (unsigned)TREE_INT_CST_LOW (gimple_call_arg (call, 0));
19574   gimple_stmt_iterator gsi = gsi_for_stmt (call);
19575   tree lhs = gimple_call_lhs (call);
19576   tree var = gimple_call_arg (call, 2);
19577   gimple_seq seq = NULL;
19578
19579   if (code == IFN_GOACC_REDUCTION_SETUP
19580       || code == IFN_GOACC_REDUCTION_TEARDOWN)
19581     {
19582       /* Setup and Teardown need to copy from/to the receiver object,
19583          if there is one.  */
19584       tree ref_to_res = gimple_call_arg (call, 1);
19585       
19586       if (!integer_zerop (ref_to_res))
19587         {
19588           tree dst = build_simple_mem_ref (ref_to_res);
19589           tree src = var;
19590           
19591           if (code == IFN_GOACC_REDUCTION_SETUP)
19592             {
19593               src = dst;
19594               dst = lhs;
19595               lhs = NULL;
19596             }
19597           gimple_seq_add_stmt (&seq, gimple_build_assign (dst, src));
19598         }
19599     }
19600
19601   /* Copy VAR to LHS, if there is an LHS.  */
19602   if (lhs)
19603     gimple_seq_add_stmt (&seq, gimple_build_assign (lhs, var));
19604
19605   gsi_replace_with_seq (&gsi, seq, true);
19606 }
19607
19608 /* Main entry point for oacc transformations which run on the device
19609    compiler after LTO, so we know what the target device is at this
19610    point (including the host fallback).  */
19611
19612 static unsigned int
19613 execute_oacc_device_lower ()
19614 {
19615   tree attrs = get_oacc_fn_attrib (current_function_decl);
19616   
19617   if (!attrs)
19618     /* Not an offloaded function.  */
19619     return 0;
19620
19621   /* Parse the default dim argument exactly once.  */
19622   if ((const void *)flag_openacc_dims != &flag_openacc_dims)
19623     {
19624       oacc_parse_default_dims (flag_openacc_dims);
19625       flag_openacc_dims = (char *)&flag_openacc_dims;
19626     } 
19627
19628   /* Discover, partition and process the loops.  */
19629   oacc_loop *loops = oacc_loop_discovery ();
19630   int fn_level = oacc_fn_attrib_level (attrs);
19631
19632   if (dump_file)
19633     fprintf (dump_file, oacc_fn_attrib_kernels_p (attrs)
19634              ? "Function is kernels offload\n"
19635              : fn_level < 0 ? "Function is parallel offload\n"
19636              : "Function is routine level %d\n", fn_level);
19637
19638   unsigned outer_mask = fn_level >= 0 ? GOMP_DIM_MASK (fn_level) - 1 : 0;
19639   unsigned used_mask = oacc_loop_partition (loops, outer_mask);
19640   int dims[GOMP_DIM_MAX];
19641
19642   oacc_validate_dims (current_function_decl, attrs, dims, fn_level, used_mask);
19643
19644   if (dump_file)
19645     {
19646       const char *comma = "Compute dimensions [";
19647       for (int ix = 0; ix != GOMP_DIM_MAX; ix++, comma = ", ")
19648         fprintf (dump_file, "%s%d", comma, dims[ix]);
19649       fprintf (dump_file, "]\n");
19650     }
19651
19652   oacc_loop_process (loops);
19653   if (dump_file)
19654     {
19655       fprintf (dump_file, "OpenACC loops\n");
19656       dump_oacc_loop (dump_file, loops, 0);
19657       fprintf (dump_file, "\n");
19658     }
19659
19660   /* Offloaded targets may introduce new basic blocks, which require
19661      dominance information to update SSA.  */
19662   calculate_dominance_info (CDI_DOMINATORS);
19663
19664   /* Now lower internal loop functions to target-specific code
19665      sequences.  */
19666   basic_block bb;
19667   FOR_ALL_BB_FN (bb, cfun)
19668     for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
19669       {
19670         gimple *stmt = gsi_stmt (gsi);
19671         if (!is_gimple_call (stmt))
19672           {
19673             gsi_next (&gsi);
19674             continue;
19675           }
19676
19677         gcall *call = as_a <gcall *> (stmt);
19678         if (!gimple_call_internal_p (call))
19679           {
19680             gsi_next (&gsi);
19681             continue;
19682           }
19683
19684         /* Rewind to allow rescan.  */
19685         gsi_prev (&gsi);
19686         bool rescan = false, remove = false;
19687         enum  internal_fn ifn_code = gimple_call_internal_fn (call);
19688
19689         switch (ifn_code)
19690           {
19691           default: break;
19692
19693           case IFN_GOACC_LOOP:
19694             oacc_xform_loop (call);
19695             rescan = true;
19696             break;
19697
19698           case IFN_GOACC_REDUCTION:
19699             /* Mark the function for SSA renaming.  */
19700             mark_virtual_operands_for_renaming (cfun);
19701
19702             /* If the level is -1, this ended up being an unused
19703                axis.  Handle as a default.  */
19704             if (integer_minus_onep (gimple_call_arg (call, 3)))
19705               default_goacc_reduction (call);
19706             else
19707               targetm.goacc.reduction (call);
19708             rescan = true;
19709             break;
19710
19711           case IFN_UNIQUE:
19712             {
19713               enum ifn_unique_kind kind
19714                 = ((enum ifn_unique_kind)
19715                    TREE_INT_CST_LOW (gimple_call_arg (call, 0)));
19716
19717               switch (kind)
19718                 {
19719                 default:
19720                   gcc_unreachable ();
19721
19722                 case IFN_UNIQUE_OACC_FORK:
19723                 case IFN_UNIQUE_OACC_JOIN:
19724                   if (integer_minus_onep (gimple_call_arg (call, 2)))
19725                     remove = true;
19726                   else if (!targetm.goacc.fork_join
19727                            (call, dims, kind == IFN_UNIQUE_OACC_FORK))
19728                     remove = true;
19729                   break;
19730
19731                 case IFN_UNIQUE_OACC_HEAD_MARK:
19732                 case IFN_UNIQUE_OACC_TAIL_MARK:
19733                   remove = true;
19734                   break;
19735                 }
19736               break;
19737             }
19738           }
19739
19740         if (gsi_end_p (gsi))
19741           /* We rewound past the beginning of the BB.  */
19742           gsi = gsi_start_bb (bb);
19743         else
19744           /* Undo the rewind.  */
19745           gsi_next (&gsi);
19746
19747         if (remove)
19748           {
19749             if (gimple_vdef (call))
19750               replace_uses_by (gimple_vdef (call), gimple_vuse (call));
19751             if (gimple_call_lhs (call))
19752               {
19753                 /* Propagate the data dependency var.  */
19754                 gimple *ass = gimple_build_assign (gimple_call_lhs (call),
19755                                                    gimple_call_arg (call, 1));
19756                 gsi_replace (&gsi, ass,  false);
19757               }
19758             else
19759               gsi_remove (&gsi, true);
19760           }
19761         else if (!rescan)
19762           /* If not rescanning, advance over the call.  */
19763           gsi_next (&gsi);
19764       }
19765
19766   free_oacc_loop (loops);
19767
19768   return 0;
19769 }
19770
19771 /* Default launch dimension validator.  Force everything to 1.  A
19772    backend that wants to provide larger dimensions must override this
19773    hook.  */
19774
19775 bool
19776 default_goacc_validate_dims (tree ARG_UNUSED (decl), int *dims,
19777                              int ARG_UNUSED (fn_level))
19778 {
19779   bool changed = false;
19780
19781   for (unsigned ix = 0; ix != GOMP_DIM_MAX; ix++)
19782     {
19783       if (dims[ix] != 1)
19784         {
19785           dims[ix] = 1;
19786           changed = true;
19787         }
19788     }
19789
19790   return changed;
19791 }
19792
19793 /* Default dimension bound is unknown on accelerator and 1 on host. */
19794
19795 int
19796 default_goacc_dim_limit (int ARG_UNUSED (axis))
19797 {
19798 #ifdef ACCEL_COMPILER
19799   return 0;
19800 #else
19801   return 1;
19802 #endif
19803 }
19804
19805 namespace {
19806
19807 const pass_data pass_data_oacc_device_lower =
19808 {
19809   GIMPLE_PASS, /* type */
19810   "oaccdevlow", /* name */
19811   OPTGROUP_NONE, /* optinfo_flags */
19812   TV_NONE, /* tv_id */
19813   PROP_cfg, /* properties_required */
19814   0 /* Possibly PROP_gimple_eomp.  */, /* properties_provided */
19815   0, /* properties_destroyed */
19816   0, /* todo_flags_start */
19817   TODO_update_ssa | TODO_cleanup_cfg, /* todo_flags_finish */
19818 };
19819
19820 class pass_oacc_device_lower : public gimple_opt_pass
19821 {
19822 public:
19823   pass_oacc_device_lower (gcc::context *ctxt)
19824     : gimple_opt_pass (pass_data_oacc_device_lower, ctxt)
19825   {}
19826
19827   /* opt_pass methods: */
19828   virtual unsigned int execute (function *)
19829     {
19830       bool gate = flag_openacc != 0;
19831
19832       if (!gate)
19833         return 0;
19834
19835       return execute_oacc_device_lower ();
19836     }
19837
19838 }; // class pass_oacc_device_lower
19839
19840 } // anon namespace
19841
19842 gimple_opt_pass *
19843 make_pass_oacc_device_lower (gcc::context *ctxt)
19844 {
19845   return new pass_oacc_device_lower (ctxt);
19846 }
19847
19848 /* "omp declare target link" handling pass.  */
19849
19850 namespace {
19851
19852 const pass_data pass_data_omp_target_link =
19853 {
19854   GIMPLE_PASS,                  /* type */
19855   "omptargetlink",              /* name */
19856   OPTGROUP_NONE,                /* optinfo_flags */
19857   TV_NONE,                      /* tv_id */
19858   PROP_ssa,                     /* properties_required */
19859   0,                            /* properties_provided */
19860   0,                            /* properties_destroyed */
19861   0,                            /* todo_flags_start */
19862   TODO_update_ssa,              /* todo_flags_finish */
19863 };
19864
19865 class pass_omp_target_link : public gimple_opt_pass
19866 {
19867 public:
19868   pass_omp_target_link (gcc::context *ctxt)
19869     : gimple_opt_pass (pass_data_omp_target_link, ctxt)
19870   {}
19871
19872   /* opt_pass methods: */
19873   virtual bool gate (function *fun)
19874     {
19875 #ifdef ACCEL_COMPILER
19876       tree attrs = DECL_ATTRIBUTES (fun->decl);
19877       return lookup_attribute ("omp declare target", attrs)
19878              || lookup_attribute ("omp target entrypoint", attrs);
19879 #else
19880       (void) fun;
19881       return false;
19882 #endif
19883     }
19884
19885   virtual unsigned execute (function *);
19886 };
19887
19888 /* Callback for walk_gimple_stmt used to scan for link var operands.  */
19889
19890 static tree
19891 find_link_var_op (tree *tp, int *walk_subtrees, void *)
19892 {
19893   tree t = *tp;
19894
19895   if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t)
19896       && lookup_attribute ("omp declare target link", DECL_ATTRIBUTES (t)))
19897     {
19898       *walk_subtrees = 0;
19899       return t;
19900     }
19901
19902   return NULL_TREE;
19903 }
19904
19905 unsigned
19906 pass_omp_target_link::execute (function *fun)
19907 {
19908   basic_block bb;
19909   FOR_EACH_BB_FN (bb, fun)
19910     {
19911       gimple_stmt_iterator gsi;
19912       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
19913         if (walk_gimple_stmt (&gsi, NULL, find_link_var_op, NULL))
19914           gimple_regimplify_operands (gsi_stmt (gsi), &gsi);
19915     }
19916
19917   return 0;
19918 }
19919
19920 } // anon namespace
19921
19922 gimple_opt_pass *
19923 make_pass_omp_target_link (gcc::context *ctxt)
19924 {
19925   return new pass_omp_target_link (ctxt);
19926 }
19927
19928 #include "gt-omp-low.h"