Import pre-release gcc-5.0 to new vendor branch
[dragonfly.git] / contrib / gcc-5.0 / 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-2015 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 "tm.h"
29 #include "hash-set.h"
30 #include "machmode.h"
31 #include "vec.h"
32 #include "double-int.h"
33 #include "input.h"
34 #include "alias.h"
35 #include "symtab.h"
36 #include "wide-int.h"
37 #include "inchash.h"
38 #include "tree.h"
39 #include "fold-const.h"
40 #include "stringpool.h"
41 #include "stor-layout.h"
42 #include "rtl.h"
43 #include "predict.h"
44 #include "hard-reg-set.h"
45 #include "function.h"
46 #include "dominance.h"
47 #include "cfg.h"
48 #include "cfganal.h"
49 #include "basic-block.h"
50 #include "tree-ssa-alias.h"
51 #include "internal-fn.h"
52 #include "gimple-fold.h"
53 #include "gimple-expr.h"
54 #include "is-a.h"
55 #include "gimple.h"
56 #include "gimplify.h"
57 #include "gimple-iterator.h"
58 #include "gimplify-me.h"
59 #include "gimple-walk.h"
60 #include "tree-iterator.h"
61 #include "tree-inline.h"
62 #include "langhooks.h"
63 #include "diagnostic-core.h"
64 #include "gimple-ssa.h"
65 #include "hash-map.h"
66 #include "plugin-api.h"
67 #include "ipa-ref.h"
68 #include "cgraph.h"
69 #include "tree-cfg.h"
70 #include "tree-phinodes.h"
71 #include "ssa-iterators.h"
72 #include "tree-ssanames.h"
73 #include "tree-into-ssa.h"
74 #include "hashtab.h"
75 #include "flags.h"
76 #include "statistics.h"
77 #include "real.h"
78 #include "fixed-value.h"
79 #include "insn-config.h"
80 #include "expmed.h"
81 #include "dojump.h"
82 #include "explow.h"
83 #include "calls.h"
84 #include "emit-rtl.h"
85 #include "varasm.h"
86 #include "stmt.h"
87 #include "expr.h"
88 #include "tree-dfa.h"
89 #include "tree-ssa.h"
90 #include "tree-pass.h"
91 #include "except.h"
92 #include "splay-tree.h"
93 #include "insn-codes.h"
94 #include "optabs.h"
95 #include "cfgloop.h"
96 #include "target.h"
97 #include "common/common-target.h"
98 #include "omp-low.h"
99 #include "gimple-low.h"
100 #include "tree-cfgcleanup.h"
101 #include "pretty-print.h"
102 #include "alloc-pool.h"
103 #include "symbol-summary.h"
104 #include "ipa-prop.h"
105 #include "tree-nested.h"
106 #include "tree-eh.h"
107 #include "cilk.h"
108 #include "context.h"
109 #include "lto-section-names.h"
110 #include "gomp-constants.h"
111
112
113 /* Lowering of OMP parallel and workshare constructs proceeds in two
114    phases.  The first phase scans the function looking for OMP statements
115    and then for variables that must be replaced to satisfy data sharing
116    clauses.  The second phase expands code for the constructs, as well as
117    re-gimplifying things when variables have been replaced with complex
118    expressions.
119
120    Final code generation is done by pass_expand_omp.  The flowgraph is
121    scanned for regions which are then moved to a new
122    function, to be invoked by the thread library, or offloaded.  */
123
124 /* OMP region information.  Every parallel and workshare
125    directive is enclosed between two markers, the OMP_* directive
126    and a corresponding OMP_RETURN statement.  */
127
128 struct omp_region
129 {
130   /* The enclosing region.  */
131   struct omp_region *outer;
132
133   /* First child region.  */
134   struct omp_region *inner;
135
136   /* Next peer region.  */
137   struct omp_region *next;
138
139   /* Block containing the omp directive as its last stmt.  */
140   basic_block entry;
141
142   /* Block containing the OMP_RETURN as its last stmt.  */
143   basic_block exit;
144
145   /* Block containing the OMP_CONTINUE as its last stmt.  */
146   basic_block cont;
147
148   /* If this is a combined parallel+workshare region, this is a list
149      of additional arguments needed by the combined parallel+workshare
150      library call.  */
151   vec<tree, va_gc> *ws_args;
152
153   /* The code for the omp directive of this region.  */
154   enum gimple_code type;
155
156   /* Schedule kind, only used for OMP_FOR type regions.  */
157   enum omp_clause_schedule_kind sched_kind;
158
159   /* True if this is a combined parallel+workshare region.  */
160   bool is_combined_parallel;
161 };
162
163 /* Levels of parallelism as defined by OpenACC.  Increasing numbers
164    correspond to deeper loop nesting levels.  */
165 #define MASK_GANG 1
166 #define MASK_WORKER 2
167 #define MASK_VECTOR 4
168
169 /* Context structure.  Used to store information about each parallel
170    directive in the code.  */
171
172 typedef struct omp_context
173 {
174   /* This field must be at the beginning, as we do "inheritance": Some
175      callback functions for tree-inline.c (e.g., omp_copy_decl)
176      receive a copy_body_data pointer that is up-casted to an
177      omp_context pointer.  */
178   copy_body_data cb;
179
180   /* The tree of contexts corresponding to the encountered constructs.  */
181   struct omp_context *outer;
182   gimple stmt;
183
184   /* Map variables to fields in a structure that allows communication
185      between sending and receiving threads.  */
186   splay_tree field_map;
187   tree record_type;
188   tree sender_decl;
189   tree receiver_decl;
190
191   /* These are used just by task contexts, if task firstprivate fn is
192      needed.  srecord_type is used to communicate from the thread
193      that encountered the task construct to task firstprivate fn,
194      record_type is allocated by GOMP_task, initialized by task firstprivate
195      fn and passed to the task body fn.  */
196   splay_tree sfield_map;
197   tree srecord_type;
198
199   /* A chain of variables to add to the top-level block surrounding the
200      construct.  In the case of a parallel, this is in the child function.  */
201   tree block_vars;
202
203   /* A map of reduction pointer variables.  For accelerators, each
204      reduction variable is replaced with an array.  Each thread, in turn,
205      is assigned to a slot on that array.  */
206   splay_tree reduction_map;
207
208   /* Label to which GOMP_cancel{,llation_point} and explicit and implicit
209      barriers should jump to during omplower pass.  */
210   tree cancel_label;
211
212   /* What to do with variables with implicitly determined sharing
213      attributes.  */
214   enum omp_clause_default_kind default_kind;
215
216   /* Nesting depth of this context.  Used to beautify error messages re
217      invalid gotos.  The outermost ctx is depth 1, with depth 0 being
218      reserved for the main body of the function.  */
219   int depth;
220
221   /* True if this parallel directive is nested within another.  */
222   bool is_nested;
223
224   /* True if this construct can be cancelled.  */
225   bool cancellable;
226
227   /* For OpenACC loops, a mask of gang, worker and vector used at
228      levels below this one.  */
229   int gwv_below;
230   /* For OpenACC loops, a mask of gang, worker and vector used at
231      this level and above.  For parallel and kernels clauses, a mask
232      indicating which of num_gangs/num_workers/num_vectors was used.  */
233   int gwv_this;
234 } omp_context;
235
236 /* A structure holding the elements of:
237    for (V = N1; V cond N2; V += STEP) [...] */
238
239 struct omp_for_data_loop
240 {
241   tree v, n1, n2, step;
242   enum tree_code cond_code;
243 };
244
245 /* A structure describing the main elements of a parallel loop.  */
246
247 struct omp_for_data
248 {
249   struct omp_for_data_loop loop;
250   tree chunk_size;
251   gomp_for *for_stmt;
252   tree pre, iter_type;
253   int collapse;
254   bool have_nowait, have_ordered;
255   enum omp_clause_schedule_kind sched_kind;
256   struct omp_for_data_loop *loops;
257 };
258
259
260 static splay_tree all_contexts;
261 static int taskreg_nesting_level;
262 static int target_nesting_level;
263 static struct omp_region *root_omp_region;
264 static bitmap task_shared_vars;
265 static vec<omp_context *> taskreg_contexts;
266
267 static void scan_omp (gimple_seq *, omp_context *);
268 static tree scan_omp_1_op (tree *, int *, void *);
269
270 #define WALK_SUBSTMTS  \
271     case GIMPLE_BIND: \
272     case GIMPLE_TRY: \
273     case GIMPLE_CATCH: \
274     case GIMPLE_EH_FILTER: \
275     case GIMPLE_TRANSACTION: \
276       /* The sub-statements for these should be walked.  */ \
277       *handled_ops_p = false; \
278       break;
279
280 /* Helper function to get the name of the array containing the partial
281    reductions for OpenACC reductions.  */
282 static const char *
283 oacc_get_reduction_array_id (tree node)
284 {
285   const char *id = IDENTIFIER_POINTER (DECL_NAME (node));
286   int len = strlen ("OACC") + strlen (id);
287   char *temp_name = XALLOCAVEC (char, len + 1);
288   snprintf (temp_name, len + 1, "OACC%s", id);
289   return IDENTIFIER_POINTER (get_identifier (temp_name));
290 }
291
292 /* Determine the number of threads OpenACC threads used to determine the
293    size of the array of partial reductions.  Currently, this is num_gangs
294    * vector_length.  This value may be different than GOACC_GET_NUM_THREADS,
295    because it is independed of the device used.  */
296
297 static tree
298 oacc_max_threads (omp_context *ctx)
299 {
300   tree nthreads, vector_length, gangs, clauses;
301
302   gangs = fold_convert (sizetype, integer_one_node);
303   vector_length = gangs;
304
305   /* The reduction clause may be nested inside a loop directive.
306      Scan for the innermost vector_length clause.  */
307   for (omp_context *oc = ctx; oc; oc = oc->outer)
308     {
309       if (gimple_code (oc->stmt) != GIMPLE_OMP_TARGET
310           || (gimple_omp_target_kind (oc->stmt)
311               != GF_OMP_TARGET_KIND_OACC_PARALLEL))
312         continue;
313
314       clauses = gimple_omp_target_clauses (oc->stmt);
315
316       vector_length = find_omp_clause (clauses, OMP_CLAUSE_VECTOR_LENGTH);
317       if (vector_length)
318         vector_length = fold_convert_loc (OMP_CLAUSE_LOCATION (vector_length),
319                                           sizetype,
320                                           OMP_CLAUSE_VECTOR_LENGTH_EXPR
321                                           (vector_length));
322       else
323         vector_length = fold_convert (sizetype, integer_one_node);
324
325       gangs = find_omp_clause (clauses, OMP_CLAUSE_NUM_GANGS);
326       if (gangs)
327         gangs = fold_convert_loc (OMP_CLAUSE_LOCATION (gangs), sizetype,
328                                   OMP_CLAUSE_NUM_GANGS_EXPR (gangs));
329       else
330         gangs = fold_convert (sizetype, integer_one_node);
331
332       break;
333     }
334
335   nthreads = fold_build2 (MULT_EXPR, sizetype, gangs, vector_length);
336
337   return nthreads;
338 }
339
340 /* Holds offload tables with decls.  */
341 vec<tree, va_gc> *offload_funcs, *offload_vars;
342
343 /* Convenience function for calling scan_omp_1_op on tree operands.  */
344
345 static inline tree
346 scan_omp_op (tree *tp, omp_context *ctx)
347 {
348   struct walk_stmt_info wi;
349
350   memset (&wi, 0, sizeof (wi));
351   wi.info = ctx;
352   wi.want_locations = true;
353
354   return walk_tree (tp, scan_omp_1_op, &wi, NULL);
355 }
356
357 static void lower_omp (gimple_seq *, omp_context *);
358 static tree lookup_decl_in_outer_ctx (tree, omp_context *);
359 static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
360
361 /* Find an OMP clause of type KIND within CLAUSES.  */
362
363 tree
364 find_omp_clause (tree clauses, enum omp_clause_code kind)
365 {
366   for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
367     if (OMP_CLAUSE_CODE (clauses) == kind)
368       return clauses;
369
370   return NULL_TREE;
371 }
372
373 /* Return true if CTX is for an omp parallel.  */
374
375 static inline bool
376 is_parallel_ctx (omp_context *ctx)
377 {
378   return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL;
379 }
380
381
382 /* Return true if CTX is for an omp task.  */
383
384 static inline bool
385 is_task_ctx (omp_context *ctx)
386 {
387   return gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
388 }
389
390
391 /* Return true if CTX is for an omp parallel or omp task.  */
392
393 static inline bool
394 is_taskreg_ctx (omp_context *ctx)
395 {
396   return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL
397          || gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
398 }
399
400
401 /* Return true if REGION is a combined parallel+workshare region.  */
402
403 static inline bool
404 is_combined_parallel (struct omp_region *region)
405 {
406   return region->is_combined_parallel;
407 }
408
409
410 /* Extract the header elements of parallel loop FOR_STMT and store
411    them into *FD.  */
412
413 static void
414 extract_omp_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
415                       struct omp_for_data_loop *loops)
416 {
417   tree t, var, *collapse_iter, *collapse_count;
418   tree count = NULL_TREE, iter_type = long_integer_type_node;
419   struct omp_for_data_loop *loop;
420   int i;
421   struct omp_for_data_loop dummy_loop;
422   location_t loc = gimple_location (for_stmt);
423   bool simd = gimple_omp_for_kind (for_stmt) & GF_OMP_FOR_SIMD;
424   bool distribute = gimple_omp_for_kind (for_stmt)
425                     == GF_OMP_FOR_KIND_DISTRIBUTE;
426
427   fd->for_stmt = for_stmt;
428   fd->pre = NULL;
429   fd->collapse = gimple_omp_for_collapse (for_stmt);
430   if (fd->collapse > 1)
431     fd->loops = loops;
432   else
433     fd->loops = &fd->loop;
434
435   fd->have_nowait = distribute || simd;
436   fd->have_ordered = false;
437   fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
438   fd->chunk_size = NULL_TREE;
439   if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_CILKFOR)
440     fd->sched_kind = OMP_CLAUSE_SCHEDULE_CILKFOR;
441   collapse_iter = NULL;
442   collapse_count = NULL;
443
444   for (t = gimple_omp_for_clauses (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
445     switch (OMP_CLAUSE_CODE (t))
446       {
447       case OMP_CLAUSE_NOWAIT:
448         fd->have_nowait = true;
449         break;
450       case OMP_CLAUSE_ORDERED:
451         fd->have_ordered = true;
452         break;
453       case OMP_CLAUSE_SCHEDULE:
454         gcc_assert (!distribute);
455         fd->sched_kind = OMP_CLAUSE_SCHEDULE_KIND (t);
456         fd->chunk_size = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t);
457         break;
458       case OMP_CLAUSE_DIST_SCHEDULE:
459         gcc_assert (distribute);
460         fd->chunk_size = OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (t);
461         break;
462       case OMP_CLAUSE_COLLAPSE:
463         if (fd->collapse > 1)
464           {
465             collapse_iter = &OMP_CLAUSE_COLLAPSE_ITERVAR (t);
466             collapse_count = &OMP_CLAUSE_COLLAPSE_COUNT (t);
467           }
468         break;
469       default:
470         break;
471       }
472
473   /* FIXME: for now map schedule(auto) to schedule(static).
474      There should be analysis to determine whether all iterations
475      are approximately the same amount of work (then schedule(static)
476      is best) or if it varies (then schedule(dynamic,N) is better).  */
477   if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_AUTO)
478     {
479       fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
480       gcc_assert (fd->chunk_size == NULL);
481     }
482   gcc_assert (fd->collapse == 1 || collapse_iter != NULL);
483   if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
484     gcc_assert (fd->chunk_size == NULL);
485   else if (fd->chunk_size == NULL)
486     {
487       /* We only need to compute a default chunk size for ordered
488          static loops and dynamic loops.  */
489       if (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
490           || fd->have_ordered)
491         fd->chunk_size = (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
492                          ? integer_zero_node : integer_one_node;
493     }
494
495   for (i = 0; i < fd->collapse; i++)
496     {
497       if (fd->collapse == 1)
498         loop = &fd->loop;
499       else if (loops != NULL)
500         loop = loops + i;
501       else
502         loop = &dummy_loop;
503
504       loop->v = gimple_omp_for_index (for_stmt, i);
505       gcc_assert (SSA_VAR_P (loop->v));
506       gcc_assert (TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
507                   || TREE_CODE (TREE_TYPE (loop->v)) == POINTER_TYPE);
508       var = TREE_CODE (loop->v) == SSA_NAME ? SSA_NAME_VAR (loop->v) : loop->v;
509       loop->n1 = gimple_omp_for_initial (for_stmt, i);
510
511       loop->cond_code = gimple_omp_for_cond (for_stmt, i);
512       loop->n2 = gimple_omp_for_final (for_stmt, i);
513       switch (loop->cond_code)
514         {
515         case LT_EXPR:
516         case GT_EXPR:
517           break;
518         case NE_EXPR:
519           gcc_assert (gimple_omp_for_kind (for_stmt)
520                       == GF_OMP_FOR_KIND_CILKSIMD
521                       || (gimple_omp_for_kind (for_stmt)
522                           == GF_OMP_FOR_KIND_CILKFOR));
523           break;
524         case LE_EXPR:
525           if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
526             loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, 1);
527           else
528             loop->n2 = fold_build2_loc (loc,
529                                     PLUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
530                                     build_int_cst (TREE_TYPE (loop->n2), 1));
531           loop->cond_code = LT_EXPR;
532           break;
533         case GE_EXPR:
534           if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
535             loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, -1);
536           else
537             loop->n2 = fold_build2_loc (loc,
538                                     MINUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
539                                     build_int_cst (TREE_TYPE (loop->n2), 1));
540           loop->cond_code = GT_EXPR;
541           break;
542         default:
543           gcc_unreachable ();
544         }
545
546       t = gimple_omp_for_incr (for_stmt, i);
547       gcc_assert (TREE_OPERAND (t, 0) == var);
548       switch (TREE_CODE (t))
549         {
550         case PLUS_EXPR:
551           loop->step = TREE_OPERAND (t, 1);
552           break;
553         case POINTER_PLUS_EXPR:
554           loop->step = fold_convert (ssizetype, TREE_OPERAND (t, 1));
555           break;
556         case MINUS_EXPR:
557           loop->step = TREE_OPERAND (t, 1);
558           loop->step = fold_build1_loc (loc,
559                                     NEGATE_EXPR, TREE_TYPE (loop->step),
560                                     loop->step);
561           break;
562         default:
563           gcc_unreachable ();
564         }
565
566       if (simd
567           || (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
568               && !fd->have_ordered))
569         {
570           if (fd->collapse == 1)
571             iter_type = TREE_TYPE (loop->v);
572           else if (i == 0
573                    || TYPE_PRECISION (iter_type)
574                       < TYPE_PRECISION (TREE_TYPE (loop->v)))
575             iter_type
576               = build_nonstandard_integer_type
577                   (TYPE_PRECISION (TREE_TYPE (loop->v)), 1);
578         }
579       else if (iter_type != long_long_unsigned_type_node)
580         {
581           if (POINTER_TYPE_P (TREE_TYPE (loop->v)))
582             iter_type = long_long_unsigned_type_node;
583           else if (TYPE_UNSIGNED (TREE_TYPE (loop->v))
584                    && TYPE_PRECISION (TREE_TYPE (loop->v))
585                       >= TYPE_PRECISION (iter_type))
586             {
587               tree n;
588
589               if (loop->cond_code == LT_EXPR)
590                 n = fold_build2_loc (loc,
591                                  PLUS_EXPR, TREE_TYPE (loop->v),
592                                  loop->n2, loop->step);
593               else
594                 n = loop->n1;
595               if (TREE_CODE (n) != INTEGER_CST
596                   || tree_int_cst_lt (TYPE_MAX_VALUE (iter_type), n))
597                 iter_type = long_long_unsigned_type_node;
598             }
599           else if (TYPE_PRECISION (TREE_TYPE (loop->v))
600                    > TYPE_PRECISION (iter_type))
601             {
602               tree n1, n2;
603
604               if (loop->cond_code == LT_EXPR)
605                 {
606                   n1 = loop->n1;
607                   n2 = fold_build2_loc (loc,
608                                     PLUS_EXPR, TREE_TYPE (loop->v),
609                                     loop->n2, loop->step);
610                 }
611               else
612                 {
613                   n1 = fold_build2_loc (loc,
614                                     MINUS_EXPR, TREE_TYPE (loop->v),
615                                     loop->n2, loop->step);
616                   n2 = loop->n1;
617                 }
618               if (TREE_CODE (n1) != INTEGER_CST
619                   || TREE_CODE (n2) != INTEGER_CST
620                   || !tree_int_cst_lt (TYPE_MIN_VALUE (iter_type), n1)
621                   || !tree_int_cst_lt (n2, TYPE_MAX_VALUE (iter_type)))
622                 iter_type = long_long_unsigned_type_node;
623             }
624         }
625
626       if (collapse_count && *collapse_count == NULL)
627         {
628           t = fold_binary (loop->cond_code, boolean_type_node,
629                            fold_convert (TREE_TYPE (loop->v), loop->n1),
630                            fold_convert (TREE_TYPE (loop->v), loop->n2));
631           if (t && integer_zerop (t))
632             count = build_zero_cst (long_long_unsigned_type_node);
633           else if ((i == 0 || count != NULL_TREE)
634                    && TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
635                    && TREE_CONSTANT (loop->n1)
636                    && TREE_CONSTANT (loop->n2)
637                    && TREE_CODE (loop->step) == INTEGER_CST)
638             {
639               tree itype = TREE_TYPE (loop->v);
640
641               if (POINTER_TYPE_P (itype))
642                 itype = signed_type_for (itype);
643               t = build_int_cst (itype, (loop->cond_code == LT_EXPR ? -1 : 1));
644               t = fold_build2_loc (loc,
645                                PLUS_EXPR, itype,
646                                fold_convert_loc (loc, itype, loop->step), t);
647               t = fold_build2_loc (loc, PLUS_EXPR, itype, t,
648                                fold_convert_loc (loc, itype, loop->n2));
649               t = fold_build2_loc (loc, MINUS_EXPR, itype, t,
650                                fold_convert_loc (loc, itype, loop->n1));
651               if (TYPE_UNSIGNED (itype) && loop->cond_code == GT_EXPR)
652                 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
653                                  fold_build1_loc (loc, NEGATE_EXPR, itype, t),
654                                  fold_build1_loc (loc, NEGATE_EXPR, itype,
655                                               fold_convert_loc (loc, itype,
656                                                                 loop->step)));
657               else
658                 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
659                                  fold_convert_loc (loc, itype, loop->step));
660               t = fold_convert_loc (loc, long_long_unsigned_type_node, t);
661               if (count != NULL_TREE)
662                 count = fold_build2_loc (loc,
663                                      MULT_EXPR, long_long_unsigned_type_node,
664                                      count, t);
665               else
666                 count = t;
667               if (TREE_CODE (count) != INTEGER_CST)
668                 count = NULL_TREE;
669             }
670           else if (count && !integer_zerop (count))
671             count = NULL_TREE;
672         }
673     }
674
675   if (count
676       && !simd
677       && (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
678           || fd->have_ordered))
679     {
680       if (!tree_int_cst_lt (count, TYPE_MAX_VALUE (long_integer_type_node)))
681         iter_type = long_long_unsigned_type_node;
682       else
683         iter_type = long_integer_type_node;
684     }
685   else if (collapse_iter && *collapse_iter != NULL)
686     iter_type = TREE_TYPE (*collapse_iter);
687   fd->iter_type = iter_type;
688   if (collapse_iter && *collapse_iter == NULL)
689     *collapse_iter = create_tmp_var (iter_type, ".iter");
690   if (collapse_count && *collapse_count == NULL)
691     {
692       if (count)
693         *collapse_count = fold_convert_loc (loc, iter_type, count);
694       else
695         *collapse_count = create_tmp_var (iter_type, ".count");
696     }
697
698   if (fd->collapse > 1)
699     {
700       fd->loop.v = *collapse_iter;
701       fd->loop.n1 = build_int_cst (TREE_TYPE (fd->loop.v), 0);
702       fd->loop.n2 = *collapse_count;
703       fd->loop.step = build_int_cst (TREE_TYPE (fd->loop.v), 1);
704       fd->loop.cond_code = LT_EXPR;
705     }
706
707   /* For OpenACC loops, force a chunk size of one, as this avoids the default
708     scheduling where several subsequent iterations are being executed by the
709     same thread.  */
710   if (gimple_omp_for_kind (for_stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
711     {
712       gcc_assert (fd->chunk_size == NULL_TREE);
713       fd->chunk_size = build_int_cst (TREE_TYPE (fd->loop.v), 1);
714     }
715 }
716
717
718 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
719    is the immediate dominator of PAR_ENTRY_BB, return true if there
720    are no data dependencies that would prevent expanding the parallel
721    directive at PAR_ENTRY_BB as a combined parallel+workshare region.
722
723    When expanding a combined parallel+workshare region, the call to
724    the child function may need additional arguments in the case of
725    GIMPLE_OMP_FOR regions.  In some cases, these arguments are
726    computed out of variables passed in from the parent to the child
727    via 'struct .omp_data_s'.  For instance:
728
729         #pragma omp parallel for schedule (guided, i * 4)
730         for (j ...)
731
732    Is lowered into:
733
734         # BLOCK 2 (PAR_ENTRY_BB)
735         .omp_data_o.i = i;
736         #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
737
738         # BLOCK 3 (WS_ENTRY_BB)
739         .omp_data_i = &.omp_data_o;
740         D.1667 = .omp_data_i->i;
741         D.1598 = D.1667 * 4;
742         #pragma omp for schedule (guided, D.1598)
743
744    When we outline the parallel region, the call to the child function
745    'bar.omp_fn.0' will need the value D.1598 in its argument list, but
746    that value is computed *after* the call site.  So, in principle we
747    cannot do the transformation.
748
749    To see whether the code in WS_ENTRY_BB blocks the combined
750    parallel+workshare call, we collect all the variables used in the
751    GIMPLE_OMP_FOR header check whether they appear on the LHS of any
752    statement in WS_ENTRY_BB.  If so, then we cannot emit the combined
753    call.
754
755    FIXME.  If we had the SSA form built at this point, we could merely
756    hoist the code in block 3 into block 2 and be done with it.  But at
757    this point we don't have dataflow information and though we could
758    hack something up here, it is really not worth the aggravation.  */
759
760 static bool
761 workshare_safe_to_combine_p (basic_block ws_entry_bb)
762 {
763   struct omp_for_data fd;
764   gimple ws_stmt = last_stmt (ws_entry_bb);
765
766   if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
767     return true;
768
769   gcc_assert (gimple_code (ws_stmt) == GIMPLE_OMP_FOR);
770
771   extract_omp_for_data (as_a <gomp_for *> (ws_stmt), &fd, NULL);
772
773   if (fd.collapse > 1 && TREE_CODE (fd.loop.n2) != INTEGER_CST)
774     return false;
775   if (fd.iter_type != long_integer_type_node)
776     return false;
777
778   /* FIXME.  We give up too easily here.  If any of these arguments
779      are not constants, they will likely involve variables that have
780      been mapped into fields of .omp_data_s for sharing with the child
781      function.  With appropriate data flow, it would be possible to
782      see through this.  */
783   if (!is_gimple_min_invariant (fd.loop.n1)
784       || !is_gimple_min_invariant (fd.loop.n2)
785       || !is_gimple_min_invariant (fd.loop.step)
786       || (fd.chunk_size && !is_gimple_min_invariant (fd.chunk_size)))
787     return false;
788
789   return true;
790 }
791
792
793 /* Collect additional arguments needed to emit a combined
794    parallel+workshare call.  WS_STMT is the workshare directive being
795    expanded.  */
796
797 static vec<tree, va_gc> *
798 get_ws_args_for (gimple par_stmt, gimple ws_stmt)
799 {
800   tree t;
801   location_t loc = gimple_location (ws_stmt);
802   vec<tree, va_gc> *ws_args;
803
804   if (gomp_for *for_stmt = dyn_cast <gomp_for *> (ws_stmt))
805     {
806       struct omp_for_data fd;
807       tree n1, n2;
808
809       extract_omp_for_data (for_stmt, &fd, NULL);
810       n1 = fd.loop.n1;
811       n2 = fd.loop.n2;
812
813       if (gimple_omp_for_combined_into_p (for_stmt))
814         {
815           tree innerc
816             = find_omp_clause (gimple_omp_parallel_clauses (par_stmt),
817                                OMP_CLAUSE__LOOPTEMP_);
818           gcc_assert (innerc);
819           n1 = OMP_CLAUSE_DECL (innerc);
820           innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
821                                     OMP_CLAUSE__LOOPTEMP_);
822           gcc_assert (innerc);
823           n2 = OMP_CLAUSE_DECL (innerc);
824         }
825
826       vec_alloc (ws_args, 3 + (fd.chunk_size != 0));
827
828       t = fold_convert_loc (loc, long_integer_type_node, n1);
829       ws_args->quick_push (t);
830
831       t = fold_convert_loc (loc, long_integer_type_node, n2);
832       ws_args->quick_push (t);
833
834       t = fold_convert_loc (loc, long_integer_type_node, fd.loop.step);
835       ws_args->quick_push (t);
836
837       if (fd.chunk_size)
838         {
839           t = fold_convert_loc (loc, long_integer_type_node, fd.chunk_size);
840           ws_args->quick_push (t);
841         }
842
843       return ws_args;
844     }
845   else if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
846     {
847       /* Number of sections is equal to the number of edges from the
848          GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
849          the exit of the sections region.  */
850       basic_block bb = single_succ (gimple_bb (ws_stmt));
851       t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
852       vec_alloc (ws_args, 1);
853       ws_args->quick_push (t);
854       return ws_args;
855     }
856
857   gcc_unreachable ();
858 }
859
860
861 /* Discover whether REGION is a combined parallel+workshare region.  */
862
863 static void
864 determine_parallel_type (struct omp_region *region)
865 {
866   basic_block par_entry_bb, par_exit_bb;
867   basic_block ws_entry_bb, ws_exit_bb;
868
869   if (region == NULL || region->inner == NULL
870       || region->exit == NULL || region->inner->exit == NULL
871       || region->inner->cont == NULL)
872     return;
873
874   /* We only support parallel+for and parallel+sections.  */
875   if (region->type != GIMPLE_OMP_PARALLEL
876       || (region->inner->type != GIMPLE_OMP_FOR
877           && region->inner->type != GIMPLE_OMP_SECTIONS))
878     return;
879
880   /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
881      WS_EXIT_BB -> PAR_EXIT_BB.  */
882   par_entry_bb = region->entry;
883   par_exit_bb = region->exit;
884   ws_entry_bb = region->inner->entry;
885   ws_exit_bb = region->inner->exit;
886
887   if (single_succ (par_entry_bb) == ws_entry_bb
888       && single_succ (ws_exit_bb) == par_exit_bb
889       && workshare_safe_to_combine_p (ws_entry_bb)
890       && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb))
891           || (last_and_only_stmt (ws_entry_bb)
892               && last_and_only_stmt (par_exit_bb))))
893     {
894       gimple par_stmt = last_stmt (par_entry_bb);
895       gimple ws_stmt = last_stmt (ws_entry_bb);
896
897       if (region->inner->type == GIMPLE_OMP_FOR)
898         {
899           /* If this is a combined parallel loop, we need to determine
900              whether or not to use the combined library calls.  There
901              are two cases where we do not apply the transformation:
902              static loops and any kind of ordered loop.  In the first
903              case, we already open code the loop so there is no need
904              to do anything else.  In the latter case, the combined
905              parallel loop call would still need extra synchronization
906              to implement ordered semantics, so there would not be any
907              gain in using the combined call.  */
908           tree clauses = gimple_omp_for_clauses (ws_stmt);
909           tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
910           if (c == NULL
911               || OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_STATIC
912               || find_omp_clause (clauses, OMP_CLAUSE_ORDERED))
913             {
914               region->is_combined_parallel = false;
915               region->inner->is_combined_parallel = false;
916               return;
917             }
918         }
919
920       region->is_combined_parallel = true;
921       region->inner->is_combined_parallel = true;
922       region->ws_args = get_ws_args_for (par_stmt, ws_stmt);
923     }
924 }
925
926
927 /* Return true if EXPR is variable sized.  */
928
929 static inline bool
930 is_variable_sized (const_tree expr)
931 {
932   return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
933 }
934
935 /* Return true if DECL is a reference type.  */
936
937 static inline bool
938 is_reference (tree decl)
939 {
940   return lang_hooks.decls.omp_privatize_by_reference (decl);
941 }
942
943 /* Return the type of a decl.  If the decl is reference type,
944    return its base type.  */
945 static inline tree
946 get_base_type (tree decl)
947 {
948   tree type = TREE_TYPE (decl);
949   if (is_reference (decl))
950     type = TREE_TYPE (type);
951   return type;
952 }
953
954 /* Lookup variables.  The "maybe" form
955    allows for the variable form to not have been entered, otherwise we
956    assert that the variable must have been entered.  */
957
958 static inline tree
959 lookup_decl (tree var, omp_context *ctx)
960 {
961   tree *n = ctx->cb.decl_map->get (var);
962   return *n;
963 }
964
965 static inline tree
966 maybe_lookup_decl (const_tree var, omp_context *ctx)
967 {
968   tree *n = ctx->cb.decl_map->get (const_cast<tree> (var));
969   return n ? *n : NULL_TREE;
970 }
971
972 static inline tree
973 lookup_field (tree var, omp_context *ctx)
974 {
975   splay_tree_node n;
976   n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
977   return (tree) n->value;
978 }
979
980 static inline tree
981 lookup_sfield (tree var, omp_context *ctx)
982 {
983   splay_tree_node n;
984   n = splay_tree_lookup (ctx->sfield_map
985                          ? ctx->sfield_map : ctx->field_map,
986                          (splay_tree_key) var);
987   return (tree) n->value;
988 }
989
990 static inline tree
991 maybe_lookup_field (tree var, omp_context *ctx)
992 {
993   splay_tree_node n;
994   n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
995   return n ? (tree) n->value : NULL_TREE;
996 }
997
998 static inline tree
999 lookup_oacc_reduction (const char *id, omp_context *ctx)
1000 {
1001   splay_tree_node n;
1002   n = splay_tree_lookup (ctx->reduction_map, (splay_tree_key) id);
1003   return (tree) n->value;
1004 }
1005
1006 static inline tree
1007 maybe_lookup_oacc_reduction (tree var, omp_context *ctx)
1008 {
1009   splay_tree_node n = NULL;
1010   if (ctx->reduction_map)
1011     n = splay_tree_lookup (ctx->reduction_map, (splay_tree_key) var);
1012   return n ? (tree) n->value : NULL_TREE;
1013 }
1014
1015 /* Return true if DECL should be copied by pointer.  SHARED_CTX is
1016    the parallel context if DECL is to be shared.  */
1017
1018 static bool
1019 use_pointer_for_field (tree decl, omp_context *shared_ctx)
1020 {
1021   if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
1022     return true;
1023
1024   /* We can only use copy-in/copy-out semantics for shared variables
1025      when we know the value is not accessible from an outer scope.  */
1026   if (shared_ctx)
1027     {
1028       gcc_assert (!is_gimple_omp_oacc (shared_ctx->stmt));
1029
1030       /* ??? Trivially accessible from anywhere.  But why would we even
1031          be passing an address in this case?  Should we simply assert
1032          this to be false, or should we have a cleanup pass that removes
1033          these from the list of mappings?  */
1034       if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
1035         return true;
1036
1037       /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
1038          without analyzing the expression whether or not its location
1039          is accessible to anyone else.  In the case of nested parallel
1040          regions it certainly may be.  */
1041       if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
1042         return true;
1043
1044       /* Do not use copy-in/copy-out for variables that have their
1045          address taken.  */
1046       if (TREE_ADDRESSABLE (decl))
1047         return true;
1048
1049       /* lower_send_shared_vars only uses copy-in, but not copy-out
1050          for these.  */
1051       if (TREE_READONLY (decl)
1052           || ((TREE_CODE (decl) == RESULT_DECL
1053                || TREE_CODE (decl) == PARM_DECL)
1054               && DECL_BY_REFERENCE (decl)))
1055         return false;
1056
1057       /* Disallow copy-in/out in nested parallel if
1058          decl is shared in outer parallel, otherwise
1059          each thread could store the shared variable
1060          in its own copy-in location, making the
1061          variable no longer really shared.  */
1062       if (shared_ctx->is_nested)
1063         {
1064           omp_context *up;
1065
1066           for (up = shared_ctx->outer; up; up = up->outer)
1067             if (is_taskreg_ctx (up) && maybe_lookup_decl (decl, up))
1068               break;
1069
1070           if (up)
1071             {
1072               tree c;
1073
1074               for (c = gimple_omp_taskreg_clauses (up->stmt);
1075                    c; c = OMP_CLAUSE_CHAIN (c))
1076                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
1077                     && OMP_CLAUSE_DECL (c) == decl)
1078                   break;
1079
1080               if (c)
1081                 goto maybe_mark_addressable_and_ret;
1082             }
1083         }
1084
1085       /* For tasks avoid using copy-in/out.  As tasks can be
1086          deferred or executed in different thread, when GOMP_task
1087          returns, the task hasn't necessarily terminated.  */
1088       if (is_task_ctx (shared_ctx))
1089         {
1090           tree outer;
1091         maybe_mark_addressable_and_ret:
1092           outer = maybe_lookup_decl_in_outer_ctx (decl, shared_ctx);
1093           if (is_gimple_reg (outer))
1094             {
1095               /* Taking address of OUTER in lower_send_shared_vars
1096                  might need regimplification of everything that uses the
1097                  variable.  */
1098               if (!task_shared_vars)
1099                 task_shared_vars = BITMAP_ALLOC (NULL);
1100               bitmap_set_bit (task_shared_vars, DECL_UID (outer));
1101               TREE_ADDRESSABLE (outer) = 1;
1102             }
1103           return true;
1104         }
1105     }
1106
1107   return false;
1108 }
1109
1110 /* Construct a new automatic decl similar to VAR.  */
1111
1112 static tree
1113 omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
1114 {
1115   tree copy = copy_var_decl (var, name, type);
1116
1117   DECL_CONTEXT (copy) = current_function_decl;
1118   DECL_CHAIN (copy) = ctx->block_vars;
1119   ctx->block_vars = copy;
1120
1121   return copy;
1122 }
1123
1124 static tree
1125 omp_copy_decl_1 (tree var, omp_context *ctx)
1126 {
1127   return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
1128 }
1129
1130 /* Build COMPONENT_REF and set TREE_THIS_VOLATILE and TREE_READONLY on it
1131    as appropriate.  */
1132 static tree
1133 omp_build_component_ref (tree obj, tree field)
1134 {
1135   tree ret = build3 (COMPONENT_REF, TREE_TYPE (field), obj, field, NULL);
1136   if (TREE_THIS_VOLATILE (field))
1137     TREE_THIS_VOLATILE (ret) |= 1;
1138   if (TREE_READONLY (field))
1139     TREE_READONLY (ret) |= 1;
1140   return ret;
1141 }
1142
1143 /* Build tree nodes to access the field for VAR on the receiver side.  */
1144
1145 static tree
1146 build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
1147 {
1148   tree x, field = lookup_field (var, ctx);
1149
1150   /* If the receiver record type was remapped in the child function,
1151      remap the field into the new record type.  */
1152   x = maybe_lookup_field (field, ctx);
1153   if (x != NULL)
1154     field = x;
1155
1156   x = build_simple_mem_ref (ctx->receiver_decl);
1157   x = omp_build_component_ref (x, field);
1158   if (by_ref)
1159     x = build_simple_mem_ref (x);
1160
1161   return x;
1162 }
1163
1164 /* Build tree nodes to access VAR in the scope outer to CTX.  In the case
1165    of a parallel, this is a component reference; for workshare constructs
1166    this is some variable.  */
1167
1168 static tree
1169 build_outer_var_ref (tree var, omp_context *ctx)
1170 {
1171   tree x;
1172
1173   if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
1174     x = var;
1175   else if (is_variable_sized (var))
1176     {
1177       x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
1178       x = build_outer_var_ref (x, ctx);
1179       x = build_simple_mem_ref (x);
1180     }
1181   else if (is_taskreg_ctx (ctx))
1182     {
1183       bool by_ref = use_pointer_for_field (var, NULL);
1184       x = build_receiver_ref (var, by_ref, ctx);
1185     }
1186   else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
1187            && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
1188     {
1189       /* #pragma omp simd isn't a worksharing construct, and can reference even
1190          private vars in its linear etc. clauses.  */
1191       x = NULL_TREE;
1192       if (ctx->outer && is_taskreg_ctx (ctx))
1193         x = lookup_decl (var, ctx->outer);
1194       else if (ctx->outer)
1195         x = maybe_lookup_decl_in_outer_ctx (var, ctx);
1196       if (x == NULL_TREE)
1197         x = var;
1198     }
1199   else if (ctx->outer)
1200     x = lookup_decl (var, ctx->outer);
1201   else if (is_reference (var))
1202     /* This can happen with orphaned constructs.  If var is reference, it is
1203        possible it is shared and as such valid.  */
1204     x = var;
1205   else
1206     gcc_unreachable ();
1207
1208   if (is_reference (var))
1209     x = build_simple_mem_ref (x);
1210
1211   return x;
1212 }
1213
1214 /* Build tree nodes to access the field for VAR on the sender side.  */
1215
1216 static tree
1217 build_sender_ref (tree var, omp_context *ctx)
1218 {
1219   tree field = lookup_sfield (var, ctx);
1220   return omp_build_component_ref (ctx->sender_decl, field);
1221 }
1222
1223 /* Add a new field for VAR inside the structure CTX->SENDER_DECL.  */
1224
1225 static void
1226 install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
1227 {
1228   tree field, type, sfield = NULL_TREE;
1229
1230   gcc_assert ((mask & 1) == 0
1231               || !splay_tree_lookup (ctx->field_map, (splay_tree_key) var));
1232   gcc_assert ((mask & 2) == 0 || !ctx->sfield_map
1233               || !splay_tree_lookup (ctx->sfield_map, (splay_tree_key) var));
1234   gcc_assert ((mask & 3) == 3
1235               || !is_gimple_omp_oacc (ctx->stmt));
1236
1237   type = TREE_TYPE (var);
1238   if (mask & 4)
1239     {
1240       gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
1241       type = build_pointer_type (build_pointer_type (type));
1242     }
1243   else if (by_ref)
1244     type = build_pointer_type (type);
1245   else if ((mask & 3) == 1 && is_reference (var))
1246     type = TREE_TYPE (type);
1247
1248   field = build_decl (DECL_SOURCE_LOCATION (var),
1249                       FIELD_DECL, DECL_NAME (var), type);
1250
1251   /* Remember what variable this field was created for.  This does have a
1252      side effect of making dwarf2out ignore this member, so for helpful
1253      debugging we clear it later in delete_omp_context.  */
1254   DECL_ABSTRACT_ORIGIN (field) = var;
1255   if (type == TREE_TYPE (var))
1256     {
1257       DECL_ALIGN (field) = DECL_ALIGN (var);
1258       DECL_USER_ALIGN (field) = DECL_USER_ALIGN (var);
1259       TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (var);
1260     }
1261   else
1262     DECL_ALIGN (field) = TYPE_ALIGN (type);
1263
1264   if ((mask & 3) == 3)
1265     {
1266       insert_field_into_struct (ctx->record_type, field);
1267       if (ctx->srecord_type)
1268         {
1269           sfield = build_decl (DECL_SOURCE_LOCATION (var),
1270                                FIELD_DECL, DECL_NAME (var), type);
1271           DECL_ABSTRACT_ORIGIN (sfield) = var;
1272           DECL_ALIGN (sfield) = DECL_ALIGN (field);
1273           DECL_USER_ALIGN (sfield) = DECL_USER_ALIGN (field);
1274           TREE_THIS_VOLATILE (sfield) = TREE_THIS_VOLATILE (field);
1275           insert_field_into_struct (ctx->srecord_type, sfield);
1276         }
1277     }
1278   else
1279     {
1280       if (ctx->srecord_type == NULL_TREE)
1281         {
1282           tree t;
1283
1284           ctx->srecord_type = lang_hooks.types.make_type (RECORD_TYPE);
1285           ctx->sfield_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1286           for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
1287             {
1288               sfield = build_decl (DECL_SOURCE_LOCATION (var),
1289                                    FIELD_DECL, DECL_NAME (t), TREE_TYPE (t));
1290               DECL_ABSTRACT_ORIGIN (sfield) = DECL_ABSTRACT_ORIGIN (t);
1291               insert_field_into_struct (ctx->srecord_type, sfield);
1292               splay_tree_insert (ctx->sfield_map,
1293                                  (splay_tree_key) DECL_ABSTRACT_ORIGIN (t),
1294                                  (splay_tree_value) sfield);
1295             }
1296         }
1297       sfield = field;
1298       insert_field_into_struct ((mask & 1) ? ctx->record_type
1299                                 : ctx->srecord_type, field);
1300     }
1301
1302   if (mask & 1)
1303     splay_tree_insert (ctx->field_map, (splay_tree_key) var,
1304                        (splay_tree_value) field);
1305   if ((mask & 2) && ctx->sfield_map)
1306     splay_tree_insert (ctx->sfield_map, (splay_tree_key) var,
1307                        (splay_tree_value) sfield);
1308 }
1309
1310 static tree
1311 install_var_local (tree var, omp_context *ctx)
1312 {
1313   tree new_var = omp_copy_decl_1 (var, ctx);
1314   insert_decl_map (&ctx->cb, var, new_var);
1315   return new_var;
1316 }
1317
1318 /* Adjust the replacement for DECL in CTX for the new context.  This means
1319    copying the DECL_VALUE_EXPR, and fixing up the type.  */
1320
1321 static void
1322 fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
1323 {
1324   tree new_decl, size;
1325
1326   new_decl = lookup_decl (decl, ctx);
1327
1328   TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
1329
1330   if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
1331       && DECL_HAS_VALUE_EXPR_P (decl))
1332     {
1333       tree ve = DECL_VALUE_EXPR (decl);
1334       walk_tree (&ve, copy_tree_body_r, &ctx->cb, NULL);
1335       SET_DECL_VALUE_EXPR (new_decl, ve);
1336       DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
1337     }
1338
1339   if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
1340     {
1341       size = remap_decl (DECL_SIZE (decl), &ctx->cb);
1342       if (size == error_mark_node)
1343         size = TYPE_SIZE (TREE_TYPE (new_decl));
1344       DECL_SIZE (new_decl) = size;
1345
1346       size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
1347       if (size == error_mark_node)
1348         size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
1349       DECL_SIZE_UNIT (new_decl) = size;
1350     }
1351 }
1352
1353 /* The callback for remap_decl.  Search all containing contexts for a
1354    mapping of the variable; this avoids having to duplicate the splay
1355    tree ahead of time.  We know a mapping doesn't already exist in the
1356    given context.  Create new mappings to implement default semantics.  */
1357
1358 static tree
1359 omp_copy_decl (tree var, copy_body_data *cb)
1360 {
1361   omp_context *ctx = (omp_context *) cb;
1362   tree new_var;
1363
1364   if (TREE_CODE (var) == LABEL_DECL)
1365     {
1366       new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
1367       DECL_CONTEXT (new_var) = current_function_decl;
1368       insert_decl_map (&ctx->cb, var, new_var);
1369       return new_var;
1370     }
1371
1372   while (!is_taskreg_ctx (ctx))
1373     {
1374       ctx = ctx->outer;
1375       if (ctx == NULL)
1376         return var;
1377       new_var = maybe_lookup_decl (var, ctx);
1378       if (new_var)
1379         return new_var;
1380     }
1381
1382   if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
1383     return var;
1384
1385   return error_mark_node;
1386 }
1387
1388
1389 /* Debugging dumps for parallel regions.  */
1390 void dump_omp_region (FILE *, struct omp_region *, int);
1391 void debug_omp_region (struct omp_region *);
1392 void debug_all_omp_regions (void);
1393
1394 /* Dump the parallel region tree rooted at REGION.  */
1395
1396 void
1397 dump_omp_region (FILE *file, struct omp_region *region, int indent)
1398 {
1399   fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
1400            gimple_code_name[region->type]);
1401
1402   if (region->inner)
1403     dump_omp_region (file, region->inner, indent + 4);
1404
1405   if (region->cont)
1406     {
1407       fprintf (file, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent, "",
1408                region->cont->index);
1409     }
1410
1411   if (region->exit)
1412     fprintf (file, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent, "",
1413              region->exit->index);
1414   else
1415     fprintf (file, "%*s[no exit marker]\n", indent, "");
1416
1417   if (region->next)
1418     dump_omp_region (file, region->next, indent);
1419 }
1420
1421 DEBUG_FUNCTION void
1422 debug_omp_region (struct omp_region *region)
1423 {
1424   dump_omp_region (stderr, region, 0);
1425 }
1426
1427 DEBUG_FUNCTION void
1428 debug_all_omp_regions (void)
1429 {
1430   dump_omp_region (stderr, root_omp_region, 0);
1431 }
1432
1433
1434 /* Create a new parallel region starting at STMT inside region PARENT.  */
1435
1436 static struct omp_region *
1437 new_omp_region (basic_block bb, enum gimple_code type,
1438                 struct omp_region *parent)
1439 {
1440   struct omp_region *region = XCNEW (struct omp_region);
1441
1442   region->outer = parent;
1443   region->entry = bb;
1444   region->type = type;
1445
1446   if (parent)
1447     {
1448       /* This is a nested region.  Add it to the list of inner
1449          regions in PARENT.  */
1450       region->next = parent->inner;
1451       parent->inner = region;
1452     }
1453   else
1454     {
1455       /* This is a toplevel region.  Add it to the list of toplevel
1456          regions in ROOT_OMP_REGION.  */
1457       region->next = root_omp_region;
1458       root_omp_region = region;
1459     }
1460
1461   return region;
1462 }
1463
1464 /* Release the memory associated with the region tree rooted at REGION.  */
1465
1466 static void
1467 free_omp_region_1 (struct omp_region *region)
1468 {
1469   struct omp_region *i, *n;
1470
1471   for (i = region->inner; i ; i = n)
1472     {
1473       n = i->next;
1474       free_omp_region_1 (i);
1475     }
1476
1477   free (region);
1478 }
1479
1480 /* Release the memory for the entire omp region tree.  */
1481
1482 void
1483 free_omp_regions (void)
1484 {
1485   struct omp_region *r, *n;
1486   for (r = root_omp_region; r ; r = n)
1487     {
1488       n = r->next;
1489       free_omp_region_1 (r);
1490     }
1491   root_omp_region = NULL;
1492 }
1493
1494
1495 /* Create a new context, with OUTER_CTX being the surrounding context.  */
1496
1497 static omp_context *
1498 new_omp_context (gimple stmt, omp_context *outer_ctx)
1499 {
1500   omp_context *ctx = XCNEW (omp_context);
1501
1502   splay_tree_insert (all_contexts, (splay_tree_key) stmt,
1503                      (splay_tree_value) ctx);
1504   ctx->stmt = stmt;
1505
1506   if (outer_ctx)
1507     {
1508       ctx->outer = outer_ctx;
1509       ctx->cb = outer_ctx->cb;
1510       ctx->cb.block = NULL;
1511       ctx->depth = outer_ctx->depth + 1;
1512       ctx->reduction_map = outer_ctx->reduction_map;
1513     }
1514   else
1515     {
1516       ctx->cb.src_fn = current_function_decl;
1517       ctx->cb.dst_fn = current_function_decl;
1518       ctx->cb.src_node = cgraph_node::get (current_function_decl);
1519       gcc_checking_assert (ctx->cb.src_node);
1520       ctx->cb.dst_node = ctx->cb.src_node;
1521       ctx->cb.src_cfun = cfun;
1522       ctx->cb.copy_decl = omp_copy_decl;
1523       ctx->cb.eh_lp_nr = 0;
1524       ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
1525       ctx->depth = 1;
1526     }
1527
1528   ctx->cb.decl_map = new hash_map<tree, tree>;
1529
1530   return ctx;
1531 }
1532
1533 static gimple_seq maybe_catch_exception (gimple_seq);
1534
1535 /* Finalize task copyfn.  */
1536
1537 static void
1538 finalize_task_copyfn (gomp_task *task_stmt)
1539 {
1540   struct function *child_cfun;
1541   tree child_fn;
1542   gimple_seq seq = NULL, new_seq;
1543   gbind *bind;
1544
1545   child_fn = gimple_omp_task_copy_fn (task_stmt);
1546   if (child_fn == NULL_TREE)
1547     return;
1548
1549   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
1550   DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
1551
1552   push_cfun (child_cfun);
1553   bind = gimplify_body (child_fn, false);
1554   gimple_seq_add_stmt (&seq, bind);
1555   new_seq = maybe_catch_exception (seq);
1556   if (new_seq != seq)
1557     {
1558       bind = gimple_build_bind (NULL, new_seq, NULL);
1559       seq = NULL;
1560       gimple_seq_add_stmt (&seq, bind);
1561     }
1562   gimple_set_body (child_fn, seq);
1563   pop_cfun ();
1564
1565   /* Inform the callgraph about the new function.  */
1566   cgraph_node::add_new_function (child_fn, false);
1567 }
1568
1569 /* Destroy a omp_context data structures.  Called through the splay tree
1570    value delete callback.  */
1571
1572 static void
1573 delete_omp_context (splay_tree_value value)
1574 {
1575   omp_context *ctx = (omp_context *) value;
1576
1577   delete ctx->cb.decl_map;
1578
1579   if (ctx->field_map)
1580     splay_tree_delete (ctx->field_map);
1581   if (ctx->sfield_map)
1582     splay_tree_delete (ctx->sfield_map);
1583   if (ctx->reduction_map
1584       /* Shared over several omp_contexts.  */
1585       && (ctx->outer == NULL
1586           || ctx->reduction_map != ctx->outer->reduction_map))
1587     splay_tree_delete (ctx->reduction_map);
1588
1589   /* We hijacked DECL_ABSTRACT_ORIGIN earlier.  We need to clear it before
1590      it produces corrupt debug information.  */
1591   if (ctx->record_type)
1592     {
1593       tree t;
1594       for (t = TYPE_FIELDS (ctx->record_type); t ; t = DECL_CHAIN (t))
1595         DECL_ABSTRACT_ORIGIN (t) = NULL;
1596     }
1597   if (ctx->srecord_type)
1598     {
1599       tree t;
1600       for (t = TYPE_FIELDS (ctx->srecord_type); t ; t = DECL_CHAIN (t))
1601         DECL_ABSTRACT_ORIGIN (t) = NULL;
1602     }
1603
1604   if (is_task_ctx (ctx))
1605     finalize_task_copyfn (as_a <gomp_task *> (ctx->stmt));
1606
1607   XDELETE (ctx);
1608 }
1609
1610 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
1611    context.  */
1612
1613 static void
1614 fixup_child_record_type (omp_context *ctx)
1615 {
1616   tree f, type = ctx->record_type;
1617
1618   /* ??? It isn't sufficient to just call remap_type here, because
1619      variably_modified_type_p doesn't work the way we expect for
1620      record types.  Testing each field for whether it needs remapping
1621      and creating a new record by hand works, however.  */
1622   for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
1623     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
1624       break;
1625   if (f)
1626     {
1627       tree name, new_fields = NULL;
1628
1629       type = lang_hooks.types.make_type (RECORD_TYPE);
1630       name = DECL_NAME (TYPE_NAME (ctx->record_type));
1631       name = build_decl (DECL_SOURCE_LOCATION (ctx->receiver_decl),
1632                          TYPE_DECL, name, type);
1633       TYPE_NAME (type) = name;
1634
1635       for (f = TYPE_FIELDS (ctx->record_type); f ; f = DECL_CHAIN (f))
1636         {
1637           tree new_f = copy_node (f);
1638           DECL_CONTEXT (new_f) = type;
1639           TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
1640           DECL_CHAIN (new_f) = new_fields;
1641           walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &ctx->cb, NULL);
1642           walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r,
1643                      &ctx->cb, NULL);
1644           walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
1645                      &ctx->cb, NULL);
1646           new_fields = new_f;
1647
1648           /* Arrange to be able to look up the receiver field
1649              given the sender field.  */
1650           splay_tree_insert (ctx->field_map, (splay_tree_key) f,
1651                              (splay_tree_value) new_f);
1652         }
1653       TYPE_FIELDS (type) = nreverse (new_fields);
1654       layout_type (type);
1655     }
1656
1657   TREE_TYPE (ctx->receiver_decl)
1658     = build_qualified_type (build_reference_type (type), TYPE_QUAL_RESTRICT);
1659 }
1660
1661 /* Instantiate decls as necessary in CTX to satisfy the data sharing
1662    specified by CLAUSES.  */
1663
1664 static void
1665 scan_sharing_clauses (tree clauses, omp_context *ctx)
1666 {
1667   tree c, decl;
1668   bool scan_array_reductions = false;
1669
1670   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1671     {
1672       bool by_ref;
1673
1674       switch (OMP_CLAUSE_CODE (c))
1675         {
1676         case OMP_CLAUSE_PRIVATE:
1677           decl = OMP_CLAUSE_DECL (c);
1678           if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
1679             goto do_private;
1680           else if (!is_variable_sized (decl))
1681             install_var_local (decl, ctx);
1682           break;
1683
1684         case OMP_CLAUSE_SHARED:
1685           decl = OMP_CLAUSE_DECL (c);
1686           /* Ignore shared directives in teams construct.  */
1687           if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
1688             {
1689               /* Global variables don't need to be copied,
1690                  the receiver side will use them directly.  */
1691               tree odecl = maybe_lookup_decl_in_outer_ctx (decl, ctx);
1692               if (is_global_var (odecl))
1693                 break;
1694               insert_decl_map (&ctx->cb, decl, odecl);
1695               break;
1696             }
1697           gcc_assert (is_taskreg_ctx (ctx));
1698           gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl))
1699                       || !is_variable_sized (decl));
1700           /* Global variables don't need to be copied,
1701              the receiver side will use them directly.  */
1702           if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1703             break;
1704           by_ref = use_pointer_for_field (decl, ctx);
1705           if (! TREE_READONLY (decl)
1706               || TREE_ADDRESSABLE (decl)
1707               || by_ref
1708               || is_reference (decl))
1709             {
1710               install_var_field (decl, by_ref, 3, ctx);
1711               install_var_local (decl, ctx);
1712               break;
1713             }
1714           /* We don't need to copy const scalar vars back.  */
1715           OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
1716           goto do_private;
1717
1718         case OMP_CLAUSE_LASTPRIVATE:
1719           /* Let the corresponding firstprivate clause create
1720              the variable.  */
1721           if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1722             break;
1723           /* FALLTHRU */
1724
1725         case OMP_CLAUSE_FIRSTPRIVATE:
1726           if (is_gimple_omp_oacc (ctx->stmt))
1727             {
1728               sorry ("clause not supported yet");
1729               break;
1730             }
1731           /* FALLTHRU */
1732         case OMP_CLAUSE_REDUCTION:
1733         case OMP_CLAUSE_LINEAR:
1734           decl = OMP_CLAUSE_DECL (c);
1735         do_private:
1736           if (is_variable_sized (decl))
1737             {
1738               if (is_task_ctx (ctx))
1739                 install_var_field (decl, false, 1, ctx);
1740               break;
1741             }
1742           else if (is_taskreg_ctx (ctx))
1743             {
1744               bool global
1745                 = is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx));
1746               by_ref = use_pointer_for_field (decl, NULL);
1747
1748               if (is_task_ctx (ctx)
1749                   && (global || by_ref || is_reference (decl)))
1750                 {
1751                   install_var_field (decl, false, 1, ctx);
1752                   if (!global)
1753                     install_var_field (decl, by_ref, 2, ctx);
1754                 }
1755               else if (!global)
1756                 install_var_field (decl, by_ref, 3, ctx);
1757             }
1758           install_var_local (decl, ctx);
1759           if (is_gimple_omp_oacc (ctx->stmt)
1760               && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
1761             {
1762               /* Create a decl for the reduction array.  */
1763               tree var = OMP_CLAUSE_DECL (c);
1764               tree type = get_base_type (var);
1765               tree ptype = build_pointer_type (type);
1766               tree array = create_tmp_var (ptype,
1767                                            oacc_get_reduction_array_id (var));
1768               omp_context *c = (ctx->field_map ? ctx : ctx->outer);
1769               install_var_field (array, true, 3, c);
1770               install_var_local (array, c);
1771
1772               /* Insert it into the current context.  */
1773               splay_tree_insert (ctx->reduction_map, (splay_tree_key)
1774                                  oacc_get_reduction_array_id (var),
1775                                  (splay_tree_value) array);
1776               splay_tree_insert (ctx->reduction_map,
1777                                  (splay_tree_key) array,
1778                                  (splay_tree_value) array);
1779             }
1780           break;
1781
1782         case OMP_CLAUSE__LOOPTEMP_:
1783           gcc_assert (is_parallel_ctx (ctx));
1784           decl = OMP_CLAUSE_DECL (c);
1785           install_var_field (decl, false, 3, ctx);
1786           install_var_local (decl, ctx);
1787           break;
1788
1789         case OMP_CLAUSE_COPYPRIVATE:
1790         case OMP_CLAUSE_COPYIN:
1791           decl = OMP_CLAUSE_DECL (c);
1792           by_ref = use_pointer_for_field (decl, NULL);
1793           install_var_field (decl, by_ref, 3, ctx);
1794           break;
1795
1796         case OMP_CLAUSE_DEFAULT:
1797           ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
1798           break;
1799
1800         case OMP_CLAUSE_FINAL:
1801         case OMP_CLAUSE_IF:
1802         case OMP_CLAUSE_NUM_THREADS:
1803         case OMP_CLAUSE_NUM_TEAMS:
1804         case OMP_CLAUSE_THREAD_LIMIT:
1805         case OMP_CLAUSE_DEVICE:
1806         case OMP_CLAUSE_SCHEDULE:
1807         case OMP_CLAUSE_DIST_SCHEDULE:
1808         case OMP_CLAUSE_DEPEND:
1809         case OMP_CLAUSE__CILK_FOR_COUNT_:
1810         case OMP_CLAUSE_NUM_GANGS:
1811         case OMP_CLAUSE_NUM_WORKERS:
1812         case OMP_CLAUSE_VECTOR_LENGTH:
1813           if (ctx->outer)
1814             scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
1815           break;
1816
1817         case OMP_CLAUSE_TO:
1818         case OMP_CLAUSE_FROM:
1819         case OMP_CLAUSE_MAP:
1820           if (ctx->outer)
1821             scan_omp_op (&OMP_CLAUSE_SIZE (c), ctx->outer);
1822           decl = OMP_CLAUSE_DECL (c);
1823           /* Global variables with "omp declare target" attribute
1824              don't need to be copied, the receiver side will use them
1825              directly.  */
1826           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
1827               && DECL_P (decl)
1828               && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
1829               && varpool_node::get_create (decl)->offloadable)
1830             break;
1831           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
1832               && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER)
1833             {
1834               /* Ignore GOMP_MAP_POINTER kind for arrays in regions that are
1835                  not offloaded; there is nothing to map for those.  */
1836               if (!is_gimple_omp_offloaded (ctx->stmt)
1837                   && !POINTER_TYPE_P (TREE_TYPE (decl))
1838                   && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
1839                 break;
1840             }
1841           if (DECL_P (decl))
1842             {
1843               if (DECL_SIZE (decl)
1844                   && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
1845                 {
1846                   tree decl2 = DECL_VALUE_EXPR (decl);
1847                   gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
1848                   decl2 = TREE_OPERAND (decl2, 0);
1849                   gcc_assert (DECL_P (decl2));
1850                   install_var_field (decl2, true, 3, ctx);
1851                   install_var_local (decl2, ctx);
1852                   install_var_local (decl, ctx);
1853                 }
1854               else
1855                 {
1856                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
1857                       && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
1858                       && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
1859                       && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
1860                     install_var_field (decl, true, 7, ctx);
1861                   else
1862                     install_var_field (decl, true, 3, ctx);
1863                   if (is_gimple_omp_offloaded (ctx->stmt))
1864                     install_var_local (decl, ctx);
1865                 }
1866             }
1867           else
1868             {
1869               tree base = get_base_address (decl);
1870               tree nc = OMP_CLAUSE_CHAIN (c);
1871               if (DECL_P (base)
1872                   && nc != NULL_TREE
1873                   && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
1874                   && OMP_CLAUSE_DECL (nc) == base
1875                   && OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_POINTER
1876                   && integer_zerop (OMP_CLAUSE_SIZE (nc)))
1877                 {
1878                   OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c) = 1;
1879                   OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (nc) = 1;
1880                 }
1881               else
1882                 {
1883                   if (ctx->outer)
1884                     {
1885                       scan_omp_op (&OMP_CLAUSE_DECL (c), ctx->outer);
1886                       decl = OMP_CLAUSE_DECL (c);
1887                     }
1888                   gcc_assert (!splay_tree_lookup (ctx->field_map,
1889                                                   (splay_tree_key) decl));
1890                   tree field
1891                     = build_decl (OMP_CLAUSE_LOCATION (c),
1892                                   FIELD_DECL, NULL_TREE, ptr_type_node);
1893                   DECL_ALIGN (field) = TYPE_ALIGN (ptr_type_node);
1894                   insert_field_into_struct (ctx->record_type, field);
1895                   splay_tree_insert (ctx->field_map, (splay_tree_key) decl,
1896                                      (splay_tree_value) field);
1897                 }
1898             }
1899           break;
1900
1901         case OMP_CLAUSE_NOWAIT:
1902         case OMP_CLAUSE_ORDERED:
1903         case OMP_CLAUSE_COLLAPSE:
1904         case OMP_CLAUSE_UNTIED:
1905         case OMP_CLAUSE_MERGEABLE:
1906         case OMP_CLAUSE_PROC_BIND:
1907         case OMP_CLAUSE_SAFELEN:
1908         case OMP_CLAUSE_ASYNC:
1909         case OMP_CLAUSE_WAIT:
1910         case OMP_CLAUSE_GANG:
1911         case OMP_CLAUSE_WORKER:
1912         case OMP_CLAUSE_VECTOR:
1913           break;
1914
1915         case OMP_CLAUSE_ALIGNED:
1916           decl = OMP_CLAUSE_DECL (c);
1917           if (is_global_var (decl)
1918               && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
1919             install_var_local (decl, ctx);
1920           break;
1921
1922         case OMP_CLAUSE_DEVICE_RESIDENT:
1923         case OMP_CLAUSE_USE_DEVICE:
1924         case OMP_CLAUSE__CACHE_:
1925         case OMP_CLAUSE_INDEPENDENT:
1926         case OMP_CLAUSE_AUTO:
1927         case OMP_CLAUSE_SEQ:
1928           sorry ("Clause not supported yet");
1929           break;
1930
1931         default:
1932           gcc_unreachable ();
1933         }
1934     }
1935
1936   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1937     {
1938       switch (OMP_CLAUSE_CODE (c))
1939         {
1940         case OMP_CLAUSE_LASTPRIVATE:
1941           /* Let the corresponding firstprivate clause create
1942              the variable.  */
1943           if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
1944             scan_array_reductions = true;
1945           if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1946             break;
1947           /* FALLTHRU */
1948
1949         case OMP_CLAUSE_FIRSTPRIVATE:
1950           if (is_gimple_omp_oacc (ctx->stmt))
1951             {
1952               sorry ("clause not supported yet");
1953               break;
1954             }
1955           /* FALLTHRU */
1956         case OMP_CLAUSE_PRIVATE:
1957         case OMP_CLAUSE_REDUCTION:
1958         case OMP_CLAUSE_LINEAR:
1959           decl = OMP_CLAUSE_DECL (c);
1960           if (is_variable_sized (decl))
1961             install_var_local (decl, ctx);
1962           fixup_remapped_decl (decl, ctx,
1963                                OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
1964                                && OMP_CLAUSE_PRIVATE_DEBUG (c));
1965           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1966               && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1967             scan_array_reductions = true;
1968           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
1969                    && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
1970             scan_array_reductions = true;
1971           break;
1972
1973         case OMP_CLAUSE_SHARED:
1974           /* Ignore shared directives in teams construct.  */
1975           if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
1976             break;
1977           decl = OMP_CLAUSE_DECL (c);
1978           if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1979             fixup_remapped_decl (decl, ctx, false);
1980           break;
1981
1982         case OMP_CLAUSE_MAP:
1983           if (!is_gimple_omp_offloaded (ctx->stmt))
1984             break;
1985           decl = OMP_CLAUSE_DECL (c);
1986           if (DECL_P (decl)
1987               && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
1988               && varpool_node::get_create (decl)->offloadable)
1989             break;
1990           if (DECL_P (decl))
1991             {
1992               if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
1993                   && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
1994                   && !COMPLETE_TYPE_P (TREE_TYPE (decl)))
1995                 {
1996                   tree new_decl = lookup_decl (decl, ctx);
1997                   TREE_TYPE (new_decl)
1998                     = remap_type (TREE_TYPE (decl), &ctx->cb);
1999                 }
2000               else if (DECL_SIZE (decl)
2001                        && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
2002                 {
2003                   tree decl2 = DECL_VALUE_EXPR (decl);
2004                   gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
2005                   decl2 = TREE_OPERAND (decl2, 0);
2006                   gcc_assert (DECL_P (decl2));
2007                   fixup_remapped_decl (decl2, ctx, false);
2008                   fixup_remapped_decl (decl, ctx, true);
2009                 }
2010               else
2011                 fixup_remapped_decl (decl, ctx, false);
2012             }
2013           break;
2014
2015         case OMP_CLAUSE_COPYPRIVATE:
2016         case OMP_CLAUSE_COPYIN:
2017         case OMP_CLAUSE_DEFAULT:
2018         case OMP_CLAUSE_IF:
2019         case OMP_CLAUSE_NUM_THREADS:
2020         case OMP_CLAUSE_NUM_TEAMS:
2021         case OMP_CLAUSE_THREAD_LIMIT:
2022         case OMP_CLAUSE_DEVICE:
2023         case OMP_CLAUSE_SCHEDULE:
2024         case OMP_CLAUSE_DIST_SCHEDULE:
2025         case OMP_CLAUSE_NOWAIT:
2026         case OMP_CLAUSE_ORDERED:
2027         case OMP_CLAUSE_COLLAPSE:
2028         case OMP_CLAUSE_UNTIED:
2029         case OMP_CLAUSE_FINAL:
2030         case OMP_CLAUSE_MERGEABLE:
2031         case OMP_CLAUSE_PROC_BIND:
2032         case OMP_CLAUSE_SAFELEN:
2033         case OMP_CLAUSE_ALIGNED:
2034         case OMP_CLAUSE_DEPEND:
2035         case OMP_CLAUSE__LOOPTEMP_:
2036         case OMP_CLAUSE_TO:
2037         case OMP_CLAUSE_FROM:
2038         case OMP_CLAUSE__CILK_FOR_COUNT_:
2039         case OMP_CLAUSE_ASYNC:
2040         case OMP_CLAUSE_WAIT:
2041         case OMP_CLAUSE_NUM_GANGS:
2042         case OMP_CLAUSE_NUM_WORKERS:
2043         case OMP_CLAUSE_VECTOR_LENGTH:
2044         case OMP_CLAUSE_GANG:
2045         case OMP_CLAUSE_WORKER:
2046         case OMP_CLAUSE_VECTOR:
2047           break;
2048
2049         case OMP_CLAUSE_DEVICE_RESIDENT:
2050         case OMP_CLAUSE_USE_DEVICE:
2051         case OMP_CLAUSE__CACHE_:
2052         case OMP_CLAUSE_INDEPENDENT:
2053         case OMP_CLAUSE_AUTO:
2054         case OMP_CLAUSE_SEQ:
2055           sorry ("Clause not supported yet");
2056           break;
2057
2058         default:
2059           gcc_unreachable ();
2060         }
2061     }
2062
2063   gcc_checking_assert (!scan_array_reductions
2064                        || !is_gimple_omp_oacc (ctx->stmt));
2065   if (scan_array_reductions)
2066     for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
2067       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
2068           && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2069         {
2070           scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
2071           scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
2072         }
2073       else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
2074                && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
2075         scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
2076       else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
2077                && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
2078         scan_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
2079 }
2080
2081 /* Create a new name for omp child function.  Returns an identifier.  If
2082    IS_CILK_FOR is true then the suffix for the child function is
2083    "_cilk_for_fn."  */
2084
2085 static tree
2086 create_omp_child_function_name (bool task_copy, bool is_cilk_for)
2087 {
2088   if (is_cilk_for)
2089     return clone_function_name (current_function_decl, "_cilk_for_fn");
2090   return clone_function_name (current_function_decl,
2091                               task_copy ? "_omp_cpyfn" : "_omp_fn");
2092 }
2093
2094 /* Returns the type of the induction variable for the child function for
2095    _Cilk_for and the types for _high and _low variables based on TYPE.  */
2096
2097 static tree
2098 cilk_for_check_loop_diff_type (tree type)
2099 {
2100   if (TYPE_PRECISION (type) <= TYPE_PRECISION (uint32_type_node))
2101     {
2102       if (TYPE_UNSIGNED (type))
2103         return uint32_type_node;
2104       else
2105         return integer_type_node;
2106     }
2107   else
2108     {
2109       if (TYPE_UNSIGNED (type))
2110         return uint64_type_node;
2111       else
2112         return long_long_integer_type_node;
2113     }
2114 }
2115
2116 /* Build a decl for the omp child function.  It'll not contain a body
2117    yet, just the bare decl.  */
2118
2119 static void
2120 create_omp_child_function (omp_context *ctx, bool task_copy)
2121 {
2122   tree decl, type, name, t;
2123
2124   tree cilk_for_count
2125     = (flag_cilkplus && gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
2126       ? find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2127                          OMP_CLAUSE__CILK_FOR_COUNT_) : NULL_TREE;
2128   tree cilk_var_type = NULL_TREE;
2129
2130   name = create_omp_child_function_name (task_copy,
2131                                          cilk_for_count != NULL_TREE);
2132   if (task_copy)
2133     type = build_function_type_list (void_type_node, ptr_type_node,
2134                                      ptr_type_node, NULL_TREE);
2135   else if (cilk_for_count)
2136     {
2137       type = TREE_TYPE (OMP_CLAUSE_OPERAND (cilk_for_count, 0));
2138       cilk_var_type = cilk_for_check_loop_diff_type (type);
2139       type = build_function_type_list (void_type_node, ptr_type_node,
2140                                        cilk_var_type, cilk_var_type, NULL_TREE);
2141     }
2142   else
2143     type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
2144
2145   decl = build_decl (gimple_location (ctx->stmt), FUNCTION_DECL, name, type);
2146
2147   gcc_checking_assert (!is_gimple_omp_oacc (ctx->stmt)
2148                        || !task_copy);
2149   if (!task_copy)
2150     ctx->cb.dst_fn = decl;
2151   else
2152     gimple_omp_task_set_copy_fn (ctx->stmt, decl);
2153
2154   TREE_STATIC (decl) = 1;
2155   TREE_USED (decl) = 1;
2156   DECL_ARTIFICIAL (decl) = 1;
2157   DECL_IGNORED_P (decl) = 0;
2158   TREE_PUBLIC (decl) = 0;
2159   DECL_UNINLINABLE (decl) = 1;
2160   DECL_EXTERNAL (decl) = 0;
2161   DECL_CONTEXT (decl) = NULL_TREE;
2162   DECL_INITIAL (decl) = make_node (BLOCK);
2163   if (cgraph_node::get (current_function_decl)->offloadable)
2164     cgraph_node::get_create (decl)->offloadable = 1;
2165   else
2166     {
2167       omp_context *octx;
2168       for (octx = ctx; octx; octx = octx->outer)
2169         if (is_gimple_omp_offloaded (octx->stmt))
2170           {
2171             cgraph_node::get_create (decl)->offloadable = 1;
2172 #ifdef ENABLE_OFFLOADING
2173             g->have_offload = true;
2174 #endif
2175             break;
2176           }
2177     }
2178
2179   t = build_decl (DECL_SOURCE_LOCATION (decl),
2180                   RESULT_DECL, NULL_TREE, void_type_node);
2181   DECL_ARTIFICIAL (t) = 1;
2182   DECL_IGNORED_P (t) = 1;
2183   DECL_CONTEXT (t) = decl;
2184   DECL_RESULT (decl) = t;
2185
2186   /* _Cilk_for's child function requires two extra parameters called
2187      __low and __high that are set the by Cilk runtime when it calls this
2188      function.  */
2189   if (cilk_for_count)
2190     {
2191       t = build_decl (DECL_SOURCE_LOCATION (decl),
2192                       PARM_DECL, get_identifier ("__high"), cilk_var_type);
2193       DECL_ARTIFICIAL (t) = 1;
2194       DECL_NAMELESS (t) = 1;
2195       DECL_ARG_TYPE (t) = ptr_type_node;
2196       DECL_CONTEXT (t) = current_function_decl;
2197       TREE_USED (t) = 1;
2198       DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
2199       DECL_ARGUMENTS (decl) = t;
2200
2201       t = build_decl (DECL_SOURCE_LOCATION (decl),
2202                       PARM_DECL, get_identifier ("__low"), cilk_var_type);
2203       DECL_ARTIFICIAL (t) = 1;
2204       DECL_NAMELESS (t) = 1;
2205       DECL_ARG_TYPE (t) = ptr_type_node;
2206       DECL_CONTEXT (t) = current_function_decl;
2207       TREE_USED (t) = 1;
2208       DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
2209       DECL_ARGUMENTS (decl) = t;
2210     }
2211
2212   tree data_name = get_identifier (".omp_data_i");
2213   t = build_decl (DECL_SOURCE_LOCATION (decl), PARM_DECL, data_name,
2214                   ptr_type_node);
2215   DECL_ARTIFICIAL (t) = 1;
2216   DECL_NAMELESS (t) = 1;
2217   DECL_ARG_TYPE (t) = ptr_type_node;
2218   DECL_CONTEXT (t) = current_function_decl;
2219   TREE_USED (t) = 1;
2220   if (cilk_for_count)
2221     DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
2222   DECL_ARGUMENTS (decl) = t;
2223   if (!task_copy)
2224     ctx->receiver_decl = t;
2225   else
2226     {
2227       t = build_decl (DECL_SOURCE_LOCATION (decl),
2228                       PARM_DECL, get_identifier (".omp_data_o"),
2229                       ptr_type_node);
2230       DECL_ARTIFICIAL (t) = 1;
2231       DECL_NAMELESS (t) = 1;
2232       DECL_ARG_TYPE (t) = ptr_type_node;
2233       DECL_CONTEXT (t) = current_function_decl;
2234       TREE_USED (t) = 1;
2235       TREE_ADDRESSABLE (t) = 1;
2236       DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
2237       DECL_ARGUMENTS (decl) = t;
2238     }
2239
2240   /* Allocate memory for the function structure.  The call to
2241      allocate_struct_function clobbers CFUN, so we need to restore
2242      it afterward.  */
2243   push_struct_function (decl);
2244   cfun->function_end_locus = gimple_location (ctx->stmt);
2245   pop_cfun ();
2246 }
2247
2248 /* Callback for walk_gimple_seq.  Check if combined parallel
2249    contains gimple_omp_for_combined_into_p OMP_FOR.  */
2250
2251 static tree
2252 find_combined_for (gimple_stmt_iterator *gsi_p,
2253                    bool *handled_ops_p,
2254                    struct walk_stmt_info *wi)
2255 {
2256   gimple stmt = gsi_stmt (*gsi_p);
2257
2258   *handled_ops_p = true;
2259   switch (gimple_code (stmt))
2260     {
2261     WALK_SUBSTMTS;
2262
2263     case GIMPLE_OMP_FOR:
2264       if (gimple_omp_for_combined_into_p (stmt)
2265           && gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR)
2266         {
2267           wi->info = stmt;
2268           return integer_zero_node;
2269         }
2270       break;
2271     default:
2272       break;
2273     }
2274   return NULL;
2275 }
2276
2277 /* Scan an OpenMP parallel directive.  */
2278
2279 static void
2280 scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
2281 {
2282   omp_context *ctx;
2283   tree name;
2284   gomp_parallel *stmt = as_a <gomp_parallel *> (gsi_stmt (*gsi));
2285
2286   /* Ignore parallel directives with empty bodies, unless there
2287      are copyin clauses.  */
2288   if (optimize > 0
2289       && empty_body_p (gimple_omp_body (stmt))
2290       && find_omp_clause (gimple_omp_parallel_clauses (stmt),
2291                           OMP_CLAUSE_COPYIN) == NULL)
2292     {
2293       gsi_replace (gsi, gimple_build_nop (), false);
2294       return;
2295     }
2296
2297   if (gimple_omp_parallel_combined_p (stmt))
2298     {
2299       struct walk_stmt_info wi;
2300
2301       memset (&wi, 0, sizeof (wi));
2302       wi.val_only = true;
2303       walk_gimple_seq (gimple_omp_body (stmt),
2304                        find_combined_for, NULL, &wi);
2305       if (wi.info)
2306         {
2307           gomp_for *for_stmt = as_a <gomp_for *> ((gimple) wi.info);
2308           struct omp_for_data fd;
2309           extract_omp_for_data (for_stmt, &fd, NULL);
2310           /* We need two temporaries with fd.loop.v type (istart/iend)
2311              and then (fd.collapse - 1) temporaries with the same
2312              type for count2 ... countN-1 vars if not constant.  */
2313           size_t count = 2, i;
2314           tree type = fd.iter_type;
2315           if (fd.collapse > 1
2316               && TREE_CODE (fd.loop.n2) != INTEGER_CST)
2317             count += fd.collapse - 1;
2318           for (i = 0; i < count; i++)
2319             {
2320               tree temp = create_tmp_var (type);
2321               tree c = build_omp_clause (UNKNOWN_LOCATION,
2322                                          OMP_CLAUSE__LOOPTEMP_);
2323               insert_decl_map (&outer_ctx->cb, temp, temp);
2324               OMP_CLAUSE_DECL (c) = temp;
2325               OMP_CLAUSE_CHAIN (c) = gimple_omp_parallel_clauses (stmt);
2326               gimple_omp_parallel_set_clauses (stmt, c);
2327             }
2328         }
2329     }
2330
2331   ctx = new_omp_context (stmt, outer_ctx);
2332   taskreg_contexts.safe_push (ctx);
2333   if (taskreg_nesting_level > 1)
2334     ctx->is_nested = true;
2335   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
2336   ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
2337   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
2338   name = create_tmp_var_name (".omp_data_s");
2339   name = build_decl (gimple_location (stmt),
2340                      TYPE_DECL, name, ctx->record_type);
2341   DECL_ARTIFICIAL (name) = 1;
2342   DECL_NAMELESS (name) = 1;
2343   TYPE_NAME (ctx->record_type) = name;
2344   create_omp_child_function (ctx, false);
2345   gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
2346
2347   scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
2348   scan_omp (gimple_omp_body_ptr (stmt), ctx);
2349
2350   if (TYPE_FIELDS (ctx->record_type) == NULL)
2351     ctx->record_type = ctx->receiver_decl = NULL;
2352 }
2353
2354 /* Scan an OpenMP task directive.  */
2355
2356 static void
2357 scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
2358 {
2359   omp_context *ctx;
2360   tree name, t;
2361   gomp_task *stmt = as_a <gomp_task *> (gsi_stmt (*gsi));
2362
2363   /* Ignore task directives with empty bodies.  */
2364   if (optimize > 0
2365       && empty_body_p (gimple_omp_body (stmt)))
2366     {
2367       gsi_replace (gsi, gimple_build_nop (), false);
2368       return;
2369     }
2370
2371   ctx = new_omp_context (stmt, outer_ctx);
2372   taskreg_contexts.safe_push (ctx);
2373   if (taskreg_nesting_level > 1)
2374     ctx->is_nested = true;
2375   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
2376   ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
2377   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
2378   name = create_tmp_var_name (".omp_data_s");
2379   name = build_decl (gimple_location (stmt),
2380                      TYPE_DECL, name, ctx->record_type);
2381   DECL_ARTIFICIAL (name) = 1;
2382   DECL_NAMELESS (name) = 1;
2383   TYPE_NAME (ctx->record_type) = name;
2384   create_omp_child_function (ctx, false);
2385   gimple_omp_task_set_child_fn (stmt, ctx->cb.dst_fn);
2386
2387   scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);
2388
2389   if (ctx->srecord_type)
2390     {
2391       name = create_tmp_var_name (".omp_data_a");
2392       name = build_decl (gimple_location (stmt),
2393                          TYPE_DECL, name, ctx->srecord_type);
2394       DECL_ARTIFICIAL (name) = 1;
2395       DECL_NAMELESS (name) = 1;
2396       TYPE_NAME (ctx->srecord_type) = name;
2397       create_omp_child_function (ctx, true);
2398     }
2399
2400   scan_omp (gimple_omp_body_ptr (stmt), ctx);
2401
2402   if (TYPE_FIELDS (ctx->record_type) == NULL)
2403     {
2404       ctx->record_type = ctx->receiver_decl = NULL;
2405       t = build_int_cst (long_integer_type_node, 0);
2406       gimple_omp_task_set_arg_size (stmt, t);
2407       t = build_int_cst (long_integer_type_node, 1);
2408       gimple_omp_task_set_arg_align (stmt, t);
2409     }
2410 }
2411
2412
2413 /* If any decls have been made addressable during scan_omp,
2414    adjust their fields if needed, and layout record types
2415    of parallel/task constructs.  */
2416
2417 static void
2418 finish_taskreg_scan (omp_context *ctx)
2419 {
2420   if (ctx->record_type == NULL_TREE)
2421     return;
2422
2423   /* If any task_shared_vars were needed, verify all
2424      OMP_CLAUSE_SHARED clauses on GIMPLE_OMP_{PARALLEL,TASK}
2425      statements if use_pointer_for_field hasn't changed
2426      because of that.  If it did, update field types now.  */
2427   if (task_shared_vars)
2428     {
2429       tree c;
2430
2431       for (c = gimple_omp_taskreg_clauses (ctx->stmt);
2432            c; c = OMP_CLAUSE_CHAIN (c))
2433         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED)
2434           {
2435             tree decl = OMP_CLAUSE_DECL (c);
2436
2437             /* Global variables don't need to be copied,
2438                the receiver side will use them directly.  */
2439             if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
2440               continue;
2441             if (!bitmap_bit_p (task_shared_vars, DECL_UID (decl))
2442                 || !use_pointer_for_field (decl, ctx))
2443               continue;
2444             tree field = lookup_field (decl, ctx);
2445             if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE
2446                 && TREE_TYPE (TREE_TYPE (field)) == TREE_TYPE (decl))
2447               continue;
2448             TREE_TYPE (field) = build_pointer_type (TREE_TYPE (decl));
2449             TREE_THIS_VOLATILE (field) = 0;
2450             DECL_USER_ALIGN (field) = 0;
2451             DECL_ALIGN (field) = TYPE_ALIGN (TREE_TYPE (field));
2452             if (TYPE_ALIGN (ctx->record_type) < DECL_ALIGN (field))
2453               TYPE_ALIGN (ctx->record_type) = DECL_ALIGN (field);
2454             if (ctx->srecord_type)
2455               {
2456                 tree sfield = lookup_sfield (decl, ctx);
2457                 TREE_TYPE (sfield) = TREE_TYPE (field);
2458                 TREE_THIS_VOLATILE (sfield) = 0;
2459                 DECL_USER_ALIGN (sfield) = 0;
2460                 DECL_ALIGN (sfield) = DECL_ALIGN (field);
2461                 if (TYPE_ALIGN (ctx->srecord_type) < DECL_ALIGN (sfield))
2462                   TYPE_ALIGN (ctx->srecord_type) = DECL_ALIGN (sfield);
2463               }
2464           }
2465     }
2466
2467   if (gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
2468     {
2469       layout_type (ctx->record_type);
2470       fixup_child_record_type (ctx);
2471     }
2472   else
2473     {
2474       location_t loc = gimple_location (ctx->stmt);
2475       tree *p, vla_fields = NULL_TREE, *q = &vla_fields;
2476       /* Move VLA fields to the end.  */
2477       p = &TYPE_FIELDS (ctx->record_type);
2478       while (*p)
2479         if (!TYPE_SIZE_UNIT (TREE_TYPE (*p))
2480             || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p))))
2481           {
2482             *q = *p;
2483             *p = TREE_CHAIN (*p);
2484             TREE_CHAIN (*q) = NULL_TREE;
2485             q = &TREE_CHAIN (*q);
2486           }
2487         else
2488           p = &DECL_CHAIN (*p);
2489       *p = vla_fields;
2490       layout_type (ctx->record_type);
2491       fixup_child_record_type (ctx);
2492       if (ctx->srecord_type)
2493         layout_type (ctx->srecord_type);
2494       tree t = fold_convert_loc (loc, long_integer_type_node,
2495                                  TYPE_SIZE_UNIT (ctx->record_type));
2496       gimple_omp_task_set_arg_size (ctx->stmt, t);
2497       t = build_int_cst (long_integer_type_node,
2498                          TYPE_ALIGN_UNIT (ctx->record_type));
2499       gimple_omp_task_set_arg_align (ctx->stmt, t);
2500     }
2501 }
2502
2503
2504 static omp_context *
2505 enclosing_target_ctx (omp_context *ctx)
2506 {
2507   while (ctx != NULL
2508          && gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET)
2509     ctx = ctx->outer;
2510   gcc_assert (ctx != NULL);
2511   return ctx;
2512 }
2513
2514 static bool
2515 oacc_loop_or_target_p (gimple stmt)
2516 {
2517   enum gimple_code outer_type = gimple_code (stmt);
2518   return ((outer_type == GIMPLE_OMP_TARGET
2519            && ((gimple_omp_target_kind (stmt)
2520                 == GF_OMP_TARGET_KIND_OACC_PARALLEL)
2521                || (gimple_omp_target_kind (stmt)
2522                    == GF_OMP_TARGET_KIND_OACC_KERNELS)))
2523           || (outer_type == GIMPLE_OMP_FOR
2524               && gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_OACC_LOOP));
2525 }
2526
2527 /* Scan a GIMPLE_OMP_FOR.  */
2528
2529 static void
2530 scan_omp_for (gomp_for *stmt, omp_context *outer_ctx)
2531 {
2532   enum gimple_code outer_type = GIMPLE_ERROR_MARK;
2533   omp_context *ctx;
2534   size_t i;
2535   tree clauses = gimple_omp_for_clauses (stmt);
2536
2537   if (outer_ctx)
2538     outer_type = gimple_code (outer_ctx->stmt);
2539
2540   ctx = new_omp_context (stmt, outer_ctx);
2541
2542   if (is_gimple_omp_oacc (stmt))
2543     {
2544       if (outer_ctx && outer_type == GIMPLE_OMP_FOR)
2545         ctx->gwv_this = outer_ctx->gwv_this;
2546       for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
2547         {
2548           int val;
2549           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_GANG)
2550             val = MASK_GANG;
2551           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_WORKER)
2552             val = MASK_WORKER;
2553           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_VECTOR)
2554             val = MASK_VECTOR;
2555           else
2556             continue;
2557           ctx->gwv_this |= val;
2558           if (!outer_ctx)
2559             {
2560               /* Skip; not nested inside a region.  */
2561               continue;
2562             }
2563           if (!oacc_loop_or_target_p (outer_ctx->stmt))
2564             {
2565               /* Skip; not nested inside an OpenACC region.  */
2566               continue;
2567             }
2568           if (outer_type == GIMPLE_OMP_FOR)
2569             outer_ctx->gwv_below |= val;
2570           if (OMP_CLAUSE_OPERAND (c, 0) != NULL_TREE)
2571             {
2572               omp_context *enclosing = enclosing_target_ctx (outer_ctx);
2573               if (gimple_omp_target_kind (enclosing->stmt)
2574                   == GF_OMP_TARGET_KIND_OACC_PARALLEL)
2575                 error_at (gimple_location (stmt),
2576                           "no arguments allowed to gang, worker and vector clauses inside parallel");
2577             }
2578         }
2579     }
2580
2581   scan_sharing_clauses (clauses, ctx);
2582
2583   scan_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
2584   for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
2585     {
2586       scan_omp_op (gimple_omp_for_index_ptr (stmt, i), ctx);
2587       scan_omp_op (gimple_omp_for_initial_ptr (stmt, i), ctx);
2588       scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
2589       scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
2590     }
2591   scan_omp (gimple_omp_body_ptr (stmt), ctx);
2592
2593   if (is_gimple_omp_oacc (stmt))
2594     {
2595       if (ctx->gwv_this & ctx->gwv_below)
2596         error_at (gimple_location (stmt),
2597                   "gang, worker and vector may occur only once in a loop nest");
2598       else if (ctx->gwv_below != 0
2599                && ctx->gwv_this > ctx->gwv_below)
2600         error_at (gimple_location (stmt),
2601                   "gang, worker and vector must occur in this order in a loop nest");
2602       if (outer_ctx && outer_type == GIMPLE_OMP_FOR)
2603         outer_ctx->gwv_below |= ctx->gwv_below;
2604     }
2605 }
2606
2607 /* Scan an OpenMP sections directive.  */
2608
2609 static void
2610 scan_omp_sections (gomp_sections *stmt, omp_context *outer_ctx)
2611 {
2612   omp_context *ctx;
2613
2614   ctx = new_omp_context (stmt, outer_ctx);
2615   scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
2616   scan_omp (gimple_omp_body_ptr (stmt), ctx);
2617 }
2618
2619 /* Scan an OpenMP single directive.  */
2620
2621 static void
2622 scan_omp_single (gomp_single *stmt, omp_context *outer_ctx)
2623 {
2624   omp_context *ctx;
2625   tree name;
2626
2627   ctx = new_omp_context (stmt, outer_ctx);
2628   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
2629   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
2630   name = create_tmp_var_name (".omp_copy_s");
2631   name = build_decl (gimple_location (stmt),
2632                      TYPE_DECL, name, ctx->record_type);
2633   TYPE_NAME (ctx->record_type) = name;
2634
2635   scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
2636   scan_omp (gimple_omp_body_ptr (stmt), ctx);
2637
2638   if (TYPE_FIELDS (ctx->record_type) == NULL)
2639     ctx->record_type = NULL;
2640   else
2641     layout_type (ctx->record_type);
2642 }
2643
2644 /* Scan a GIMPLE_OMP_TARGET.  */
2645
2646 static void
2647 scan_omp_target (gomp_target *stmt, omp_context *outer_ctx)
2648 {
2649   omp_context *ctx;
2650   tree name;
2651   bool offloaded = is_gimple_omp_offloaded (stmt);
2652   tree clauses = gimple_omp_target_clauses (stmt);
2653
2654   ctx = new_omp_context (stmt, outer_ctx);
2655   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
2656   ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
2657   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
2658   name = create_tmp_var_name (".omp_data_t");
2659   name = build_decl (gimple_location (stmt),
2660                      TYPE_DECL, name, ctx->record_type);
2661   DECL_ARTIFICIAL (name) = 1;
2662   DECL_NAMELESS (name) = 1;
2663   TYPE_NAME (ctx->record_type) = name;
2664   if (offloaded)
2665     {
2666       if (is_gimple_omp_oacc (stmt))
2667         ctx->reduction_map = splay_tree_new (splay_tree_compare_pointers,
2668                                              0, 0);
2669
2670       create_omp_child_function (ctx, false);
2671       gimple_omp_target_set_child_fn (stmt, ctx->cb.dst_fn);
2672     }
2673
2674   if (is_gimple_omp_oacc (stmt))
2675     {
2676       for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
2677         {
2678           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_GANGS)
2679             ctx->gwv_this |= MASK_GANG;
2680           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_WORKERS)
2681             ctx->gwv_this |= MASK_WORKER;
2682           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_VECTOR_LENGTH)
2683             ctx->gwv_this |= MASK_VECTOR;
2684         }
2685     }
2686
2687   scan_sharing_clauses (clauses, ctx);
2688   scan_omp (gimple_omp_body_ptr (stmt), ctx);
2689
2690   if (TYPE_FIELDS (ctx->record_type) == NULL)
2691     ctx->record_type = ctx->receiver_decl = NULL;
2692   else
2693     {
2694       TYPE_FIELDS (ctx->record_type)
2695         = nreverse (TYPE_FIELDS (ctx->record_type));
2696 #ifdef ENABLE_CHECKING
2697       tree field;
2698       unsigned int align = DECL_ALIGN (TYPE_FIELDS (ctx->record_type));
2699       for (field = TYPE_FIELDS (ctx->record_type);
2700            field;
2701            field = DECL_CHAIN (field))
2702         gcc_assert (DECL_ALIGN (field) == align);
2703 #endif
2704       layout_type (ctx->record_type);
2705       if (offloaded)
2706         fixup_child_record_type (ctx);
2707     }
2708 }
2709
2710 /* Scan an OpenMP teams directive.  */
2711
2712 static void
2713 scan_omp_teams (gomp_teams *stmt, omp_context *outer_ctx)
2714 {
2715   omp_context *ctx = new_omp_context (stmt, outer_ctx);
2716   scan_sharing_clauses (gimple_omp_teams_clauses (stmt), ctx);
2717   scan_omp (gimple_omp_body_ptr (stmt), ctx);
2718 }
2719
2720 /* Check nesting restrictions.  */
2721 static bool
2722 check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
2723 {
2724   /* No nesting of non-OpenACC STMT (that is, an OpenMP one, or a GOMP builtin)
2725      inside an OpenACC CTX.  */
2726   if (!(is_gimple_omp (stmt)
2727         && is_gimple_omp_oacc (stmt)))
2728     {
2729       for (omp_context *ctx_ = ctx; ctx_ != NULL; ctx_ = ctx_->outer)
2730         if (is_gimple_omp (ctx_->stmt)
2731             && is_gimple_omp_oacc (ctx_->stmt))
2732           {
2733             error_at (gimple_location (stmt),
2734                       "non-OpenACC construct inside of OpenACC region");
2735             return false;
2736           }
2737     }
2738
2739   if (ctx != NULL)
2740     {
2741       if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
2742           && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
2743         {
2744           error_at (gimple_location (stmt),
2745                     "OpenMP constructs may not be nested inside simd region");
2746           return false;
2747         }
2748       else if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
2749         {
2750           if ((gimple_code (stmt) != GIMPLE_OMP_FOR
2751                || (gimple_omp_for_kind (stmt)
2752                    != GF_OMP_FOR_KIND_DISTRIBUTE))
2753               && gimple_code (stmt) != GIMPLE_OMP_PARALLEL)
2754             {
2755               error_at (gimple_location (stmt),
2756                         "only distribute or parallel constructs are allowed to "
2757                         "be closely nested inside teams construct");
2758               return false;
2759             }
2760         }
2761     }
2762   switch (gimple_code (stmt))
2763     {
2764     case GIMPLE_OMP_FOR:
2765       if (gimple_omp_for_kind (stmt) & GF_OMP_FOR_SIMD)
2766         return true;
2767       if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_DISTRIBUTE)
2768         {
2769           if (ctx != NULL && gimple_code (ctx->stmt) != GIMPLE_OMP_TEAMS)
2770             {
2771               error_at (gimple_location (stmt),
2772                         "distribute construct must be closely nested inside "
2773                         "teams construct");
2774               return false;
2775             }
2776           return true;
2777         }
2778       /* FALLTHRU */
2779     case GIMPLE_CALL:
2780       if (is_gimple_call (stmt)
2781           && (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2782               == BUILT_IN_GOMP_CANCEL
2783               || DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2784                  == BUILT_IN_GOMP_CANCELLATION_POINT))
2785         {
2786           const char *bad = NULL;
2787           const char *kind = NULL;
2788           if (ctx == NULL)
2789             {
2790               error_at (gimple_location (stmt), "orphaned %qs construct",
2791                         DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2792                         == BUILT_IN_GOMP_CANCEL
2793                         ? "#pragma omp cancel"
2794                         : "#pragma omp cancellation point");
2795               return false;
2796             }
2797           switch (tree_fits_shwi_p (gimple_call_arg (stmt, 0))
2798                   ? tree_to_shwi (gimple_call_arg (stmt, 0))
2799                   : 0)
2800             {
2801             case 1:
2802               if (gimple_code (ctx->stmt) != GIMPLE_OMP_PARALLEL)
2803                 bad = "#pragma omp parallel";
2804               else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2805                        == BUILT_IN_GOMP_CANCEL
2806                        && !integer_zerop (gimple_call_arg (stmt, 1)))
2807                 ctx->cancellable = true;
2808               kind = "parallel";
2809               break;
2810             case 2:
2811               if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
2812                   || gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR)
2813                 bad = "#pragma omp for";
2814               else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2815                        == BUILT_IN_GOMP_CANCEL
2816                        && !integer_zerop (gimple_call_arg (stmt, 1)))
2817                 {
2818                   ctx->cancellable = true;
2819                   if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
2820                                        OMP_CLAUSE_NOWAIT))
2821                     warning_at (gimple_location (stmt), 0,
2822                                 "%<#pragma omp cancel for%> inside "
2823                                 "%<nowait%> for construct");
2824                   if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
2825                                        OMP_CLAUSE_ORDERED))
2826                     warning_at (gimple_location (stmt), 0,
2827                                 "%<#pragma omp cancel for%> inside "
2828                                 "%<ordered%> for construct");
2829                 }
2830               kind = "for";
2831               break;
2832             case 4:
2833               if (gimple_code (ctx->stmt) != GIMPLE_OMP_SECTIONS
2834                   && gimple_code (ctx->stmt) != GIMPLE_OMP_SECTION)
2835                 bad = "#pragma omp sections";
2836               else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2837                        == BUILT_IN_GOMP_CANCEL
2838                        && !integer_zerop (gimple_call_arg (stmt, 1)))
2839                 {
2840                   if (gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS)
2841                     {
2842                       ctx->cancellable = true;
2843                       if (find_omp_clause (gimple_omp_sections_clauses
2844                                                                 (ctx->stmt),
2845                                            OMP_CLAUSE_NOWAIT))
2846                         warning_at (gimple_location (stmt), 0,
2847                                     "%<#pragma omp cancel sections%> inside "
2848                                     "%<nowait%> sections construct");
2849                     }
2850                   else
2851                     {
2852                       gcc_assert (ctx->outer
2853                                   && gimple_code (ctx->outer->stmt)
2854                                      == GIMPLE_OMP_SECTIONS);
2855                       ctx->outer->cancellable = true;
2856                       if (find_omp_clause (gimple_omp_sections_clauses
2857                                                         (ctx->outer->stmt),
2858                                            OMP_CLAUSE_NOWAIT))
2859                         warning_at (gimple_location (stmt), 0,
2860                                     "%<#pragma omp cancel sections%> inside "
2861                                     "%<nowait%> sections construct");
2862                     }
2863                 }
2864               kind = "sections";
2865               break;
2866             case 8:
2867               if (gimple_code (ctx->stmt) != GIMPLE_OMP_TASK)
2868                 bad = "#pragma omp task";
2869               else
2870                 ctx->cancellable = true;
2871               kind = "taskgroup";
2872               break;
2873             default:
2874               error_at (gimple_location (stmt), "invalid arguments");
2875               return false;
2876             }
2877           if (bad)
2878             {
2879               error_at (gimple_location (stmt),
2880                         "%<%s %s%> construct not closely nested inside of %qs",
2881                         DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2882                         == BUILT_IN_GOMP_CANCEL
2883                         ? "#pragma omp cancel"
2884                         : "#pragma omp cancellation point", kind, bad);
2885               return false;
2886             }
2887         }
2888       /* FALLTHRU */
2889     case GIMPLE_OMP_SECTIONS:
2890     case GIMPLE_OMP_SINGLE:
2891       for (; ctx != NULL; ctx = ctx->outer)
2892         switch (gimple_code (ctx->stmt))
2893           {
2894           case GIMPLE_OMP_FOR:
2895           case GIMPLE_OMP_SECTIONS:
2896           case GIMPLE_OMP_SINGLE:
2897           case GIMPLE_OMP_ORDERED:
2898           case GIMPLE_OMP_MASTER:
2899           case GIMPLE_OMP_TASK:
2900           case GIMPLE_OMP_CRITICAL:
2901             if (is_gimple_call (stmt))
2902               {
2903                 if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2904                     != BUILT_IN_GOMP_BARRIER)
2905                   return true;
2906                 error_at (gimple_location (stmt),
2907                           "barrier region may not be closely nested inside "
2908                           "of work-sharing, critical, ordered, master or "
2909                           "explicit task region");
2910                 return false;
2911               }
2912             error_at (gimple_location (stmt),
2913                       "work-sharing region may not be closely nested inside "
2914                       "of work-sharing, critical, ordered, master or explicit "
2915                       "task region");
2916             return false;
2917           case GIMPLE_OMP_PARALLEL:
2918             return true;
2919           default:
2920             break;
2921           }
2922       break;
2923     case GIMPLE_OMP_MASTER:
2924       for (; ctx != NULL; ctx = ctx->outer)
2925         switch (gimple_code (ctx->stmt))
2926           {
2927           case GIMPLE_OMP_FOR:
2928           case GIMPLE_OMP_SECTIONS:
2929           case GIMPLE_OMP_SINGLE:
2930           case GIMPLE_OMP_TASK:
2931             error_at (gimple_location (stmt),
2932                       "master region may not be closely nested inside "
2933                       "of work-sharing or explicit task region");
2934             return false;
2935           case GIMPLE_OMP_PARALLEL:
2936             return true;
2937           default:
2938             break;
2939           }
2940       break;
2941     case GIMPLE_OMP_ORDERED:
2942       for (; ctx != NULL; ctx = ctx->outer)
2943         switch (gimple_code (ctx->stmt))
2944           {
2945           case GIMPLE_OMP_CRITICAL:
2946           case GIMPLE_OMP_TASK:
2947             error_at (gimple_location (stmt),
2948                       "ordered region may not be closely nested inside "
2949                       "of critical or explicit task region");
2950             return false;
2951           case GIMPLE_OMP_FOR:
2952             if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
2953                                  OMP_CLAUSE_ORDERED) == NULL)
2954               {
2955                 error_at (gimple_location (stmt),
2956                           "ordered region must be closely nested inside "
2957                           "a loop region with an ordered clause");
2958                 return false;
2959               }
2960             return true;
2961           case GIMPLE_OMP_PARALLEL:
2962             error_at (gimple_location (stmt),
2963                       "ordered region must be closely nested inside "
2964                       "a loop region with an ordered clause");
2965             return false;
2966           default:
2967             break;
2968           }
2969       break;
2970     case GIMPLE_OMP_CRITICAL:
2971       {
2972         tree this_stmt_name
2973           = gimple_omp_critical_name (as_a <gomp_critical *> (stmt));
2974         for (; ctx != NULL; ctx = ctx->outer)
2975           if (gomp_critical *other_crit
2976                 = dyn_cast <gomp_critical *> (ctx->stmt))
2977             if (this_stmt_name == gimple_omp_critical_name (other_crit))
2978               {
2979                 error_at (gimple_location (stmt),
2980                           "critical region may not be nested inside a critical "
2981                           "region with the same name");
2982                 return false;
2983               }
2984       }
2985       break;
2986     case GIMPLE_OMP_TEAMS:
2987       if (ctx == NULL
2988           || gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET
2989           || gimple_omp_target_kind (ctx->stmt) != GF_OMP_TARGET_KIND_REGION)
2990         {
2991           error_at (gimple_location (stmt),
2992                     "teams construct not closely nested inside of target "
2993                     "region");
2994           return false;
2995         }
2996       break;
2997     case GIMPLE_OMP_TARGET:
2998       for (; ctx != NULL; ctx = ctx->outer)
2999         {
3000           if (gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET)
3001             {
3002               if (is_gimple_omp (stmt)
3003                   && is_gimple_omp_oacc (stmt)
3004                   && is_gimple_omp (ctx->stmt))
3005                 {
3006                   error_at (gimple_location (stmt),
3007                             "OpenACC construct inside of non-OpenACC region");
3008                   return false;
3009                 }
3010               continue;
3011             }
3012
3013           const char *stmt_name, *ctx_stmt_name;
3014           switch (gimple_omp_target_kind (stmt))
3015             {
3016             case GF_OMP_TARGET_KIND_REGION: stmt_name = "target"; break;
3017             case GF_OMP_TARGET_KIND_DATA: stmt_name = "target data"; break;
3018             case GF_OMP_TARGET_KIND_UPDATE: stmt_name = "target update"; break;
3019             case GF_OMP_TARGET_KIND_OACC_PARALLEL: stmt_name = "parallel"; break;
3020             case GF_OMP_TARGET_KIND_OACC_KERNELS: stmt_name = "kernels"; break;
3021             case GF_OMP_TARGET_KIND_OACC_DATA: stmt_name = "data"; break;
3022             case GF_OMP_TARGET_KIND_OACC_UPDATE: stmt_name = "update"; break;
3023             case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA: stmt_name = "enter/exit data"; break;
3024             default: gcc_unreachable ();
3025             }
3026           switch (gimple_omp_target_kind (ctx->stmt))
3027             {
3028             case GF_OMP_TARGET_KIND_REGION: ctx_stmt_name = "target"; break;
3029             case GF_OMP_TARGET_KIND_DATA: ctx_stmt_name = "target data"; break;
3030             case GF_OMP_TARGET_KIND_OACC_PARALLEL: ctx_stmt_name = "parallel"; break;
3031             case GF_OMP_TARGET_KIND_OACC_KERNELS: ctx_stmt_name = "kernels"; break;
3032             case GF_OMP_TARGET_KIND_OACC_DATA: ctx_stmt_name = "data"; break;
3033             default: gcc_unreachable ();
3034             }
3035
3036           /* OpenACC/OpenMP mismatch?  */
3037           if (is_gimple_omp_oacc (stmt)
3038               != is_gimple_omp_oacc (ctx->stmt))
3039             {
3040               error_at (gimple_location (stmt),
3041                         "%s %s construct inside of %s %s region",
3042                         (is_gimple_omp_oacc (stmt)
3043                          ? "OpenACC" : "OpenMP"), stmt_name,
3044                         (is_gimple_omp_oacc (ctx->stmt)
3045                          ? "OpenACC" : "OpenMP"), ctx_stmt_name);
3046               return false;
3047             }
3048           if (is_gimple_omp_offloaded (ctx->stmt))
3049             {
3050               /* No GIMPLE_OMP_TARGET inside offloaded OpenACC CTX.  */
3051               if (is_gimple_omp_oacc (ctx->stmt))
3052                 {
3053                   error_at (gimple_location (stmt),
3054                             "%s construct inside of %s region",
3055                             stmt_name, ctx_stmt_name);
3056                   return false;
3057                 }
3058               else
3059                 {
3060                   gcc_checking_assert (!is_gimple_omp_oacc (stmt));
3061                   warning_at (gimple_location (stmt), 0,
3062                               "%s construct inside of %s region",
3063                               stmt_name, ctx_stmt_name);
3064                 }
3065             }
3066         }
3067       break;
3068     default:
3069       break;
3070     }
3071   return true;
3072 }
3073
3074
3075 /* Helper function scan_omp.
3076
3077    Callback for walk_tree or operators in walk_gimple_stmt used to
3078    scan for OMP directives in TP.  */
3079
3080 static tree
3081 scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
3082 {
3083   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
3084   omp_context *ctx = (omp_context *) wi->info;
3085   tree t = *tp;
3086
3087   switch (TREE_CODE (t))
3088     {
3089     case VAR_DECL:
3090     case PARM_DECL:
3091     case LABEL_DECL:
3092     case RESULT_DECL:
3093       if (ctx)
3094         *tp = remap_decl (t, &ctx->cb);
3095       break;
3096
3097     default:
3098       if (ctx && TYPE_P (t))
3099         *tp = remap_type (t, &ctx->cb);
3100       else if (!DECL_P (t))
3101         {
3102           *walk_subtrees = 1;
3103           if (ctx)
3104             {
3105               tree tem = remap_type (TREE_TYPE (t), &ctx->cb);
3106               if (tem != TREE_TYPE (t))
3107                 {
3108                   if (TREE_CODE (t) == INTEGER_CST)
3109                     *tp = wide_int_to_tree (tem, t);
3110                   else
3111                     TREE_TYPE (t) = tem;
3112                 }
3113             }
3114         }
3115       break;
3116     }
3117
3118   return NULL_TREE;
3119 }
3120
3121 /* Return true if FNDECL is a setjmp or a longjmp.  */
3122
3123 static bool
3124 setjmp_or_longjmp_p (const_tree fndecl)
3125 {
3126   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
3127       && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SETJMP
3128           || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LONGJMP))
3129     return true;
3130
3131   tree declname = DECL_NAME (fndecl);
3132   if (!declname)
3133     return false;
3134   const char *name = IDENTIFIER_POINTER (declname);
3135   return !strcmp (name, "setjmp") || !strcmp (name, "longjmp");
3136 }
3137
3138
3139 /* Helper function for scan_omp.
3140
3141    Callback for walk_gimple_stmt used to scan for OMP directives in
3142    the current statement in GSI.  */
3143
3144 static tree
3145 scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
3146                  struct walk_stmt_info *wi)
3147 {
3148   gimple stmt = gsi_stmt (*gsi);
3149   omp_context *ctx = (omp_context *) wi->info;
3150
3151   if (gimple_has_location (stmt))
3152     input_location = gimple_location (stmt);
3153
3154   /* Check the nesting restrictions.  */
3155   bool remove = false;
3156   if (is_gimple_omp (stmt))
3157     remove = !check_omp_nesting_restrictions (stmt, ctx);
3158   else if (is_gimple_call (stmt))
3159     {
3160       tree fndecl = gimple_call_fndecl (stmt);
3161       if (fndecl)
3162         {
3163           if (setjmp_or_longjmp_p (fndecl)
3164               && ctx
3165               && gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
3166               && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
3167             {
3168               remove = true;
3169               error_at (gimple_location (stmt),
3170                         "setjmp/longjmp inside simd construct");
3171             }
3172           else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3173             switch (DECL_FUNCTION_CODE (fndecl))
3174               {
3175               case BUILT_IN_GOMP_BARRIER:
3176               case BUILT_IN_GOMP_CANCEL:
3177               case BUILT_IN_GOMP_CANCELLATION_POINT:
3178               case BUILT_IN_GOMP_TASKYIELD:
3179               case BUILT_IN_GOMP_TASKWAIT:
3180               case BUILT_IN_GOMP_TASKGROUP_START:
3181               case BUILT_IN_GOMP_TASKGROUP_END:
3182                 remove = !check_omp_nesting_restrictions (stmt, ctx);
3183                 break;
3184               default:
3185                 break;
3186               }
3187         }
3188     }
3189   if (remove)
3190     {
3191       stmt = gimple_build_nop ();
3192       gsi_replace (gsi, stmt, false);
3193     }
3194
3195   *handled_ops_p = true;
3196
3197   switch (gimple_code (stmt))
3198     {
3199     case GIMPLE_OMP_PARALLEL:
3200       taskreg_nesting_level++;
3201       scan_omp_parallel (gsi, ctx);
3202       taskreg_nesting_level--;
3203       break;
3204
3205     case GIMPLE_OMP_TASK:
3206       taskreg_nesting_level++;
3207       scan_omp_task (gsi, ctx);
3208       taskreg_nesting_level--;
3209       break;
3210
3211     case GIMPLE_OMP_FOR:
3212       scan_omp_for (as_a <gomp_for *> (stmt), ctx);
3213       break;
3214
3215     case GIMPLE_OMP_SECTIONS:
3216       scan_omp_sections (as_a <gomp_sections *> (stmt), ctx);
3217       break;
3218
3219     case GIMPLE_OMP_SINGLE:
3220       scan_omp_single (as_a <gomp_single *> (stmt), ctx);
3221       break;
3222
3223     case GIMPLE_OMP_SECTION:
3224     case GIMPLE_OMP_MASTER:
3225     case GIMPLE_OMP_TASKGROUP:
3226     case GIMPLE_OMP_ORDERED:
3227     case GIMPLE_OMP_CRITICAL:
3228       ctx = new_omp_context (stmt, ctx);
3229       scan_omp (gimple_omp_body_ptr (stmt), ctx);
3230       break;
3231
3232     case GIMPLE_OMP_TARGET:
3233       scan_omp_target (as_a <gomp_target *> (stmt), ctx);
3234       break;
3235
3236     case GIMPLE_OMP_TEAMS:
3237       scan_omp_teams (as_a <gomp_teams *> (stmt), ctx);
3238       break;
3239
3240     case GIMPLE_BIND:
3241       {
3242         tree var;
3243
3244         *handled_ops_p = false;
3245         if (ctx)
3246           for (var = gimple_bind_vars (as_a <gbind *> (stmt));
3247                var ;
3248                var = DECL_CHAIN (var))
3249             insert_decl_map (&ctx->cb, var, var);
3250       }
3251       break;
3252     default:
3253       *handled_ops_p = false;
3254       break;
3255     }
3256
3257   return NULL_TREE;
3258 }
3259
3260
3261 /* Scan all the statements starting at the current statement.  CTX
3262    contains context information about the OMP directives and
3263    clauses found during the scan.  */
3264
3265 static void
3266 scan_omp (gimple_seq *body_p, omp_context *ctx)
3267 {
3268   location_t saved_location;
3269   struct walk_stmt_info wi;
3270
3271   memset (&wi, 0, sizeof (wi));
3272   wi.info = ctx;
3273   wi.want_locations = true;
3274
3275   saved_location = input_location;
3276   walk_gimple_seq_mod (body_p, scan_omp_1_stmt, scan_omp_1_op, &wi);
3277   input_location = saved_location;
3278 }
3279 \f
3280 /* Re-gimplification and code generation routines.  */
3281
3282 /* Build a call to GOMP_barrier.  */
3283
3284 static gimple
3285 build_omp_barrier (tree lhs)
3286 {
3287   tree fndecl = builtin_decl_explicit (lhs ? BUILT_IN_GOMP_BARRIER_CANCEL
3288                                            : BUILT_IN_GOMP_BARRIER);
3289   gcall *g = gimple_build_call (fndecl, 0);
3290   if (lhs)
3291     gimple_call_set_lhs (g, lhs);
3292   return g;
3293 }
3294
3295 /* If a context was created for STMT when it was scanned, return it.  */
3296
3297 static omp_context *
3298 maybe_lookup_ctx (gimple stmt)
3299 {
3300   splay_tree_node n;
3301   n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
3302   return n ? (omp_context *) n->value : NULL;
3303 }
3304
3305
3306 /* Find the mapping for DECL in CTX or the immediately enclosing
3307    context that has a mapping for DECL.
3308
3309    If CTX is a nested parallel directive, we may have to use the decl
3310    mappings created in CTX's parent context.  Suppose that we have the
3311    following parallel nesting (variable UIDs showed for clarity):
3312
3313         iD.1562 = 0;
3314         #omp parallel shared(iD.1562)           -> outer parallel
3315           iD.1562 = iD.1562 + 1;
3316
3317           #omp parallel shared (iD.1562)        -> inner parallel
3318              iD.1562 = iD.1562 - 1;
3319
3320    Each parallel structure will create a distinct .omp_data_s structure
3321    for copying iD.1562 in/out of the directive:
3322
3323         outer parallel          .omp_data_s.1.i -> iD.1562
3324         inner parallel          .omp_data_s.2.i -> iD.1562
3325
3326    A shared variable mapping will produce a copy-out operation before
3327    the parallel directive and a copy-in operation after it.  So, in
3328    this case we would have:
3329
3330         iD.1562 = 0;
3331         .omp_data_o.1.i = iD.1562;
3332         #omp parallel shared(iD.1562)           -> outer parallel
3333           .omp_data_i.1 = &.omp_data_o.1
3334           .omp_data_i.1->i = .omp_data_i.1->i + 1;
3335
3336           .omp_data_o.2.i = iD.1562;            -> **
3337           #omp parallel shared(iD.1562)         -> inner parallel
3338             .omp_data_i.2 = &.omp_data_o.2
3339             .omp_data_i.2->i = .omp_data_i.2->i - 1;
3340
3341
3342     ** This is a problem.  The symbol iD.1562 cannot be referenced
3343        inside the body of the outer parallel region.  But since we are
3344        emitting this copy operation while expanding the inner parallel
3345        directive, we need to access the CTX structure of the outer
3346        parallel directive to get the correct mapping:
3347
3348           .omp_data_o.2.i = .omp_data_i.1->i
3349
3350     Since there may be other workshare or parallel directives enclosing
3351     the parallel directive, it may be necessary to walk up the context
3352     parent chain.  This is not a problem in general because nested
3353     parallelism happens only rarely.  */
3354
3355 static tree
3356 lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
3357 {
3358   tree t;
3359   omp_context *up;
3360
3361   for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
3362     t = maybe_lookup_decl (decl, up);
3363
3364   gcc_assert (!ctx->is_nested || t || is_global_var (decl));
3365
3366   return t ? t : decl;
3367 }
3368
3369
3370 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
3371    in outer contexts.  */
3372
3373 static tree
3374 maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
3375 {
3376   tree t = NULL;
3377   omp_context *up;
3378
3379   for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
3380     t = maybe_lookup_decl (decl, up);
3381
3382   return t ? t : decl;
3383 }
3384
3385
3386 /* Construct the initialization value for reduction CLAUSE.  */
3387
3388 tree
3389 omp_reduction_init (tree clause, tree type)
3390 {
3391   location_t loc = OMP_CLAUSE_LOCATION (clause);
3392   switch (OMP_CLAUSE_REDUCTION_CODE (clause))
3393     {
3394     case PLUS_EXPR:
3395     case MINUS_EXPR:
3396     case BIT_IOR_EXPR:
3397     case BIT_XOR_EXPR:
3398     case TRUTH_OR_EXPR:
3399     case TRUTH_ORIF_EXPR:
3400     case TRUTH_XOR_EXPR:
3401     case NE_EXPR:
3402       return build_zero_cst (type);
3403
3404     case MULT_EXPR:
3405     case TRUTH_AND_EXPR:
3406     case TRUTH_ANDIF_EXPR:
3407     case EQ_EXPR:
3408       return fold_convert_loc (loc, type, integer_one_node);
3409
3410     case BIT_AND_EXPR:
3411       return fold_convert_loc (loc, type, integer_minus_one_node);
3412
3413     case MAX_EXPR:
3414       if (SCALAR_FLOAT_TYPE_P (type))
3415         {
3416           REAL_VALUE_TYPE max, min;
3417           if (HONOR_INFINITIES (type))
3418             {
3419               real_inf (&max);
3420               real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
3421             }
3422           else
3423             real_maxval (&min, 1, TYPE_MODE (type));
3424           return build_real (type, min);
3425         }
3426       else
3427         {
3428           gcc_assert (INTEGRAL_TYPE_P (type));
3429           return TYPE_MIN_VALUE (type);
3430         }
3431
3432     case MIN_EXPR:
3433       if (SCALAR_FLOAT_TYPE_P (type))
3434         {
3435           REAL_VALUE_TYPE max;
3436           if (HONOR_INFINITIES (type))
3437             real_inf (&max);
3438           else
3439             real_maxval (&max, 0, TYPE_MODE (type));
3440           return build_real (type, max);
3441         }
3442       else
3443         {
3444           gcc_assert (INTEGRAL_TYPE_P (type));
3445           return TYPE_MAX_VALUE (type);
3446         }
3447
3448     default:
3449       gcc_unreachable ();
3450     }
3451 }
3452
3453 /* Return alignment to be assumed for var in CLAUSE, which should be
3454    OMP_CLAUSE_ALIGNED.  */
3455
3456 static tree
3457 omp_clause_aligned_alignment (tree clause)
3458 {
3459   if (OMP_CLAUSE_ALIGNED_ALIGNMENT (clause))
3460     return OMP_CLAUSE_ALIGNED_ALIGNMENT (clause);
3461
3462   /* Otherwise return implementation defined alignment.  */
3463   unsigned int al = 1;
3464   machine_mode mode, vmode;
3465   int vs = targetm.vectorize.autovectorize_vector_sizes ();
3466   if (vs)
3467     vs = 1 << floor_log2 (vs);
3468   static enum mode_class classes[]
3469     = { MODE_INT, MODE_VECTOR_INT, MODE_FLOAT, MODE_VECTOR_FLOAT };
3470   for (int i = 0; i < 4; i += 2)
3471     for (mode = GET_CLASS_NARROWEST_MODE (classes[i]);
3472          mode != VOIDmode;
3473          mode = GET_MODE_WIDER_MODE (mode))
3474       {
3475         vmode = targetm.vectorize.preferred_simd_mode (mode);
3476         if (GET_MODE_CLASS (vmode) != classes[i + 1])
3477           continue;
3478         while (vs
3479                && GET_MODE_SIZE (vmode) < vs
3480                && GET_MODE_2XWIDER_MODE (vmode) != VOIDmode)
3481           vmode = GET_MODE_2XWIDER_MODE (vmode);
3482         
3483         tree type = lang_hooks.types.type_for_mode (mode, 1);
3484         if (type == NULL_TREE || TYPE_MODE (type) != mode)
3485           continue;
3486         type = build_vector_type (type, GET_MODE_SIZE (vmode)
3487                                         / GET_MODE_SIZE (mode));
3488         if (TYPE_MODE (type) != vmode)
3489           continue;
3490         if (TYPE_ALIGN_UNIT (type) > al)
3491           al = TYPE_ALIGN_UNIT (type);
3492       }
3493   return build_int_cst (integer_type_node, al);
3494 }
3495
3496 /* Return maximum possible vectorization factor for the target.  */
3497
3498 static int
3499 omp_max_vf (void)
3500 {
3501   if (!optimize
3502       || optimize_debug
3503       || !flag_tree_loop_optimize
3504       || (!flag_tree_loop_vectorize
3505           && (global_options_set.x_flag_tree_loop_vectorize
3506               || global_options_set.x_flag_tree_vectorize)))
3507     return 1;
3508
3509   int vs = targetm.vectorize.autovectorize_vector_sizes ();
3510   if (vs)
3511     {
3512       vs = 1 << floor_log2 (vs);
3513       return vs;
3514     }
3515   machine_mode vqimode = targetm.vectorize.preferred_simd_mode (QImode);
3516   if (GET_MODE_CLASS (vqimode) == MODE_VECTOR_INT)
3517     return GET_MODE_NUNITS (vqimode);
3518   return 1;
3519 }
3520
3521 /* Helper function of lower_rec_input_clauses, used for #pragma omp simd
3522    privatization.  */
3523
3524 static bool
3525 lower_rec_simd_input_clauses (tree new_var, omp_context *ctx, int &max_vf,
3526                               tree &idx, tree &lane, tree &ivar, tree &lvar)
3527 {
3528   if (max_vf == 0)
3529     {
3530       max_vf = omp_max_vf ();
3531       if (max_vf > 1)
3532         {
3533           tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
3534                                     OMP_CLAUSE_SAFELEN);
3535           if (c && TREE_CODE (OMP_CLAUSE_SAFELEN_EXPR (c)) != INTEGER_CST)
3536             max_vf = 1;
3537           else if (c && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c),
3538                                           max_vf) == -1)
3539             max_vf = tree_to_shwi (OMP_CLAUSE_SAFELEN_EXPR (c));
3540         }
3541       if (max_vf > 1)
3542         {
3543           idx = create_tmp_var (unsigned_type_node);
3544           lane = create_tmp_var (unsigned_type_node);
3545         }
3546     }
3547   if (max_vf == 1)
3548     return false;
3549
3550   tree atype = build_array_type_nelts (TREE_TYPE (new_var), max_vf);
3551   tree avar = create_tmp_var_raw (atype);
3552   if (TREE_ADDRESSABLE (new_var))
3553     TREE_ADDRESSABLE (avar) = 1;
3554   DECL_ATTRIBUTES (avar)
3555     = tree_cons (get_identifier ("omp simd array"), NULL,
3556                  DECL_ATTRIBUTES (avar));
3557   gimple_add_tmp_var (avar);
3558   ivar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, idx,
3559                  NULL_TREE, NULL_TREE);
3560   lvar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, lane,
3561                  NULL_TREE, NULL_TREE);
3562   if (DECL_P (new_var))
3563     {
3564       SET_DECL_VALUE_EXPR (new_var, lvar);
3565       DECL_HAS_VALUE_EXPR_P (new_var) = 1;
3566     }
3567   return true;
3568 }
3569
3570 /* Helper function of lower_rec_input_clauses.  For a reference
3571    in simd reduction, add an underlying variable it will reference.  */
3572
3573 static void
3574 handle_simd_reference (location_t loc, tree new_vard, gimple_seq *ilist)
3575 {
3576   tree z = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_vard)));
3577   if (TREE_CONSTANT (z))
3578     {
3579       const char *name = NULL;
3580       if (DECL_NAME (new_vard))
3581         name = IDENTIFIER_POINTER (DECL_NAME (new_vard));
3582
3583       z = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_vard)), name);
3584       gimple_add_tmp_var (z);
3585       TREE_ADDRESSABLE (z) = 1;
3586       z = build_fold_addr_expr_loc (loc, z);
3587       gimplify_assign (new_vard, z, ilist);
3588     }
3589 }
3590
3591 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
3592    from the receiver (aka child) side and initializers for REFERENCE_TYPE
3593    private variables.  Initialization statements go in ILIST, while calls
3594    to destructors go in DLIST.  */
3595
3596 static void
3597 lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
3598                          omp_context *ctx, struct omp_for_data *fd)
3599 {
3600   tree c, dtor, copyin_seq, x, ptr;
3601   bool copyin_by_ref = false;
3602   bool lastprivate_firstprivate = false;
3603   bool reduction_omp_orig_ref = false;
3604   int pass;
3605   bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
3606                   && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD);
3607   int max_vf = 0;
3608   tree lane = NULL_TREE, idx = NULL_TREE;
3609   tree ivar = NULL_TREE, lvar = NULL_TREE;
3610   gimple_seq llist[2] = { NULL, NULL };
3611
3612   copyin_seq = NULL;
3613
3614   /* Set max_vf=1 (which will later enforce safelen=1) in simd loops
3615      with data sharing clauses referencing variable sized vars.  That
3616      is unnecessarily hard to support and very unlikely to result in
3617      vectorized code anyway.  */
3618   if (is_simd)
3619     for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
3620       switch (OMP_CLAUSE_CODE (c))
3621         {
3622         case OMP_CLAUSE_LINEAR:
3623           if (OMP_CLAUSE_LINEAR_ARRAY (c))
3624             max_vf = 1;
3625           /* FALLTHRU */
3626         case OMP_CLAUSE_REDUCTION:
3627         case OMP_CLAUSE_PRIVATE:
3628         case OMP_CLAUSE_FIRSTPRIVATE:
3629         case OMP_CLAUSE_LASTPRIVATE:
3630           if (is_variable_sized (OMP_CLAUSE_DECL (c)))
3631             max_vf = 1;
3632           break;
3633         default:
3634           continue;
3635         }
3636
3637   /* Do all the fixed sized types in the first pass, and the variable sized
3638      types in the second pass.  This makes sure that the scalar arguments to
3639      the variable sized types are processed before we use them in the
3640      variable sized operations.  */
3641   for (pass = 0; pass < 2; ++pass)
3642     {
3643       for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
3644         {
3645           enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
3646           tree var, new_var;
3647           bool by_ref;
3648           location_t clause_loc = OMP_CLAUSE_LOCATION (c);
3649
3650           switch (c_kind)
3651             {
3652             case OMP_CLAUSE_PRIVATE:
3653               if (OMP_CLAUSE_PRIVATE_DEBUG (c))
3654                 continue;
3655               break;
3656             case OMP_CLAUSE_SHARED:
3657               /* Ignore shared directives in teams construct.  */
3658               if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
3659                 continue;
3660               if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
3661                 {
3662                   gcc_assert (is_global_var (OMP_CLAUSE_DECL (c)));
3663                   continue;
3664                 }
3665             case OMP_CLAUSE_FIRSTPRIVATE:
3666             case OMP_CLAUSE_COPYIN:
3667             case OMP_CLAUSE_LINEAR:
3668               break;
3669             case OMP_CLAUSE_REDUCTION:
3670               if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
3671                 reduction_omp_orig_ref = true;
3672               break;
3673             case OMP_CLAUSE__LOOPTEMP_:
3674               /* Handle _looptemp_ clauses only on parallel.  */
3675               if (fd)
3676                 continue;
3677               break;
3678             case OMP_CLAUSE_LASTPRIVATE:
3679               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
3680                 {
3681                   lastprivate_firstprivate = true;
3682                   if (pass != 0)
3683                     continue;
3684                 }
3685               /* Even without corresponding firstprivate, if
3686                  decl is Fortran allocatable, it needs outer var
3687                  reference.  */
3688               else if (pass == 0
3689                        && lang_hooks.decls.omp_private_outer_ref
3690                                                         (OMP_CLAUSE_DECL (c)))
3691                 lastprivate_firstprivate = true;
3692               break;
3693             case OMP_CLAUSE_ALIGNED:
3694               if (pass == 0)
3695                 continue;
3696               var = OMP_CLAUSE_DECL (c);
3697               if (TREE_CODE (TREE_TYPE (var)) == POINTER_TYPE
3698                   && !is_global_var (var))
3699                 {
3700                   new_var = maybe_lookup_decl (var, ctx);
3701                   if (new_var == NULL_TREE)
3702                     new_var = maybe_lookup_decl_in_outer_ctx (var, ctx);
3703                   x = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
3704                   x = build_call_expr_loc (clause_loc, x, 2, new_var,
3705                                            omp_clause_aligned_alignment (c));
3706                   x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
3707                   x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
3708                   gimplify_and_add (x, ilist);
3709                 }
3710               else if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE
3711                        && is_global_var (var))
3712                 {
3713                   tree ptype = build_pointer_type (TREE_TYPE (var)), t, t2;
3714                   new_var = lookup_decl (var, ctx);
3715                   t = maybe_lookup_decl_in_outer_ctx (var, ctx);
3716                   t = build_fold_addr_expr_loc (clause_loc, t);
3717                   t2 = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
3718                   t = build_call_expr_loc (clause_loc, t2, 2, t,
3719                                            omp_clause_aligned_alignment (c));
3720                   t = fold_convert_loc (clause_loc, ptype, t);
3721                   x = create_tmp_var (ptype);
3722                   t = build2 (MODIFY_EXPR, ptype, x, t);
3723                   gimplify_and_add (t, ilist);
3724                   t = build_simple_mem_ref_loc (clause_loc, x);
3725                   SET_DECL_VALUE_EXPR (new_var, t);
3726                   DECL_HAS_VALUE_EXPR_P (new_var) = 1;
3727                 }
3728               continue;
3729             default:
3730               continue;
3731             }
3732
3733           new_var = var = OMP_CLAUSE_DECL (c);
3734           if (c_kind != OMP_CLAUSE_COPYIN)
3735             new_var = lookup_decl (var, ctx);
3736
3737           if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
3738             {
3739               if (pass != 0)
3740                 continue;
3741             }
3742           else if (is_variable_sized (var))
3743             {
3744               /* For variable sized types, we need to allocate the
3745                  actual storage here.  Call alloca and store the
3746                  result in the pointer decl that we created elsewhere.  */
3747               if (pass == 0)
3748                 continue;
3749
3750               if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
3751                 {
3752                   gcall *stmt;
3753                   tree tmp, atmp;
3754
3755                   ptr = DECL_VALUE_EXPR (new_var);
3756                   gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
3757                   ptr = TREE_OPERAND (ptr, 0);
3758                   gcc_assert (DECL_P (ptr));
3759                   x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
3760
3761                   /* void *tmp = __builtin_alloca */
3762                   atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
3763                   stmt = gimple_build_call (atmp, 1, x);
3764                   tmp = create_tmp_var_raw (ptr_type_node);
3765                   gimple_add_tmp_var (tmp);
3766                   gimple_call_set_lhs (stmt, tmp);
3767
3768                   gimple_seq_add_stmt (ilist, stmt);
3769
3770                   x = fold_convert_loc (clause_loc, TREE_TYPE (ptr), tmp);
3771                   gimplify_assign (ptr, x, ilist);
3772                 }
3773             }
3774           else if (is_reference (var))
3775             {
3776               /* For references that are being privatized for Fortran,
3777                  allocate new backing storage for the new pointer
3778                  variable.  This allows us to avoid changing all the
3779                  code that expects a pointer to something that expects
3780                  a direct variable.  */
3781               if (pass == 0)
3782                 continue;
3783
3784               x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
3785               if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
3786                 {
3787                   x = build_receiver_ref (var, false, ctx);
3788                   x = build_fold_addr_expr_loc (clause_loc, x);
3789                 }
3790               else if (TREE_CONSTANT (x))
3791                 {
3792                   /* For reduction in SIMD loop, defer adding the
3793                      initialization of the reference, because if we decide
3794                      to use SIMD array for it, the initilization could cause
3795                      expansion ICE.  */
3796                   if (c_kind == OMP_CLAUSE_REDUCTION && is_simd)
3797                     x = NULL_TREE;
3798                   else
3799                     {
3800                       const char *name = NULL;
3801                       if (DECL_NAME (var))
3802                         name = IDENTIFIER_POINTER (DECL_NAME (new_var));
3803
3804                       x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
3805                                               name);
3806                       gimple_add_tmp_var (x);
3807                       TREE_ADDRESSABLE (x) = 1;
3808                       x = build_fold_addr_expr_loc (clause_loc, x);
3809                     }
3810                 }
3811               else
3812                 {
3813                   tree atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
3814                   x = build_call_expr_loc (clause_loc, atmp, 1, x);
3815                 }
3816
3817               if (x)
3818                 {
3819                   x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
3820                   gimplify_assign (new_var, x, ilist);
3821                 }
3822
3823               new_var = build_simple_mem_ref_loc (clause_loc, new_var);
3824             }
3825           else if (c_kind == OMP_CLAUSE_REDUCTION
3826                    && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
3827             {
3828               if (pass == 0)
3829                 continue;
3830             }
3831           else if (pass != 0)
3832             continue;
3833
3834           switch (OMP_CLAUSE_CODE (c))
3835             {
3836             case OMP_CLAUSE_SHARED:
3837               /* Ignore shared directives in teams construct.  */
3838               if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
3839                 continue;
3840               /* Shared global vars are just accessed directly.  */
3841               if (is_global_var (new_var))
3842                 break;
3843               /* Set up the DECL_VALUE_EXPR for shared variables now.  This
3844                  needs to be delayed until after fixup_child_record_type so
3845                  that we get the correct type during the dereference.  */
3846               by_ref = use_pointer_for_field (var, ctx);
3847               x = build_receiver_ref (var, by_ref, ctx);
3848               SET_DECL_VALUE_EXPR (new_var, x);
3849               DECL_HAS_VALUE_EXPR_P (new_var) = 1;
3850
3851               /* ??? If VAR is not passed by reference, and the variable
3852                  hasn't been initialized yet, then we'll get a warning for
3853                  the store into the omp_data_s structure.  Ideally, we'd be
3854                  able to notice this and not store anything at all, but
3855                  we're generating code too early.  Suppress the warning.  */
3856               if (!by_ref)
3857                 TREE_NO_WARNING (var) = 1;
3858               break;
3859
3860             case OMP_CLAUSE_LASTPRIVATE:
3861               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
3862                 break;
3863               /* FALLTHRU */
3864
3865             case OMP_CLAUSE_PRIVATE:
3866               if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE)
3867                 x = build_outer_var_ref (var, ctx);
3868               else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
3869                 {
3870                   if (is_task_ctx (ctx))
3871                     x = build_receiver_ref (var, false, ctx);
3872                   else
3873                     x = build_outer_var_ref (var, ctx);
3874                 }
3875               else
3876                 x = NULL;
3877             do_private:
3878               tree nx;
3879               nx = lang_hooks.decls.omp_clause_default_ctor (c, new_var, x);
3880               if (is_simd)
3881                 {
3882                   tree y = lang_hooks.decls.omp_clause_dtor (c, new_var);
3883                   if ((TREE_ADDRESSABLE (new_var) || nx || y
3884                        || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
3885                       && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
3886                                                        idx, lane, ivar, lvar))
3887                     {
3888                       if (nx)
3889                         x = lang_hooks.decls.omp_clause_default_ctor
3890                                                 (c, unshare_expr (ivar), x);
3891                       if (nx && x)
3892                         gimplify_and_add (x, &llist[0]);
3893                       if (y)
3894                         {
3895                           y = lang_hooks.decls.omp_clause_dtor (c, ivar);
3896                           if (y)
3897                             {
3898                               gimple_seq tseq = NULL;
3899
3900                               dtor = y;
3901                               gimplify_stmt (&dtor, &tseq);
3902                               gimple_seq_add_seq (&llist[1], tseq);
3903                             }
3904                         }
3905                       break;
3906                     }
3907                 }
3908               if (nx)
3909                 gimplify_and_add (nx, ilist);
3910               /* FALLTHRU */
3911
3912             do_dtor:
3913               x = lang_hooks.decls.omp_clause_dtor (c, new_var);
3914               if (x)
3915                 {
3916                   gimple_seq tseq = NULL;
3917
3918                   dtor = x;
3919                   gimplify_stmt (&dtor, &tseq);
3920                   gimple_seq_add_seq (dlist, tseq);
3921                 }
3922               break;
3923
3924             case OMP_CLAUSE_LINEAR:
3925               if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
3926                 goto do_firstprivate;
3927               if (OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
3928                 x = NULL;
3929               else
3930                 x = build_outer_var_ref (var, ctx);
3931               goto do_private;
3932
3933             case OMP_CLAUSE_FIRSTPRIVATE:
3934               if (is_task_ctx (ctx))
3935                 {
3936                   if (is_reference (var) || is_variable_sized (var))
3937                     goto do_dtor;
3938                   else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var,
3939                                                                           ctx))
3940                            || use_pointer_for_field (var, NULL))
3941                     {
3942                       x = build_receiver_ref (var, false, ctx);
3943                       SET_DECL_VALUE_EXPR (new_var, x);
3944                       DECL_HAS_VALUE_EXPR_P (new_var) = 1;
3945                       goto do_dtor;
3946                     }
3947                 }
3948             do_firstprivate:
3949               x = build_outer_var_ref (var, ctx);
3950               if (is_simd)
3951                 {
3952                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
3953                       && gimple_omp_for_combined_into_p (ctx->stmt))
3954                     {
3955                       tree t = OMP_CLAUSE_LINEAR_STEP (c);
3956                       tree stept = TREE_TYPE (t);
3957                       tree ct = find_omp_clause (clauses,
3958                                                  OMP_CLAUSE__LOOPTEMP_);
3959                       gcc_assert (ct);
3960                       tree l = OMP_CLAUSE_DECL (ct);
3961                       tree n1 = fd->loop.n1;
3962                       tree step = fd->loop.step;
3963                       tree itype = TREE_TYPE (l);
3964                       if (POINTER_TYPE_P (itype))
3965                         itype = signed_type_for (itype);
3966                       l = fold_build2 (MINUS_EXPR, itype, l, n1);
3967                       if (TYPE_UNSIGNED (itype)
3968                           && fd->loop.cond_code == GT_EXPR)
3969                         l = fold_build2 (TRUNC_DIV_EXPR, itype,
3970                                          fold_build1 (NEGATE_EXPR, itype, l),
3971                                          fold_build1 (NEGATE_EXPR,
3972                                                       itype, step));
3973                       else
3974                         l = fold_build2 (TRUNC_DIV_EXPR, itype, l, step);
3975                       t = fold_build2 (MULT_EXPR, stept,
3976                                        fold_convert (stept, l), t);
3977
3978                       if (OMP_CLAUSE_LINEAR_ARRAY (c))
3979                         {
3980                           x = lang_hooks.decls.omp_clause_linear_ctor
3981                                                         (c, new_var, x, t);
3982                           gimplify_and_add (x, ilist);
3983                           goto do_dtor;
3984                         }
3985
3986                       if (POINTER_TYPE_P (TREE_TYPE (x)))
3987                         x = fold_build2 (POINTER_PLUS_EXPR,
3988                                          TREE_TYPE (x), x, t);
3989                       else
3990                         x = fold_build2 (PLUS_EXPR, TREE_TYPE (x), x, t);
3991                     }
3992
3993                   if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
3994                        || TREE_ADDRESSABLE (new_var))
3995                       && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
3996                                                        idx, lane, ivar, lvar))
3997                     {
3998                       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
3999                         {
4000                           tree iv = create_tmp_var (TREE_TYPE (new_var));
4001                           x = lang_hooks.decls.omp_clause_copy_ctor (c, iv, x);
4002                           gimplify_and_add (x, ilist);
4003                           gimple_stmt_iterator gsi
4004                             = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt));
4005                           gassign *g
4006                             = gimple_build_assign (unshare_expr (lvar), iv);
4007                           gsi_insert_before_without_update (&gsi, g,
4008                                                             GSI_SAME_STMT);
4009                           tree t = OMP_CLAUSE_LINEAR_STEP (c);
4010                           enum tree_code code = PLUS_EXPR;
4011                           if (POINTER_TYPE_P (TREE_TYPE (new_var)))
4012                             code = POINTER_PLUS_EXPR;
4013                           g = gimple_build_assign (iv, code, iv, t);
4014                           gsi_insert_before_without_update (&gsi, g,
4015                                                             GSI_SAME_STMT);
4016                           break;
4017                         }
4018                       x = lang_hooks.decls.omp_clause_copy_ctor
4019                                                 (c, unshare_expr (ivar), x);
4020                       gimplify_and_add (x, &llist[0]);
4021                       x = lang_hooks.decls.omp_clause_dtor (c, ivar);
4022                       if (x)
4023                         {
4024                           gimple_seq tseq = NULL;
4025
4026                           dtor = x;
4027                           gimplify_stmt (&dtor, &tseq);
4028                           gimple_seq_add_seq (&llist[1], tseq);
4029                         }
4030                       break;
4031                     }
4032                 }
4033               x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
4034               gimplify_and_add (x, ilist);
4035               goto do_dtor;
4036
4037             case OMP_CLAUSE__LOOPTEMP_:
4038               gcc_assert (is_parallel_ctx (ctx));
4039               x = build_outer_var_ref (var, ctx);
4040               x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
4041               gimplify_and_add (x, ilist);
4042               break;
4043
4044             case OMP_CLAUSE_COPYIN:
4045               by_ref = use_pointer_for_field (var, NULL);
4046               x = build_receiver_ref (var, by_ref, ctx);
4047               x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
4048               append_to_statement_list (x, &copyin_seq);
4049               copyin_by_ref |= by_ref;
4050               break;
4051
4052             case OMP_CLAUSE_REDUCTION:
4053               if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
4054                 {
4055                   tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
4056                   gimple tseq;
4057                   x = build_outer_var_ref (var, ctx);
4058
4059                   if (is_reference (var)
4060                       && !useless_type_conversion_p (TREE_TYPE (placeholder),
4061                                                      TREE_TYPE (x)))
4062                     x = build_fold_addr_expr_loc (clause_loc, x);
4063                   SET_DECL_VALUE_EXPR (placeholder, x);
4064                   DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
4065                   tree new_vard = new_var;
4066                   if (is_reference (var))
4067                     {
4068                       gcc_assert (TREE_CODE (new_var) == MEM_REF);
4069                       new_vard = TREE_OPERAND (new_var, 0);
4070                       gcc_assert (DECL_P (new_vard));
4071                     }
4072                   if (is_simd
4073                       && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
4074                                                        idx, lane, ivar, lvar))
4075                     {
4076                       if (new_vard == new_var)
4077                         {
4078                           gcc_assert (DECL_VALUE_EXPR (new_var) == lvar);
4079                           SET_DECL_VALUE_EXPR (new_var, ivar);
4080                         }
4081                       else
4082                         {
4083                           SET_DECL_VALUE_EXPR (new_vard,
4084                                                build_fold_addr_expr (ivar));
4085                           DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
4086                         }
4087                       x = lang_hooks.decls.omp_clause_default_ctor
4088                                 (c, unshare_expr (ivar),
4089                                  build_outer_var_ref (var, ctx));
4090                       if (x)
4091                         gimplify_and_add (x, &llist[0]);
4092                       if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
4093                         {
4094                           tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
4095                           lower_omp (&tseq, ctx);
4096                           gimple_seq_add_seq (&llist[0], tseq);
4097                         }
4098                       OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
4099                       tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
4100                       lower_omp (&tseq, ctx);
4101                       gimple_seq_add_seq (&llist[1], tseq);
4102                       OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
4103                       DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
4104                       if (new_vard == new_var)
4105                         SET_DECL_VALUE_EXPR (new_var, lvar);
4106                       else
4107                         SET_DECL_VALUE_EXPR (new_vard,
4108                                              build_fold_addr_expr (lvar));
4109                       x = lang_hooks.decls.omp_clause_dtor (c, ivar);
4110                       if (x)
4111                         {
4112                           tseq = NULL;
4113                           dtor = x;
4114                           gimplify_stmt (&dtor, &tseq);
4115                           gimple_seq_add_seq (&llist[1], tseq);
4116                         }
4117                       break;
4118                     }
4119                   /* If this is a reference to constant size reduction var
4120                      with placeholder, we haven't emitted the initializer
4121                      for it because it is undesirable if SIMD arrays are used.
4122                      But if they aren't used, we need to emit the deferred
4123                      initialization now.  */
4124                   else if (is_reference (var) && is_simd)
4125                     handle_simd_reference (clause_loc, new_vard, ilist);
4126                   x = lang_hooks.decls.omp_clause_default_ctor
4127                                 (c, unshare_expr (new_var),
4128                                  build_outer_var_ref (var, ctx));
4129                   if (x)
4130                     gimplify_and_add (x, ilist);
4131                   if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
4132                     {
4133                       tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
4134                       lower_omp (&tseq, ctx);
4135                       gimple_seq_add_seq (ilist, tseq);
4136                     }
4137                   OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
4138                   if (is_simd)
4139                     {
4140                       tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
4141                       lower_omp (&tseq, ctx);
4142                       gimple_seq_add_seq (dlist, tseq);
4143                       OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
4144                     }
4145                   DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
4146                   goto do_dtor;
4147                 }
4148               else
4149                 {
4150                   x = omp_reduction_init (c, TREE_TYPE (new_var));
4151                   gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
4152                   enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
4153
4154                   /* reduction(-:var) sums up the partial results, so it
4155                      acts identically to reduction(+:var).  */
4156                   if (code == MINUS_EXPR)
4157                     code = PLUS_EXPR;
4158
4159                   tree new_vard = new_var;
4160                   if (is_simd && is_reference (var))
4161                     {
4162                       gcc_assert (TREE_CODE (new_var) == MEM_REF);
4163                       new_vard = TREE_OPERAND (new_var, 0);
4164                       gcc_assert (DECL_P (new_vard));
4165                     }
4166                   if (is_simd
4167                       && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
4168                                                        idx, lane, ivar, lvar))
4169                     {
4170                       tree ref = build_outer_var_ref (var, ctx);
4171
4172                       gimplify_assign (unshare_expr (ivar), x, &llist[0]);
4173
4174                       x = build2 (code, TREE_TYPE (ref), ref, ivar);
4175                       ref = build_outer_var_ref (var, ctx);
4176                       gimplify_assign (ref, x, &llist[1]);
4177
4178                       if (new_vard != new_var)
4179                         {
4180                           SET_DECL_VALUE_EXPR (new_vard,
4181                                                build_fold_addr_expr (lvar));
4182                           DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
4183                         }
4184                     }
4185                   else
4186                     {
4187                       if (is_reference (var) && is_simd)
4188                         handle_simd_reference (clause_loc, new_vard, ilist);
4189                       gimplify_assign (new_var, x, ilist);
4190                       if (is_simd)
4191                         {
4192                           tree ref = build_outer_var_ref (var, ctx);
4193
4194                           x = build2 (code, TREE_TYPE (ref), ref, new_var);
4195                           ref = build_outer_var_ref (var, ctx);
4196                           gimplify_assign (ref, x, dlist);
4197                         }
4198                     }
4199                 }
4200               break;
4201
4202             default:
4203               gcc_unreachable ();
4204             }
4205         }
4206     }
4207
4208   if (lane)
4209     {
4210       tree uid = create_tmp_var (ptr_type_node, "simduid");
4211       /* Don't want uninit warnings on simduid, it is always uninitialized,
4212          but we use it not for the value, but for the DECL_UID only.  */
4213       TREE_NO_WARNING (uid) = 1;
4214       gimple g
4215         = gimple_build_call_internal (IFN_GOMP_SIMD_LANE, 1, uid);
4216       gimple_call_set_lhs (g, lane);
4217       gimple_stmt_iterator gsi = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt));
4218       gsi_insert_before_without_update (&gsi, g, GSI_SAME_STMT);
4219       c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SIMDUID_);
4220       OMP_CLAUSE__SIMDUID__DECL (c) = uid;
4221       OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
4222       gimple_omp_for_set_clauses (ctx->stmt, c);
4223       g = gimple_build_assign (lane, INTEGER_CST,
4224                                build_int_cst (unsigned_type_node, 0));
4225       gimple_seq_add_stmt (ilist, g);
4226       for (int i = 0; i < 2; i++)
4227         if (llist[i])
4228           {
4229             tree vf = create_tmp_var (unsigned_type_node);
4230             g = gimple_build_call_internal (IFN_GOMP_SIMD_VF, 1, uid);
4231             gimple_call_set_lhs (g, vf);
4232             gimple_seq *seq = i == 0 ? ilist : dlist;
4233             gimple_seq_add_stmt (seq, g);
4234             tree t = build_int_cst (unsigned_type_node, 0);
4235             g = gimple_build_assign (idx, INTEGER_CST, t);
4236             gimple_seq_add_stmt (seq, g);
4237             tree body = create_artificial_label (UNKNOWN_LOCATION);
4238             tree header = create_artificial_label (UNKNOWN_LOCATION);
4239             tree end = create_artificial_label (UNKNOWN_LOCATION);
4240             gimple_seq_add_stmt (seq, gimple_build_goto (header));
4241             gimple_seq_add_stmt (seq, gimple_build_label (body));
4242             gimple_seq_add_seq (seq, llist[i]);
4243             t = build_int_cst (unsigned_type_node, 1);
4244             g = gimple_build_assign (idx, PLUS_EXPR, idx, t);
4245             gimple_seq_add_stmt (seq, g);
4246             gimple_seq_add_stmt (seq, gimple_build_label (header));
4247             g = gimple_build_cond (LT_EXPR, idx, vf, body, end);
4248             gimple_seq_add_stmt (seq, g);
4249             gimple_seq_add_stmt (seq, gimple_build_label (end));
4250           }
4251     }
4252
4253   /* The copyin sequence is not to be executed by the main thread, since
4254      that would result in self-copies.  Perhaps not visible to scalars,
4255      but it certainly is to C++ operator=.  */
4256   if (copyin_seq)
4257     {
4258       x = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM),
4259                            0);
4260       x = build2 (NE_EXPR, boolean_type_node, x,
4261                   build_int_cst (TREE_TYPE (x), 0));
4262       x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
4263       gimplify_and_add (x, ilist);
4264     }
4265
4266   /* If any copyin variable is passed by reference, we must ensure the
4267      master thread doesn't modify it before it is copied over in all
4268      threads.  Similarly for variables in both firstprivate and
4269      lastprivate clauses we need to ensure the lastprivate copying
4270      happens after firstprivate copying in all threads.  And similarly
4271      for UDRs if initializer expression refers to omp_orig.  */
4272   if (copyin_by_ref || lastprivate_firstprivate || reduction_omp_orig_ref)
4273     {
4274       /* Don't add any barrier for #pragma omp simd or
4275          #pragma omp distribute.  */
4276       if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
4277           || gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_FOR)
4278         gimple_seq_add_stmt (ilist, build_omp_barrier (NULL_TREE));
4279     }
4280
4281   /* If max_vf is non-zero, then we can use only a vectorization factor
4282      up to the max_vf we chose.  So stick it into the safelen clause.  */
4283   if (max_vf)
4284     {
4285       tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
4286                                 OMP_CLAUSE_SAFELEN);
4287       if (c == NULL_TREE
4288           || (TREE_CODE (OMP_CLAUSE_SAFELEN_EXPR (c)) == INTEGER_CST
4289               && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c),
4290                                    max_vf) == 1))
4291         {
4292           c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
4293           OMP_CLAUSE_SAFELEN_EXPR (c) = build_int_cst (integer_type_node,
4294                                                        max_vf);
4295           OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
4296           gimple_omp_for_set_clauses (ctx->stmt, c);
4297         }
4298     }
4299 }
4300
4301
4302 /* Generate code to implement the LASTPRIVATE clauses.  This is used for
4303    both parallel and workshare constructs.  PREDICATE may be NULL if it's
4304    always true.   */
4305
4306 static void
4307 lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
4308                            omp_context *ctx)
4309 {
4310   tree x, c, label = NULL, orig_clauses = clauses;
4311   bool par_clauses = false;
4312   tree simduid = NULL, lastlane = NULL;
4313
4314   /* Early exit if there are no lastprivate or linear clauses.  */
4315   for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
4316     if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LASTPRIVATE
4317         || (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LINEAR
4318             && !OMP_CLAUSE_LINEAR_NO_COPYOUT (clauses)))
4319       break;
4320   if (clauses == NULL)
4321     {
4322       /* If this was a workshare clause, see if it had been combined
4323          with its parallel.  In that case, look for the clauses on the
4324          parallel statement itself.  */
4325       if (is_parallel_ctx (ctx))
4326         return;
4327
4328       ctx = ctx->outer;
4329       if (ctx == NULL || !is_parallel_ctx (ctx))
4330         return;
4331
4332       clauses = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
4333                                  OMP_CLAUSE_LASTPRIVATE);
4334       if (clauses == NULL)
4335         return;
4336       par_clauses = true;
4337     }
4338
4339   if (predicate)
4340     {
4341       gcond *stmt;
4342       tree label_true, arm1, arm2;
4343
4344       label = create_artificial_label (UNKNOWN_LOCATION);
4345       label_true = create_artificial_label (UNKNOWN_LOCATION);
4346       arm1 = TREE_OPERAND (predicate, 0);
4347       arm2 = TREE_OPERAND (predicate, 1);
4348       gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
4349       gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
4350       stmt = gimple_build_cond (TREE_CODE (predicate), arm1, arm2,
4351                                 label_true, label);
4352       gimple_seq_add_stmt (stmt_list, stmt);
4353       gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
4354     }
4355
4356   if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
4357       && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
4358     {
4359       simduid = find_omp_clause (orig_clauses, OMP_CLAUSE__SIMDUID_);
4360       if (simduid)
4361         simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
4362     }
4363
4364   for (c = clauses; c ;)
4365     {
4366       tree var, new_var;
4367       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
4368
4369       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
4370           || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
4371               && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
4372         {
4373           var = OMP_CLAUSE_DECL (c);
4374           new_var = lookup_decl (var, ctx);
4375
4376           if (simduid && DECL_HAS_VALUE_EXPR_P (new_var))
4377             {
4378               tree val = DECL_VALUE_EXPR (new_var);
4379               if (TREE_CODE (val) == ARRAY_REF
4380                   && VAR_P (TREE_OPERAND (val, 0))
4381                   && lookup_attribute ("omp simd array",
4382                                        DECL_ATTRIBUTES (TREE_OPERAND (val,
4383                                                                       0))))
4384                 {
4385                   if (lastlane == NULL)
4386                     {
4387                       lastlane = create_tmp_var (unsigned_type_node);
4388                       gcall *g
4389                         = gimple_build_call_internal (IFN_GOMP_SIMD_LAST_LANE,
4390                                                       2, simduid,
4391                                                       TREE_OPERAND (val, 1));
4392                       gimple_call_set_lhs (g, lastlane);
4393                       gimple_seq_add_stmt (stmt_list, g);
4394                     }
4395                   new_var = build4 (ARRAY_REF, TREE_TYPE (val),
4396                                     TREE_OPERAND (val, 0), lastlane,
4397                                     NULL_TREE, NULL_TREE);
4398                 }
4399             }
4400
4401           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
4402               && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
4403             {
4404               lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
4405               gimple_seq_add_seq (stmt_list,
4406                                   OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
4407               OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
4408             }
4409           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
4410                    && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
4411             {
4412               lower_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
4413               gimple_seq_add_seq (stmt_list,
4414                                   OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
4415               OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) = NULL;
4416             }
4417
4418           x = build_outer_var_ref (var, ctx);
4419           if (is_reference (var))
4420             new_var = build_simple_mem_ref_loc (clause_loc, new_var);
4421           x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
4422           gimplify_and_add (x, stmt_list);
4423         }
4424       c = OMP_CLAUSE_CHAIN (c);
4425       if (c == NULL && !par_clauses)
4426         {
4427           /* If this was a workshare clause, see if it had been combined
4428              with its parallel.  In that case, continue looking for the
4429              clauses also on the parallel statement itself.  */
4430           if (is_parallel_ctx (ctx))
4431             break;
4432
4433           ctx = ctx->outer;
4434           if (ctx == NULL || !is_parallel_ctx (ctx))
4435             break;
4436
4437           c = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
4438                                OMP_CLAUSE_LASTPRIVATE);
4439           par_clauses = true;
4440         }
4441     }
4442
4443   if (label)
4444     gimple_seq_add_stmt (stmt_list, gimple_build_label (label));
4445 }
4446
4447 static void
4448 oacc_lower_reduction_var_helper (gimple_seq *stmt_seqp, omp_context *ctx,
4449                                  tree tid, tree var, tree new_var)
4450 {
4451   /* The atomic add at the end of the sum creates unnecessary
4452      write contention on accelerators.  To work around this,
4453      create an array to store the partial reductions. Later, in
4454      lower_omp_for (for openacc), the values of array will be
4455      combined.  */
4456
4457   tree t = NULL_TREE, array, x;
4458   tree type = get_base_type (var);
4459   gimple stmt;
4460
4461   /* Now insert the partial reductions into the array.  */
4462
4463   /* Find the reduction array.  */
4464
4465   tree ptype = build_pointer_type (type);
4466
4467   t = lookup_oacc_reduction (oacc_get_reduction_array_id (var), ctx);
4468   t = build_receiver_ref (t, false, ctx->outer);
4469
4470   array = create_tmp_var (ptype);
4471   gimplify_assign (array, t, stmt_seqp);
4472
4473   tree ptr = create_tmp_var (TREE_TYPE (array));
4474
4475   /* Find the reduction array.  */
4476
4477   /* testing a unary conversion.  */
4478   tree offset = create_tmp_var (sizetype);
4479   gimplify_assign (offset, TYPE_SIZE_UNIT (type),
4480                    stmt_seqp);
4481   t = create_tmp_var (sizetype);
4482   gimplify_assign (t, unshare_expr (fold_build1 (NOP_EXPR, sizetype, tid)),
4483                    stmt_seqp);
4484   stmt = gimple_build_assign (offset, MULT_EXPR, offset, t);
4485   gimple_seq_add_stmt (stmt_seqp, stmt);
4486
4487   /* Offset expression.  Does the POINTER_PLUS_EXPR take care
4488      of adding sizeof(var) to the array?  */
4489   ptr = create_tmp_var (ptype);
4490   stmt = gimple_build_assign (unshare_expr (ptr), POINTER_PLUS_EXPR, array,
4491                               offset);
4492   gimple_seq_add_stmt (stmt_seqp, stmt);
4493
4494   /* Move the local sum to gfc$sum[i].  */
4495   x = unshare_expr (build_simple_mem_ref (ptr));
4496   stmt = gimplify_assign (x, new_var, stmt_seqp);
4497 }
4498
4499 /* Generate code to implement the REDUCTION clauses.  */
4500
4501 static void
4502 lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
4503 {
4504   gimple_seq sub_seq = NULL;
4505   gimple stmt;
4506   tree x, c, tid = NULL_TREE;
4507   int count = 0;
4508
4509   /* SIMD reductions are handled in lower_rec_input_clauses.  */
4510   if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
4511       && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
4512     return;
4513
4514   /* First see if there is exactly one reduction clause.  Use OMP_ATOMIC
4515      update in that case, otherwise use a lock.  */
4516   for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
4517     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
4518       {
4519         if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
4520           {
4521             /* Never use OMP_ATOMIC for array reductions or UDRs.  */
4522             count = -1;
4523             break;
4524           }
4525         count++;
4526       }
4527
4528   if (count == 0)
4529     return;
4530
4531   /* Initialize thread info for OpenACC.  */
4532   if (is_gimple_omp_oacc (ctx->stmt))
4533     {
4534       /* Get the current thread id.  */
4535       tree call = builtin_decl_explicit (BUILT_IN_GOACC_GET_THREAD_NUM);
4536       tid = create_tmp_var (TREE_TYPE (TREE_TYPE (call)));
4537       gimple stmt = gimple_build_call (call, 0);
4538       gimple_call_set_lhs (stmt, tid);
4539       gimple_seq_add_stmt (stmt_seqp, stmt);
4540     }
4541
4542   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
4543     {
4544       tree var, ref, new_var;
4545       enum tree_code code;
4546       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
4547
4548       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
4549         continue;
4550
4551       var = OMP_CLAUSE_DECL (c);
4552       new_var = lookup_decl (var, ctx);
4553       if (is_reference (var))
4554         new_var = build_simple_mem_ref_loc (clause_loc, new_var);
4555       ref = build_outer_var_ref (var, ctx);
4556       code = OMP_CLAUSE_REDUCTION_CODE (c);
4557
4558       /* reduction(-:var) sums up the partial results, so it acts
4559          identically to reduction(+:var).  */
4560       if (code == MINUS_EXPR)
4561         code = PLUS_EXPR;
4562
4563       if (is_gimple_omp_oacc (ctx->stmt))
4564         {
4565           gcc_checking_assert (!OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
4566
4567           oacc_lower_reduction_var_helper (stmt_seqp, ctx, tid, var, new_var);
4568         }
4569       else if (count == 1)
4570         {
4571           tree addr = build_fold_addr_expr_loc (clause_loc, ref);
4572
4573           addr = save_expr (addr);
4574           ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
4575           x = fold_build2_loc (clause_loc, code, TREE_TYPE (ref), ref, new_var);
4576           x = build2 (OMP_ATOMIC, void_type_node, addr, x);
4577           gimplify_and_add (x, stmt_seqp);
4578           return;
4579         }
4580       else if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
4581         {
4582           tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
4583
4584           if (is_reference (var)
4585               && !useless_type_conversion_p (TREE_TYPE (placeholder),
4586                                              TREE_TYPE (ref)))
4587             ref = build_fold_addr_expr_loc (clause_loc, ref);
4588           SET_DECL_VALUE_EXPR (placeholder, ref);
4589           DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
4590           lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
4591           gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
4592           OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
4593           OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
4594         }
4595       else
4596         {
4597           x = build2 (code, TREE_TYPE (ref), ref, new_var);
4598           ref = build_outer_var_ref (var, ctx);
4599           gimplify_assign (ref, x, &sub_seq);
4600         }
4601     }
4602
4603   if (is_gimple_omp_oacc (ctx->stmt))
4604     return;
4605
4606   stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START),
4607                             0);
4608   gimple_seq_add_stmt (stmt_seqp, stmt);
4609
4610   gimple_seq_add_seq (stmt_seqp, sub_seq);
4611
4612   stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END),
4613                             0);
4614   gimple_seq_add_stmt (stmt_seqp, stmt);
4615 }
4616
4617
4618 /* Generate code to implement the COPYPRIVATE clauses.  */
4619
4620 static void
4621 lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist,
4622                             omp_context *ctx)
4623 {
4624   tree c;
4625
4626   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
4627     {
4628       tree var, new_var, ref, x;
4629       bool by_ref;
4630       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
4631
4632       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
4633         continue;
4634
4635       var = OMP_CLAUSE_DECL (c);
4636       by_ref = use_pointer_for_field (var, NULL);
4637
4638       ref = build_sender_ref (var, ctx);
4639       x = new_var = lookup_decl_in_outer_ctx (var, ctx);
4640       if (by_ref)
4641         {
4642           x = build_fold_addr_expr_loc (clause_loc, new_var);
4643           x = fold_convert_loc (clause_loc, TREE_TYPE (ref), x);
4644         }
4645       gimplify_assign (ref, x, slist);
4646
4647       ref = build_receiver_ref (var, false, ctx);
4648       if (by_ref)
4649         {
4650           ref = fold_convert_loc (clause_loc,
4651                                   build_pointer_type (TREE_TYPE (new_var)),
4652                                   ref);
4653           ref = build_fold_indirect_ref_loc (clause_loc, ref);
4654         }
4655       if (is_reference (var))
4656         {
4657           ref = fold_convert_loc (clause_loc, TREE_TYPE (new_var), ref);
4658           ref = build_simple_mem_ref_loc (clause_loc, ref);
4659           new_var = build_simple_mem_ref_loc (clause_loc, new_var);
4660         }
4661       x = lang_hooks.decls.omp_clause_assign_op (c, new_var, ref);
4662       gimplify_and_add (x, rlist);
4663     }
4664 }
4665
4666
4667 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
4668    and REDUCTION from the sender (aka parent) side.  */
4669
4670 static void
4671 lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist,
4672                     omp_context *ctx)
4673 {
4674   tree c;
4675
4676   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
4677     {
4678       tree val, ref, x, var;
4679       bool by_ref, do_in = false, do_out = false;
4680       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
4681
4682       switch (OMP_CLAUSE_CODE (c))
4683         {
4684         case OMP_CLAUSE_PRIVATE:
4685           if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
4686             break;
4687           continue;
4688         case OMP_CLAUSE_FIRSTPRIVATE:
4689         case OMP_CLAUSE_COPYIN:
4690         case OMP_CLAUSE_LASTPRIVATE:
4691         case OMP_CLAUSE_REDUCTION:
4692         case OMP_CLAUSE__LOOPTEMP_:
4693           break;
4694         default:
4695           continue;
4696         }
4697
4698       val = OMP_CLAUSE_DECL (c);
4699       var = lookup_decl_in_outer_ctx (val, ctx);
4700
4701       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
4702           && is_global_var (var))
4703         continue;
4704       if (is_variable_sized (val))
4705         continue;
4706       by_ref = use_pointer_for_field (val, NULL);
4707
4708       switch (OMP_CLAUSE_CODE (c))
4709         {
4710         case OMP_CLAUSE_PRIVATE:
4711         case OMP_CLAUSE_FIRSTPRIVATE:
4712         case OMP_CLAUSE_COPYIN:
4713         case OMP_CLAUSE__LOOPTEMP_:
4714           do_in = true;
4715           break;
4716
4717         case OMP_CLAUSE_LASTPRIVATE:
4718           if (by_ref || is_reference (val))
4719             {
4720               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
4721                 continue;
4722               do_in = true;
4723             }
4724           else
4725             {
4726               do_out = true;
4727               if (lang_hooks.decls.omp_private_outer_ref (val))
4728                 do_in = true;
4729             }
4730           break;
4731
4732         case OMP_CLAUSE_REDUCTION:
4733           do_in = true;
4734           do_out = !(by_ref || is_reference (val));
4735           break;
4736
4737         default:
4738           gcc_unreachable ();
4739         }
4740
4741       if (do_in)
4742         {
4743           ref = build_sender_ref (val, ctx);
4744           x = by_ref ? build_fold_addr_expr_loc (clause_loc, var) : var;
4745           gimplify_assign (ref, x, ilist);
4746           if (is_task_ctx (ctx))
4747             DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref, 1)) = NULL;
4748         }
4749
4750       if (do_out)
4751         {
4752           ref = build_sender_ref (val, ctx);
4753           gimplify_assign (var, ref, olist);
4754         }
4755     }
4756 }
4757
4758 /* Generate code to implement SHARED from the sender (aka parent)
4759    side.  This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
4760    list things that got automatically shared.  */
4761
4762 static void
4763 lower_send_shared_vars (gimple_seq *ilist, gimple_seq *olist, omp_context *ctx)
4764 {
4765   tree var, ovar, nvar, f, x, record_type;
4766
4767   if (ctx->record_type == NULL)
4768     return;
4769
4770   record_type = ctx->srecord_type ? ctx->srecord_type : ctx->record_type;
4771   for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
4772     {
4773       ovar = DECL_ABSTRACT_ORIGIN (f);
4774       nvar = maybe_lookup_decl (ovar, ctx);
4775       if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
4776         continue;
4777
4778       /* If CTX is a nested parallel directive.  Find the immediately
4779          enclosing parallel or workshare construct that contains a
4780          mapping for OVAR.  */
4781       var = lookup_decl_in_outer_ctx (ovar, ctx);
4782
4783       if (use_pointer_for_field (ovar, ctx))
4784         {
4785           x = build_sender_ref (ovar, ctx);
4786           var = build_fold_addr_expr (var);
4787           gimplify_assign (x, var, ilist);
4788         }
4789       else
4790         {
4791           x = build_sender_ref (ovar, ctx);
4792           gimplify_assign (x, var, ilist);
4793
4794           if (!TREE_READONLY (var)
4795               /* We don't need to receive a new reference to a result
4796                  or parm decl.  In fact we may not store to it as we will
4797                  invalidate any pending RSO and generate wrong gimple
4798                  during inlining.  */
4799               && !((TREE_CODE (var) == RESULT_DECL
4800                     || TREE_CODE (var) == PARM_DECL)
4801                    && DECL_BY_REFERENCE (var)))
4802             {
4803               x = build_sender_ref (ovar, ctx);
4804               gimplify_assign (var, x, olist);
4805             }
4806         }
4807     }
4808 }
4809
4810
4811 /* A convenience function to build an empty GIMPLE_COND with just the
4812    condition.  */
4813
4814 static gcond *
4815 gimple_build_cond_empty (tree cond)
4816 {
4817   enum tree_code pred_code;
4818   tree lhs, rhs;
4819
4820   gimple_cond_get_ops_from_tree (cond, &pred_code, &lhs, &rhs);
4821   return gimple_build_cond (pred_code, lhs, rhs, NULL_TREE, NULL_TREE);
4822 }
4823
4824
4825 /* Build the function calls to GOMP_parallel_start etc to actually
4826    generate the parallel operation.  REGION is the parallel region
4827    being expanded.  BB is the block where to insert the code.  WS_ARGS
4828    will be set if this is a call to a combined parallel+workshare
4829    construct, it contains the list of additional arguments needed by
4830    the workshare construct.  */
4831
4832 static void
4833 expand_parallel_call (struct omp_region *region, basic_block bb,
4834                       gomp_parallel *entry_stmt,
4835                       vec<tree, va_gc> *ws_args)
4836 {
4837   tree t, t1, t2, val, cond, c, clauses, flags;
4838   gimple_stmt_iterator gsi;
4839   gimple stmt;
4840   enum built_in_function start_ix;
4841   int start_ix2;
4842   location_t clause_loc;
4843   vec<tree, va_gc> *args;
4844
4845   clauses = gimple_omp_parallel_clauses (entry_stmt);
4846
4847   /* Determine what flavor of GOMP_parallel we will be
4848      emitting.  */
4849   start_ix = BUILT_IN_GOMP_PARALLEL;
4850   if (is_combined_parallel (region))
4851     {
4852       switch (region->inner->type)
4853         {
4854         case GIMPLE_OMP_FOR:
4855           gcc_assert (region->inner->sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
4856           start_ix2 = ((int)BUILT_IN_GOMP_PARALLEL_LOOP_STATIC
4857                        + (region->inner->sched_kind
4858                           == OMP_CLAUSE_SCHEDULE_RUNTIME
4859                           ? 3 : region->inner->sched_kind));
4860           start_ix = (enum built_in_function)start_ix2;
4861           break;
4862         case GIMPLE_OMP_SECTIONS:
4863           start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS;
4864           break;
4865         default:
4866           gcc_unreachable ();
4867         }
4868     }
4869
4870   /* By default, the value of NUM_THREADS is zero (selected at run time)
4871      and there is no conditional.  */
4872   cond = NULL_TREE;
4873   val = build_int_cst (unsigned_type_node, 0);
4874   flags = build_int_cst (unsigned_type_node, 0);
4875
4876   c = find_omp_clause (clauses, OMP_CLAUSE_IF);
4877   if (c)
4878     cond = OMP_CLAUSE_IF_EXPR (c);
4879
4880   c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
4881   if (c)
4882     {
4883       val = OMP_CLAUSE_NUM_THREADS_EXPR (c);
4884       clause_loc = OMP_CLAUSE_LOCATION (c);
4885     }
4886   else
4887     clause_loc = gimple_location (entry_stmt);
4888
4889   c = find_omp_clause (clauses, OMP_CLAUSE_PROC_BIND);
4890   if (c)
4891     flags = build_int_cst (unsigned_type_node, OMP_CLAUSE_PROC_BIND_KIND (c));
4892
4893   /* Ensure 'val' is of the correct type.  */
4894   val = fold_convert_loc (clause_loc, unsigned_type_node, val);
4895
4896   /* If we found the clause 'if (cond)', build either
4897      (cond != 0) or (cond ? val : 1u).  */
4898   if (cond)
4899     {
4900       cond = gimple_boolify (cond);
4901
4902       if (integer_zerop (val))
4903         val = fold_build2_loc (clause_loc,
4904                            EQ_EXPR, unsigned_type_node, cond,
4905                            build_int_cst (TREE_TYPE (cond), 0));
4906       else
4907         {
4908           basic_block cond_bb, then_bb, else_bb;
4909           edge e, e_then, e_else;
4910           tree tmp_then, tmp_else, tmp_join, tmp_var;
4911
4912           tmp_var = create_tmp_var (TREE_TYPE (val));
4913           if (gimple_in_ssa_p (cfun))
4914             {
4915               tmp_then = make_ssa_name (tmp_var);
4916               tmp_else = make_ssa_name (tmp_var);
4917               tmp_join = make_ssa_name (tmp_var);
4918             }
4919           else
4920             {
4921               tmp_then = tmp_var;
4922               tmp_else = tmp_var;
4923               tmp_join = tmp_var;
4924             }
4925
4926           e = split_block (bb, NULL);
4927           cond_bb = e->src;
4928           bb = e->dest;
4929           remove_edge (e);
4930
4931           then_bb = create_empty_bb (cond_bb);
4932           else_bb = create_empty_bb (then_bb);
4933           set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
4934           set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
4935
4936           stmt = gimple_build_cond_empty (cond);
4937           gsi = gsi_start_bb (cond_bb);
4938           gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4939
4940           gsi = gsi_start_bb (then_bb);
4941           stmt = gimple_build_assign (tmp_then, val);
4942           gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4943
4944           gsi = gsi_start_bb (else_bb);
4945           stmt = gimple_build_assign
4946                    (tmp_else, build_int_cst (unsigned_type_node, 1));
4947           gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4948
4949           make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
4950           make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
4951           add_bb_to_loop (then_bb, cond_bb->loop_father);
4952           add_bb_to_loop (else_bb, cond_bb->loop_father);
4953           e_then = make_edge (then_bb, bb, EDGE_FALLTHRU);
4954           e_else = make_edge (else_bb, bb, EDGE_FALLTHRU);
4955
4956           if (gimple_in_ssa_p (cfun))
4957             {
4958               gphi *phi = create_phi_node (tmp_join, bb);
4959               add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION);
4960               add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION);
4961             }
4962
4963           val = tmp_join;
4964         }
4965
4966       gsi = gsi_start_bb (bb);
4967       val = force_gimple_operand_gsi (&gsi, val, true, NULL_TREE,
4968                                       false, GSI_CONTINUE_LINKING);
4969     }
4970
4971   gsi = gsi_last_bb (bb);
4972   t = gimple_omp_parallel_data_arg (entry_stmt);
4973   if (t == NULL)
4974     t1 = null_pointer_node;
4975   else
4976     t1 = build_fold_addr_expr (t);
4977   t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
4978
4979   vec_alloc (args, 4 + vec_safe_length (ws_args));
4980   args->quick_push (t2);
4981   args->quick_push (t1);
4982   args->quick_push (val);
4983   if (ws_args)
4984     args->splice (*ws_args);
4985   args->quick_push (flags);
4986
4987   t = build_call_expr_loc_vec (UNKNOWN_LOCATION,
4988                                builtin_decl_explicit (start_ix), args);
4989
4990   force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4991                             false, GSI_CONTINUE_LINKING);
4992 }
4993
4994 /* Insert a function call whose name is FUNC_NAME with the information from
4995    ENTRY_STMT into the basic_block BB.  */
4996
4997 static void
4998 expand_cilk_for_call (basic_block bb, gomp_parallel *entry_stmt,
4999                       vec <tree, va_gc> *ws_args)
5000 {
5001   tree t, t1, t2;
5002   gimple_stmt_iterator gsi;
5003   vec <tree, va_gc> *args;
5004
5005   gcc_assert (vec_safe_length (ws_args) == 2);
5006   tree func_name = (*ws_args)[0];
5007   tree grain = (*ws_args)[1];
5008
5009   tree clauses = gimple_omp_parallel_clauses (entry_stmt);
5010   tree count = find_omp_clause (clauses, OMP_CLAUSE__CILK_FOR_COUNT_);
5011   gcc_assert (count != NULL_TREE);
5012   count = OMP_CLAUSE_OPERAND (count, 0);
5013
5014   gsi = gsi_last_bb (bb);
5015   t = gimple_omp_parallel_data_arg (entry_stmt);
5016   if (t == NULL)
5017     t1 = null_pointer_node;
5018   else
5019     t1 = build_fold_addr_expr (t);
5020   t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
5021
5022   vec_alloc (args, 4);
5023   args->quick_push (t2);
5024   args->quick_push (t1);
5025   args->quick_push (count);
5026   args->quick_push (grain);
5027   t = build_call_expr_loc_vec (UNKNOWN_LOCATION, func_name, args);
5028
5029   force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, false,
5030                             GSI_CONTINUE_LINKING);
5031 }
5032
5033 /* Build the function call to GOMP_task to actually
5034    generate the task operation.  BB is the block where to insert the code.  */
5035
5036 static void
5037 expand_task_call (basic_block bb, gomp_task *entry_stmt)
5038 {
5039   tree t, t1, t2, t3, flags, cond, c, c2, clauses, depend;
5040   gimple_stmt_iterator gsi;
5041   location_t loc = gimple_location (entry_stmt);
5042
5043   clauses = gimple_omp_task_clauses (entry_stmt);
5044
5045   c = find_omp_clause (clauses, OMP_CLAUSE_IF);
5046   if (c)
5047     cond = gimple_boolify (OMP_CLAUSE_IF_EXPR (c));
5048   else
5049     cond = boolean_true_node;
5050
5051   c = find_omp_clause (clauses, OMP_CLAUSE_UNTIED);
5052   c2 = find_omp_clause (clauses, OMP_CLAUSE_MERGEABLE);
5053   depend = find_omp_clause (clauses, OMP_CLAUSE_DEPEND);
5054   flags = build_int_cst (unsigned_type_node,
5055                          (c ? 1 : 0) + (c2 ? 4 : 0) + (depend ? 8 : 0));
5056
5057   c = find_omp_clause (clauses, OMP_CLAUSE_FINAL);
5058   if (c)
5059     {
5060       c = gimple_boolify (OMP_CLAUSE_FINAL_EXPR (c));
5061       c = fold_build3_loc (loc, COND_EXPR, unsigned_type_node, c,
5062                            build_int_cst (unsigned_type_node, 2),
5063                            build_int_cst (unsigned_type_node, 0));
5064       flags = fold_build2_loc (loc, PLUS_EXPR, unsigned_type_node, flags, c);
5065     }
5066   if (depend)
5067     depend = OMP_CLAUSE_DECL (depend);
5068   else
5069     depend = build_int_cst (ptr_type_node, 0);
5070
5071   gsi = gsi_last_bb (bb);
5072   t = gimple_omp_task_data_arg (entry_stmt);
5073   if (t == NULL)
5074     t2 = null_pointer_node;
5075   else
5076     t2 = build_fold_addr_expr_loc (loc, t);
5077   t1 = build_fold_addr_expr_loc (loc, gimple_omp_task_child_fn (entry_stmt));
5078   t = gimple_omp_task_copy_fn (entry_stmt);
5079   if (t == NULL)
5080     t3 = null_pointer_node;
5081   else
5082     t3 = build_fold_addr_expr_loc (loc, t);
5083
5084   t = build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_TASK),
5085                        8, t1, t2, t3,
5086                        gimple_omp_task_arg_size (entry_stmt),
5087                        gimple_omp_task_arg_align (entry_stmt), cond, flags,
5088                        depend);
5089
5090   force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
5091                             false, GSI_CONTINUE_LINKING);
5092 }
5093
5094
5095 /* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
5096    catch handler and return it.  This prevents programs from violating the
5097    structured block semantics with throws.  */
5098
5099 static gimple_seq
5100 maybe_catch_exception (gimple_seq body)
5101 {
5102   gimple g;
5103   tree decl;
5104
5105   if (!flag_exceptions)
5106     return body;
5107
5108   if (lang_hooks.eh_protect_cleanup_actions != NULL)
5109     decl = lang_hooks.eh_protect_cleanup_actions ();
5110   else
5111     decl = builtin_decl_explicit (BUILT_IN_TRAP);
5112
5113   g = gimple_build_eh_must_not_throw (decl);
5114   g = gimple_build_try (body, gimple_seq_alloc_with_stmt (g),
5115                         GIMPLE_TRY_CATCH);
5116
5117  return gimple_seq_alloc_with_stmt (g);
5118 }
5119
5120 /* Chain all the DECLs in LIST by their TREE_CHAIN fields.  */
5121
5122 static tree
5123 vec2chain (vec<tree, va_gc> *v)
5124 {
5125   tree chain = NULL_TREE, t;
5126   unsigned ix;
5127
5128   FOR_EACH_VEC_SAFE_ELT_REVERSE (v, ix, t)
5129     {
5130       DECL_CHAIN (t) = chain;
5131       chain = t;
5132     }
5133
5134   return chain;
5135 }
5136
5137
5138 /* Remove barriers in REGION->EXIT's block.  Note that this is only
5139    valid for GIMPLE_OMP_PARALLEL regions.  Since the end of a parallel region
5140    is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
5141    left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
5142    removed.  */
5143
5144 static void
5145 remove_exit_barrier (struct omp_region *region)
5146 {
5147   gimple_stmt_iterator gsi;
5148   basic_block exit_bb;
5149   edge_iterator ei;
5150   edge e;
5151   gimple stmt;
5152   int any_addressable_vars = -1;
5153
5154   exit_bb = region->exit;
5155
5156   /* If the parallel region doesn't return, we don't have REGION->EXIT
5157      block at all.  */
5158   if (! exit_bb)
5159     return;
5160
5161   /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN.  The
5162      workshare's GIMPLE_OMP_RETURN will be in a preceding block.  The kinds of
5163      statements that can appear in between are extremely limited -- no
5164      memory operations at all.  Here, we allow nothing at all, so the
5165      only thing we allow to precede this GIMPLE_OMP_RETURN is a label.  */
5166   gsi = gsi_last_bb (exit_bb);
5167   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
5168   gsi_prev (&gsi);
5169   if (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
5170     return;
5171
5172   FOR_EACH_EDGE (e, ei, exit_bb->preds)
5173     {
5174       gsi = gsi_last_bb (e->src);
5175       if (gsi_end_p (gsi))
5176         continue;
5177       stmt = gsi_stmt (gsi);
5178       if (gimple_code (stmt) == GIMPLE_OMP_RETURN
5179           && !gimple_omp_return_nowait_p (stmt))
5180         {
5181           /* OpenMP 3.0 tasks unfortunately prevent this optimization
5182              in many cases.  If there could be tasks queued, the barrier
5183              might be needed to let the tasks run before some local
5184              variable of the parallel that the task uses as shared
5185              runs out of scope.  The task can be spawned either
5186              from within current function (this would be easy to check)
5187              or from some function it calls and gets passed an address
5188              of such a variable.  */
5189           if (any_addressable_vars < 0)
5190             {
5191               gomp_parallel *parallel_stmt
5192                 = as_a <gomp_parallel *> (last_stmt (region->entry));
5193               tree child_fun = gimple_omp_parallel_child_fn (parallel_stmt);
5194               tree local_decls, block, decl;
5195               unsigned ix;
5196
5197               any_addressable_vars = 0;
5198               FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (child_fun), ix, decl)
5199                 if (TREE_ADDRESSABLE (decl))
5200                   {
5201                     any_addressable_vars = 1;
5202                     break;
5203                   }
5204               for (block = gimple_block (stmt);
5205                    !any_addressable_vars
5206                    && block
5207                    && TREE_CODE (block) == BLOCK;
5208                    block = BLOCK_SUPERCONTEXT (block))
5209                 {
5210                   for (local_decls = BLOCK_VARS (block);
5211                        local_decls;
5212                        local_decls = DECL_CHAIN (local_decls))
5213                     if (TREE_ADDRESSABLE (local_decls))
5214                       {
5215                         any_addressable_vars = 1;
5216                         break;
5217                       }
5218                   if (block == gimple_block (parallel_stmt))
5219                     break;
5220                 }
5221             }
5222           if (!any_addressable_vars)
5223             gimple_omp_return_set_nowait (stmt);
5224         }
5225     }
5226 }
5227
5228 static void
5229 remove_exit_barriers (struct omp_region *region)
5230 {
5231   if (region->type == GIMPLE_OMP_PARALLEL)
5232     remove_exit_barrier (region);
5233
5234   if (region->inner)
5235     {
5236       region = region->inner;
5237       remove_exit_barriers (region);
5238       while (region->next)
5239         {
5240           region = region->next;
5241           remove_exit_barriers (region);
5242         }
5243     }
5244 }
5245
5246 /* Optimize omp_get_thread_num () and omp_get_num_threads ()
5247    calls.  These can't be declared as const functions, but
5248    within one parallel body they are constant, so they can be
5249    transformed there into __builtin_omp_get_{thread_num,num_threads} ()
5250    which are declared const.  Similarly for task body, except
5251    that in untied task omp_get_thread_num () can change at any task
5252    scheduling point.  */
5253
5254 static void
5255 optimize_omp_library_calls (gimple entry_stmt)
5256 {
5257   basic_block bb;
5258   gimple_stmt_iterator gsi;
5259   tree thr_num_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
5260   tree thr_num_id = DECL_ASSEMBLER_NAME (thr_num_tree);
5261   tree num_thr_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
5262   tree num_thr_id = DECL_ASSEMBLER_NAME (num_thr_tree);
5263   bool untied_task = (gimple_code (entry_stmt) == GIMPLE_OMP_TASK
5264                       && find_omp_clause (gimple_omp_task_clauses (entry_stmt),
5265                                           OMP_CLAUSE_UNTIED) != NULL);
5266
5267   FOR_EACH_BB_FN (bb, cfun)
5268     for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5269       {
5270         gimple call = gsi_stmt (gsi);
5271         tree decl;
5272
5273         if (is_gimple_call (call)
5274             && (decl = gimple_call_fndecl (call))
5275             && DECL_EXTERNAL (decl)
5276             && TREE_PUBLIC (decl)
5277             && DECL_INITIAL (decl) == NULL)
5278           {
5279             tree built_in;
5280
5281             if (DECL_NAME (decl) == thr_num_id)
5282               {
5283                 /* In #pragma omp task untied omp_get_thread_num () can change
5284                    during the execution of the task region.  */
5285                 if (untied_task)
5286                   continue;
5287                 built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
5288               }
5289             else if (DECL_NAME (decl) == num_thr_id)
5290               built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
5291             else
5292               continue;
5293
5294             if (DECL_ASSEMBLER_NAME (decl) != DECL_ASSEMBLER_NAME (built_in)
5295                 || gimple_call_num_args (call) != 0)
5296               continue;
5297
5298             if (flag_exceptions && !TREE_NOTHROW (decl))
5299               continue;
5300
5301             if (TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE
5302                 || !types_compatible_p (TREE_TYPE (TREE_TYPE (decl)),
5303                                         TREE_TYPE (TREE_TYPE (built_in))))
5304               continue;
5305
5306             gimple_call_set_fndecl (call, built_in);
5307           }
5308       }
5309 }
5310
5311 /* Callback for expand_omp_build_assign.  Return non-NULL if *tp needs to be
5312    regimplified.  */
5313
5314 static tree
5315 expand_omp_regimplify_p (tree *tp, int *walk_subtrees, void *)
5316 {
5317   tree t = *tp;
5318
5319   /* Any variable with DECL_VALUE_EXPR needs to be regimplified.  */
5320   if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
5321     return t;
5322
5323   if (TREE_CODE (t) == ADDR_EXPR)
5324     recompute_tree_invariant_for_addr_expr (t);
5325
5326   *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
5327   return NULL_TREE;
5328 }
5329
5330 /* Prepend TO = FROM assignment before *GSI_P.  */
5331
5332 static void
5333 expand_omp_build_assign (gimple_stmt_iterator *gsi_p, tree to, tree from)
5334 {
5335   bool simple_p = DECL_P (to) && TREE_ADDRESSABLE (to);
5336   from = force_gimple_operand_gsi (gsi_p, from, simple_p, NULL_TREE,
5337                                    true, GSI_SAME_STMT);
5338   gimple stmt = gimple_build_assign (to, from);
5339   gsi_insert_before (gsi_p, stmt, GSI_SAME_STMT);
5340   if (walk_tree (&from, expand_omp_regimplify_p, NULL, NULL)
5341       || walk_tree (&to, expand_omp_regimplify_p, NULL, NULL))
5342     {
5343       gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
5344       gimple_regimplify_operands (stmt, &gsi);
5345     }
5346 }
5347
5348 /* Expand the OpenMP parallel or task directive starting at REGION.  */
5349
5350 static void
5351 expand_omp_taskreg (struct omp_region *region)
5352 {
5353   basic_block entry_bb, exit_bb, new_bb;
5354   struct function *child_cfun;
5355   tree child_fn, block, t;
5356   gimple_stmt_iterator gsi;
5357   gimple entry_stmt, stmt;
5358   edge e;
5359   vec<tree, va_gc> *ws_args;
5360
5361   entry_stmt = last_stmt (region->entry);
5362   child_fn = gimple_omp_taskreg_child_fn (entry_stmt);
5363   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
5364
5365   entry_bb = region->entry;
5366   exit_bb = region->exit;
5367
5368   bool is_cilk_for
5369     = (flag_cilkplus
5370        && gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL
5371        && find_omp_clause (gimple_omp_parallel_clauses (entry_stmt),
5372                            OMP_CLAUSE__CILK_FOR_COUNT_) != NULL_TREE);
5373
5374   if (is_cilk_for)
5375     /* If it is a _Cilk_for statement, it is modelled *like* a parallel for,
5376        and the inner statement contains the name of the built-in function
5377        and grain.  */
5378     ws_args = region->inner->ws_args;
5379   else if (is_combined_parallel (region))
5380     ws_args = region->ws_args;
5381   else
5382     ws_args = NULL;
5383
5384   if (child_cfun->cfg)
5385     {
5386       /* Due to inlining, it may happen that we have already outlined
5387          the region, in which case all we need to do is make the
5388          sub-graph unreachable and emit the parallel call.  */
5389       edge entry_succ_e, exit_succ_e;
5390
5391       entry_succ_e = single_succ_edge (entry_bb);
5392
5393       gsi = gsi_last_bb (entry_bb);
5394       gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_PARALLEL
5395                   || gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_TASK);
5396       gsi_remove (&gsi, true);
5397
5398       new_bb = entry_bb;
5399       if (exit_bb)
5400         {
5401           exit_succ_e = single_succ_edge (exit_bb);
5402           make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
5403         }
5404       remove_edge_and_dominated_blocks (entry_succ_e);
5405     }
5406   else
5407     {
5408       unsigned srcidx, dstidx, num;
5409
5410       /* If the parallel region needs data sent from the parent
5411          function, then the very first statement (except possible
5412          tree profile counter updates) of the parallel body
5413          is a copy assignment .OMP_DATA_I = &.OMP_DATA_O.  Since
5414          &.OMP_DATA_O is passed as an argument to the child function,
5415          we need to replace it with the argument as seen by the child
5416          function.
5417
5418          In most cases, this will end up being the identity assignment
5419          .OMP_DATA_I = .OMP_DATA_I.  However, if the parallel body had
5420          a function call that has been inlined, the original PARM_DECL
5421          .OMP_DATA_I may have been converted into a different local
5422          variable.  In which case, we need to keep the assignment.  */
5423       if (gimple_omp_taskreg_data_arg (entry_stmt))
5424         {
5425           basic_block entry_succ_bb = single_succ (entry_bb);
5426           tree arg, narg;
5427           gimple parcopy_stmt = NULL;
5428
5429           for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
5430             {
5431               gimple stmt;
5432
5433               gcc_assert (!gsi_end_p (gsi));
5434               stmt = gsi_stmt (gsi);
5435               if (gimple_code (stmt) != GIMPLE_ASSIGN)
5436                 continue;
5437
5438               if (gimple_num_ops (stmt) == 2)
5439                 {
5440                   tree arg = gimple_assign_rhs1 (stmt);
5441
5442                   /* We're ignore the subcode because we're
5443                      effectively doing a STRIP_NOPS.  */
5444
5445                   if (TREE_CODE (arg) == ADDR_EXPR
5446                       && TREE_OPERAND (arg, 0)
5447                         == gimple_omp_taskreg_data_arg (entry_stmt))
5448                     {
5449                       parcopy_stmt = stmt;
5450                       break;
5451                     }
5452                 }
5453             }
5454
5455           gcc_assert (parcopy_stmt != NULL);
5456           arg = DECL_ARGUMENTS (child_fn);
5457
5458           if (!gimple_in_ssa_p (cfun))
5459             {
5460               if (gimple_assign_lhs (parcopy_stmt) == arg)
5461                 gsi_remove (&gsi, true);
5462               else
5463                 {
5464                   /* ?? Is setting the subcode really necessary ??  */
5465                   gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (arg));
5466                   gimple_assign_set_rhs1 (parcopy_stmt, arg);
5467                 }
5468             }
5469           else
5470             {
5471               /* If we are in ssa form, we must load the value from the default
5472                  definition of the argument.  That should not be defined now,
5473                  since the argument is not used uninitialized.  */
5474               gcc_assert (ssa_default_def (cfun, arg) == NULL);
5475               narg = make_ssa_name (arg, gimple_build_nop ());
5476               set_ssa_default_def (cfun, arg, narg);
5477               /* ?? Is setting the subcode really necessary ??  */
5478               gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (narg));
5479               gimple_assign_set_rhs1 (parcopy_stmt, narg);
5480               update_stmt (parcopy_stmt);
5481             }
5482         }
5483
5484       /* Declare local variables needed in CHILD_CFUN.  */
5485       block = DECL_INITIAL (child_fn);
5486       BLOCK_VARS (block) = vec2chain (child_cfun->local_decls);
5487       /* The gimplifier could record temporaries in parallel/task block
5488          rather than in containing function's local_decls chain,
5489          which would mean cgraph missed finalizing them.  Do it now.  */
5490       for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
5491         if (TREE_CODE (t) == VAR_DECL
5492             && TREE_STATIC (t)
5493             && !DECL_EXTERNAL (t))
5494           varpool_node::finalize_decl (t);
5495       DECL_SAVED_TREE (child_fn) = NULL;
5496       /* We'll create a CFG for child_fn, so no gimple body is needed.  */
5497       gimple_set_body (child_fn, NULL);
5498       TREE_USED (block) = 1;
5499
5500       /* Reset DECL_CONTEXT on function arguments.  */
5501       for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
5502         DECL_CONTEXT (t) = child_fn;
5503
5504       /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
5505          so that it can be moved to the child function.  */
5506       gsi = gsi_last_bb (entry_bb);
5507       stmt = gsi_stmt (gsi);
5508       gcc_assert (stmt && (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
5509                            || gimple_code (stmt) == GIMPLE_OMP_TASK));
5510       gsi_remove (&gsi, true);
5511       e = split_block (entry_bb, stmt);
5512       entry_bb = e->dest;
5513       single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
5514
5515       /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR.  */
5516       if (exit_bb)
5517         {
5518           gsi = gsi_last_bb (exit_bb);
5519           gcc_assert (!gsi_end_p (gsi)
5520                       && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
5521           stmt = gimple_build_return (NULL);
5522           gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
5523           gsi_remove (&gsi, true);
5524         }
5525
5526       /* Move the parallel region into CHILD_CFUN.  */
5527
5528       if (gimple_in_ssa_p (cfun))
5529         {
5530           init_tree_ssa (child_cfun);
5531           init_ssa_operands (child_cfun);
5532           child_cfun->gimple_df->in_ssa_p = true;
5533           block = NULL_TREE;
5534         }
5535       else
5536         block = gimple_block (entry_stmt);
5537
5538       new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
5539       if (exit_bb)
5540         single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
5541       /* When the OMP expansion process cannot guarantee an up-to-date
5542          loop tree arrange for the child function to fixup loops.  */
5543       if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
5544         child_cfun->x_current_loops->state |= LOOPS_NEED_FIXUP;
5545
5546       /* Remove non-local VAR_DECLs from child_cfun->local_decls list.  */
5547       num = vec_safe_length (child_cfun->local_decls);
5548       for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
5549         {
5550           t = (*child_cfun->local_decls)[srcidx];
5551           if (DECL_CONTEXT (t) == cfun->decl)
5552             continue;
5553           if (srcidx != dstidx)
5554             (*child_cfun->local_decls)[dstidx] = t;
5555           dstidx++;
5556         }
5557       if (dstidx != num)
5558         vec_safe_truncate (child_cfun->local_decls, dstidx);
5559
5560       /* Inform the callgraph about the new function.  */
5561       DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
5562       cgraph_node::add_new_function (child_fn, true);
5563
5564       /* Fix the callgraph edges for child_cfun.  Those for cfun will be
5565          fixed in a following pass.  */
5566       push_cfun (child_cfun);
5567       if (optimize)
5568         optimize_omp_library_calls (entry_stmt);
5569       cgraph_edge::rebuild_edges ();
5570
5571       /* Some EH regions might become dead, see PR34608.  If
5572          pass_cleanup_cfg isn't the first pass to happen with the
5573          new child, these dead EH edges might cause problems.
5574          Clean them up now.  */
5575       if (flag_exceptions)
5576         {
5577           basic_block bb;
5578           bool changed = false;
5579
5580           FOR_EACH_BB_FN (bb, cfun)
5581             changed |= gimple_purge_dead_eh_edges (bb);
5582           if (changed)
5583             cleanup_tree_cfg ();
5584         }
5585       if (gimple_in_ssa_p (cfun))
5586         update_ssa (TODO_update_ssa);
5587       pop_cfun ();
5588     }
5589
5590   /* Emit a library call to launch the children threads.  */
5591   if (is_cilk_for)
5592     expand_cilk_for_call (new_bb,
5593                           as_a <gomp_parallel *> (entry_stmt), ws_args);
5594   else if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
5595     expand_parallel_call (region, new_bb,
5596                           as_a <gomp_parallel *> (entry_stmt), ws_args);
5597   else
5598     expand_task_call (new_bb, as_a <gomp_task *> (entry_stmt));
5599   if (gimple_in_ssa_p (cfun))
5600     update_ssa (TODO_update_ssa_only_virtuals);
5601 }
5602
5603
5604 /* Helper function for expand_omp_{for_*,simd}.  If this is the outermost
5605    of the combined collapse > 1 loop constructs, generate code like:
5606         if (__builtin_expect (N32 cond3 N31, 0)) goto ZERO_ITER_BB;
5607         if (cond3 is <)
5608           adj = STEP3 - 1;
5609         else
5610           adj = STEP3 + 1;
5611         count3 = (adj + N32 - N31) / STEP3;
5612         if (__builtin_expect (N22 cond2 N21, 0)) goto ZERO_ITER_BB;
5613         if (cond2 is <)
5614           adj = STEP2 - 1;
5615         else
5616           adj = STEP2 + 1;
5617         count2 = (adj + N22 - N21) / STEP2;
5618         if (__builtin_expect (N12 cond1 N11, 0)) goto ZERO_ITER_BB;
5619         if (cond1 is <)
5620           adj = STEP1 - 1;
5621         else
5622           adj = STEP1 + 1;
5623         count1 = (adj + N12 - N11) / STEP1;
5624         count = count1 * count2 * count3;
5625    Furthermore, if ZERO_ITER_BB is NULL, create a BB which does:
5626         count = 0;
5627    and set ZERO_ITER_BB to that bb.  If this isn't the outermost
5628    of the combined loop constructs, just initialize COUNTS array
5629    from the _looptemp_ clauses.  */
5630
5631 /* NOTE: It *could* be better to moosh all of the BBs together,
5632    creating one larger BB with all the computation and the unexpected
5633    jump at the end.  I.e.
5634
5635    bool zero3, zero2, zero1, zero;
5636
5637    zero3 = N32 c3 N31;
5638    count3 = (N32 - N31) /[cl] STEP3;
5639    zero2 = N22 c2 N21;
5640    count2 = (N22 - N21) /[cl] STEP2;
5641    zero1 = N12 c1 N11;
5642    count1 = (N12 - N11) /[cl] STEP1;
5643    zero = zero3 || zero2 || zero1;
5644    count = count1 * count2 * count3;
5645    if (__builtin_expect(zero, false)) goto zero_iter_bb;
5646
5647    After all, we expect the zero=false, and thus we expect to have to
5648    evaluate all of the comparison expressions, so short-circuiting
5649    oughtn't be a win.  Since the condition isn't protecting a
5650    denominator, we're not concerned about divide-by-zero, so we can
5651    fully evaluate count even if a numerator turned out to be wrong.
5652
5653    It seems like putting this all together would create much better
5654    scheduling opportunities, and less pressure on the chip's branch
5655    predictor.  */
5656
5657 static void
5658 expand_omp_for_init_counts (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
5659                             basic_block &entry_bb, tree *counts,
5660                             basic_block &zero_iter_bb, int &first_zero_iter,
5661                             basic_block &l2_dom_bb)
5662 {
5663   tree t, type = TREE_TYPE (fd->loop.v);
5664   edge e, ne;
5665   int i;
5666
5667   /* Collapsed loops need work for expansion into SSA form.  */
5668   gcc_assert (!gimple_in_ssa_p (cfun));
5669
5670   if (gimple_omp_for_combined_into_p (fd->for_stmt)
5671       && TREE_CODE (fd->loop.n2) != INTEGER_CST)
5672     {
5673       /* First two _looptemp_ clauses are for istart/iend, counts[0]
5674          isn't supposed to be handled, as the inner loop doesn't
5675          use it.  */
5676       tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
5677                                      OMP_CLAUSE__LOOPTEMP_);
5678       gcc_assert (innerc);
5679       for (i = 0; i < fd->collapse; i++)
5680         {
5681           innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
5682                                     OMP_CLAUSE__LOOPTEMP_);
5683           gcc_assert (innerc);
5684           if (i)
5685             counts[i] = OMP_CLAUSE_DECL (innerc);
5686           else
5687             counts[0] = NULL_TREE;
5688         }
5689       return;
5690     }
5691
5692   for (i = 0; i < fd->collapse; i++)
5693     {
5694       tree itype = TREE_TYPE (fd->loops[i].v);
5695
5696       if (SSA_VAR_P (fd->loop.n2)
5697           && ((t = fold_binary (fd->loops[i].cond_code, boolean_type_node,
5698                                 fold_convert (itype, fd->loops[i].n1),
5699                                 fold_convert (itype, fd->loops[i].n2)))
5700               == NULL_TREE || !integer_onep (t)))
5701         {
5702           gcond *cond_stmt;
5703           tree n1, n2;
5704           n1 = fold_convert (itype, unshare_expr (fd->loops[i].n1));
5705           n1 = force_gimple_operand_gsi (gsi, n1, true, NULL_TREE,
5706                                          true, GSI_SAME_STMT);
5707           n2 = fold_convert (itype, unshare_expr (fd->loops[i].n2));
5708           n2 = force_gimple_operand_gsi (gsi, n2, true, NULL_TREE,
5709                                          true, GSI_SAME_STMT);
5710           cond_stmt = gimple_build_cond (fd->loops[i].cond_code, n1, n2,
5711                                          NULL_TREE, NULL_TREE);
5712           gsi_insert_before (gsi, cond_stmt, GSI_SAME_STMT);
5713           if (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
5714                          expand_omp_regimplify_p, NULL, NULL)
5715               || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
5716                             expand_omp_regimplify_p, NULL, NULL))
5717             {
5718               *gsi = gsi_for_stmt (cond_stmt);
5719               gimple_regimplify_operands (cond_stmt, gsi);
5720             }
5721           e = split_block (entry_bb, cond_stmt);
5722           if (zero_iter_bb == NULL)
5723             {
5724               gassign *assign_stmt;
5725               first_zero_iter = i;
5726               zero_iter_bb = create_empty_bb (entry_bb);
5727               add_bb_to_loop (zero_iter_bb, entry_bb->loop_father);
5728               *gsi = gsi_after_labels (zero_iter_bb);
5729               assign_stmt = gimple_build_assign (fd->loop.n2,
5730                                                  build_zero_cst (type));
5731               gsi_insert_before (gsi, assign_stmt, GSI_SAME_STMT);
5732               set_immediate_dominator (CDI_DOMINATORS, zero_iter_bb,
5733                                        entry_bb);
5734             }
5735           ne = make_edge (entry_bb, zero_iter_bb, EDGE_FALSE_VALUE);
5736           ne->probability = REG_BR_PROB_BASE / 2000 - 1;
5737           e->flags = EDGE_TRUE_VALUE;
5738           e->probability = REG_BR_PROB_BASE - ne->probability;
5739           if (l2_dom_bb == NULL)
5740             l2_dom_bb = entry_bb;
5741           entry_bb = e->dest;
5742           *gsi = gsi_last_bb (entry_bb);
5743         }
5744
5745       if (POINTER_TYPE_P (itype))
5746         itype = signed_type_for (itype);
5747       t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR
5748                                  ? -1 : 1));
5749       t = fold_build2 (PLUS_EXPR, itype,
5750                        fold_convert (itype, fd->loops[i].step), t);
5751       t = fold_build2 (PLUS_EXPR, itype, t,
5752                        fold_convert (itype, fd->loops[i].n2));
5753       t = fold_build2 (MINUS_EXPR, itype, t,
5754                        fold_convert (itype, fd->loops[i].n1));
5755       /* ?? We could probably use CEIL_DIV_EXPR instead of
5756          TRUNC_DIV_EXPR and adjusting by hand.  Unless we can't
5757          generate the same code in the end because generically we
5758          don't know that the values involved must be negative for
5759          GT??  */
5760       if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
5761         t = fold_build2 (TRUNC_DIV_EXPR, itype,
5762                          fold_build1 (NEGATE_EXPR, itype, t),
5763                          fold_build1 (NEGATE_EXPR, itype,
5764                                       fold_convert (itype,
5765                                                     fd->loops[i].step)));
5766       else
5767         t = fold_build2 (TRUNC_DIV_EXPR, itype, t,
5768                          fold_convert (itype, fd->loops[i].step));
5769       t = fold_convert (type, t);
5770       if (TREE_CODE (t) == INTEGER_CST)
5771         counts[i] = t;
5772       else
5773         {
5774           counts[i] = create_tmp_reg (type, ".count");
5775           expand_omp_build_assign (gsi, counts[i], t);
5776         }
5777       if (SSA_VAR_P (fd->loop.n2))
5778         {
5779           if (i == 0)
5780             t = counts[0];
5781           else
5782             t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
5783           expand_omp_build_assign (gsi, fd->loop.n2, t);
5784         }
5785     }
5786 }
5787
5788
5789 /* Helper function for expand_omp_{for_*,simd}.  Generate code like:
5790         T = V;
5791         V3 = N31 + (T % count3) * STEP3;
5792         T = T / count3;
5793         V2 = N21 + (T % count2) * STEP2;
5794         T = T / count2;
5795         V1 = N11 + T * STEP1;
5796    if this loop doesn't have an inner loop construct combined with it.
5797    If it does have an inner loop construct combined with it and the
5798    iteration count isn't known constant, store values from counts array
5799    into its _looptemp_ temporaries instead.  */
5800
5801 static void
5802 expand_omp_for_init_vars (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
5803                           tree *counts, gimple inner_stmt, tree startvar)
5804 {
5805   int i;
5806   if (gimple_omp_for_combined_p (fd->for_stmt))
5807     {
5808       /* If fd->loop.n2 is constant, then no propagation of the counts
5809          is needed, they are constant.  */
5810       if (TREE_CODE (fd->loop.n2) == INTEGER_CST)
5811         return;
5812
5813       tree clauses = gimple_code (inner_stmt) == GIMPLE_OMP_PARALLEL
5814                      ? gimple_omp_parallel_clauses (inner_stmt)
5815                      : gimple_omp_for_clauses (inner_stmt);
5816       /* First two _looptemp_ clauses are for istart/iend, counts[0]
5817          isn't supposed to be handled, as the inner loop doesn't
5818          use it.  */
5819       tree innerc = find_omp_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
5820       gcc_assert (innerc);
5821       for (i = 0; i < fd->collapse; i++)
5822         {
5823           innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
5824                                     OMP_CLAUSE__LOOPTEMP_);
5825           gcc_assert (innerc);
5826           if (i)
5827             {
5828               tree tem = OMP_CLAUSE_DECL (innerc);
5829               tree t = fold_convert (TREE_TYPE (tem), counts[i]);
5830               t = force_gimple_operand_gsi (gsi, t, false, NULL_TREE,
5831                                             false, GSI_CONTINUE_LINKING);
5832               gassign *stmt = gimple_build_assign (tem, t);
5833               gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
5834             }
5835         }
5836       return;
5837     }
5838
5839   tree type = TREE_TYPE (fd->loop.v);
5840   tree tem = create_tmp_reg (type, ".tem");
5841   gassign *stmt = gimple_build_assign (tem, startvar);
5842   gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
5843
5844   for (i = fd->collapse - 1; i >= 0; i--)
5845     {
5846       tree vtype = TREE_TYPE (fd->loops[i].v), itype, t;
5847       itype = vtype;
5848       if (POINTER_TYPE_P (vtype))
5849         itype = signed_type_for (vtype);
5850       if (i != 0)
5851         t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
5852       else
5853         t = tem;
5854       t = fold_convert (itype, t);
5855       t = fold_build2 (MULT_EXPR, itype, t,
5856                        fold_convert (itype, fd->loops[i].step));
5857       if (POINTER_TYPE_P (vtype))
5858         t = fold_build_pointer_plus (fd->loops[i].n1, t);
5859       else
5860         t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
5861       t = force_gimple_operand_gsi (gsi, t,
5862                                     DECL_P (fd->loops[i].v)
5863                                     && TREE_ADDRESSABLE (fd->loops[i].v),
5864                                     NULL_TREE, false,
5865                                     GSI_CONTINUE_LINKING);
5866       stmt = gimple_build_assign (fd->loops[i].v, t);
5867       gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
5868       if (i != 0)
5869         {
5870           t = fold_build2 (TRUNC_DIV_EXPR, type, tem, counts[i]);
5871           t = force_gimple_operand_gsi (gsi, t, false, NULL_TREE,
5872                                         false, GSI_CONTINUE_LINKING);
5873           stmt = gimple_build_assign (tem, t);
5874           gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
5875         }
5876     }
5877 }
5878
5879
5880 /* Helper function for expand_omp_for_*.  Generate code like:
5881     L10:
5882         V3 += STEP3;
5883         if (V3 cond3 N32) goto BODY_BB; else goto L11;
5884     L11:
5885         V3 = N31;
5886         V2 += STEP2;
5887         if (V2 cond2 N22) goto BODY_BB; else goto L12;
5888     L12:
5889         V2 = N21;
5890         V1 += STEP1;
5891         goto BODY_BB;  */
5892
5893 static basic_block
5894 extract_omp_for_update_vars (struct omp_for_data *fd, basic_block cont_bb,
5895                              basic_block body_bb)
5896 {
5897   basic_block last_bb, bb, collapse_bb = NULL;
5898   int i;
5899   gimple_stmt_iterator gsi;
5900   edge e;
5901   tree t;
5902   gimple stmt;
5903
5904   last_bb = cont_bb;
5905   for (i = fd->collapse - 1; i >= 0; i--)
5906     {
5907       tree vtype = TREE_TYPE (fd->loops[i].v);
5908
5909       bb = create_empty_bb (last_bb);
5910       add_bb_to_loop (bb, last_bb->loop_father);
5911       gsi = gsi_start_bb (bb);
5912
5913       if (i < fd->collapse - 1)
5914         {
5915           e = make_edge (last_bb, bb, EDGE_FALSE_VALUE);
5916           e->probability = REG_BR_PROB_BASE / 8;
5917
5918           t = fd->loops[i + 1].n1;
5919           t = force_gimple_operand_gsi (&gsi, t,
5920                                         DECL_P (fd->loops[i + 1].v)
5921                                         && TREE_ADDRESSABLE (fd->loops[i
5922                                                                        + 1].v),
5923                                         NULL_TREE, false,
5924                                         GSI_CONTINUE_LINKING);
5925           stmt = gimple_build_assign (fd->loops[i + 1].v, t);
5926           gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
5927         }
5928       else
5929         collapse_bb = bb;
5930
5931       set_immediate_dominator (CDI_DOMINATORS, bb, last_bb);
5932
5933       if (POINTER_TYPE_P (vtype))
5934         t = fold_build_pointer_plus (fd->loops[i].v, fd->loops[i].step);
5935       else
5936         t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v, fd->loops[i].step);
5937       t = force_gimple_operand_gsi (&gsi, t,
5938                                     DECL_P (fd->loops[i].v)
5939                                     && TREE_ADDRESSABLE (fd->loops[i].v),
5940                                     NULL_TREE, false, GSI_CONTINUE_LINKING);
5941       stmt = gimple_build_assign (fd->loops[i].v, t);
5942       gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
5943
5944       if (i > 0)
5945         {
5946           t = fd->loops[i].n2;
5947           t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
5948                                         false, GSI_CONTINUE_LINKING);
5949           tree v = fd->loops[i].v;
5950           if (DECL_P (v) && TREE_ADDRESSABLE (v))
5951             v = force_gimple_operand_gsi (&gsi, v, true, NULL_TREE,
5952                                           false, GSI_CONTINUE_LINKING);
5953           t = fold_build2 (fd->loops[i].cond_code, boolean_type_node, v, t);
5954           stmt = gimple_build_cond_empty (t);
5955           gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
5956           e = make_edge (bb, body_bb, EDGE_TRUE_VALUE);
5957           e->probability = REG_BR_PROB_BASE * 7 / 8;
5958         }
5959       else
5960         make_edge (bb, body_bb, EDGE_FALLTHRU);
5961       last_bb = bb;
5962     }
5963
5964   return collapse_bb;
5965 }
5966
5967
5968 /* A subroutine of expand_omp_for.  Generate code for a parallel
5969    loop with any schedule.  Given parameters:
5970
5971         for (V = N1; V cond N2; V += STEP) BODY;
5972
5973    where COND is "<" or ">", we generate pseudocode
5974
5975         more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
5976         if (more) goto L0; else goto L3;
5977     L0:
5978         V = istart0;
5979         iend = iend0;
5980     L1:
5981         BODY;
5982         V += STEP;
5983         if (V cond iend) goto L1; else goto L2;
5984     L2:
5985         if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
5986     L3:
5987
5988     If this is a combined omp parallel loop, instead of the call to
5989     GOMP_loop_foo_start, we call GOMP_loop_foo_next.
5990     If this is gimple_omp_for_combined_p loop, then instead of assigning
5991     V and iend in L0 we assign the first two _looptemp_ clause decls of the
5992     inner GIMPLE_OMP_FOR and V += STEP; and
5993     if (V cond iend) goto L1; else goto L2; are removed.
5994
5995     For collapsed loops, given parameters:
5996       collapse(3)
5997       for (V1 = N11; V1 cond1 N12; V1 += STEP1)
5998         for (V2 = N21; V2 cond2 N22; V2 += STEP2)
5999           for (V3 = N31; V3 cond3 N32; V3 += STEP3)
6000             BODY;
6001
6002     we generate pseudocode
6003
6004         if (__builtin_expect (N32 cond3 N31, 0)) goto Z0;
6005         if (cond3 is <)
6006           adj = STEP3 - 1;
6007         else
6008           adj = STEP3 + 1;
6009         count3 = (adj + N32 - N31) / STEP3;
6010         if (__builtin_expect (N22 cond2 N21, 0)) goto Z0;
6011         if (cond2 is <)
6012           adj = STEP2 - 1;
6013         else
6014           adj = STEP2 + 1;
6015         count2 = (adj + N22 - N21) / STEP2;
6016         if (__builtin_expect (N12 cond1 N11, 0)) goto Z0;
6017         if (cond1 is <)
6018           adj = STEP1 - 1;
6019         else
6020           adj = STEP1 + 1;
6021         count1 = (adj + N12 - N11) / STEP1;
6022         count = count1 * count2 * count3;
6023         goto Z1;
6024     Z0:
6025         count = 0;
6026     Z1:
6027         more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
6028         if (more) goto L0; else goto L3;
6029     L0:
6030         V = istart0;
6031         T = V;
6032         V3 = N31 + (T % count3) * STEP3;
6033         T = T / count3;
6034         V2 = N21 + (T % count2) * STEP2;
6035         T = T / count2;
6036         V1 = N11 + T * STEP1;
6037         iend = iend0;
6038     L1:
6039         BODY;
6040         V += 1;
6041         if (V < iend) goto L10; else goto L2;
6042     L10:
6043         V3 += STEP3;
6044         if (V3 cond3 N32) goto L1; else goto L11;
6045     L11:
6046         V3 = N31;
6047         V2 += STEP2;
6048         if (V2 cond2 N22) goto L1; else goto L12;
6049     L12:
6050         V2 = N21;
6051         V1 += STEP1;
6052         goto L1;
6053     L2:
6054         if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
6055     L3:
6056
6057       */
6058
6059 static void
6060 expand_omp_for_generic (struct omp_region *region,
6061                         struct omp_for_data *fd,
6062                         enum built_in_function start_fn,
6063                         enum built_in_function next_fn,
6064                         gimple inner_stmt)
6065 {
6066   tree type, istart0, iend0, iend;
6067   tree t, vmain, vback, bias = NULL_TREE;
6068   basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, collapse_bb;
6069   basic_block l2_bb = NULL, l3_bb = NULL;
6070   gimple_stmt_iterator gsi;
6071   gassign *assign_stmt;
6072   bool in_combined_parallel = is_combined_parallel (region);
6073   bool broken_loop = region->cont == NULL;
6074   edge e, ne;
6075   tree *counts = NULL;
6076   int i;
6077
6078   gcc_assert (!broken_loop || !in_combined_parallel);
6079   gcc_assert (fd->iter_type == long_integer_type_node
6080               || !in_combined_parallel);
6081
6082   type = TREE_TYPE (fd->loop.v);
6083   istart0 = create_tmp_var (fd->iter_type, ".istart0");
6084   iend0 = create_tmp_var (fd->iter_type, ".iend0");
6085   TREE_ADDRESSABLE (istart0) = 1;
6086   TREE_ADDRESSABLE (iend0) = 1;
6087
6088   /* See if we need to bias by LLONG_MIN.  */
6089   if (fd->iter_type == long_long_unsigned_type_node
6090       && TREE_CODE (type) == INTEGER_TYPE
6091       && !TYPE_UNSIGNED (type))
6092     {
6093       tree n1, n2;
6094
6095       if (fd->loop.cond_code == LT_EXPR)
6096         {
6097           n1 = fd->loop.n1;
6098           n2 = fold_build2 (PLUS_EXPR, type, fd->loop.n2, fd->loop.step);
6099         }
6100       else
6101         {
6102           n1 = fold_build2 (MINUS_EXPR, type, fd->loop.n2, fd->loop.step);
6103           n2 = fd->loop.n1;
6104         }
6105       if (TREE_CODE (n1) != INTEGER_CST
6106           || TREE_CODE (n2) != INTEGER_CST
6107           || ((tree_int_cst_sgn (n1) < 0) ^ (tree_int_cst_sgn (n2) < 0)))
6108         bias = fold_convert (fd->iter_type, TYPE_MIN_VALUE (type));
6109     }
6110
6111   entry_bb = region->entry;
6112   cont_bb = region->cont;
6113   collapse_bb = NULL;
6114   gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
6115   gcc_assert (broken_loop
6116               || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
6117   l0_bb = split_edge (FALLTHRU_EDGE (entry_bb));
6118   l1_bb = single_succ (l0_bb);
6119   if (!broken_loop)
6120     {
6121       l2_bb = create_empty_bb (cont_bb);
6122       gcc_assert (BRANCH_EDGE (cont_bb)->dest == l1_bb);
6123       gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
6124     }
6125   else
6126     l2_bb = NULL;
6127   l3_bb = BRANCH_EDGE (entry_bb)->dest;
6128   exit_bb = region->exit;
6129
6130   gsi = gsi_last_bb (entry_bb);
6131
6132   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
6133   if (fd->collapse > 1)
6134     {
6135       int first_zero_iter = -1;
6136       basic_block zero_iter_bb = NULL, l2_dom_bb = NULL;
6137
6138       counts = XALLOCAVEC (tree, fd->collapse);
6139       expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
6140                                   zero_iter_bb, first_zero_iter,
6141                                   l2_dom_bb);
6142
6143       if (zero_iter_bb)
6144         {
6145           /* Some counts[i] vars might be uninitialized if
6146              some loop has zero iterations.  But the body shouldn't
6147              be executed in that case, so just avoid uninit warnings.  */
6148           for (i = first_zero_iter; i < fd->collapse; i++)
6149             if (SSA_VAR_P (counts[i]))
6150               TREE_NO_WARNING (counts[i]) = 1;
6151           gsi_prev (&gsi);
6152           e = split_block (entry_bb, gsi_stmt (gsi));
6153           entry_bb = e->dest;
6154           make_edge (zero_iter_bb, entry_bb, EDGE_FALLTHRU);
6155           gsi = gsi_last_bb (entry_bb);
6156           set_immediate_dominator (CDI_DOMINATORS, entry_bb,
6157                                    get_immediate_dominator (CDI_DOMINATORS,
6158                                                             zero_iter_bb));
6159         }
6160     }
6161   if (in_combined_parallel)
6162     {
6163       /* In a combined parallel loop, emit a call to
6164          GOMP_loop_foo_next.  */
6165       t = build_call_expr (builtin_decl_explicit (next_fn), 2,
6166                            build_fold_addr_expr (istart0),
6167                            build_fold_addr_expr (iend0));
6168     }
6169   else
6170     {
6171       tree t0, t1, t2, t3, t4;
6172       /* If this is not a combined parallel loop, emit a call to
6173          GOMP_loop_foo_start in ENTRY_BB.  */
6174       t4 = build_fold_addr_expr (iend0);
6175       t3 = build_fold_addr_expr (istart0);
6176       t2 = fold_convert (fd->iter_type, fd->loop.step);
6177       t1 = fd->loop.n2;
6178       t0 = fd->loop.n1;
6179       if (gimple_omp_for_combined_into_p (fd->for_stmt))
6180         {
6181           tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
6182                                          OMP_CLAUSE__LOOPTEMP_);
6183           gcc_assert (innerc);
6184           t0 = OMP_CLAUSE_DECL (innerc);
6185           innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
6186                                     OMP_CLAUSE__LOOPTEMP_);
6187           gcc_assert (innerc);
6188           t1 = OMP_CLAUSE_DECL (innerc);
6189         }
6190       if (POINTER_TYPE_P (TREE_TYPE (t0))
6191           && TYPE_PRECISION (TREE_TYPE (t0))
6192              != TYPE_PRECISION (fd->iter_type))
6193         {
6194           /* Avoid casting pointers to integer of a different size.  */
6195           tree itype = signed_type_for (type);
6196           t1 = fold_convert (fd->iter_type, fold_convert (itype, t1));
6197           t0 = fold_convert (fd->iter_type, fold_convert (itype, t0));
6198         }
6199       else
6200         {
6201           t1 = fold_convert (fd->iter_type, t1);
6202           t0 = fold_convert (fd->iter_type, t0);
6203         }
6204       if (bias)
6205         {
6206           t1 = fold_build2 (PLUS_EXPR, fd->iter_type, t1, bias);
6207           t0 = fold_build2 (PLUS_EXPR, fd->iter_type, t0, bias);
6208         }
6209       if (fd->iter_type == long_integer_type_node)
6210         {
6211           if (fd->chunk_size)
6212             {
6213               t = fold_convert (fd->iter_type, fd->chunk_size);
6214               t = build_call_expr (builtin_decl_explicit (start_fn),
6215                                    6, t0, t1, t2, t, t3, t4);
6216             }
6217           else
6218             t = build_call_expr (builtin_decl_explicit (start_fn),
6219                                  5, t0, t1, t2, t3, t4);
6220         }
6221       else
6222         {
6223           tree t5;
6224           tree c_bool_type;
6225           tree bfn_decl;
6226
6227           /* The GOMP_loop_ull_*start functions have additional boolean
6228              argument, true for < loops and false for > loops.
6229              In Fortran, the C bool type can be different from
6230              boolean_type_node.  */
6231           bfn_decl = builtin_decl_explicit (start_fn);
6232           c_bool_type = TREE_TYPE (TREE_TYPE (bfn_decl));
6233           t5 = build_int_cst (c_bool_type,
6234                               fd->loop.cond_code == LT_EXPR ? 1 : 0);
6235           if (fd->chunk_size)
6236             {
6237               tree bfn_decl = builtin_decl_explicit (start_fn);
6238               t = fold_convert (fd->iter_type, fd->chunk_size);
6239               t = build_call_expr (bfn_decl, 7, t5, t0, t1, t2, t, t3, t4);
6240             }
6241           else
6242             t = build_call_expr (builtin_decl_explicit (start_fn),
6243                                  6, t5, t0, t1, t2, t3, t4);
6244         }
6245     }
6246   if (TREE_TYPE (t) != boolean_type_node)
6247     t = fold_build2 (NE_EXPR, boolean_type_node,
6248                      t, build_int_cst (TREE_TYPE (t), 0));
6249   t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
6250                                 true, GSI_SAME_STMT);
6251   gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
6252
6253   /* Remove the GIMPLE_OMP_FOR statement.  */
6254   gsi_remove (&gsi, true);
6255
6256   /* Iteration setup for sequential loop goes in L0_BB.  */
6257   tree startvar = fd->loop.v;
6258   tree endvar = NULL_TREE;
6259
6260   if (gimple_omp_for_combined_p (fd->for_stmt))
6261     {
6262       gcc_assert (gimple_code (inner_stmt) == GIMPLE_OMP_FOR
6263                   && gimple_omp_for_kind (inner_stmt)
6264                      == GF_OMP_FOR_KIND_SIMD);
6265       tree innerc = find_omp_clause (gimple_omp_for_clauses (inner_stmt),
6266                                      OMP_CLAUSE__LOOPTEMP_);
6267       gcc_assert (innerc);
6268       startvar = OMP_CLAUSE_DECL (innerc);
6269       innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
6270                                 OMP_CLAUSE__LOOPTEMP_);
6271       gcc_assert (innerc);
6272       endvar = OMP_CLAUSE_DECL (innerc);
6273     }
6274
6275   gsi = gsi_start_bb (l0_bb);
6276   t = istart0;
6277   if (bias)
6278     t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
6279   if (POINTER_TYPE_P (TREE_TYPE (startvar)))
6280     t = fold_convert (signed_type_for (TREE_TYPE (startvar)), t);
6281   t = fold_convert (TREE_TYPE (startvar), t);
6282   t = force_gimple_operand_gsi (&gsi, t,
6283                                 DECL_P (startvar)
6284                                 && TREE_ADDRESSABLE (startvar),
6285                                 NULL_TREE, false, GSI_CONTINUE_LINKING);
6286   assign_stmt = gimple_build_assign (startvar, t);
6287   gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
6288
6289   t = iend0;
6290   if (bias)
6291     t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
6292   if (POINTER_TYPE_P (TREE_TYPE (startvar)))
6293     t = fold_convert (signed_type_for (TREE_TYPE (startvar)), t);
6294   t = fold_convert (TREE_TYPE (startvar), t);
6295   iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
6296                                    false, GSI_CONTINUE_LINKING);
6297   if (endvar)
6298     {
6299       assign_stmt = gimple_build_assign (endvar, iend);
6300       gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
6301       if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (iend)))
6302         assign_stmt = gimple_build_assign (fd->loop.v, iend);
6303       else
6304         assign_stmt = gimple_build_assign (fd->loop.v, NOP_EXPR, iend);
6305       gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
6306     }
6307   if (fd->collapse > 1)
6308     expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
6309
6310   if (!broken_loop)
6311     {
6312       /* Code to control the increment and predicate for the sequential
6313          loop goes in the CONT_BB.  */
6314       gsi = gsi_last_bb (cont_bb);
6315       gomp_continue *cont_stmt = as_a <gomp_continue *> (gsi_stmt (gsi));
6316       gcc_assert (gimple_code (cont_stmt) == GIMPLE_OMP_CONTINUE);
6317       vmain = gimple_omp_continue_control_use (cont_stmt);
6318       vback = gimple_omp_continue_control_def (cont_stmt);
6319
6320       if (!gimple_omp_for_combined_p (fd->for_stmt))
6321         {
6322           if (POINTER_TYPE_P (type))
6323             t = fold_build_pointer_plus (vmain, fd->loop.step);
6324           else
6325             t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
6326           t = force_gimple_operand_gsi (&gsi, t,
6327                                         DECL_P (vback)
6328                                         && TREE_ADDRESSABLE (vback),
6329                                         NULL_TREE, true, GSI_SAME_STMT);
6330           assign_stmt = gimple_build_assign (vback, t);
6331           gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
6332
6333           t = build2 (fd->loop.cond_code, boolean_type_node,
6334                       DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback,
6335                       iend);
6336           gcond *cond_stmt = gimple_build_cond_empty (t);
6337           gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
6338         }
6339
6340       /* Remove GIMPLE_OMP_CONTINUE.  */
6341       gsi_remove (&gsi, true);
6342
6343       if (fd->collapse > 1 && !gimple_omp_for_combined_p (fd->for_stmt))
6344         collapse_bb = extract_omp_for_update_vars (fd, cont_bb, l1_bb);
6345
6346       /* Emit code to get the next parallel iteration in L2_BB.  */
6347       gsi = gsi_start_bb (l2_bb);
6348
6349       t = build_call_expr (builtin_decl_explicit (next_fn), 2,
6350                            build_fold_addr_expr (istart0),
6351                            build_fold_addr_expr (iend0));
6352       t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
6353                                     false, GSI_CONTINUE_LINKING);
6354       if (TREE_TYPE (t) != boolean_type_node)
6355         t = fold_build2 (NE_EXPR, boolean_type_node,
6356                          t, build_int_cst (TREE_TYPE (t), 0));
6357       gcond *cond_stmt = gimple_build_cond_empty (t);
6358       gsi_insert_after (&gsi, cond_stmt, GSI_CONTINUE_LINKING);
6359     }
6360
6361   /* Add the loop cleanup function.  */
6362   gsi = gsi_last_bb (exit_bb);
6363   if (gimple_omp_return_nowait_p (gsi_stmt (gsi)))
6364     t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_NOWAIT);
6365   else if (gimple_omp_return_lhs (gsi_stmt (gsi)))
6366     t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_CANCEL);
6367   else
6368     t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END);
6369   gcall *call_stmt = gimple_build_call (t, 0);
6370   if (gimple_omp_return_lhs (gsi_stmt (gsi)))
6371     gimple_call_set_lhs (call_stmt, gimple_omp_return_lhs (gsi_stmt (gsi)));
6372   gsi_insert_after (&gsi, call_stmt, GSI_SAME_STMT);
6373   gsi_remove (&gsi, true);
6374
6375   /* Connect the new blocks.  */
6376   find_edge (entry_bb, l0_bb)->flags = EDGE_TRUE_VALUE;
6377   find_edge (entry_bb, l3_bb)->flags = EDGE_FALSE_VALUE;
6378
6379   if (!broken_loop)
6380     {
6381       gimple_seq phis;
6382
6383       e = find_edge (cont_bb, l3_bb);
6384       ne = make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
6385
6386       phis = phi_nodes (l3_bb);
6387       for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
6388         {
6389           gimple phi = gsi_stmt (gsi);
6390           SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, ne),
6391                    PHI_ARG_DEF_FROM_EDGE (phi, e));
6392         }
6393       remove_edge (e);
6394
6395       make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
6396       add_bb_to_loop (l2_bb, cont_bb->loop_father);
6397       e = find_edge (cont_bb, l1_bb);
6398       if (gimple_omp_for_combined_p (fd->for_stmt))
6399         {
6400           remove_edge (e);
6401           e = NULL;
6402         }
6403       else if (fd->collapse > 1)
6404         {
6405           remove_edge (e);
6406           e = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
6407         }
6408       else
6409         e->flags = EDGE_TRUE_VALUE;
6410       if (e)
6411         {
6412           e->probability = REG_BR_PROB_BASE * 7 / 8;
6413           find_edge (cont_bb, l2_bb)->probability = REG_BR_PROB_BASE / 8;
6414         }
6415       else
6416         {
6417           e = find_edge (cont_bb, l2_bb);
6418           e->flags = EDGE_FALLTHRU;
6419         }
6420       make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
6421
6422       set_immediate_dominator (CDI_DOMINATORS, l2_bb,
6423                                recompute_dominator (CDI_DOMINATORS, l2_bb));
6424       set_immediate_dominator (CDI_DOMINATORS, l3_bb,
6425                                recompute_dominator (CDI_DOMINATORS, l3_bb));
6426       set_immediate_dominator (CDI_DOMINATORS, l0_bb,
6427                                recompute_dominator (CDI_DOMINATORS, l0_bb));
6428       set_immediate_dominator (CDI_DOMINATORS, l1_bb,
6429                                recompute_dominator (CDI_DOMINATORS, l1_bb));
6430
6431       struct loop *outer_loop = alloc_loop ();
6432       outer_loop->header = l0_bb;
6433       outer_loop->latch = l2_bb;
6434       add_loop (outer_loop, l0_bb->loop_father);
6435
6436       if (!gimple_omp_for_combined_p (fd->for_stmt))
6437         {
6438           struct loop *loop = alloc_loop ();
6439           loop->header = l1_bb;
6440           /* The loop may have multiple latches.  */
6441           add_loop (loop, outer_loop);
6442         }
6443     }
6444 }
6445
6446
6447 /* A subroutine of expand_omp_for.  Generate code for a parallel
6448    loop with static schedule and no specified chunk size.  Given
6449    parameters:
6450
6451         for (V = N1; V cond N2; V += STEP) BODY;
6452
6453    where COND is "<" or ">", we generate pseudocode
6454
6455         if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
6456         if (cond is <)
6457           adj = STEP - 1;
6458         else
6459           adj = STEP + 1;
6460         if ((__typeof (V)) -1 > 0 && cond is >)
6461           n = -(adj + N2 - N1) / -STEP;
6462         else
6463           n = (adj + N2 - N1) / STEP;
6464         q = n / nthreads;
6465         tt = n % nthreads;
6466         if (threadid < tt) goto L3; else goto L4;
6467     L3:
6468         tt = 0;
6469         q = q + 1;
6470     L4:
6471         s0 = q * threadid + tt;
6472         e0 = s0 + q;
6473         V = s0 * STEP + N1;
6474         if (s0 >= e0) goto L2; else goto L0;
6475     L0:
6476         e = e0 * STEP + N1;
6477     L1:
6478         BODY;
6479         V += STEP;
6480         if (V cond e) goto L1;
6481     L2:
6482 */
6483
6484 static void
6485 expand_omp_for_static_nochunk (struct omp_region *region,
6486                                struct omp_for_data *fd,
6487                                gimple inner_stmt)
6488 {
6489   tree n, q, s0, e0, e, t, tt, nthreads, threadid;
6490   tree type, itype, vmain, vback;
6491   basic_block entry_bb, second_bb, third_bb, exit_bb, seq_start_bb;
6492   basic_block body_bb, cont_bb, collapse_bb = NULL;
6493   basic_block fin_bb;
6494   gimple_stmt_iterator gsi;
6495   edge ep;
6496   bool broken_loop = region->cont == NULL;
6497   tree *counts = NULL;
6498   tree n1, n2, step;
6499
6500   gcc_checking_assert ((gimple_omp_for_kind (fd->for_stmt)
6501                         != GF_OMP_FOR_KIND_OACC_LOOP)
6502                        || !inner_stmt);
6503
6504   itype = type = TREE_TYPE (fd->loop.v);
6505   if (POINTER_TYPE_P (type))
6506     itype = signed_type_for (type);
6507
6508   entry_bb = region->entry;
6509   cont_bb = region->cont;
6510   gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
6511   fin_bb = BRANCH_EDGE (entry_bb)->dest;
6512   gcc_assert (broken_loop
6513               || (fin_bb == FALLTHRU_EDGE (cont_bb)->dest));
6514   seq_start_bb = split_edge (FALLTHRU_EDGE (entry_bb));
6515   body_bb = single_succ (seq_start_bb);
6516   if (!broken_loop)
6517     {
6518       gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
6519       gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
6520     }
6521   exit_bb = region->exit;
6522
6523   /* Iteration space partitioning goes in ENTRY_BB.  */
6524   gsi = gsi_last_bb (entry_bb);
6525   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
6526
6527   if (fd->collapse > 1)
6528     {
6529       int first_zero_iter = -1;
6530       basic_block l2_dom_bb = NULL;
6531
6532       counts = XALLOCAVEC (tree, fd->collapse);
6533       expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
6534                                   fin_bb, first_zero_iter,
6535                                   l2_dom_bb);
6536       t = NULL_TREE;
6537     }
6538   else if (gimple_omp_for_combined_into_p (fd->for_stmt))
6539     t = integer_one_node;
6540   else
6541     t = fold_binary (fd->loop.cond_code, boolean_type_node,
6542                      fold_convert (type, fd->loop.n1),
6543                      fold_convert (type, fd->loop.n2));
6544   if (fd->collapse == 1
6545       && TYPE_UNSIGNED (type)
6546       && (t == NULL_TREE || !integer_onep (t)))
6547     {
6548       n1 = fold_convert (type, unshare_expr (fd->loop.n1));
6549       n1 = force_gimple_operand_gsi (&gsi, n1, true, NULL_TREE,
6550                                      true, GSI_SAME_STMT);
6551       n2 = fold_convert (type, unshare_expr (fd->loop.n2));
6552       n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE,
6553                                      true, GSI_SAME_STMT);
6554       gcond *cond_stmt = gimple_build_cond (fd->loop.cond_code, n1, n2,
6555                                                  NULL_TREE, NULL_TREE);
6556       gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
6557       if (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
6558                      expand_omp_regimplify_p, NULL, NULL)
6559           || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
6560                         expand_omp_regimplify_p, NULL, NULL))
6561         {
6562           gsi = gsi_for_stmt (cond_stmt);
6563           gimple_regimplify_operands (cond_stmt, &gsi);
6564         }
6565       ep = split_block (entry_bb, cond_stmt);
6566       ep->flags = EDGE_TRUE_VALUE;
6567       entry_bb = ep->dest;
6568       ep->probability = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1);
6569       ep = make_edge (ep->src, fin_bb, EDGE_FALSE_VALUE);
6570       ep->probability = REG_BR_PROB_BASE / 2000 - 1;
6571       if (gimple_in_ssa_p (cfun))
6572         {
6573           int dest_idx = find_edge (entry_bb, fin_bb)->dest_idx;
6574           for (gphi_iterator gpi = gsi_start_phis (fin_bb);
6575                !gsi_end_p (gpi); gsi_next (&gpi))
6576             {
6577               gphi *phi = gpi.phi ();
6578               add_phi_arg (phi, gimple_phi_arg_def (phi, dest_idx),
6579                            ep, UNKNOWN_LOCATION);
6580             }
6581         }
6582       gsi = gsi_last_bb (entry_bb);
6583     }
6584
6585   switch (gimple_omp_for_kind (fd->for_stmt))
6586     {
6587     case GF_OMP_FOR_KIND_FOR:
6588       nthreads = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
6589       threadid = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
6590       break;
6591     case GF_OMP_FOR_KIND_DISTRIBUTE:
6592       nthreads = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_TEAMS);
6593       threadid = builtin_decl_explicit (BUILT_IN_OMP_GET_TEAM_NUM);
6594       break;
6595     case GF_OMP_FOR_KIND_OACC_LOOP:
6596       nthreads = builtin_decl_explicit (BUILT_IN_GOACC_GET_NUM_THREADS);
6597       threadid = builtin_decl_explicit (BUILT_IN_GOACC_GET_THREAD_NUM);
6598       break;
6599     default:
6600       gcc_unreachable ();
6601     }
6602   nthreads = build_call_expr (nthreads, 0);
6603   nthreads = fold_convert (itype, nthreads);
6604   nthreads = force_gimple_operand_gsi (&gsi, nthreads, true, NULL_TREE,
6605                                        true, GSI_SAME_STMT);
6606   threadid = build_call_expr (threadid, 0);
6607   threadid = fold_convert (itype, threadid);
6608   threadid = force_gimple_operand_gsi (&gsi, threadid, true, NULL_TREE,
6609                                        true, GSI_SAME_STMT);
6610
6611   n1 = fd->loop.n1;
6612   n2 = fd->loop.n2;
6613   step = fd->loop.step;
6614   if (gimple_omp_for_combined_into_p (fd->for_stmt))
6615     {
6616       tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
6617                                      OMP_CLAUSE__LOOPTEMP_);
6618       gcc_assert (innerc);
6619       n1 = OMP_CLAUSE_DECL (innerc);
6620       innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
6621                                 OMP_CLAUSE__LOOPTEMP_);
6622       gcc_assert (innerc);
6623       n2 = OMP_CLAUSE_DECL (innerc);
6624     }
6625   n1 = force_gimple_operand_gsi (&gsi, fold_convert (type, n1),
6626                                  true, NULL_TREE, true, GSI_SAME_STMT);
6627   n2 = force_gimple_operand_gsi (&gsi, fold_convert (itype, n2),
6628                                  true, NULL_TREE, true, GSI_SAME_STMT);
6629   step = force_gimple_operand_gsi (&gsi, fold_convert (itype, step),
6630                                    true, NULL_TREE, true, GSI_SAME_STMT);
6631
6632   t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
6633   t = fold_build2 (PLUS_EXPR, itype, step, t);
6634   t = fold_build2 (PLUS_EXPR, itype, t, n2);
6635   t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, n1));
6636   if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
6637     t = fold_build2 (TRUNC_DIV_EXPR, itype,
6638                      fold_build1 (NEGATE_EXPR, itype, t),
6639                      fold_build1 (NEGATE_EXPR, itype, step));
6640   else
6641     t = fold_build2 (TRUNC_DIV_EXPR, itype, t, step);
6642   t = fold_convert (itype, t);
6643   n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
6644
6645   q = create_tmp_reg (itype, "q");
6646   t = fold_build2 (TRUNC_DIV_EXPR, itype, n, nthreads);
6647   t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
6648   gsi_insert_before (&gsi, gimple_build_assign (q, t), GSI_SAME_STMT);
6649
6650   tt = create_tmp_reg (itype, "tt");
6651   t = fold_build2 (TRUNC_MOD_EXPR, itype, n, nthreads);
6652   t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
6653   gsi_insert_before (&gsi, gimple_build_assign (tt, t), GSI_SAME_STMT);
6654
6655   t = build2 (LT_EXPR, boolean_type_node, threadid, tt);
6656   gcond *cond_stmt = gimple_build_cond_empty (t);
6657   gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
6658
6659   second_bb = split_block (entry_bb, cond_stmt)->dest;
6660   gsi = gsi_last_bb (second_bb);
6661   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
6662
6663   gsi_insert_before (&gsi, gimple_build_assign (tt, build_int_cst (itype, 0)),
6664                      GSI_SAME_STMT);
6665   gassign *assign_stmt
6666     = gimple_build_assign (q, PLUS_EXPR, q, build_int_cst (itype, 1));
6667   gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
6668
6669   third_bb = split_block (second_bb, assign_stmt)->dest;
6670   gsi = gsi_last_bb (third_bb);
6671   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
6672
6673   t = build2 (MULT_EXPR, itype, q, threadid);
6674   t = build2 (PLUS_EXPR, itype, t, tt);
6675   s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
6676
6677   t = fold_build2 (PLUS_EXPR, itype, s0, q);
6678   e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
6679
6680   t = build2 (GE_EXPR, boolean_type_node, s0, e0);
6681   gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
6682
6683   /* Remove the GIMPLE_OMP_FOR statement.  */
6684   gsi_remove (&gsi, true);
6685
6686   /* Setup code for sequential iteration goes in SEQ_START_BB.  */
6687   gsi = gsi_start_bb (seq_start_bb);
6688
6689   tree startvar = fd->loop.v;
6690   tree endvar = NULL_TREE;
6691
6692   if (gimple_omp_for_combined_p (fd->for_stmt))
6693     {
6694       tree clauses = gimple_code (inner_stmt) == GIMPLE_OMP_PARALLEL
6695                      ? gimple_omp_parallel_clauses (inner_stmt)
6696                      : gimple_omp_for_clauses (inner_stmt);
6697       tree innerc = find_omp_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
6698       gcc_assert (innerc);
6699       startvar = OMP_CLAUSE_DECL (innerc);
6700       innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
6701                                 OMP_CLAUSE__LOOPTEMP_);
6702       gcc_assert (innerc);
6703       endvar = OMP_CLAUSE_DECL (innerc);
6704     }
6705   t = fold_convert (itype, s0);
6706   t = fold_build2 (MULT_EXPR, itype, t, step);
6707   if (POINTER_TYPE_P (type))
6708     t = fold_build_pointer_plus (n1, t);
6709   else
6710     t = fold_build2 (PLUS_EXPR, type, t, n1);
6711   t = fold_convert (TREE_TYPE (startvar), t);
6712   t = force_gimple_operand_gsi (&gsi, t,
6713                                 DECL_P (startvar)
6714                                 && TREE_ADDRESSABLE (startvar),
6715                                 NULL_TREE, false, GSI_CONTINUE_LINKING);
6716   assign_stmt = gimple_build_assign (startvar, t);
6717   gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
6718
6719   t = fold_convert (itype, e0);
6720   t = fold_build2 (MULT_EXPR, itype, t, step);
6721   if (POINTER_TYPE_P (type))
6722     t = fold_build_pointer_plus (n1, t);
6723   else
6724     t = fold_build2 (PLUS_EXPR, type, t, n1);
6725   t = fold_convert (TREE_TYPE (startvar), t);
6726   e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
6727                                 false, GSI_CONTINUE_LINKING);
6728   if (endvar)
6729     {
6730       assign_stmt = gimple_build_assign (endvar, e);
6731       gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
6732       if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
6733         assign_stmt = gimple_build_assign (fd->loop.v, e);
6734       else
6735         assign_stmt = gimple_build_assign (fd->loop.v, NOP_EXPR, e);
6736       gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
6737     }
6738   if (fd->collapse > 1)
6739     expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
6740
6741   if (!broken_loop)
6742     {
6743       /* The code controlling the sequential loop replaces the
6744          GIMPLE_OMP_CONTINUE.  */
6745       gsi = gsi_last_bb (cont_bb);
6746       gomp_continue *cont_stmt = as_a <gomp_continue *> (gsi_stmt (gsi));
6747       gcc_assert (gimple_code (cont_stmt) == GIMPLE_OMP_CONTINUE);
6748       vmain = gimple_omp_continue_control_use (cont_stmt);
6749       vback = gimple_omp_continue_control_def (cont_stmt);
6750
6751       if (!gimple_omp_for_combined_p (fd->for_stmt))
6752         {
6753           if (POINTER_TYPE_P (type))
6754             t = fold_build_pointer_plus (vmain, step);
6755           else
6756             t = fold_build2 (PLUS_EXPR, type, vmain, step);
6757           t = force_gimple_operand_gsi (&gsi, t,
6758                                         DECL_P (vback)
6759                                         && TREE_ADDRESSABLE (vback),
6760                                         NULL_TREE, true, GSI_SAME_STMT);
6761           assign_stmt = gimple_build_assign (vback, t);
6762           gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
6763
6764           t = build2 (fd->loop.cond_code, boolean_type_node,
6765                       DECL_P (vback) && TREE_ADDRESSABLE (vback)
6766                       ? t : vback, e);
6767           gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
6768         }
6769
6770       /* Remove the GIMPLE_OMP_CONTINUE statement.  */
6771       gsi_remove (&gsi, true);
6772
6773       if (fd->collapse > 1 && !gimple_omp_for_combined_p (fd->for_stmt))
6774         collapse_bb = extract_omp_for_update_vars (fd, cont_bb, body_bb);
6775     }
6776
6777   /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing.  */
6778   gsi = gsi_last_bb (exit_bb);
6779   if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
6780     {
6781       t = gimple_omp_return_lhs (gsi_stmt (gsi));
6782       if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
6783         gcc_checking_assert (t == NULL_TREE);
6784       else
6785         gsi_insert_after (&gsi, build_omp_barrier (t), GSI_SAME_STMT);
6786     }
6787   gsi_remove (&gsi, true);
6788
6789   /* Connect all the blocks.  */
6790   ep = make_edge (entry_bb, third_bb, EDGE_FALSE_VALUE);
6791   ep->probability = REG_BR_PROB_BASE / 4 * 3;
6792   ep = find_edge (entry_bb, second_bb);
6793   ep->flags = EDGE_TRUE_VALUE;
6794   ep->probability = REG_BR_PROB_BASE / 4;
6795   find_edge (third_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
6796   find_edge (third_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
6797
6798   if (!broken_loop)
6799     {
6800       ep = find_edge (cont_bb, body_bb);
6801       if (gimple_omp_for_combined_p (fd->for_stmt))
6802         {
6803           remove_edge (ep);
6804           ep = NULL;
6805         }
6806       else if (fd->collapse > 1)
6807         {
6808           remove_edge (ep);
6809           ep = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
6810         }
6811       else
6812         ep->flags = EDGE_TRUE_VALUE;
6813       find_edge (cont_bb, fin_bb)->flags
6814         = ep ? EDGE_FALSE_VALUE : EDGE_FALLTHRU;
6815     }
6816
6817   set_immediate_dominator (CDI_DOMINATORS, second_bb, entry_bb);
6818   set_immediate_dominator (CDI_DOMINATORS, third_bb, entry_bb);
6819   set_immediate_dominator (CDI_DOMINATORS, seq_start_bb, third_bb);
6820
6821   set_immediate_dominator (CDI_DOMINATORS, body_bb,
6822                            recompute_dominator (CDI_DOMINATORS, body_bb));
6823   set_immediate_dominator (CDI_DOMINATORS, fin_bb,
6824                            recompute_dominator (CDI_DOMINATORS, fin_bb));
6825
6826   if (!broken_loop && !gimple_omp_for_combined_p (fd->for_stmt))
6827     {
6828       struct loop *loop = alloc_loop ();
6829       loop->header = body_bb;
6830       if (collapse_bb == NULL)
6831         loop->latch = cont_bb;
6832       add_loop (loop, body_bb->loop_father);
6833     }
6834 }
6835
6836
6837 /* A subroutine of expand_omp_for.  Generate code for a parallel
6838    loop with static schedule and a specified chunk size.  Given
6839    parameters:
6840
6841         for (V = N1; V cond N2; V += STEP) BODY;
6842
6843    where COND is "<" or ">", we generate pseudocode
6844
6845         if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
6846         if (cond is <)
6847           adj = STEP - 1;
6848         else
6849           adj = STEP + 1;
6850         if ((__typeof (V)) -1 > 0 && cond is >)
6851           n = -(adj + N2 - N1) / -STEP;
6852         else
6853           n = (adj + N2 - N1) / STEP;
6854         trip = 0;
6855         V = threadid * CHUNK * STEP + N1;  -- this extra definition of V is
6856                                               here so that V is defined
6857                                               if the loop is not entered
6858     L0:
6859         s0 = (trip * nthreads + threadid) * CHUNK;
6860         e0 = min(s0 + CHUNK, n);
6861         if (s0 < n) goto L1; else goto L4;
6862     L1:
6863         V = s0 * STEP + N1;
6864         e = e0 * STEP + N1;
6865     L2:
6866         BODY;
6867         V += STEP;
6868         if (V cond e) goto L2; else goto L3;
6869     L3:
6870         trip += 1;
6871         goto L0;
6872     L4:
6873 */
6874
6875 static void
6876 expand_omp_for_static_chunk (struct omp_region *region,
6877                              struct omp_for_data *fd, gimple inner_stmt)
6878 {
6879   tree n, s0, e0, e, t;
6880   tree trip_var, trip_init, trip_main, trip_back, nthreads, threadid;
6881   tree type, itype, vmain, vback, vextra;
6882   basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
6883   basic_block trip_update_bb = NULL, cont_bb, collapse_bb = NULL, fin_bb;
6884   gimple_stmt_iterator gsi;
6885   edge se;
6886   bool broken_loop = region->cont == NULL;
6887   tree *counts = NULL;
6888   tree n1, n2, step;
6889
6890   gcc_checking_assert ((gimple_omp_for_kind (fd->for_stmt)
6891                         != GF_OMP_FOR_KIND_OACC_LOOP)
6892                        || !inner_stmt);
6893
6894   itype = type = TREE_TYPE (fd->loop.v);
6895   if (POINTER_TYPE_P (type))
6896     itype = signed_type_for (type);
6897
6898   entry_bb = region->entry;
6899   se = split_block (entry_bb, last_stmt (entry_bb));
6900   entry_bb = se->src;
6901   iter_part_bb = se->dest;
6902   cont_bb = region->cont;
6903   gcc_assert (EDGE_COUNT (iter_part_bb->succs) == 2);
6904   fin_bb = BRANCH_EDGE (iter_part_bb)->dest;
6905   gcc_assert (broken_loop
6906               || fin_bb == FALLTHRU_EDGE (cont_bb)->dest);
6907   seq_start_bb = split_edge (FALLTHRU_EDGE (iter_part_bb));
6908   body_bb = single_succ (seq_start_bb);
6909   if (!broken_loop)
6910     {
6911       gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
6912       gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
6913       trip_update_bb = split_edge (FALLTHRU_EDGE (cont_bb));
6914     }
6915   exit_bb = region->exit;
6916
6917   /* Trip and adjustment setup goes in ENTRY_BB.  */
6918   gsi = gsi_last_bb (entry_bb);
6919   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
6920
6921   if (fd->collapse > 1)
6922     {
6923       int first_zero_iter = -1;
6924       basic_block l2_dom_bb = NULL;
6925
6926       counts = XALLOCAVEC (tree, fd->collapse);
6927       expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
6928                                   fin_bb, first_zero_iter,
6929                                   l2_dom_bb);
6930       t = NULL_TREE;
6931     }
6932   else if (gimple_omp_for_combined_into_p (fd->for_stmt))
6933     t = integer_one_node;
6934   else
6935     t = fold_binary (fd->loop.cond_code, boolean_type_node,
6936                      fold_convert (type, fd->loop.n1),
6937                      fold_convert (type, fd->loop.n2));
6938   if (fd->collapse == 1
6939       && TYPE_UNSIGNED (type)
6940       && (t == NULL_TREE || !integer_onep (t)))
6941     {
6942       n1 = fold_convert (type, unshare_expr (fd->loop.n1));
6943       n1 = force_gimple_operand_gsi (&gsi, n1, true, NULL_TREE,
6944                                      true, GSI_SAME_STMT);
6945       n2 = fold_convert (type, unshare_expr (fd->loop.n2));
6946       n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE,
6947                                      true, GSI_SAME_STMT);
6948       gcond *cond_stmt = gimple_build_cond (fd->loop.cond_code, n1, n2,
6949                                                  NULL_TREE, NULL_TREE);
6950       gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
6951       if (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
6952                      expand_omp_regimplify_p, NULL, NULL)
6953           || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
6954                         expand_omp_regimplify_p, NULL, NULL))
6955         {
6956           gsi = gsi_for_stmt (cond_stmt);
6957           gimple_regimplify_operands (cond_stmt, &gsi);
6958         }
6959       se = split_block (entry_bb, cond_stmt);
6960       se->flags = EDGE_TRUE_VALUE;
6961       entry_bb = se->dest;
6962       se->probability = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1);
6963       se = make_edge (se->src, fin_bb, EDGE_FALSE_VALUE);
6964       se->probability = REG_BR_PROB_BASE / 2000 - 1;
6965       if (gimple_in_ssa_p (cfun))
6966         {
6967           int dest_idx = find_edge (entry_bb, fin_bb)->dest_idx;
6968           for (gphi_iterator gpi = gsi_start_phis (fin_bb);
6969                !gsi_end_p (gpi); gsi_next (&gpi))
6970             {
6971               gphi *phi = gpi.phi ();
6972               add_phi_arg (phi, gimple_phi_arg_def (phi, dest_idx),
6973                            se, UNKNOWN_LOCATION);
6974             }
6975         }
6976       gsi = gsi_last_bb (entry_bb);
6977     }
6978
6979   switch (gimple_omp_for_kind (fd->for_stmt))
6980     {
6981     case GF_OMP_FOR_KIND_FOR:
6982       nthreads = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
6983       threadid = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
6984       break;
6985     case GF_OMP_FOR_KIND_DISTRIBUTE:
6986       nthreads = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_TEAMS);
6987       threadid = builtin_decl_explicit (BUILT_IN_OMP_GET_TEAM_NUM);
6988       break;
6989     case GF_OMP_FOR_KIND_OACC_LOOP:
6990       nthreads = builtin_decl_explicit (BUILT_IN_GOACC_GET_NUM_THREADS);
6991       threadid = builtin_decl_explicit (BUILT_IN_GOACC_GET_THREAD_NUM);
6992       break;
6993     default:
6994       gcc_unreachable ();
6995     }
6996   nthreads = build_call_expr (nthreads, 0);
6997   nthreads = fold_convert (itype, nthreads);
6998   nthreads = force_gimple_operand_gsi (&gsi, nthreads, true, NULL_TREE,
6999                                        true, GSI_SAME_STMT);
7000   threadid = build_call_expr (threadid, 0);
7001   threadid = fold_convert (itype, threadid);
7002   threadid = force_gimple_operand_gsi (&gsi, threadid, true, NULL_TREE,
7003                                        true, GSI_SAME_STMT);
7004
7005   n1 = fd->loop.n1;
7006   n2 = fd->loop.n2;
7007   step = fd->loop.step;
7008   if (gimple_omp_for_combined_into_p (fd->for_stmt))
7009     {
7010       tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
7011                                      OMP_CLAUSE__LOOPTEMP_);
7012       gcc_assert (innerc);
7013       n1 = OMP_CLAUSE_DECL (innerc);
7014       innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
7015                                 OMP_CLAUSE__LOOPTEMP_);
7016       gcc_assert (innerc);
7017       n2 = OMP_CLAUSE_DECL (innerc);
7018     }
7019   n1 = force_gimple_operand_gsi (&gsi, fold_convert (type, n1),
7020                                  true, NULL_TREE, true, GSI_SAME_STMT);
7021   n2 = force_gimple_operand_gsi (&gsi, fold_convert (itype, n2),
7022                                  true, NULL_TREE, true, GSI_SAME_STMT);
7023   step = force_gimple_operand_gsi (&gsi, fold_convert (itype, step),
7024                                    true, NULL_TREE, true, GSI_SAME_STMT);
7025   fd->chunk_size
7026     = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->chunk_size),
7027                                 true, NULL_TREE, true, GSI_SAME_STMT);
7028
7029   t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
7030   t = fold_build2 (PLUS_EXPR, itype, step, t);
7031   t = fold_build2 (PLUS_EXPR, itype, t, n2);
7032   t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, n1));
7033   if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
7034     t = fold_build2 (TRUNC_DIV_EXPR, itype,
7035                      fold_build1 (NEGATE_EXPR, itype, t),
7036                      fold_build1 (NEGATE_EXPR, itype, step));
7037   else
7038     t = fold_build2 (TRUNC_DIV_EXPR, itype, t, step);
7039   t = fold_convert (itype, t);
7040   n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
7041                                 true, GSI_SAME_STMT);
7042
7043   trip_var = create_tmp_reg (itype, ".trip");
7044   if (gimple_in_ssa_p (cfun))
7045     {
7046       trip_init = make_ssa_name (trip_var);
7047       trip_main = make_ssa_name (trip_var);
7048       trip_back = make_ssa_name (trip_var);
7049     }
7050   else
7051     {
7052       trip_init = trip_var;
7053       trip_main = trip_var;
7054       trip_back = trip_var;
7055     }
7056
7057   gassign *assign_stmt
7058     = gimple_build_assign (trip_init, build_int_cst (itype, 0));
7059   gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
7060
7061   t = fold_build2 (MULT_EXPR, itype, threadid, fd->chunk_size);
7062   t = fold_build2 (MULT_EXPR, itype, t, step);
7063   if (POINTER_TYPE_P (type))
7064     t = fold_build_pointer_plus (n1, t);
7065   else
7066     t = fold_build2 (PLUS_EXPR, type, t, n1);
7067   vextra = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
7068                                      true, GSI_SAME_STMT);
7069
7070   /* Remove the GIMPLE_OMP_FOR.  */
7071   gsi_remove (&gsi, true);
7072
7073   /* Iteration space partitioning goes in ITER_PART_BB.  */
7074   gsi = gsi_last_bb (iter_part_bb);
7075
7076   t = fold_build2 (MULT_EXPR, itype, trip_main, nthreads);
7077   t = fold_build2 (PLUS_EXPR, itype, t, threadid);
7078   t = fold_build2 (MULT_EXPR, itype, t, fd->chunk_size);
7079   s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
7080                                  false, GSI_CONTINUE_LINKING);
7081
7082   t = fold_build2 (PLUS_EXPR, itype, s0, fd->chunk_size);
7083   t = fold_build2 (MIN_EXPR, itype, t, n);
7084   e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
7085                                  false, GSI_CONTINUE_LINKING);
7086
7087   t = build2 (LT_EXPR, boolean_type_node, s0, n);
7088   gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_CONTINUE_LINKING);
7089
7090   /* Setup code for sequential iteration goes in SEQ_START_BB.  */
7091   gsi = gsi_start_bb (seq_start_bb);
7092
7093   tree startvar = fd->loop.v;
7094   tree endvar = NULL_TREE;
7095
7096   if (gimple_omp_for_combined_p (fd->for_stmt))
7097     {
7098       tree clauses = gimple_code (inner_stmt) == GIMPLE_OMP_PARALLEL
7099                      ? gimple_omp_parallel_clauses (inner_stmt)
7100                      : gimple_omp_for_clauses (inner_stmt);
7101       tree innerc = find_omp_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
7102       gcc_assert (innerc);
7103       startvar = OMP_CLAUSE_DECL (innerc);
7104       innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
7105                                 OMP_CLAUSE__LOOPTEMP_);
7106       gcc_assert (innerc);
7107       endvar = OMP_CLAUSE_DECL (innerc);
7108     }
7109
7110   t = fold_convert (itype, s0);
7111   t = fold_build2 (MULT_EXPR, itype, t, step);
7112   if (POINTER_TYPE_P (type))
7113     t = fold_build_pointer_plus (n1, t);
7114   else
7115     t = fold_build2 (PLUS_EXPR, type, t, n1);
7116   t = fold_convert (TREE_TYPE (startvar), t);
7117   t = force_gimple_operand_gsi (&gsi, t,
7118                                 DECL_P (startvar)
7119                                 && TREE_ADDRESSABLE (startvar),
7120                                 NULL_TREE, false, GSI_CONTINUE_LINKING);
7121   assign_stmt = gimple_build_assign (startvar, t);
7122   gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
7123
7124   t = fold_convert (itype, e0);
7125   t = fold_build2 (MULT_EXPR, itype, t, step);
7126   if (POINTER_TYPE_P (type))
7127     t = fold_build_pointer_plus (n1, t);
7128   else
7129     t = fold_build2 (PLUS_EXPR, type, t, n1);
7130   t = fold_convert (TREE_TYPE (startvar), t);
7131   e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
7132                                 false, GSI_CONTINUE_LINKING);
7133   if (endvar)
7134     {
7135       assign_stmt = gimple_build_assign (endvar, e);
7136       gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
7137       if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
7138         assign_stmt = gimple_build_assign (fd->loop.v, e);
7139       else
7140         assign_stmt = gimple_build_assign (fd->loop.v, NOP_EXPR, e);
7141       gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
7142     }
7143   if (fd->collapse > 1)
7144     expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
7145
7146   if (!broken_loop)
7147     {
7148       /* The code controlling the sequential loop goes in CONT_BB,
7149          replacing the GIMPLE_OMP_CONTINUE.  */
7150       gsi = gsi_last_bb (cont_bb);
7151       gomp_continue *cont_stmt = as_a <gomp_continue *> (gsi_stmt (gsi));
7152       vmain = gimple_omp_continue_control_use (cont_stmt);
7153       vback = gimple_omp_continue_control_def (cont_stmt);
7154
7155       if (!gimple_omp_for_combined_p (fd->for_stmt))
7156         {
7157           if (POINTER_TYPE_P (type))
7158             t = fold_build_pointer_plus (vmain, step);
7159           else
7160             t = fold_build2 (PLUS_EXPR, type, vmain, step);
7161           if (DECL_P (vback) && TREE_ADDRESSABLE (vback))
7162             t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
7163                                           true, GSI_SAME_STMT);
7164           assign_stmt = gimple_build_assign (vback, t);
7165           gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
7166
7167           t = build2 (fd->loop.cond_code, boolean_type_node,
7168                       DECL_P (vback) && TREE_ADDRESSABLE (vback)
7169                       ? t : vback, e);
7170           gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
7171         }
7172
7173       /* Remove GIMPLE_OMP_CONTINUE.  */
7174       gsi_remove (&gsi, true);
7175
7176       if (fd->collapse > 1 && !gimple_omp_for_combined_p (fd->for_stmt))
7177         collapse_bb = extract_omp_for_update_vars (fd, cont_bb, body_bb);
7178
7179       /* Trip update code goes into TRIP_UPDATE_BB.  */
7180       gsi = gsi_start_bb (trip_update_bb);
7181
7182       t = build_int_cst (itype, 1);
7183       t = build2 (PLUS_EXPR, itype, trip_main, t);
7184       assign_stmt = gimple_build_assign (trip_back, t);
7185       gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
7186     }
7187
7188   /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing.  */
7189   gsi = gsi_last_bb (exit_bb);
7190   if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
7191     {
7192       t = gimple_omp_return_lhs (gsi_stmt (gsi));
7193       if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
7194         gcc_checking_assert (t == NULL_TREE);
7195       else
7196         gsi_insert_after (&gsi, build_omp_barrier (t), GSI_SAME_STMT);
7197     }
7198   gsi_remove (&gsi, true);
7199
7200   /* Connect the new blocks.  */
7201   find_edge (iter_part_bb, seq_start_bb)->flags = EDGE_TRUE_VALUE;
7202   find_edge (iter_part_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
7203
7204   if (!broken_loop)
7205     {
7206       se = find_edge (cont_bb, body_bb);
7207       if (gimple_omp_for_combined_p (fd->for_stmt))
7208         {
7209           remove_edge (se);
7210           se = NULL;
7211         }
7212       else if (fd->collapse > 1)
7213         {
7214           remove_edge (se);
7215           se = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
7216         }
7217       else
7218         se->flags = EDGE_TRUE_VALUE;
7219       find_edge (cont_bb, trip_update_bb)->flags
7220         = se ? EDGE_FALSE_VALUE : EDGE_FALLTHRU;
7221
7222       redirect_edge_and_branch (single_succ_edge (trip_update_bb), iter_part_bb);
7223     }
7224
7225   if (gimple_in_ssa_p (cfun))
7226     {
7227       gphi_iterator psi;
7228       gphi *phi;
7229       edge re, ene;
7230       edge_var_map *vm;
7231       size_t i;
7232
7233       gcc_assert (fd->collapse == 1 && !broken_loop);
7234
7235       /* When we redirect the edge from trip_update_bb to iter_part_bb, we
7236          remove arguments of the phi nodes in fin_bb.  We need to create
7237          appropriate phi nodes in iter_part_bb instead.  */
7238       se = single_pred_edge (fin_bb);
7239       re = single_succ_edge (trip_update_bb);
7240       vec<edge_var_map> *head = redirect_edge_var_map_vector (re);
7241       ene = single_succ_edge (entry_bb);
7242
7243       psi = gsi_start_phis (fin_bb);
7244       for (i = 0; !gsi_end_p (psi) && head->iterate (i, &vm);
7245            gsi_next (&psi), ++i)
7246         {
7247           gphi *nphi;
7248           source_location locus;
7249
7250           phi = psi.phi ();
7251           t = gimple_phi_result (phi);
7252           gcc_assert (t == redirect_edge_var_map_result (vm));
7253           nphi = create_phi_node (t, iter_part_bb);
7254
7255           t = PHI_ARG_DEF_FROM_EDGE (phi, se);
7256           locus = gimple_phi_arg_location_from_edge (phi, se);
7257
7258           /* A special case -- fd->loop.v is not yet computed in
7259              iter_part_bb, we need to use vextra instead.  */
7260           if (t == fd->loop.v)
7261             t = vextra;
7262           add_phi_arg (nphi, t, ene, locus);
7263           locus = redirect_edge_var_map_location (vm);
7264           add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus);
7265         }
7266       gcc_assert (gsi_end_p (psi) && i == head->length ());
7267       redirect_edge_var_map_clear (re);
7268       while (1)
7269         {
7270           psi = gsi_start_phis (fin_bb);
7271           if (gsi_end_p (psi))
7272             break;
7273           remove_phi_node (&psi, false);
7274         }
7275
7276       /* Make phi node for trip.  */
7277       phi = create_phi_node (trip_main, iter_part_bb);
7278       add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb),
7279                    UNKNOWN_LOCATION);
7280       add_phi_arg (phi, trip_init, single_succ_edge (entry_bb),
7281                    UNKNOWN_LOCATION);
7282     }
7283
7284   if (!broken_loop)
7285     set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
7286   set_immediate_dominator (CDI_DOMINATORS, iter_part_bb,
7287                            recompute_dominator (CDI_DOMINATORS, iter_part_bb));
7288   set_immediate_dominator (CDI_DOMINATORS, fin_bb,
7289                            recompute_dominator (CDI_DOMINATORS, fin_bb));
7290   set_immediate_dominator (CDI_DOMINATORS, seq_start_bb,
7291                            recompute_dominator (CDI_DOMINATORS, seq_start_bb));
7292   set_immediate_dominator (CDI_DOMINATORS, body_bb,
7293                            recompute_dominator (CDI_DOMINATORS, body_bb));
7294
7295   if (!broken_loop)
7296     {
7297       struct loop *trip_loop = alloc_loop ();
7298       trip_loop->header = iter_part_bb;
7299       trip_loop->latch = trip_update_bb;
7300       add_loop (trip_loop, iter_part_bb->loop_father);
7301
7302       if (!gimple_omp_for_combined_p (fd->for_stmt))
7303         {
7304           struct loop *loop = alloc_loop ();
7305           loop->header = body_bb;
7306           if (collapse_bb == NULL)
7307             loop->latch = cont_bb;
7308           add_loop (loop, trip_loop);
7309         }
7310     }
7311 }
7312
7313 /* A subroutine of expand_omp_for.  Generate code for _Cilk_for loop.
7314    Given parameters:
7315    for (V = N1; V cond N2; V += STEP) BODY;
7316
7317    where COND is "<" or ">" or "!=", we generate pseudocode
7318
7319    for (ind_var = low; ind_var < high; ind_var++)
7320      {
7321        V = n1 + (ind_var * STEP)
7322
7323        <BODY>
7324      }
7325
7326    In the above pseudocode, low and high are function parameters of the
7327    child function.  In the function below, we are inserting a temp.
7328    variable that will be making a call to two OMP functions that will not be
7329    found in the body of _Cilk_for (since OMP_FOR cannot be mixed
7330    with _Cilk_for).  These functions are replaced with low and high
7331    by the function that handles taskreg.  */
7332
7333
7334 static void
7335 expand_cilk_for (struct omp_region *region, struct omp_for_data *fd)
7336 {
7337   bool broken_loop = region->cont == NULL;
7338   basic_block entry_bb = region->entry;
7339   basic_block cont_bb = region->cont;
7340
7341   gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
7342   gcc_assert (broken_loop
7343               || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
7344   basic_block l0_bb = FALLTHRU_EDGE (entry_bb)->dest;
7345   basic_block l1_bb, l2_bb;
7346
7347   if (!broken_loop)
7348     {
7349       gcc_assert (BRANCH_EDGE (cont_bb)->dest == l0_bb);
7350       gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
7351       l1_bb = split_block (cont_bb, last_stmt (cont_bb))->dest;
7352       l2_bb = BRANCH_EDGE (entry_bb)->dest;
7353     }
7354   else
7355     {
7356       BRANCH_EDGE (entry_bb)->flags &= ~EDGE_ABNORMAL;
7357       l1_bb = split_edge (BRANCH_EDGE (entry_bb));
7358       l2_bb = single_succ (l1_bb);
7359     }
7360   basic_block exit_bb = region->exit;
7361   basic_block l2_dom_bb = NULL;
7362
7363   gimple_stmt_iterator gsi = gsi_last_bb (entry_bb);
7364
7365   /* Below statements until the "tree high_val = ..." are pseudo statements
7366      used to pass information to be used by expand_omp_taskreg.
7367      low_val and high_val will be replaced by the __low and __high
7368      parameter from the child function.
7369
7370      The call_exprs part is a place-holder, it is mainly used
7371      to distinctly identify to the top-level part that this is
7372      where we should put low and high (reasoning given in header
7373      comment).  */
7374
7375   tree child_fndecl
7376     = gimple_omp_parallel_child_fn (
7377         as_a <gomp_parallel *> (last_stmt (region->outer->entry)));
7378   tree t, low_val = NULL_TREE, high_val = NULL_TREE;
7379   for (t = DECL_ARGUMENTS (child_fndecl); t; t = TREE_CHAIN (t))
7380     {
7381       if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__high"))
7382         high_val = t;
7383       else if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__low"))
7384         low_val = t;
7385     }
7386   gcc_assert (low_val && high_val);
7387
7388   tree type = TREE_TYPE (low_val);
7389   tree ind_var = create_tmp_reg (type, "__cilk_ind_var");
7390   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
7391
7392   /* Not needed in SSA form right now.  */
7393   gcc_assert (!gimple_in_ssa_p (cfun));
7394   if (l2_dom_bb == NULL)
7395     l2_dom_bb = l1_bb;
7396
7397   tree n1 = low_val;
7398   tree n2 = high_val;
7399
7400   gimple stmt = gimple_build_assign (ind_var, n1);
7401
7402   /* Replace the GIMPLE_OMP_FOR statement.  */
7403   gsi_replace (&gsi, stmt, true);
7404
7405   if (!broken_loop)
7406     {
7407       /* Code to control the increment goes in the CONT_BB.  */
7408       gsi = gsi_last_bb (cont_bb);
7409       stmt = gsi_stmt (gsi);
7410       gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
7411       stmt = gimple_build_assign (ind_var, PLUS_EXPR, ind_var,
7412                                   build_one_cst (type));
7413
7414       /* Replace GIMPLE_OMP_CONTINUE.  */
7415       gsi_replace (&gsi, stmt, true);
7416     }
7417
7418   /* Emit the condition in L1_BB.  */
7419   gsi = gsi_after_labels (l1_bb);
7420   t = fold_build2 (MULT_EXPR, TREE_TYPE (fd->loop.step),
7421                    fold_convert (TREE_TYPE (fd->loop.step), ind_var),
7422                    fd->loop.step);
7423   if (POINTER_TYPE_P (TREE_TYPE (fd->loop.n1)))
7424     t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (fd->loop.n1),
7425                      fd->loop.n1, fold_convert (sizetype, t));
7426   else
7427     t = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->loop.n1),
7428                      fd->loop.n1, fold_convert (TREE_TYPE (fd->loop.n1), t));
7429   t = fold_convert (TREE_TYPE (fd->loop.v), t);
7430   expand_omp_build_assign (&gsi, fd->loop.v, t);
7431
7432   /* The condition is always '<' since the runtime will fill in the low
7433      and high values.  */
7434   stmt = gimple_build_cond (LT_EXPR, ind_var, n2, NULL_TREE, NULL_TREE);
7435   gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
7436
7437   /* Remove GIMPLE_OMP_RETURN.  */
7438   gsi = gsi_last_bb (exit_bb);
7439   gsi_remove (&gsi, true);
7440
7441   /* Connect the new blocks.  */
7442   remove_edge (FALLTHRU_EDGE (entry_bb));
7443
7444   edge e, ne;
7445   if (!broken_loop)
7446     {
7447       remove_edge (BRANCH_EDGE (entry_bb));
7448       make_edge (entry_bb, l1_bb, EDGE_FALLTHRU);
7449
7450       e = BRANCH_EDGE (l1_bb);
7451       ne = FALLTHRU_EDGE (l1_bb);
7452       e->flags = EDGE_TRUE_VALUE;
7453     }
7454   else
7455     {
7456       single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
7457
7458       ne = single_succ_edge (l1_bb);
7459       e = make_edge (l1_bb, l0_bb, EDGE_TRUE_VALUE);
7460
7461     }
7462   ne->flags = EDGE_FALSE_VALUE;
7463   e->probability = REG_BR_PROB_BASE * 7 / 8;
7464   ne->probability = REG_BR_PROB_BASE / 8;
7465
7466   set_immediate_dominator (CDI_DOMINATORS, l1_bb, entry_bb);
7467   set_immediate_dominator (CDI_DOMINATORS, l2_bb, l2_dom_bb);
7468   set_immediate_dominator (CDI_DOMINATORS, l0_bb, l1_bb);
7469
7470   if (!broken_loop)
7471     {
7472       struct loop *loop = alloc_loop ();
7473       loop->header = l1_bb;
7474       loop->latch = cont_bb;
7475       add_loop (loop, l1_bb->loop_father);
7476       loop->safelen = INT_MAX;
7477     }
7478
7479   /* Pick the correct library function based on the precision of the
7480      induction variable type.  */
7481   tree lib_fun = NULL_TREE;
7482   if (TYPE_PRECISION (type) == 32)
7483     lib_fun = cilk_for_32_fndecl;
7484   else if (TYPE_PRECISION (type) == 64)
7485     lib_fun = cilk_for_64_fndecl;
7486   else
7487     gcc_unreachable ();
7488
7489   gcc_assert (fd->sched_kind == OMP_CLAUSE_SCHEDULE_CILKFOR);
7490
7491   /* WS_ARGS contains the library function flavor to call:
7492      __libcilkrts_cilk_for_64 or __libcilkrts_cilk_for_32), and the
7493      user-defined grain value.  If the user does not define one, then zero
7494      is passed in by the parser.  */
7495   vec_alloc (region->ws_args, 2);
7496   region->ws_args->quick_push (lib_fun);
7497   region->ws_args->quick_push (fd->chunk_size);
7498 }
7499
7500 /* A subroutine of expand_omp_for.  Generate code for a simd non-worksharing
7501    loop.  Given parameters:
7502
7503         for (V = N1; V cond N2; V += STEP) BODY;
7504
7505    where COND is "<" or ">", we generate pseudocode
7506
7507         V = N1;
7508         goto L1;
7509     L0:
7510         BODY;
7511         V += STEP;
7512     L1:
7513         if (V cond N2) goto L0; else goto L2;
7514     L2:
7515
7516     For collapsed loops, given parameters:
7517       collapse(3)
7518       for (V1 = N11; V1 cond1 N12; V1 += STEP1)
7519         for (V2 = N21; V2 cond2 N22; V2 += STEP2)
7520           for (V3 = N31; V3 cond3 N32; V3 += STEP3)
7521             BODY;
7522
7523     we generate pseudocode
7524
7525         if (cond3 is <)
7526           adj = STEP3 - 1;
7527         else
7528           adj = STEP3 + 1;
7529         count3 = (adj + N32 - N31) / STEP3;
7530         if (cond2 is <)
7531           adj = STEP2 - 1;
7532         else
7533           adj = STEP2 + 1;
7534         count2 = (adj + N22 - N21) / STEP2;
7535         if (cond1 is <)
7536           adj = STEP1 - 1;
7537         else
7538           adj = STEP1 + 1;
7539         count1 = (adj + N12 - N11) / STEP1;
7540         count = count1 * count2 * count3;
7541         V = 0;
7542         V1 = N11;
7543         V2 = N21;
7544         V3 = N31;
7545         goto L1;
7546     L0:
7547         BODY;
7548         V += 1;
7549         V3 += STEP3;
7550         V2 += (V3 cond3 N32) ? 0 : STEP2;
7551         V3 = (V3 cond3 N32) ? V3 : N31;
7552         V1 += (V2 cond2 N22) ? 0 : STEP1;
7553         V2 = (V2 cond2 N22) ? V2 : N21;
7554     L1:
7555         if (V < count) goto L0; else goto L2;
7556     L2:
7557
7558       */
7559
7560 static void
7561 expand_omp_simd (struct omp_region *region, struct omp_for_data *fd)
7562 {
7563   tree type, t;
7564   basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, l2_bb, l2_dom_bb;
7565   gimple_stmt_iterator gsi;
7566   gimple stmt;
7567   gcond *cond_stmt;
7568   bool broken_loop = region->cont == NULL;
7569   edge e, ne;
7570   tree *counts = NULL;
7571   int i;
7572   tree safelen = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
7573                                   OMP_CLAUSE_SAFELEN);
7574   tree simduid = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
7575                                   OMP_CLAUSE__SIMDUID_);
7576   tree n1, n2;
7577
7578   type = TREE_TYPE (fd->loop.v);
7579   entry_bb = region->entry;
7580   cont_bb = region->cont;
7581   gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
7582   gcc_assert (broken_loop
7583               || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
7584   l0_bb = FALLTHRU_EDGE (entry_bb)->dest;
7585   if (!broken_loop)
7586     {
7587       gcc_assert (BRANCH_EDGE (cont_bb)->dest == l0_bb);
7588       gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
7589       l1_bb = split_block (cont_bb, last_stmt (cont_bb))->dest;
7590       l2_bb = BRANCH_EDGE (entry_bb)->dest;
7591     }
7592   else
7593     {
7594       BRANCH_EDGE (entry_bb)->flags &= ~EDGE_ABNORMAL;
7595       l1_bb = split_edge (BRANCH_EDGE (entry_bb));
7596       l2_bb = single_succ (l1_bb);
7597     }
7598   exit_bb = region->exit;
7599   l2_dom_bb = NULL;
7600
7601   gsi = gsi_last_bb (entry_bb);
7602
7603   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
7604   /* Not needed in SSA form right now.  */
7605   gcc_assert (!gimple_in_ssa_p (cfun));
7606   if (fd->collapse > 1)
7607     {
7608       int first_zero_iter = -1;
7609       basic_block zero_iter_bb = l2_bb;
7610
7611       counts = XALLOCAVEC (tree, fd->collapse);
7612       expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
7613                                   zero_iter_bb, first_zero_iter,
7614                                   l2_dom_bb);
7615     }
7616   if (l2_dom_bb == NULL)
7617     l2_dom_bb = l1_bb;
7618
7619   n1 = fd->loop.n1;
7620   n2 = fd->loop.n2;
7621   if (gimple_omp_for_combined_into_p (fd->for_stmt))
7622     {
7623       tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
7624                                      OMP_CLAUSE__LOOPTEMP_);
7625       gcc_assert (innerc);
7626       n1 = OMP_CLAUSE_DECL (innerc);
7627       innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
7628                                 OMP_CLAUSE__LOOPTEMP_);
7629       gcc_assert (innerc);
7630       n2 = OMP_CLAUSE_DECL (innerc);
7631       expand_omp_build_assign (&gsi, fd->loop.v,
7632                                fold_convert (type, n1));
7633       if (fd->collapse > 1)
7634         {
7635           gsi_prev (&gsi);
7636           expand_omp_for_init_vars (fd, &gsi, counts, NULL, n1);
7637           gsi_next (&gsi);
7638         }
7639     }
7640   else
7641     {
7642       expand_omp_build_assign (&gsi, fd->loop.v,
7643                                fold_convert (type, fd->loop.n1));
7644       if (fd->collapse > 1)
7645         for (i = 0; i < fd->collapse; i++)
7646           {
7647             tree itype = TREE_TYPE (fd->loops[i].v);
7648             if (POINTER_TYPE_P (itype))
7649               itype = signed_type_for (itype);
7650             t = fold_convert (TREE_TYPE (fd->loops[i].v), fd->loops[i].n1);
7651             expand_omp_build_assign (&gsi, fd->loops[i].v, t);
7652           }
7653       }
7654
7655   /* Remove the GIMPLE_OMP_FOR statement.  */
7656   gsi_remove (&gsi, true);
7657
7658   if (!broken_loop)
7659     {
7660       /* Code to control the increment goes in the CONT_BB.  */
7661       gsi = gsi_last_bb (cont_bb);
7662       stmt = gsi_stmt (gsi);
7663       gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
7664
7665       if (POINTER_TYPE_P (type))
7666         t = fold_build_pointer_plus (fd->loop.v, fd->loop.step);
7667       else
7668         t = fold_build2 (PLUS_EXPR, type, fd->loop.v, fd->loop.step);
7669       expand_omp_build_assign (&gsi, fd->loop.v, t);
7670
7671       if (fd->collapse > 1)
7672         {
7673           i = fd->collapse - 1;
7674           if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i].v)))
7675             {
7676               t = fold_convert (sizetype, fd->loops[i].step);
7677               t = fold_build_pointer_plus (fd->loops[i].v, t);
7678             }
7679           else
7680             {
7681               t = fold_convert (TREE_TYPE (fd->loops[i].v),
7682                                 fd->loops[i].step);
7683               t = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->loops[i].v),
7684                                fd->loops[i].v, t);
7685             }
7686           expand_omp_build_assign (&gsi, fd->loops[i].v, t);
7687
7688           for (i = fd->collapse - 1; i > 0; i--)
7689             {
7690               tree itype = TREE_TYPE (fd->loops[i].v);
7691               tree itype2 = TREE_TYPE (fd->loops[i - 1].v);
7692               if (POINTER_TYPE_P (itype2))
7693                 itype2 = signed_type_for (itype2);
7694               t = build3 (COND_EXPR, itype2,
7695                           build2 (fd->loops[i].cond_code, boolean_type_node,
7696                                   fd->loops[i].v,
7697                                   fold_convert (itype, fd->loops[i].n2)),
7698                           build_int_cst (itype2, 0),
7699                           fold_convert (itype2, fd->loops[i - 1].step));
7700               if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i - 1].v)))
7701                 t = fold_build_pointer_plus (fd->loops[i - 1].v, t);
7702               else
7703                 t = fold_build2 (PLUS_EXPR, itype2, fd->loops[i - 1].v, t);
7704               expand_omp_build_assign (&gsi, fd->loops[i - 1].v, t);
7705
7706               t = build3 (COND_EXPR, itype,
7707                           build2 (fd->loops[i].cond_code, boolean_type_node,
7708                                   fd->loops[i].v,
7709                                   fold_convert (itype, fd->loops[i].n2)),
7710                           fd->loops[i].v,
7711                           fold_convert (itype, fd->loops[i].n1));
7712               expand_omp_build_assign (&gsi, fd->loops[i].v, t);
7713             }
7714         }
7715
7716       /* Remove GIMPLE_OMP_CONTINUE.  */
7717       gsi_remove (&gsi, true);
7718     }
7719
7720   /* Emit the condition in L1_BB.  */
7721   gsi = gsi_start_bb (l1_bb);
7722
7723   t = fold_convert (type, n2);
7724   t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
7725                                 false, GSI_CONTINUE_LINKING);
7726   t = build2 (fd->loop.cond_code, boolean_type_node, fd->loop.v, t);
7727   cond_stmt = gimple_build_cond_empty (t);
7728   gsi_insert_after (&gsi, cond_stmt, GSI_CONTINUE_LINKING);
7729   if (walk_tree (gimple_cond_lhs_ptr (cond_stmt), expand_omp_regimplify_p,
7730                  NULL, NULL)
7731       || walk_tree (gimple_cond_rhs_ptr (cond_stmt), expand_omp_regimplify_p,
7732                     NULL, NULL))
7733     {
7734       gsi = gsi_for_stmt (cond_stmt);
7735       gimple_regimplify_operands (cond_stmt, &gsi);
7736     }
7737
7738   /* Remove GIMPLE_OMP_RETURN.  */
7739   gsi = gsi_last_bb (exit_bb);
7740   gsi_remove (&gsi, true);
7741
7742   /* Connect the new blocks.  */
7743   remove_edge (FALLTHRU_EDGE (entry_bb));
7744
7745   if (!broken_loop)
7746     {
7747       remove_edge (BRANCH_EDGE (entry_bb));
7748       make_edge (entry_bb, l1_bb, EDGE_FALLTHRU);
7749
7750       e = BRANCH_EDGE (l1_bb);
7751       ne = FALLTHRU_EDGE (l1_bb);
7752       e->flags = EDGE_TRUE_VALUE;
7753     }
7754   else
7755     {
7756       single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
7757
7758       ne = single_succ_edge (l1_bb);
7759       e = make_edge (l1_bb, l0_bb, EDGE_TRUE_VALUE);
7760
7761     }
7762   ne->flags = EDGE_FALSE_VALUE;
7763   e->probability = REG_BR_PROB_BASE * 7 / 8;
7764   ne->probability = REG_BR_PROB_BASE / 8;
7765
7766   set_immediate_dominator (CDI_DOMINATORS, l1_bb, entry_bb);
7767   set_immediate_dominator (CDI_DOMINATORS, l2_bb, l2_dom_bb);
7768   set_immediate_dominator (CDI_DOMINATORS, l0_bb, l1_bb);
7769
7770   if (!broken_loop)
7771     {
7772       struct loop *loop = alloc_loop ();
7773       loop->header = l1_bb;
7774       loop->latch = cont_bb;
7775       add_loop (loop, l1_bb->loop_father);
7776       if (safelen == NULL_TREE)
7777         loop->safelen = INT_MAX;
7778       else
7779         {
7780           safelen = OMP_CLAUSE_SAFELEN_EXPR (safelen);
7781           if (TREE_CODE (safelen) != INTEGER_CST)
7782             loop->safelen = 0;
7783           else if (!tree_fits_uhwi_p (safelen)
7784                    || tree_to_uhwi (safelen) > INT_MAX)
7785             loop->safelen = INT_MAX;
7786           else
7787             loop->safelen = tree_to_uhwi (safelen);
7788           if (loop->safelen == 1)
7789             loop->safelen = 0;
7790         }
7791       if (simduid)
7792         {
7793           loop->simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
7794           cfun->has_simduid_loops = true;
7795         }
7796       /* If not -fno-tree-loop-vectorize, hint that we want to vectorize
7797          the loop.  */
7798       if ((flag_tree_loop_vectorize
7799            || (!global_options_set.x_flag_tree_loop_vectorize
7800                && !global_options_set.x_flag_tree_vectorize))
7801           && flag_tree_loop_optimize
7802           && loop->safelen > 1)
7803         {
7804           loop->force_vectorize = true;
7805           cfun->has_force_vectorize_loops = true;
7806         }
7807     }
7808 }
7809
7810
7811 /* Expand the OMP loop defined by REGION.  */
7812
7813 static void
7814 expand_omp_for (struct omp_region *region, gimple inner_stmt)
7815 {
7816   struct omp_for_data fd;
7817   struct omp_for_data_loop *loops;
7818
7819   loops
7820     = (struct omp_for_data_loop *)
7821       alloca (gimple_omp_for_collapse (last_stmt (region->entry))
7822               * sizeof (struct omp_for_data_loop));
7823   extract_omp_for_data (as_a <gomp_for *> (last_stmt (region->entry)),
7824                         &fd, loops);
7825   region->sched_kind = fd.sched_kind;
7826
7827   gcc_assert (EDGE_COUNT (region->entry->succs) == 2);
7828   BRANCH_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
7829   FALLTHRU_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
7830   if (region->cont)
7831     {
7832       gcc_assert (EDGE_COUNT (region->cont->succs) == 2);
7833       BRANCH_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
7834       FALLTHRU_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
7835     }
7836   else
7837     /* If there isn't a continue then this is a degerate case where
7838        the introduction of abnormal edges during lowering will prevent
7839        original loops from being detected.  Fix that up.  */
7840     loops_state_set (LOOPS_NEED_FIXUP);
7841
7842   if (gimple_omp_for_kind (fd.for_stmt) & GF_OMP_FOR_SIMD)
7843     expand_omp_simd (region, &fd);
7844   else if (gimple_omp_for_kind (fd.for_stmt) == GF_OMP_FOR_KIND_CILKFOR)
7845     expand_cilk_for (region, &fd);
7846   else if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
7847            && !fd.have_ordered)
7848     {
7849       if (fd.chunk_size == NULL)
7850         expand_omp_for_static_nochunk (region, &fd, inner_stmt);
7851       else
7852         expand_omp_for_static_chunk (region, &fd, inner_stmt);
7853     }
7854   else
7855     {
7856       int fn_index, start_ix, next_ix;
7857
7858       gcc_assert (gimple_omp_for_kind (fd.for_stmt)
7859                   == GF_OMP_FOR_KIND_FOR);
7860       if (fd.chunk_size == NULL
7861           && fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
7862         fd.chunk_size = integer_zero_node;
7863       gcc_assert (fd.sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
7864       fn_index = (fd.sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
7865                   ? 3 : fd.sched_kind;
7866       fn_index += fd.have_ordered * 4;
7867       start_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_START) + fn_index;
7868       next_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_NEXT) + fn_index;
7869       if (fd.iter_type == long_long_unsigned_type_node)
7870         {
7871           start_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_START
7872                         - (int)BUILT_IN_GOMP_LOOP_STATIC_START);
7873           next_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT
7874                       - (int)BUILT_IN_GOMP_LOOP_STATIC_NEXT);
7875         }
7876       expand_omp_for_generic (region, &fd, (enum built_in_function) start_ix,
7877                               (enum built_in_function) next_ix, inner_stmt);
7878     }
7879
7880   if (gimple_in_ssa_p (cfun))
7881     update_ssa (TODO_update_ssa_only_virtuals);
7882 }
7883
7884
7885 /* Expand code for an OpenMP sections directive.  In pseudo code, we generate
7886
7887         v = GOMP_sections_start (n);
7888     L0:
7889         switch (v)
7890           {
7891           case 0:
7892             goto L2;
7893           case 1:
7894             section 1;
7895             goto L1;
7896           case 2:
7897             ...
7898           case n:
7899             ...
7900           default:
7901             abort ();
7902           }
7903     L1:
7904         v = GOMP_sections_next ();
7905         goto L0;
7906     L2:
7907         reduction;
7908
7909     If this is a combined parallel sections, replace the call to
7910     GOMP_sections_start with call to GOMP_sections_next.  */
7911
7912 static void
7913 expand_omp_sections (struct omp_region *region)
7914 {
7915   tree t, u, vin = NULL, vmain, vnext, l2;
7916   unsigned len;
7917   basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
7918   gimple_stmt_iterator si, switch_si;
7919   gomp_sections *sections_stmt;
7920   gimple stmt;
7921   gomp_continue *cont;
7922   edge_iterator ei;
7923   edge e;
7924   struct omp_region *inner;
7925   unsigned i, casei;
7926   bool exit_reachable = region->cont != NULL;
7927
7928   gcc_assert (region->exit != NULL);
7929   entry_bb = region->entry;
7930   l0_bb = single_succ (entry_bb);
7931   l1_bb = region->cont;
7932   l2_bb = region->exit;
7933   if (single_pred_p (l2_bb) && single_pred (l2_bb) == l0_bb)
7934     l2 = gimple_block_label (l2_bb);
7935   else
7936     {
7937       /* This can happen if there are reductions.  */
7938       len = EDGE_COUNT (l0_bb->succs);
7939       gcc_assert (len > 0);
7940       e = EDGE_SUCC (l0_bb, len - 1);
7941       si = gsi_last_bb (e->dest);
7942       l2 = NULL_TREE;
7943       if (gsi_end_p (si)
7944           || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
7945         l2 = gimple_block_label (e->dest);
7946       else
7947         FOR_EACH_EDGE (e, ei, l0_bb->succs)
7948           {
7949             si = gsi_last_bb (e->dest);
7950             if (gsi_end_p (si)
7951                 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
7952               {
7953                 l2 = gimple_block_label (e->dest);
7954                 break;
7955               }
7956           }
7957     }
7958   if (exit_reachable)
7959     default_bb = create_empty_bb (l1_bb->prev_bb);
7960   else
7961     default_bb = create_empty_bb (l0_bb);
7962
7963   /* We will build a switch() with enough cases for all the
7964      GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
7965      and a default case to abort if something goes wrong.  */
7966   len = EDGE_COUNT (l0_bb->succs);
7967
7968   /* Use vec::quick_push on label_vec throughout, since we know the size
7969      in advance.  */
7970   auto_vec<tree> label_vec (len);
7971
7972   /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
7973      GIMPLE_OMP_SECTIONS statement.  */
7974   si = gsi_last_bb (entry_bb);
7975   sections_stmt = as_a <gomp_sections *> (gsi_stmt (si));
7976   gcc_assert (gimple_code (sections_stmt) == GIMPLE_OMP_SECTIONS);
7977   vin = gimple_omp_sections_control (sections_stmt);
7978   if (!is_combined_parallel (region))
7979     {
7980       /* If we are not inside a combined parallel+sections region,
7981          call GOMP_sections_start.  */
7982       t = build_int_cst (unsigned_type_node, len - 1);
7983       u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START);
7984       stmt = gimple_build_call (u, 1, t);
7985     }
7986   else
7987     {
7988       /* Otherwise, call GOMP_sections_next.  */
7989       u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
7990       stmt = gimple_build_call (u, 0);
7991     }
7992   gimple_call_set_lhs (stmt, vin);
7993   gsi_insert_after (&si, stmt, GSI_SAME_STMT);
7994   gsi_remove (&si, true);
7995
7996   /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
7997      L0_BB.  */
7998   switch_si = gsi_last_bb (l0_bb);
7999   gcc_assert (gimple_code (gsi_stmt (switch_si)) == GIMPLE_OMP_SECTIONS_SWITCH);
8000   if (exit_reachable)
8001     {
8002       cont = as_a <gomp_continue *> (last_stmt (l1_bb));
8003       gcc_assert (gimple_code (cont) == GIMPLE_OMP_CONTINUE);
8004       vmain = gimple_omp_continue_control_use (cont);
8005       vnext = gimple_omp_continue_control_def (cont);
8006     }
8007   else
8008     {
8009       vmain = vin;
8010       vnext = NULL_TREE;
8011     }
8012
8013   t = build_case_label (build_int_cst (unsigned_type_node, 0), NULL, l2);
8014   label_vec.quick_push (t);
8015   i = 1;
8016
8017   /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR.  */
8018   for (inner = region->inner, casei = 1;
8019        inner;
8020        inner = inner->next, i++, casei++)
8021     {
8022       basic_block s_entry_bb, s_exit_bb;
8023
8024       /* Skip optional reduction region.  */
8025       if (inner->type == GIMPLE_OMP_ATOMIC_LOAD)
8026         {
8027           --i;
8028           --casei;
8029           continue;
8030         }
8031
8032       s_entry_bb = inner->entry;
8033       s_exit_bb = inner->exit;
8034
8035       t = gimple_block_label (s_entry_bb);
8036       u = build_int_cst (unsigned_type_node, casei);
8037       u = build_case_label (u, NULL, t);
8038       label_vec.quick_push (u);
8039
8040       si = gsi_last_bb (s_entry_bb);
8041       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SECTION);
8042       gcc_assert (i < len || gimple_omp_section_last_p (gsi_stmt (si)));
8043       gsi_remove (&si, true);
8044       single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
8045
8046       if (s_exit_bb == NULL)
8047         continue;
8048
8049       si = gsi_last_bb (s_exit_bb);
8050       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
8051       gsi_remove (&si, true);
8052
8053       single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
8054     }
8055
8056   /* Error handling code goes in DEFAULT_BB.  */
8057   t = gimple_block_label (default_bb);
8058   u = build_case_label (NULL, NULL, t);
8059   make_edge (l0_bb, default_bb, 0);
8060   add_bb_to_loop (default_bb, current_loops->tree_root);
8061
8062   stmt = gimple_build_switch (vmain, u, label_vec);
8063   gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
8064   gsi_remove (&switch_si, true);
8065
8066   si = gsi_start_bb (default_bb);
8067   stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
8068   gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
8069
8070   if (exit_reachable)
8071     {
8072       tree bfn_decl;
8073
8074       /* Code to get the next section goes in L1_BB.  */
8075       si = gsi_last_bb (l1_bb);
8076       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CONTINUE);
8077
8078       bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
8079       stmt = gimple_build_call (bfn_decl, 0);
8080       gimple_call_set_lhs (stmt, vnext);
8081       gsi_insert_after (&si, stmt, GSI_SAME_STMT);
8082       gsi_remove (&si, true);
8083
8084       single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
8085     }
8086
8087   /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB.  */
8088   si = gsi_last_bb (l2_bb);
8089   if (gimple_omp_return_nowait_p (gsi_stmt (si)))
8090     t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT);
8091   else if (gimple_omp_return_lhs (gsi_stmt (si)))
8092     t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_CANCEL);
8093   else
8094     t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END);
8095   stmt = gimple_build_call (t, 0);
8096   if (gimple_omp_return_lhs (gsi_stmt (si)))
8097     gimple_call_set_lhs (stmt, gimple_omp_return_lhs (gsi_stmt (si)));
8098   gsi_insert_after (&si, stmt, GSI_SAME_STMT);
8099   gsi_remove (&si, true);
8100
8101   set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb);
8102 }
8103
8104
8105 /* Expand code for an OpenMP single directive.  We've already expanded
8106    much of the code, here we simply place the GOMP_barrier call.  */
8107
8108 static void
8109 expand_omp_single (struct omp_region *region)
8110 {
8111   basic_block entry_bb, exit_bb;
8112   gimple_stmt_iterator si;
8113
8114   entry_bb = region->entry;
8115   exit_bb = region->exit;
8116
8117   si = gsi_last_bb (entry_bb);
8118   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE);
8119   gsi_remove (&si, true);
8120   single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
8121
8122   si = gsi_last_bb (exit_bb);
8123   if (!gimple_omp_return_nowait_p (gsi_stmt (si)))
8124     {
8125       tree t = gimple_omp_return_lhs (gsi_stmt (si));
8126       gsi_insert_after (&si, build_omp_barrier (t), GSI_SAME_STMT);
8127     }
8128   gsi_remove (&si, true);
8129   single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
8130 }
8131
8132
8133 /* Generic expansion for OpenMP synchronization directives: master,
8134    ordered and critical.  All we need to do here is remove the entry
8135    and exit markers for REGION.  */
8136
8137 static void
8138 expand_omp_synch (struct omp_region *region)
8139 {
8140   basic_block entry_bb, exit_bb;
8141   gimple_stmt_iterator si;
8142
8143   entry_bb = region->entry;
8144   exit_bb = region->exit;
8145
8146   si = gsi_last_bb (entry_bb);
8147   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE
8148               || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASTER
8149               || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_TASKGROUP
8150               || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ORDERED
8151               || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CRITICAL
8152               || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_TEAMS);
8153   gsi_remove (&si, true);
8154   single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
8155
8156   if (exit_bb)
8157     {
8158       si = gsi_last_bb (exit_bb);
8159       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
8160       gsi_remove (&si, true);
8161       single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
8162     }
8163 }
8164
8165 /* A subroutine of expand_omp_atomic.  Attempt to implement the atomic
8166    operation as a normal volatile load.  */
8167
8168 static bool
8169 expand_omp_atomic_load (basic_block load_bb, tree addr,
8170                         tree loaded_val, int index)
8171 {
8172   enum built_in_function tmpbase;
8173   gimple_stmt_iterator gsi;
8174   basic_block store_bb;
8175   location_t loc;
8176   gimple stmt;
8177   tree decl, call, type, itype;
8178
8179   gsi = gsi_last_bb (load_bb);
8180   stmt = gsi_stmt (gsi);
8181   gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
8182   loc = gimple_location (stmt);
8183
8184   /* ??? If the target does not implement atomic_load_optab[mode], and mode
8185      is smaller than word size, then expand_atomic_load assumes that the load
8186      is atomic.  We could avoid the builtin entirely in this case.  */
8187
8188   tmpbase = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
8189   decl = builtin_decl_explicit (tmpbase);
8190   if (decl == NULL_TREE)
8191     return false;
8192
8193   type = TREE_TYPE (loaded_val);
8194   itype = TREE_TYPE (TREE_TYPE (decl));
8195
8196   call = build_call_expr_loc (loc, decl, 2, addr,
8197                               build_int_cst (NULL,
8198                                              gimple_omp_atomic_seq_cst_p (stmt)
8199                                              ? MEMMODEL_SEQ_CST
8200                                              : MEMMODEL_RELAXED));
8201   if (!useless_type_conversion_p (type, itype))
8202     call = fold_build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
8203   call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
8204
8205   force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
8206   gsi_remove (&gsi, true);
8207
8208   store_bb = single_succ (load_bb);
8209   gsi = gsi_last_bb (store_bb);
8210   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
8211   gsi_remove (&gsi, true);
8212
8213   if (gimple_in_ssa_p (cfun))
8214     update_ssa (TODO_update_ssa_no_phi);
8215
8216   return true;
8217 }
8218
8219 /* A subroutine of expand_omp_atomic.  Attempt to implement the atomic
8220    operation as a normal volatile store.  */
8221
8222 static bool
8223 expand_omp_atomic_store (basic_block load_bb, tree addr,
8224                          tree loaded_val, tree stored_val, int index)
8225 {
8226   enum built_in_function tmpbase;
8227   gimple_stmt_iterator gsi;
8228   basic_block store_bb = single_succ (load_bb);
8229   location_t loc;
8230   gimple stmt;
8231   tree decl, call, type, itype;
8232   machine_mode imode;
8233   bool exchange;
8234
8235   gsi = gsi_last_bb (load_bb);
8236   stmt = gsi_stmt (gsi);
8237   gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
8238
8239   /* If the load value is needed, then this isn't a store but an exchange.  */
8240   exchange = gimple_omp_atomic_need_value_p (stmt);
8241
8242   gsi = gsi_last_bb (store_bb);
8243   stmt = gsi_stmt (gsi);
8244   gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE);
8245   loc = gimple_location (stmt);
8246
8247   /* ??? If the target does not implement atomic_store_optab[mode], and mode
8248      is smaller than word size, then expand_atomic_store assumes that the store
8249      is atomic.  We could avoid the builtin entirely in this case.  */
8250
8251   tmpbase = (exchange ? BUILT_IN_ATOMIC_EXCHANGE_N : BUILT_IN_ATOMIC_STORE_N);
8252   tmpbase = (enum built_in_function) ((int) tmpbase + index + 1);
8253   decl = builtin_decl_explicit (tmpbase);
8254   if (decl == NULL_TREE)
8255     return false;
8256
8257   type = TREE_TYPE (stored_val);
8258
8259   /* Dig out the type of the function's second argument.  */
8260   itype = TREE_TYPE (decl);
8261   itype = TYPE_ARG_TYPES (itype);
8262   itype = TREE_CHAIN (itype);
8263   itype = TREE_VALUE (itype);
8264   imode = TYPE_MODE (itype);
8265
8266   if (exchange && !can_atomic_exchange_p (imode, true))
8267     return false;
8268
8269   if (!useless_type_conversion_p (itype, type))
8270     stored_val = fold_build1_loc (loc, VIEW_CONVERT_EXPR, itype, stored_val);
8271   call = build_call_expr_loc (loc, decl, 3, addr, stored_val,
8272                               build_int_cst (NULL,
8273                                              gimple_omp_atomic_seq_cst_p (stmt)
8274                                              ? MEMMODEL_SEQ_CST
8275                                              : MEMMODEL_RELAXED));
8276   if (exchange)
8277     {
8278       if (!useless_type_conversion_p (type, itype))
8279         call = build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
8280       call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
8281     }
8282
8283   force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
8284   gsi_remove (&gsi, true);
8285
8286   /* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above.  */
8287   gsi = gsi_last_bb (load_bb);
8288   gsi_remove (&gsi, true);
8289
8290   if (gimple_in_ssa_p (cfun))
8291     update_ssa (TODO_update_ssa_no_phi);
8292
8293   return true;
8294 }
8295
8296 /* A subroutine of expand_omp_atomic.  Attempt to implement the atomic
8297    operation as a __atomic_fetch_op builtin.  INDEX is log2 of the
8298    size of the data type, and thus usable to find the index of the builtin
8299    decl.  Returns false if the expression is not of the proper form.  */
8300
8301 static bool
8302 expand_omp_atomic_fetch_op (basic_block load_bb,
8303                             tree addr, tree loaded_val,
8304                             tree stored_val, int index)
8305 {
8306   enum built_in_function oldbase, newbase, tmpbase;
8307   tree decl, itype, call;
8308   tree lhs, rhs;
8309   basic_block store_bb = single_succ (load_bb);
8310   gimple_stmt_iterator gsi;
8311   gimple stmt;
8312   location_t loc;
8313   enum tree_code code;
8314   bool need_old, need_new;
8315   machine_mode imode;
8316   bool seq_cst;
8317
8318   /* We expect to find the following sequences:
8319
8320    load_bb:
8321        GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
8322
8323    store_bb:
8324        val = tmp OP something; (or: something OP tmp)
8325        GIMPLE_OMP_STORE (val)
8326
8327   ???FIXME: Allow a more flexible sequence.
8328   Perhaps use data flow to pick the statements.
8329
8330   */
8331
8332   gsi = gsi_after_labels (store_bb);
8333   stmt = gsi_stmt (gsi);
8334   loc = gimple_location (stmt);
8335   if (!is_gimple_assign (stmt))
8336     return false;
8337   gsi_next (&gsi);
8338   if (gimple_code (gsi_stmt (gsi)) != GIMPLE_OMP_ATOMIC_STORE)
8339     return false;
8340   need_new = gimple_omp_atomic_need_value_p (gsi_stmt (gsi));
8341   need_old = gimple_omp_atomic_need_value_p (last_stmt (load_bb));
8342   seq_cst = gimple_omp_atomic_seq_cst_p (last_stmt (load_bb));
8343   gcc_checking_assert (!need_old || !need_new);
8344
8345   if (!operand_equal_p (gimple_assign_lhs (stmt), stored_val, 0))
8346     return false;
8347
8348   /* Check for one of the supported fetch-op operations.  */
8349   code = gimple_assign_rhs_code (stmt);
8350   switch (code)
8351     {
8352     case PLUS_EXPR:
8353     case POINTER_PLUS_EXPR:
8354       oldbase = BUILT_IN_ATOMIC_FETCH_ADD_N;
8355       newbase = BUILT_IN_ATOMIC_ADD_FETCH_N;
8356       break;
8357     case MINUS_EXPR:
8358       oldbase = BUILT_IN_ATOMIC_FETCH_SUB_N;
8359       newbase = BUILT_IN_ATOMIC_SUB_FETCH_N;
8360       break;
8361     case BIT_AND_EXPR:
8362       oldbase = BUILT_IN_ATOMIC_FETCH_AND_N;
8363       newbase = BUILT_IN_ATOMIC_AND_FETCH_N;
8364       break;
8365     case BIT_IOR_EXPR:
8366       oldbase = BUILT_IN_ATOMIC_FETCH_OR_N;
8367       newbase = BUILT_IN_ATOMIC_OR_FETCH_N;
8368       break;
8369     case BIT_XOR_EXPR:
8370       oldbase = BUILT_IN_ATOMIC_FETCH_XOR_N;
8371       newbase = BUILT_IN_ATOMIC_XOR_FETCH_N;
8372       break;
8373     default:
8374       return false;
8375     }
8376
8377   /* Make sure the expression is of the proper form.  */
8378   if (operand_equal_p (gimple_assign_rhs1 (stmt), loaded_val, 0))
8379     rhs = gimple_assign_rhs2 (stmt);
8380   else if (commutative_tree_code (gimple_assign_rhs_code (stmt))
8381            && operand_equal_p (gimple_assign_rhs2 (stmt), loaded_val, 0))
8382     rhs = gimple_assign_rhs1 (stmt);
8383   else
8384     return false;
8385
8386   tmpbase = ((enum built_in_function)
8387              ((need_new ? newbase : oldbase) + index + 1));
8388   decl = builtin_decl_explicit (tmpbase);
8389   if (decl == NULL_TREE)
8390     return false;
8391   itype = TREE_TYPE (TREE_TYPE (decl));
8392   imode = TYPE_MODE (itype);
8393
8394   /* We could test all of the various optabs involved, but the fact of the
8395      matter is that (with the exception of i486 vs i586 and xadd) all targets
8396      that support any atomic operaton optab also implements compare-and-swap.
8397      Let optabs.c take care of expanding any compare-and-swap loop.  */
8398   if (!can_compare_and_swap_p (imode, true))
8399     return false;
8400
8401   gsi = gsi_last_bb (load_bb);
8402   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_LOAD);
8403
8404   /* OpenMP does not imply any barrier-like semantics on its atomic ops.
8405      It only requires that the operation happen atomically.  Thus we can
8406      use the RELAXED memory model.  */
8407   call = build_call_expr_loc (loc, decl, 3, addr,
8408                               fold_convert_loc (loc, itype, rhs),
8409                               build_int_cst (NULL,
8410                                              seq_cst ? MEMMODEL_SEQ_CST
8411                                                      : MEMMODEL_RELAXED));
8412
8413   if (need_old || need_new)
8414     {
8415       lhs = need_old ? loaded_val : stored_val;
8416       call = fold_convert_loc (loc, TREE_TYPE (lhs), call);
8417       call = build2_loc (loc, MODIFY_EXPR, void_type_node, lhs, call);
8418     }
8419   else
8420     call = fold_convert_loc (loc, void_type_node, call);
8421   force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
8422   gsi_remove (&gsi, true);
8423
8424   gsi = gsi_last_bb (store_bb);
8425   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
8426   gsi_remove (&gsi, true);
8427   gsi = gsi_last_bb (store_bb);
8428   gsi_remove (&gsi, true);
8429
8430   if (gimple_in_ssa_p (cfun))
8431     update_ssa (TODO_update_ssa_no_phi);
8432
8433   return true;
8434 }
8435
8436 /* A subroutine of expand_omp_atomic.  Implement the atomic operation as:
8437
8438       oldval = *addr;
8439       repeat:
8440         newval = rhs;    // with oldval replacing *addr in rhs
8441         oldval = __sync_val_compare_and_swap (addr, oldval, newval);
8442         if (oldval != newval)
8443           goto repeat;
8444
8445    INDEX is log2 of the size of the data type, and thus usable to find the
8446    index of the builtin decl.  */
8447
8448 static bool
8449 expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
8450                             tree addr, tree loaded_val, tree stored_val,
8451                             int index)
8452 {
8453   tree loadedi, storedi, initial, new_storedi, old_vali;
8454   tree type, itype, cmpxchg, iaddr;
8455   gimple_stmt_iterator si;
8456   basic_block loop_header = single_succ (load_bb);
8457   gimple phi, stmt;
8458   edge e;
8459   enum built_in_function fncode;
8460
8461   /* ??? We need a non-pointer interface to __atomic_compare_exchange in
8462      order to use the RELAXED memory model effectively.  */
8463   fncode = (enum built_in_function)((int)BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
8464                                     + index + 1);
8465   cmpxchg = builtin_decl_explicit (fncode);
8466   if (cmpxchg == NULL_TREE)
8467     return false;
8468   type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
8469   itype = TREE_TYPE (TREE_TYPE (cmpxchg));
8470
8471   if (!can_compare_and_swap_p (TYPE_MODE (itype), true))
8472     return false;
8473
8474   /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD.  */
8475   si = gsi_last_bb (load_bb);
8476   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
8477
8478   /* For floating-point values, we'll need to view-convert them to integers
8479      so that we can perform the atomic compare and swap.  Simplify the
8480      following code by always setting up the "i"ntegral variables.  */
8481   if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
8482     {
8483       tree iaddr_val;
8484
8485       iaddr = create_tmp_reg (build_pointer_type_for_mode (itype, ptr_mode,
8486                                                            true));
8487       iaddr_val
8488         = force_gimple_operand_gsi (&si,
8489                                     fold_convert (TREE_TYPE (iaddr), addr),
8490                                     false, NULL_TREE, true, GSI_SAME_STMT);
8491       stmt = gimple_build_assign (iaddr, iaddr_val);
8492       gsi_insert_before (&si, stmt, GSI_SAME_STMT);
8493       loadedi = create_tmp_var (itype);
8494       if (gimple_in_ssa_p (cfun))
8495         loadedi = make_ssa_name (loadedi);
8496     }
8497   else
8498     {
8499       iaddr = addr;
8500       loadedi = loaded_val;
8501     }
8502
8503   fncode = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
8504   tree loaddecl = builtin_decl_explicit (fncode);
8505   if (loaddecl)
8506     initial
8507       = fold_convert (TREE_TYPE (TREE_TYPE (iaddr)),
8508                       build_call_expr (loaddecl, 2, iaddr,
8509                                        build_int_cst (NULL_TREE,
8510                                                       MEMMODEL_RELAXED)));
8511   else
8512     initial = build2 (MEM_REF, TREE_TYPE (TREE_TYPE (iaddr)), iaddr,
8513                       build_int_cst (TREE_TYPE (iaddr), 0));
8514
8515   initial
8516     = force_gimple_operand_gsi (&si, initial, true, NULL_TREE, true,
8517                                 GSI_SAME_STMT);
8518
8519   /* Move the value to the LOADEDI temporary.  */
8520   if (gimple_in_ssa_p (cfun))
8521     {
8522       gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header)));
8523       phi = create_phi_node (loadedi, loop_header);
8524       SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (load_bb)),
8525                initial);
8526     }
8527   else
8528     gsi_insert_before (&si,
8529                        gimple_build_assign (loadedi, initial),
8530                        GSI_SAME_STMT);
8531   if (loadedi != loaded_val)
8532     {
8533       gimple_stmt_iterator gsi2;
8534       tree x;
8535
8536       x = build1 (VIEW_CONVERT_EXPR, type, loadedi);
8537       gsi2 = gsi_start_bb (loop_header);
8538       if (gimple_in_ssa_p (cfun))
8539         {
8540           gassign *stmt;
8541           x = force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
8542                                         true, GSI_SAME_STMT);
8543           stmt = gimple_build_assign (loaded_val, x);
8544           gsi_insert_before (&gsi2, stmt, GSI_SAME_STMT);
8545         }
8546       else
8547         {
8548           x = build2 (MODIFY_EXPR, TREE_TYPE (loaded_val), loaded_val, x);
8549           force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
8550                                     true, GSI_SAME_STMT);
8551         }
8552     }
8553   gsi_remove (&si, true);
8554
8555   si = gsi_last_bb (store_bb);
8556   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
8557
8558   if (iaddr == addr)
8559     storedi = stored_val;
8560   else
8561     storedi =
8562       force_gimple_operand_gsi (&si,
8563                                 build1 (VIEW_CONVERT_EXPR, itype,
8564                                         stored_val), true, NULL_TREE, true,
8565                                 GSI_SAME_STMT);
8566
8567   /* Build the compare&swap statement.  */
8568   new_storedi = build_call_expr (cmpxchg, 3, iaddr, loadedi, storedi);
8569   new_storedi = force_gimple_operand_gsi (&si,
8570                                           fold_convert (TREE_TYPE (loadedi),
8571                                                         new_storedi),
8572                                           true, NULL_TREE,
8573                                           true, GSI_SAME_STMT);
8574
8575   if (gimple_in_ssa_p (cfun))
8576     old_vali = loadedi;
8577   else
8578     {
8579       old_vali = create_tmp_var (TREE_TYPE (loadedi));
8580       stmt = gimple_build_assign (old_vali, loadedi);
8581       gsi_insert_before (&si, stmt, GSI_SAME_STMT);
8582
8583       stmt = gimple_build_assign (loadedi, new_storedi);
8584       gsi_insert_before (&si, stmt, GSI_SAME_STMT);
8585     }
8586
8587   /* Note that we always perform the comparison as an integer, even for
8588      floating point.  This allows the atomic operation to properly
8589      succeed even with NaNs and -0.0.  */
8590   stmt = gimple_build_cond_empty
8591            (build2 (NE_EXPR, boolean_type_node,
8592                     new_storedi, old_vali));
8593   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
8594
8595   /* Update cfg.  */
8596   e = single_succ_edge (store_bb);
8597   e->flags &= ~EDGE_FALLTHRU;
8598   e->flags |= EDGE_FALSE_VALUE;
8599
8600   e = make_edge (store_bb, loop_header, EDGE_TRUE_VALUE);
8601
8602   /* Copy the new value to loadedi (we already did that before the condition
8603      if we are not in SSA).  */
8604   if (gimple_in_ssa_p (cfun))
8605     {
8606       phi = gimple_seq_first_stmt (phi_nodes (loop_header));
8607       SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), new_storedi);
8608     }
8609
8610   /* Remove GIMPLE_OMP_ATOMIC_STORE.  */
8611   gsi_remove (&si, true);
8612
8613   struct loop *loop = alloc_loop ();
8614   loop->header = loop_header;
8615   loop->latch = store_bb;
8616   add_loop (loop, loop_header->loop_father);
8617
8618   if (gimple_in_ssa_p (cfun))
8619     update_ssa (TODO_update_ssa_no_phi);
8620
8621   return true;
8622 }
8623
8624 /* A subroutine of expand_omp_atomic.  Implement the atomic operation as:
8625
8626                                   GOMP_atomic_start ();
8627                                   *addr = rhs;
8628                                   GOMP_atomic_end ();
8629
8630    The result is not globally atomic, but works so long as all parallel
8631    references are within #pragma omp atomic directives.  According to
8632    responses received from omp@openmp.org, appears to be within spec.
8633    Which makes sense, since that's how several other compilers handle
8634    this situation as well.
8635    LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
8636    expanding.  STORED_VAL is the operand of the matching
8637    GIMPLE_OMP_ATOMIC_STORE.
8638
8639    We replace
8640    GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
8641    loaded_val = *addr;
8642
8643    and replace
8644    GIMPLE_OMP_ATOMIC_STORE (stored_val)  with
8645    *addr = stored_val;
8646 */
8647
8648 static bool
8649 expand_omp_atomic_mutex (basic_block load_bb, basic_block store_bb,
8650                          tree addr, tree loaded_val, tree stored_val)
8651 {
8652   gimple_stmt_iterator si;
8653   gassign *stmt;
8654   tree t;
8655
8656   si = gsi_last_bb (load_bb);
8657   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
8658
8659   t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
8660   t = build_call_expr (t, 0);
8661   force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
8662
8663   stmt = gimple_build_assign (loaded_val, build_simple_mem_ref (addr));
8664   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
8665   gsi_remove (&si, true);
8666
8667   si = gsi_last_bb (store_bb);
8668   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
8669
8670   stmt = gimple_build_assign (build_simple_mem_ref (unshare_expr (addr)),
8671                               stored_val);
8672   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
8673
8674   t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
8675   t = build_call_expr (t, 0);
8676   force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
8677   gsi_remove (&si, true);
8678
8679   if (gimple_in_ssa_p (cfun))
8680     update_ssa (TODO_update_ssa_no_phi);
8681   return true;
8682 }
8683
8684 /* Expand an GIMPLE_OMP_ATOMIC statement.  We try to expand
8685    using expand_omp_atomic_fetch_op. If it failed, we try to
8686    call expand_omp_atomic_pipeline, and if it fails too, the
8687    ultimate fallback is wrapping the operation in a mutex
8688    (expand_omp_atomic_mutex).  REGION is the atomic region built
8689    by build_omp_regions_1().  */
8690
8691 static void
8692 expand_omp_atomic (struct omp_region *region)
8693 {
8694   basic_block load_bb = region->entry, store_bb = region->exit;
8695   gomp_atomic_load *load = as_a <gomp_atomic_load *> (last_stmt (load_bb));
8696   gomp_atomic_store *store = as_a <gomp_atomic_store *> (last_stmt (store_bb));
8697   tree loaded_val = gimple_omp_atomic_load_lhs (load);
8698   tree addr = gimple_omp_atomic_load_rhs (load);
8699   tree stored_val = gimple_omp_atomic_store_val (store);
8700   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
8701   HOST_WIDE_INT index;
8702
8703   /* Make sure the type is one of the supported sizes.  */
8704   index = tree_to_uhwi (TYPE_SIZE_UNIT (type));
8705   index = exact_log2 (index);
8706   if (index >= 0 && index <= 4)
8707     {
8708       unsigned int align = TYPE_ALIGN_UNIT (type);
8709
8710       /* __sync builtins require strict data alignment.  */
8711       if (exact_log2 (align) >= index)
8712         {
8713           /* Atomic load.  */
8714           if (loaded_val == stored_val
8715               && (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
8716                   || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
8717               && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
8718               && expand_omp_atomic_load (load_bb, addr, loaded_val, index))
8719             return;
8720
8721           /* Atomic store.  */
8722           if ((GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
8723                || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
8724               && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
8725               && store_bb == single_succ (load_bb)
8726               && first_stmt (store_bb) == store
8727               && expand_omp_atomic_store (load_bb, addr, loaded_val,
8728                                           stored_val, index))
8729             return;
8730
8731           /* When possible, use specialized atomic update functions.  */
8732           if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
8733               && store_bb == single_succ (load_bb)
8734               && expand_omp_atomic_fetch_op (load_bb, addr,
8735                                              loaded_val, stored_val, index))
8736             return;
8737
8738           /* If we don't have specialized __sync builtins, try and implement
8739              as a compare and swap loop.  */
8740           if (expand_omp_atomic_pipeline (load_bb, store_bb, addr,
8741                                           loaded_val, stored_val, index))
8742             return;
8743         }
8744     }
8745
8746   /* The ultimate fallback is wrapping the operation in a mutex.  */
8747   expand_omp_atomic_mutex (load_bb, store_bb, addr, loaded_val, stored_val);
8748 }
8749
8750
8751 /* Expand the GIMPLE_OMP_TARGET starting at REGION.  */
8752
8753 static void
8754 expand_omp_target (struct omp_region *region)
8755 {
8756   basic_block entry_bb, exit_bb, new_bb;
8757   struct function *child_cfun;
8758   tree child_fn, block, t;
8759   gimple_stmt_iterator gsi;
8760   gomp_target *entry_stmt;
8761   gimple stmt;
8762   edge e;
8763   bool offloaded, data_region;
8764
8765   entry_stmt = as_a <gomp_target *> (last_stmt (region->entry));
8766   new_bb = region->entry;
8767
8768   offloaded = is_gimple_omp_offloaded (entry_stmt);
8769   switch (gimple_omp_target_kind (entry_stmt))
8770     {
8771     case GF_OMP_TARGET_KIND_REGION:
8772     case GF_OMP_TARGET_KIND_UPDATE:
8773     case GF_OMP_TARGET_KIND_OACC_PARALLEL:
8774     case GF_OMP_TARGET_KIND_OACC_KERNELS:
8775     case GF_OMP_TARGET_KIND_OACC_UPDATE:
8776     case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
8777       data_region = false;
8778       break;
8779     case GF_OMP_TARGET_KIND_DATA:
8780     case GF_OMP_TARGET_KIND_OACC_DATA:
8781       data_region = true;
8782       break;
8783     default:
8784       gcc_unreachable ();
8785     }
8786
8787   child_fn = NULL_TREE;
8788   child_cfun = NULL;
8789   if (offloaded)
8790     {
8791       child_fn = gimple_omp_target_child_fn (entry_stmt);
8792       child_cfun = DECL_STRUCT_FUNCTION (child_fn);
8793     }
8794
8795   /* Supported by expand_omp_taskreg, but not here.  */
8796   if (child_cfun != NULL)
8797     gcc_checking_assert (!child_cfun->cfg);
8798   gcc_checking_assert (!gimple_in_ssa_p (cfun));
8799
8800   entry_bb = region->entry;
8801   exit_bb = region->exit;
8802
8803   if (offloaded)
8804     {
8805       unsigned srcidx, dstidx, num;
8806
8807       /* If the offloading region needs data sent from the parent
8808          function, then the very first statement (except possible
8809          tree profile counter updates) of the offloading body
8810          is a copy assignment .OMP_DATA_I = &.OMP_DATA_O.  Since
8811          &.OMP_DATA_O is passed as an argument to the child function,
8812          we need to replace it with the argument as seen by the child
8813          function.
8814
8815          In most cases, this will end up being the identity assignment
8816          .OMP_DATA_I = .OMP_DATA_I.  However, if the offloading body had
8817          a function call that has been inlined, the original PARM_DECL
8818          .OMP_DATA_I may have been converted into a different local
8819          variable.  In which case, we need to keep the assignment.  */
8820       tree data_arg = gimple_omp_target_data_arg (entry_stmt);
8821       if (data_arg)
8822         {
8823           basic_block entry_succ_bb = single_succ (entry_bb);
8824           gimple_stmt_iterator gsi;
8825           tree arg;
8826           gimple tgtcopy_stmt = NULL;
8827           tree sender = TREE_VEC_ELT (data_arg, 0);
8828
8829           for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
8830             {
8831               gcc_assert (!gsi_end_p (gsi));
8832               stmt = gsi_stmt (gsi);
8833               if (gimple_code (stmt) != GIMPLE_ASSIGN)
8834                 continue;
8835
8836               if (gimple_num_ops (stmt) == 2)
8837                 {
8838                   tree arg = gimple_assign_rhs1 (stmt);
8839
8840                   /* We're ignoring the subcode because we're
8841                      effectively doing a STRIP_NOPS.  */
8842
8843                   if (TREE_CODE (arg) == ADDR_EXPR
8844                       && TREE_OPERAND (arg, 0) == sender)
8845                     {
8846                       tgtcopy_stmt = stmt;
8847                       break;
8848                     }
8849                 }
8850             }
8851
8852           gcc_assert (tgtcopy_stmt != NULL);
8853           arg = DECL_ARGUMENTS (child_fn);
8854
8855           gcc_assert (gimple_assign_lhs (tgtcopy_stmt) == arg);
8856           gsi_remove (&gsi, true);
8857         }
8858
8859       /* Declare local variables needed in CHILD_CFUN.  */
8860       block = DECL_INITIAL (child_fn);
8861       BLOCK_VARS (block) = vec2chain (child_cfun->local_decls);
8862       /* The gimplifier could record temporaries in the offloading block
8863          rather than in containing function's local_decls chain,
8864          which would mean cgraph missed finalizing them.  Do it now.  */
8865       for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
8866         if (TREE_CODE (t) == VAR_DECL
8867             && TREE_STATIC (t)
8868             && !DECL_EXTERNAL (t))
8869           varpool_node::finalize_decl (t);
8870       DECL_SAVED_TREE (child_fn) = NULL;
8871       /* We'll create a CFG for child_fn, so no gimple body is needed.  */
8872       gimple_set_body (child_fn, NULL);
8873       TREE_USED (block) = 1;
8874
8875       /* Reset DECL_CONTEXT on function arguments.  */
8876       for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
8877         DECL_CONTEXT (t) = child_fn;
8878
8879       /* Split ENTRY_BB at GIMPLE_*,
8880          so that it can be moved to the child function.  */
8881       gsi = gsi_last_bb (entry_bb);
8882       stmt = gsi_stmt (gsi);
8883       gcc_assert (stmt
8884                   && gimple_code (stmt) == gimple_code (entry_stmt));
8885       gsi_remove (&gsi, true);
8886       e = split_block (entry_bb, stmt);
8887       entry_bb = e->dest;
8888       single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
8889
8890       /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR.  */
8891       if (exit_bb)
8892         {
8893           gsi = gsi_last_bb (exit_bb);
8894           gcc_assert (!gsi_end_p (gsi)
8895                       && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
8896           stmt = gimple_build_return (NULL);
8897           gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
8898           gsi_remove (&gsi, true);
8899         }
8900
8901       /* Move the offloading region into CHILD_CFUN.  */
8902
8903       block = gimple_block (entry_stmt);
8904
8905       new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
8906       if (exit_bb)
8907         single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
8908       /* When the OMP expansion process cannot guarantee an up-to-date
8909          loop tree arrange for the child function to fixup loops.  */
8910       if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
8911         child_cfun->x_current_loops->state |= LOOPS_NEED_FIXUP;
8912
8913       /* Remove non-local VAR_DECLs from child_cfun->local_decls list.  */
8914       num = vec_safe_length (child_cfun->local_decls);
8915       for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
8916         {
8917           t = (*child_cfun->local_decls)[srcidx];
8918           if (DECL_CONTEXT (t) == cfun->decl)
8919             continue;
8920           if (srcidx != dstidx)
8921             (*child_cfun->local_decls)[dstidx] = t;
8922           dstidx++;
8923         }
8924       if (dstidx != num)
8925         vec_safe_truncate (child_cfun->local_decls, dstidx);
8926
8927       /* Inform the callgraph about the new function.  */
8928       DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
8929       cgraph_node::add_new_function (child_fn, true);
8930
8931 #ifdef ENABLE_OFFLOADING
8932       /* Add the new function to the offload table.  */
8933       vec_safe_push (offload_funcs, child_fn);
8934 #endif
8935
8936       /* Fix the callgraph edges for child_cfun.  Those for cfun will be
8937          fixed in a following pass.  */
8938       push_cfun (child_cfun);
8939       cgraph_edge::rebuild_edges ();
8940
8941 #ifdef ENABLE_OFFLOADING
8942       /* Prevent IPA from removing child_fn as unreachable, since there are no
8943          refs from the parent function to child_fn in offload LTO mode.  */
8944       struct cgraph_node *node = cgraph_node::get (child_fn);
8945       node->mark_force_output ();
8946 #endif
8947
8948       /* Some EH regions might become dead, see PR34608.  If
8949          pass_cleanup_cfg isn't the first pass to happen with the
8950          new child, these dead EH edges might cause problems.
8951          Clean them up now.  */
8952       if (flag_exceptions)
8953         {
8954           basic_block bb;
8955           bool changed = false;
8956
8957           FOR_EACH_BB_FN (bb, cfun)
8958             changed |= gimple_purge_dead_eh_edges (bb);
8959           if (changed)
8960             cleanup_tree_cfg ();
8961         }
8962       pop_cfun ();
8963     }
8964
8965   /* Emit a library call to launch the offloading region, or do data
8966      transfers.  */
8967   tree t1, t2, t3, t4, device, cond, c, clauses;
8968   enum built_in_function start_ix;
8969   location_t clause_loc;
8970
8971   switch (gimple_omp_target_kind (entry_stmt))
8972     {
8973     case GF_OMP_TARGET_KIND_REGION:
8974       start_ix = BUILT_IN_GOMP_TARGET;
8975       break;
8976     case GF_OMP_TARGET_KIND_DATA:
8977       start_ix = BUILT_IN_GOMP_TARGET_DATA;
8978       break;
8979     case GF_OMP_TARGET_KIND_UPDATE:
8980       start_ix = BUILT_IN_GOMP_TARGET_UPDATE;
8981       break;
8982     case GF_OMP_TARGET_KIND_OACC_PARALLEL:
8983     case GF_OMP_TARGET_KIND_OACC_KERNELS:
8984       start_ix = BUILT_IN_GOACC_PARALLEL;
8985       break;
8986     case GF_OMP_TARGET_KIND_OACC_DATA:
8987       start_ix = BUILT_IN_GOACC_DATA_START;
8988       break;
8989     case GF_OMP_TARGET_KIND_OACC_UPDATE:
8990       start_ix = BUILT_IN_GOACC_UPDATE;
8991       break;
8992     case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
8993       start_ix = BUILT_IN_GOACC_ENTER_EXIT_DATA;
8994       break;
8995     default:
8996       gcc_unreachable ();
8997     }
8998
8999   clauses = gimple_omp_target_clauses (entry_stmt);
9000
9001   /* By default, the value of DEVICE is GOMP_DEVICE_ICV (let runtime
9002      library choose) and there is no conditional.  */
9003   cond = NULL_TREE;
9004   device = build_int_cst (integer_type_node, GOMP_DEVICE_ICV);
9005
9006   c = find_omp_clause (clauses, OMP_CLAUSE_IF);
9007   if (c)
9008     cond = OMP_CLAUSE_IF_EXPR (c);
9009
9010   c = find_omp_clause (clauses, OMP_CLAUSE_DEVICE);
9011   if (c)
9012     {
9013       /* Even if we pass it to all library function calls, it is currently only
9014          defined/used for the OpenMP target ones.  */
9015       gcc_checking_assert (start_ix == BUILT_IN_GOMP_TARGET
9016                            || start_ix == BUILT_IN_GOMP_TARGET_DATA
9017                            || start_ix == BUILT_IN_GOMP_TARGET_UPDATE);
9018
9019       device = OMP_CLAUSE_DEVICE_ID (c);
9020       clause_loc = OMP_CLAUSE_LOCATION (c);
9021     }
9022   else
9023     clause_loc = gimple_location (entry_stmt);
9024
9025   /* Ensure 'device' is of the correct type.  */
9026   device = fold_convert_loc (clause_loc, integer_type_node, device);
9027
9028   /* If we found the clause 'if (cond)', build
9029      (cond ? device : GOMP_DEVICE_HOST_FALLBACK).  */
9030   if (cond)
9031     {
9032       cond = gimple_boolify (cond);
9033
9034       basic_block cond_bb, then_bb, else_bb;
9035       edge e;
9036       tree tmp_var;
9037
9038       tmp_var = create_tmp_var (TREE_TYPE (device));
9039       if (offloaded)
9040         e = split_block (new_bb, NULL);
9041       else
9042         {
9043           gsi = gsi_last_bb (new_bb);
9044           gsi_prev (&gsi);
9045           e = split_block (new_bb, gsi_stmt (gsi));
9046         }
9047       cond_bb = e->src;
9048       new_bb = e->dest;
9049       remove_edge (e);
9050
9051       then_bb = create_empty_bb (cond_bb);
9052       else_bb = create_empty_bb (then_bb);
9053       set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
9054       set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
9055
9056       stmt = gimple_build_cond_empty (cond);
9057       gsi = gsi_last_bb (cond_bb);
9058       gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
9059
9060       gsi = gsi_start_bb (then_bb);
9061       stmt = gimple_build_assign (tmp_var, device);
9062       gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
9063
9064       gsi = gsi_start_bb (else_bb);
9065       stmt = gimple_build_assign (tmp_var,
9066                                   build_int_cst (integer_type_node,
9067                                                  GOMP_DEVICE_HOST_FALLBACK));
9068       gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
9069
9070       make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
9071       make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
9072       add_bb_to_loop (then_bb, cond_bb->loop_father);
9073       add_bb_to_loop (else_bb, cond_bb->loop_father);
9074       make_edge (then_bb, new_bb, EDGE_FALLTHRU);
9075       make_edge (else_bb, new_bb, EDGE_FALLTHRU);
9076
9077       device = tmp_var;
9078     }
9079
9080   gsi = gsi_last_bb (new_bb);
9081   t = gimple_omp_target_data_arg (entry_stmt);
9082   if (t == NULL)
9083     {
9084       t1 = size_zero_node;
9085       t2 = build_zero_cst (ptr_type_node);
9086       t3 = t2;
9087       t4 = t2;
9088     }
9089   else
9090     {
9091       t1 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (TREE_VEC_ELT (t, 1))));
9092       t1 = size_binop (PLUS_EXPR, t1, size_int (1));
9093       t2 = build_fold_addr_expr (TREE_VEC_ELT (t, 0));
9094       t3 = build_fold_addr_expr (TREE_VEC_ELT (t, 1));
9095       t4 = build_fold_addr_expr (TREE_VEC_ELT (t, 2));
9096     }
9097
9098   gimple g;
9099   vec<tree> *args;
9100   /* The maximum number used by any start_ix, without varargs.  */
9101   unsigned int argcnt = 11;
9102
9103   vec_alloc (args, argcnt);
9104   args->quick_push (device);
9105   if (offloaded)
9106     args->quick_push (build_fold_addr_expr (child_fn));
9107   switch (start_ix)
9108     {
9109     case BUILT_IN_GOMP_TARGET:
9110     case BUILT_IN_GOMP_TARGET_DATA:
9111     case BUILT_IN_GOMP_TARGET_UPDATE:
9112       /* This const void * is part of the current ABI, but we're not actually
9113          using it.  */
9114       args->quick_push (build_zero_cst (ptr_type_node));
9115       break;
9116     case BUILT_IN_GOACC_DATA_START:
9117     case BUILT_IN_GOACC_ENTER_EXIT_DATA:
9118     case BUILT_IN_GOACC_PARALLEL:
9119     case BUILT_IN_GOACC_UPDATE:
9120       break;
9121     default:
9122       gcc_unreachable ();
9123     }
9124   args->quick_push (t1);
9125   args->quick_push (t2);
9126   args->quick_push (t3);
9127   args->quick_push (t4);
9128   switch (start_ix)
9129     {
9130     case BUILT_IN_GOACC_DATA_START:
9131     case BUILT_IN_GOMP_TARGET:
9132     case BUILT_IN_GOMP_TARGET_DATA:
9133     case BUILT_IN_GOMP_TARGET_UPDATE:
9134       break;
9135     case BUILT_IN_GOACC_PARALLEL:
9136       {
9137         tree t_num_gangs, t_num_workers, t_vector_length;
9138
9139         /* Default values for num_gangs, num_workers, and vector_length.  */
9140         t_num_gangs = t_num_workers = t_vector_length
9141           = fold_convert_loc (gimple_location (entry_stmt),
9142                               integer_type_node, integer_one_node);
9143         /* ..., but if present, use the value specified by the respective
9144            clause, making sure that are of the correct type.  */
9145         c = find_omp_clause (clauses, OMP_CLAUSE_NUM_GANGS);
9146         if (c)
9147           t_num_gangs = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
9148                                           integer_type_node,
9149                                           OMP_CLAUSE_NUM_GANGS_EXPR (c));
9150         c = find_omp_clause (clauses, OMP_CLAUSE_NUM_WORKERS);
9151         if (c)
9152           t_num_workers = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
9153                                             integer_type_node,
9154                                             OMP_CLAUSE_NUM_WORKERS_EXPR (c));
9155         c = find_omp_clause (clauses, OMP_CLAUSE_VECTOR_LENGTH);
9156         if (c)
9157           t_vector_length = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
9158                                               integer_type_node,
9159                                               OMP_CLAUSE_VECTOR_LENGTH_EXPR (c));
9160         args->quick_push (t_num_gangs);
9161         args->quick_push (t_num_workers);
9162         args->quick_push (t_vector_length);
9163       }
9164       /* FALLTHRU */
9165     case BUILT_IN_GOACC_ENTER_EXIT_DATA:
9166     case BUILT_IN_GOACC_UPDATE:
9167       {
9168         tree t_async;
9169         int t_wait_idx;
9170
9171         /* Default values for t_async.  */
9172         t_async = fold_convert_loc (gimple_location (entry_stmt),
9173                                     integer_type_node,
9174                                     build_int_cst (integer_type_node,
9175                                                    GOMP_ASYNC_SYNC));
9176         /* ..., but if present, use the value specified by the respective
9177            clause, making sure that is of the correct type.  */
9178         c = find_omp_clause (clauses, OMP_CLAUSE_ASYNC);
9179         if (c)
9180           t_async = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
9181                                       integer_type_node,
9182                                       OMP_CLAUSE_ASYNC_EXPR (c));
9183
9184         args->quick_push (t_async);
9185         /* Save the index, and... */
9186         t_wait_idx = args->length ();
9187         /* ... push a default value.  */
9188         args->quick_push (fold_convert_loc (gimple_location (entry_stmt),
9189                                             integer_type_node,
9190                                             integer_zero_node));
9191         c = find_omp_clause (clauses, OMP_CLAUSE_WAIT);
9192         if (c)
9193           {
9194             int n = 0;
9195
9196             for (; c; c = OMP_CLAUSE_CHAIN (c))
9197               {
9198                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_WAIT)
9199                   {
9200                     args->safe_push (fold_convert_loc (OMP_CLAUSE_LOCATION (c),
9201                                                        integer_type_node,
9202                                                        OMP_CLAUSE_WAIT_EXPR (c)));
9203                     n++;
9204                   }
9205               }
9206
9207             /* Now that we know the number, replace the default value.  */
9208             args->ordered_remove (t_wait_idx);
9209             args->quick_insert (t_wait_idx,
9210                                 fold_convert_loc (gimple_location (entry_stmt),
9211                                                   integer_type_node,
9212                                                   build_int_cst (integer_type_node, n)));
9213           }
9214       }
9215       break;
9216     default:
9217       gcc_unreachable ();
9218     }
9219
9220   g = gimple_build_call_vec (builtin_decl_explicit (start_ix), *args);
9221   args->release ();
9222   gimple_set_location (g, gimple_location (entry_stmt));
9223   gsi_insert_before (&gsi, g, GSI_SAME_STMT);
9224   if (!offloaded)
9225     {
9226       g = gsi_stmt (gsi);
9227       gcc_assert (g && gimple_code (g) == GIMPLE_OMP_TARGET);
9228       gsi_remove (&gsi, true);
9229     }
9230   if (data_region
9231       && region->exit)
9232     {
9233       gsi = gsi_last_bb (region->exit);
9234       g = gsi_stmt (gsi);
9235       gcc_assert (g && gimple_code (g) == GIMPLE_OMP_RETURN);
9236       gsi_remove (&gsi, true);
9237     }
9238 }
9239
9240
9241 /* Expand the parallel region tree rooted at REGION.  Expansion
9242    proceeds in depth-first order.  Innermost regions are expanded
9243    first.  This way, parallel regions that require a new function to
9244    be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
9245    internal dependencies in their body.  */
9246
9247 static void
9248 expand_omp (struct omp_region *region)
9249 {
9250   while (region)
9251     {
9252       location_t saved_location;
9253       gimple inner_stmt = NULL;
9254
9255       /* First, determine whether this is a combined parallel+workshare
9256          region.  */
9257       if (region->type == GIMPLE_OMP_PARALLEL)
9258         determine_parallel_type (region);
9259
9260       if (region->type == GIMPLE_OMP_FOR
9261           && gimple_omp_for_combined_p (last_stmt (region->entry)))
9262         inner_stmt = last_stmt (region->inner->entry);
9263
9264       if (region->inner)
9265         expand_omp (region->inner);
9266
9267       saved_location = input_location;
9268       if (gimple_has_location (last_stmt (region->entry)))
9269         input_location = gimple_location (last_stmt (region->entry));
9270
9271       switch (region->type)
9272         {
9273         case GIMPLE_OMP_PARALLEL:
9274         case GIMPLE_OMP_TASK:
9275           expand_omp_taskreg (region);
9276           break;
9277
9278         case GIMPLE_OMP_FOR:
9279           expand_omp_for (region, inner_stmt);
9280           break;
9281
9282         case GIMPLE_OMP_SECTIONS:
9283           expand_omp_sections (region);
9284           break;
9285
9286         case GIMPLE_OMP_SECTION:
9287           /* Individual omp sections are handled together with their
9288              parent GIMPLE_OMP_SECTIONS region.  */
9289           break;
9290
9291         case GIMPLE_OMP_SINGLE:
9292           expand_omp_single (region);
9293           break;
9294
9295         case GIMPLE_OMP_MASTER:
9296         case GIMPLE_OMP_TASKGROUP:
9297         case GIMPLE_OMP_ORDERED:
9298         case GIMPLE_OMP_CRITICAL:
9299         case GIMPLE_OMP_TEAMS:
9300           expand_omp_synch (region);
9301           break;
9302
9303         case GIMPLE_OMP_ATOMIC_LOAD:
9304           expand_omp_atomic (region);
9305           break;
9306
9307         case GIMPLE_OMP_TARGET:
9308           expand_omp_target (region);
9309           break;
9310
9311         default:
9312           gcc_unreachable ();
9313         }
9314
9315       input_location = saved_location;
9316       region = region->next;
9317     }
9318 }
9319
9320
9321 /* Helper for build_omp_regions.  Scan the dominator tree starting at
9322    block BB.  PARENT is the region that contains BB.  If SINGLE_TREE is
9323    true, the function ends once a single tree is built (otherwise, whole
9324    forest of OMP constructs may be built).  */
9325
9326 static void
9327 build_omp_regions_1 (basic_block bb, struct omp_region *parent,
9328                      bool single_tree)
9329 {
9330   gimple_stmt_iterator gsi;
9331   gimple stmt;
9332   basic_block son;
9333
9334   gsi = gsi_last_bb (bb);
9335   if (!gsi_end_p (gsi) && is_gimple_omp (gsi_stmt (gsi)))
9336     {
9337       struct omp_region *region;
9338       enum gimple_code code;
9339
9340       stmt = gsi_stmt (gsi);
9341       code = gimple_code (stmt);
9342       if (code == GIMPLE_OMP_RETURN)
9343         {
9344           /* STMT is the return point out of region PARENT.  Mark it
9345              as the exit point and make PARENT the immediately
9346              enclosing region.  */
9347           gcc_assert (parent);
9348           region = parent;
9349           region->exit = bb;
9350           parent = parent->outer;
9351         }
9352       else if (code == GIMPLE_OMP_ATOMIC_STORE)
9353         {
9354           /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
9355              GIMPLE_OMP_RETURN, but matches with
9356              GIMPLE_OMP_ATOMIC_LOAD.  */
9357           gcc_assert (parent);
9358           gcc_assert (parent->type == GIMPLE_OMP_ATOMIC_LOAD);
9359           region = parent;
9360           region->exit = bb;
9361           parent = parent->outer;
9362         }
9363       else if (code == GIMPLE_OMP_CONTINUE)
9364         {
9365           gcc_assert (parent);
9366           parent->cont = bb;
9367         }
9368       else if (code == GIMPLE_OMP_SECTIONS_SWITCH)
9369         {
9370           /* GIMPLE_OMP_SECTIONS_SWITCH is part of
9371              GIMPLE_OMP_SECTIONS, and we do nothing for it.  */
9372         }
9373       else
9374         {
9375           region = new_omp_region (bb, code, parent);
9376           /* Otherwise...  */
9377           if (code == GIMPLE_OMP_TARGET)
9378             {
9379               switch (gimple_omp_target_kind (stmt))
9380                 {
9381                 case GF_OMP_TARGET_KIND_REGION:
9382                 case GF_OMP_TARGET_KIND_DATA:
9383                 case GF_OMP_TARGET_KIND_OACC_PARALLEL:
9384                 case GF_OMP_TARGET_KIND_OACC_KERNELS:
9385                 case GF_OMP_TARGET_KIND_OACC_DATA:
9386                   break;
9387                 case GF_OMP_TARGET_KIND_UPDATE:
9388                 case GF_OMP_TARGET_KIND_OACC_UPDATE:
9389                 case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
9390                   /* ..., other than for those stand-alone directives...  */
9391                   region = NULL;
9392                   break;
9393                 default:
9394                   gcc_unreachable ();
9395                 }
9396             }
9397           /* ..., this directive becomes the parent for a new region.  */
9398           if (region)
9399             parent = region;
9400         }
9401     }
9402
9403   if (single_tree && !parent)
9404     return;
9405
9406   for (son = first_dom_son (CDI_DOMINATORS, bb);
9407        son;
9408        son = next_dom_son (CDI_DOMINATORS, son))
9409     build_omp_regions_1 (son, parent, single_tree);
9410 }
9411
9412 /* Builds the tree of OMP regions rooted at ROOT, storing it to
9413    root_omp_region.  */
9414
9415 static void
9416 build_omp_regions_root (basic_block root)
9417 {
9418   gcc_assert (root_omp_region == NULL);
9419   build_omp_regions_1 (root, NULL, true);
9420   gcc_assert (root_omp_region != NULL);
9421 }
9422
9423 /* Expands omp construct (and its subconstructs) starting in HEAD.  */
9424
9425 void
9426 omp_expand_local (basic_block head)
9427 {
9428   build_omp_regions_root (head);
9429   if (dump_file && (dump_flags & TDF_DETAILS))
9430     {
9431       fprintf (dump_file, "\nOMP region tree\n\n");
9432       dump_omp_region (dump_file, root_omp_region, 0);
9433       fprintf (dump_file, "\n");
9434     }
9435
9436   remove_exit_barriers (root_omp_region);
9437   expand_omp (root_omp_region);
9438
9439   free_omp_regions ();
9440 }
9441
9442 /* Scan the CFG and build a tree of OMP regions.  Return the root of
9443    the OMP region tree.  */
9444
9445 static void
9446 build_omp_regions (void)
9447 {
9448   gcc_assert (root_omp_region == NULL);
9449   calculate_dominance_info (CDI_DOMINATORS);
9450   build_omp_regions_1 (ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, false);
9451 }
9452
9453 /* Main entry point for expanding OMP-GIMPLE into runtime calls.  */
9454
9455 static unsigned int
9456 execute_expand_omp (void)
9457 {
9458   build_omp_regions ();
9459
9460   if (!root_omp_region)
9461     return 0;
9462
9463   if (dump_file)
9464     {
9465       fprintf (dump_file, "\nOMP region tree\n\n");
9466       dump_omp_region (dump_file, root_omp_region, 0);
9467       fprintf (dump_file, "\n");
9468     }
9469
9470   remove_exit_barriers (root_omp_region);
9471
9472   expand_omp (root_omp_region);
9473
9474   cleanup_tree_cfg ();
9475
9476   free_omp_regions ();
9477
9478   return 0;
9479 }
9480
9481 /* OMP expansion -- the default pass, run before creation of SSA form.  */
9482
9483 namespace {
9484
9485 const pass_data pass_data_expand_omp =
9486 {
9487   GIMPLE_PASS, /* type */
9488   "ompexp", /* name */
9489   OPTGROUP_NONE, /* optinfo_flags */
9490   TV_NONE, /* tv_id */
9491   PROP_gimple_any, /* properties_required */
9492   PROP_gimple_eomp, /* properties_provided */
9493   0, /* properties_destroyed */
9494   0, /* todo_flags_start */
9495   0, /* todo_flags_finish */
9496 };
9497
9498 class pass_expand_omp : public gimple_opt_pass
9499 {
9500 public:
9501   pass_expand_omp (gcc::context *ctxt)
9502     : gimple_opt_pass (pass_data_expand_omp, ctxt)
9503   {}
9504
9505   /* opt_pass methods: */
9506   virtual unsigned int execute (function *)
9507     {
9508       bool gate = ((flag_cilkplus != 0 || flag_openacc != 0 || flag_openmp != 0
9509                     || flag_openmp_simd != 0)
9510                    && !seen_error ());
9511
9512       /* This pass always runs, to provide PROP_gimple_eomp.
9513          But often, there is nothing to do.  */
9514       if (!gate)
9515         return 0;
9516
9517       return execute_expand_omp ();
9518     }
9519
9520 }; // class pass_expand_omp
9521
9522 } // anon namespace
9523
9524 gimple_opt_pass *
9525 make_pass_expand_omp (gcc::context *ctxt)
9526 {
9527   return new pass_expand_omp (ctxt);
9528 }
9529
9530 namespace {
9531
9532 const pass_data pass_data_expand_omp_ssa =
9533 {
9534   GIMPLE_PASS, /* type */
9535   "ompexpssa", /* name */
9536   OPTGROUP_NONE, /* optinfo_flags */
9537   TV_NONE, /* tv_id */
9538   PROP_cfg | PROP_ssa, /* properties_required */
9539   PROP_gimple_eomp, /* properties_provided */
9540   0, /* properties_destroyed */
9541   0, /* todo_flags_start */
9542   TODO_cleanup_cfg | TODO_rebuild_alias, /* todo_flags_finish */
9543 };
9544
9545 class pass_expand_omp_ssa : public gimple_opt_pass
9546 {
9547 public:
9548   pass_expand_omp_ssa (gcc::context *ctxt)
9549     : gimple_opt_pass (pass_data_expand_omp_ssa, ctxt)
9550   {}
9551
9552   /* opt_pass methods: */
9553   virtual bool gate (function *fun)
9554     {
9555       return !(fun->curr_properties & PROP_gimple_eomp);
9556     }
9557   virtual unsigned int execute (function *) { return execute_expand_omp (); }
9558
9559 }; // class pass_expand_omp_ssa
9560
9561 } // anon namespace
9562
9563 gimple_opt_pass *
9564 make_pass_expand_omp_ssa (gcc::context *ctxt)
9565 {
9566   return new pass_expand_omp_ssa (ctxt);
9567 }
9568 \f
9569 /* Routines to lower OMP directives into OMP-GIMPLE.  */
9570
9571 /* Helper function to preform, potentially COMPLEX_TYPE, operation and
9572    convert it to gimple.  */
9573 static void
9574 oacc_gimple_assign (tree dest, tree_code op, tree src, gimple_seq *seq)
9575 {
9576   gimple stmt;
9577
9578   if (TREE_CODE (TREE_TYPE (dest)) != COMPLEX_TYPE)
9579     {
9580       stmt = gimple_build_assign (dest, op, dest, src);
9581       gimple_seq_add_stmt (seq, stmt);
9582       return;
9583     }
9584
9585   tree t = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
9586   tree rdest = fold_build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (dest)), dest);
9587   gimplify_assign (t, rdest, seq);
9588   rdest = t;
9589
9590   t = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
9591   tree idest = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (dest)), dest);
9592   gimplify_assign (t, idest, seq);
9593   idest = t;
9594
9595   t = create_tmp_var (TREE_TYPE (TREE_TYPE (src)));
9596   tree rsrc = fold_build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (src)), src);
9597   gimplify_assign (t, rsrc, seq);
9598   rsrc = t;
9599
9600   t = create_tmp_var (TREE_TYPE (TREE_TYPE (src)));
9601   tree isrc = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (src)), src);
9602   gimplify_assign (t, isrc, seq);
9603   isrc = t;
9604
9605   tree r = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
9606   tree i = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
9607   tree result;
9608
9609   if (op == PLUS_EXPR)
9610     {
9611       stmt = gimple_build_assign (r, op, rdest, rsrc);
9612       gimple_seq_add_stmt (seq, stmt);
9613
9614       stmt = gimple_build_assign (i, op, idest, isrc);
9615       gimple_seq_add_stmt (seq, stmt);
9616     }
9617   else if (op == MULT_EXPR)
9618     {
9619       /* Let x = a + ib = dest, y = c + id = src.
9620          x * y = (ac - bd) + i(ad + bc)  */
9621       tree ac = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
9622       tree bd = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
9623       tree ad = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
9624       tree bc = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
9625
9626       stmt = gimple_build_assign (ac, MULT_EXPR, rdest, rsrc);
9627       gimple_seq_add_stmt (seq, stmt);
9628
9629       stmt = gimple_build_assign (bd, MULT_EXPR, idest, isrc);
9630       gimple_seq_add_stmt (seq, stmt);
9631
9632       stmt = gimple_build_assign (r, MINUS_EXPR, ac, bd);
9633       gimple_seq_add_stmt (seq, stmt);
9634
9635       stmt = gimple_build_assign (ad, MULT_EXPR, rdest, isrc);
9636       gimple_seq_add_stmt (seq, stmt);
9637
9638       stmt = gimple_build_assign (bd, MULT_EXPR, idest, rsrc);
9639       gimple_seq_add_stmt (seq, stmt);
9640
9641       stmt = gimple_build_assign (i, PLUS_EXPR, ad, bc);
9642       gimple_seq_add_stmt (seq, stmt);
9643     }
9644   else
9645     gcc_unreachable ();
9646
9647   result = build2 (COMPLEX_EXPR, TREE_TYPE (dest), r, i);
9648   gimplify_assign (dest, result, seq);
9649 }
9650
9651 /* Helper function to initialize local data for the reduction arrays.
9652    The reduction arrays need to be placed inside the calling function
9653    for accelerators, or else the host won't be able to preform the final
9654    reduction.  */
9655
9656 static void
9657 oacc_initialize_reduction_data (tree clauses, tree nthreads,
9658                                 gimple_seq *stmt_seqp, omp_context *ctx)
9659 {
9660   tree c, t, oc;
9661   gimple stmt;
9662   omp_context *octx;
9663
9664   /* Find the innermost OpenACC parallel context.  */
9665   if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
9666       && (gimple_omp_target_kind (ctx->stmt)
9667           == GF_OMP_TARGET_KIND_OACC_PARALLEL))
9668     octx = ctx;
9669   else
9670     octx = ctx->outer;
9671   gcc_checking_assert (gimple_code (octx->stmt) == GIMPLE_OMP_TARGET
9672                        && (gimple_omp_target_kind (octx->stmt)
9673                            == GF_OMP_TARGET_KIND_OACC_PARALLEL));
9674
9675   /* Extract the clauses.  */
9676   oc = gimple_omp_target_clauses (octx->stmt);
9677
9678   /* Find the last outer clause.  */
9679   for (; oc && OMP_CLAUSE_CHAIN (oc); oc = OMP_CLAUSE_CHAIN (oc))
9680     ;
9681
9682   /* Allocate arrays for each reduction variable.  */
9683   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
9684     {
9685       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
9686         continue;
9687
9688       tree var = OMP_CLAUSE_DECL (c);
9689       tree type = get_base_type (var);
9690       tree array = lookup_oacc_reduction (oacc_get_reduction_array_id (var),
9691                                           ctx);
9692       tree size, call;
9693
9694       /* Calculate size of the reduction array.  */
9695       t = create_tmp_var (TREE_TYPE (nthreads));
9696       stmt = gimple_build_assign (t, MULT_EXPR, nthreads,
9697                                   fold_convert (TREE_TYPE (nthreads),
9698                                                 TYPE_SIZE_UNIT (type)));
9699       gimple_seq_add_stmt (stmt_seqp, stmt);
9700
9701       size = create_tmp_var (sizetype);
9702       gimplify_assign (size, fold_build1 (NOP_EXPR, sizetype, t), stmt_seqp);
9703
9704       /* Now allocate memory for it.  */
9705       call = unshare_expr (builtin_decl_explicit (BUILT_IN_ALLOCA));
9706       stmt = gimple_build_call (call, 1, size);
9707       gimple_call_set_lhs (stmt, array);
9708       gimple_seq_add_stmt (stmt_seqp, stmt);
9709
9710       /* Map this array into the accelerator.  */
9711
9712       /* Add the reduction array to the list of clauses.  */
9713       tree x = array;
9714       t = build_omp_clause (gimple_location (ctx->stmt), OMP_CLAUSE_MAP);
9715       OMP_CLAUSE_SET_MAP_KIND (t, GOMP_MAP_FORCE_FROM);
9716       OMP_CLAUSE_DECL (t) = x;
9717       OMP_CLAUSE_CHAIN (t) = NULL;
9718       if (oc)
9719         OMP_CLAUSE_CHAIN (oc) = t;
9720       else
9721         gimple_omp_target_set_clauses (as_a <gomp_target *> (octx->stmt), t);
9722       OMP_CLAUSE_SIZE (t) = size;
9723       oc = t;
9724     }
9725 }
9726
9727 /* Helper function to process the array of partial reductions.  Nthreads
9728    indicates the number of threads.  Unfortunately, GOACC_GET_NUM_THREADS
9729    cannot be used here, because nthreads on the host may be different than
9730    on the accelerator. */
9731
9732 static void
9733 oacc_finalize_reduction_data (tree clauses, tree nthreads,
9734                               gimple_seq *stmt_seqp, omp_context *ctx)
9735 {
9736   tree c, x, var, array, loop_header, loop_body, loop_exit, type;
9737   gimple stmt;
9738
9739   /* Create for loop.
9740
9741      let var = the original reduction variable
9742      let array = reduction variable array
9743
9744      for (i = 0; i < nthreads; i++)
9745        var op= array[i]
9746  */
9747
9748   loop_header = create_artificial_label (UNKNOWN_LOCATION);
9749   loop_body = create_artificial_label (UNKNOWN_LOCATION);
9750   loop_exit = create_artificial_label (UNKNOWN_LOCATION);
9751
9752   /* Create and initialize an index variable.  */
9753   tree ix = create_tmp_var (sizetype);
9754   gimplify_assign (ix, fold_build1 (NOP_EXPR, sizetype, integer_zero_node),
9755                    stmt_seqp);
9756
9757   /* Insert the loop header label here.  */
9758   gimple_seq_add_stmt (stmt_seqp, gimple_build_label (loop_header));
9759
9760   /* Exit loop if ix >= nthreads.  */
9761   x = create_tmp_var (sizetype);
9762   gimplify_assign (x, fold_build1 (NOP_EXPR, sizetype, nthreads), stmt_seqp);
9763   stmt = gimple_build_cond (GE_EXPR, ix, x, loop_exit, loop_body);
9764   gimple_seq_add_stmt (stmt_seqp, stmt);
9765
9766   /* Insert the loop body label here.  */
9767   gimple_seq_add_stmt (stmt_seqp, gimple_build_label (loop_body));
9768
9769   /* Collapse each reduction array, one element at a time.  */
9770   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
9771     {
9772       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
9773         continue;
9774
9775       tree_code reduction_code = OMP_CLAUSE_REDUCTION_CODE (c);
9776
9777       /* reduction(-:var) sums up the partial results, so it acts
9778          identically to reduction(+:var).  */
9779       if (reduction_code == MINUS_EXPR)
9780         reduction_code = PLUS_EXPR;
9781
9782       /* Set up reduction variable var.  */
9783       var = OMP_CLAUSE_DECL (c);
9784       type = get_base_type (var);
9785       array = lookup_oacc_reduction (oacc_get_reduction_array_id
9786                                      (OMP_CLAUSE_DECL (c)), ctx);
9787
9788       /* Calculate the array offset.  */
9789       tree offset = create_tmp_var (sizetype);
9790       gimplify_assign (offset, TYPE_SIZE_UNIT (type), stmt_seqp);
9791       stmt = gimple_build_assign (offset, MULT_EXPR, offset, ix);
9792       gimple_seq_add_stmt (stmt_seqp, stmt);
9793
9794       tree ptr = create_tmp_var (TREE_TYPE (array));
9795       stmt = gimple_build_assign (ptr, POINTER_PLUS_EXPR, array, offset);
9796       gimple_seq_add_stmt (stmt_seqp, stmt);
9797
9798       /* Extract array[ix] into mem.  */
9799       tree mem = create_tmp_var (type);
9800       gimplify_assign (mem, build_simple_mem_ref (ptr), stmt_seqp);
9801
9802       /* Find the original reduction variable.  */
9803       if (is_reference (var))
9804         var = build_simple_mem_ref (var);
9805
9806       tree t = create_tmp_var (type);
9807
9808       x = lang_hooks.decls.omp_clause_assign_op (c, t, var);
9809       gimplify_and_add (unshare_expr(x), stmt_seqp);
9810
9811       /* var = var op mem */
9812       switch (OMP_CLAUSE_REDUCTION_CODE (c))
9813         {
9814         case TRUTH_ANDIF_EXPR:
9815         case TRUTH_ORIF_EXPR:
9816           t = fold_build2 (OMP_CLAUSE_REDUCTION_CODE (c), integer_type_node,
9817                            t, mem);
9818           gimplify_and_add (t, stmt_seqp);
9819           break;
9820         default:
9821           /* The lhs isn't a gimple_reg when var is COMPLEX_TYPE.  */
9822           oacc_gimple_assign (t, OMP_CLAUSE_REDUCTION_CODE (c), mem,
9823                               stmt_seqp);
9824         }
9825
9826       t = fold_build1 (NOP_EXPR, TREE_TYPE (var), t);
9827       x = lang_hooks.decls.omp_clause_assign_op (c, var, t);
9828       gimplify_and_add (unshare_expr(x), stmt_seqp);
9829     }
9830
9831   /* Increment the induction variable.  */
9832   tree one = fold_build1 (NOP_EXPR, sizetype, integer_one_node);
9833   stmt = gimple_build_assign (ix, PLUS_EXPR, ix, one);
9834   gimple_seq_add_stmt (stmt_seqp, stmt);
9835
9836   /* Go back to the top of the loop.  */
9837   gimple_seq_add_stmt (stmt_seqp, gimple_build_goto (loop_header));
9838
9839   /* Place the loop exit label here.  */
9840   gimple_seq_add_stmt (stmt_seqp, gimple_build_label (loop_exit));
9841 }
9842
9843 /* Scan through all of the gimple stmts searching for an OMP_FOR_EXPR, and
9844    scan that for reductions.  */
9845
9846 static void
9847 oacc_process_reduction_data (gimple_seq *body, gimple_seq *in_stmt_seqp,
9848                         gimple_seq *out_stmt_seqp, omp_context *ctx)
9849 {
9850   gimple_stmt_iterator gsi;
9851   gimple_seq inner = NULL;
9852
9853   /* A collapse clause may have inserted a new bind block.  */
9854   gsi = gsi_start (*body);
9855   while (!gsi_end_p (gsi))
9856     {
9857       gimple stmt = gsi_stmt (gsi);
9858       if (gbind *bind_stmt = dyn_cast <gbind *> (stmt))
9859         {
9860           inner = gimple_bind_body (bind_stmt);
9861           body = &inner;
9862           gsi = gsi_start (*body);
9863         }
9864       else if (dyn_cast <gomp_for *> (stmt))
9865         break;
9866       else
9867         gsi_next (&gsi);
9868     }
9869
9870   for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
9871     {
9872       tree clauses, nthreads, t, c, acc_device, acc_device_host, call,
9873         enter, exit;
9874       bool reduction_found = false;
9875
9876       gimple stmt = gsi_stmt (gsi);
9877
9878       switch (gimple_code (stmt))
9879         {
9880         case GIMPLE_OMP_FOR:
9881           clauses = gimple_omp_for_clauses (stmt);
9882
9883           /* Search for a reduction clause.  */
9884           for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
9885             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
9886               {
9887                 reduction_found = true;
9888                 break;
9889               }
9890
9891           if (!reduction_found)
9892             break;
9893
9894           ctx = maybe_lookup_ctx (stmt);
9895           t = NULL_TREE;
9896
9897           /* Extract the number of threads.  */
9898           nthreads = create_tmp_var (sizetype);
9899           t = oacc_max_threads (ctx);
9900           gimplify_assign (nthreads, t, in_stmt_seqp);
9901
9902           /* Determine if this is kernel will be executed on the host.  */
9903           call = builtin_decl_explicit (BUILT_IN_ACC_GET_DEVICE_TYPE);
9904           acc_device = create_tmp_var (integer_type_node, ".acc_device_type");
9905           stmt = gimple_build_call (call, 0);
9906           gimple_call_set_lhs (stmt, acc_device);
9907           gimple_seq_add_stmt (in_stmt_seqp, stmt);
9908
9909           /* Set nthreads = 1 for ACC_DEVICE_TYPE=host.  */
9910           acc_device_host = create_tmp_var (integer_type_node,
9911                                             ".acc_device_host");
9912           gimplify_assign (acc_device_host,
9913                            build_int_cst (integer_type_node,
9914                                           GOMP_DEVICE_HOST),
9915                            in_stmt_seqp);
9916
9917           enter = create_artificial_label (UNKNOWN_LOCATION);
9918           exit = create_artificial_label (UNKNOWN_LOCATION);
9919
9920           stmt = gimple_build_cond (EQ_EXPR, acc_device, acc_device_host,
9921                                     enter, exit);
9922           gimple_seq_add_stmt (in_stmt_seqp, stmt);
9923           gimple_seq_add_stmt (in_stmt_seqp, gimple_build_label (enter));
9924           gimplify_assign (nthreads, fold_build1 (NOP_EXPR, sizetype,
9925                                                   integer_one_node),
9926                            in_stmt_seqp);
9927           gimple_seq_add_stmt (in_stmt_seqp, gimple_build_label (exit));
9928
9929           /* Also, set nthreads = 1 for ACC_DEVICE_TYPE=host_nonshm.  */
9930           gimplify_assign (acc_device_host,
9931                            build_int_cst (integer_type_node,
9932                                           GOMP_DEVICE_HOST_NONSHM),
9933                            in_stmt_seqp);
9934
9935           enter = create_artificial_label (UNKNOWN_LOCATION);
9936           exit = create_artificial_label (UNKNOWN_LOCATION);
9937
9938           stmt = gimple_build_cond (EQ_EXPR, acc_device, acc_device_host,
9939                                     enter, exit);
9940           gimple_seq_add_stmt (in_stmt_seqp, stmt);
9941           gimple_seq_add_stmt (in_stmt_seqp, gimple_build_label (enter));
9942           gimplify_assign (nthreads, fold_build1 (NOP_EXPR, sizetype,
9943                                                   integer_one_node),
9944                            in_stmt_seqp);
9945           gimple_seq_add_stmt (in_stmt_seqp, gimple_build_label (exit));
9946
9947           oacc_initialize_reduction_data (clauses, nthreads, in_stmt_seqp,
9948                                           ctx);
9949           oacc_finalize_reduction_data (clauses, nthreads, out_stmt_seqp, ctx);
9950           break;
9951         default:
9952           // Scan for other directives which support reduction here.
9953           break;
9954         }
9955     }
9956 }
9957
9958 /* If ctx is a worksharing context inside of a cancellable parallel
9959    region and it isn't nowait, add lhs to its GIMPLE_OMP_RETURN
9960    and conditional branch to parallel's cancel_label to handle
9961    cancellation in the implicit barrier.  */
9962
9963 static void
9964 maybe_add_implicit_barrier_cancel (omp_context *ctx, gimple_seq *body)
9965 {
9966   gimple omp_return = gimple_seq_last_stmt (*body);
9967   gcc_assert (gimple_code (omp_return) == GIMPLE_OMP_RETURN);
9968   if (gimple_omp_return_nowait_p (omp_return))
9969     return;
9970   if (ctx->outer
9971       && gimple_code (ctx->outer->stmt) == GIMPLE_OMP_PARALLEL
9972       && ctx->outer->cancellable)
9973     {
9974       tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
9975       tree c_bool_type = TREE_TYPE (TREE_TYPE (fndecl));
9976       tree lhs = create_tmp_var (c_bool_type);
9977       gimple_omp_return_set_lhs (omp_return, lhs);
9978       tree fallthru_label = create_artificial_label (UNKNOWN_LOCATION);
9979       gimple g = gimple_build_cond (NE_EXPR, lhs,
9980                                     fold_convert (c_bool_type,
9981                                                   boolean_false_node),
9982                                     ctx->outer->cancel_label, fallthru_label);
9983       gimple_seq_add_stmt (body, g);
9984       gimple_seq_add_stmt (body, gimple_build_label (fallthru_label));
9985     }
9986 }
9987
9988 /* Lower the OpenMP sections directive in the current statement in GSI_P.
9989    CTX is the enclosing OMP context for the current statement.  */
9990
9991 static void
9992 lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
9993 {
9994   tree block, control;
9995   gimple_stmt_iterator tgsi;
9996   gomp_sections *stmt;
9997   gimple t;
9998   gbind *new_stmt, *bind;
9999   gimple_seq ilist, dlist, olist, new_body;
10000
10001   stmt = as_a <gomp_sections *> (gsi_stmt (*gsi_p));
10002
10003   push_gimplify_context ();
10004
10005   dlist = NULL;
10006   ilist = NULL;
10007   lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
10008                            &ilist, &dlist, ctx, NULL);
10009
10010   new_body = gimple_omp_body (stmt);
10011   gimple_omp_set_body (stmt, NULL);
10012   tgsi = gsi_start (new_body);
10013   for (; !gsi_end_p (tgsi); gsi_next (&tgsi))
10014     {
10015       omp_context *sctx;
10016       gimple sec_start;
10017
10018       sec_start = gsi_stmt (tgsi);
10019       sctx = maybe_lookup_ctx (sec_start);
10020       gcc_assert (sctx);
10021
10022       lower_omp (gimple_omp_body_ptr (sec_start), sctx);
10023       gsi_insert_seq_after (&tgsi, gimple_omp_body (sec_start),
10024                             GSI_CONTINUE_LINKING);
10025       gimple_omp_set_body (sec_start, NULL);
10026
10027       if (gsi_one_before_end_p (tgsi))
10028         {
10029           gimple_seq l = NULL;
10030           lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
10031                                      &l, ctx);
10032           gsi_insert_seq_after (&tgsi, l, GSI_CONTINUE_LINKING);
10033           gimple_omp_section_set_last (sec_start);
10034         }
10035
10036       gsi_insert_after (&tgsi, gimple_build_omp_return (false),
10037                         GSI_CONTINUE_LINKING);
10038     }
10039
10040   block = make_node (BLOCK);
10041   bind = gimple_build_bind (NULL, new_body, block);
10042
10043   olist = NULL;
10044   lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
10045
10046   block = make_node (BLOCK);
10047   new_stmt = gimple_build_bind (NULL, NULL, block);
10048   gsi_replace (gsi_p, new_stmt, true);
10049
10050   pop_gimplify_context (new_stmt);
10051   gimple_bind_append_vars (new_stmt, ctx->block_vars);
10052   BLOCK_VARS (block) = gimple_bind_vars (bind);
10053   if (BLOCK_VARS (block))
10054     TREE_USED (block) = 1;
10055
10056   new_body = NULL;
10057   gimple_seq_add_seq (&new_body, ilist);
10058   gimple_seq_add_stmt (&new_body, stmt);
10059   gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
10060   gimple_seq_add_stmt (&new_body, bind);
10061
10062   control = create_tmp_var (unsigned_type_node, ".section");
10063   t = gimple_build_omp_continue (control, control);
10064   gimple_omp_sections_set_control (stmt, control);
10065   gimple_seq_add_stmt (&new_body, t);
10066
10067   gimple_seq_add_seq (&new_body, olist);
10068   if (ctx->cancellable)
10069     gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
10070   gimple_seq_add_seq (&new_body, dlist);
10071
10072   new_body = maybe_catch_exception (new_body);
10073
10074   t = gimple_build_omp_return
10075         (!!find_omp_clause (gimple_omp_sections_clauses (stmt),
10076                             OMP_CLAUSE_NOWAIT));
10077   gimple_seq_add_stmt (&new_body, t);
10078   maybe_add_implicit_barrier_cancel (ctx, &new_body);
10079
10080   gimple_bind_set_body (new_stmt, new_body);
10081 }
10082
10083
10084 /* A subroutine of lower_omp_single.  Expand the simple form of
10085    a GIMPLE_OMP_SINGLE, without a copyprivate clause:
10086
10087         if (GOMP_single_start ())
10088           BODY;
10089         [ GOMP_barrier (); ]    -> unless 'nowait' is present.
10090
10091   FIXME.  It may be better to delay expanding the logic of this until
10092   pass_expand_omp.  The expanded logic may make the job more difficult
10093   to a synchronization analysis pass.  */
10094
10095 static void
10096 lower_omp_single_simple (gomp_single *single_stmt, gimple_seq *pre_p)
10097 {
10098   location_t loc = gimple_location (single_stmt);
10099   tree tlabel = create_artificial_label (loc);
10100   tree flabel = create_artificial_label (loc);
10101   gimple call, cond;
10102   tree lhs, decl;
10103
10104   decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START);
10105   lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)));
10106   call = gimple_build_call (decl, 0);
10107   gimple_call_set_lhs (call, lhs);
10108   gimple_seq_add_stmt (pre_p, call);
10109
10110   cond = gimple_build_cond (EQ_EXPR, lhs,
10111                             fold_convert_loc (loc, TREE_TYPE (lhs),
10112                                               boolean_true_node),
10113                             tlabel, flabel);
10114   gimple_seq_add_stmt (pre_p, cond);
10115   gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
10116   gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
10117   gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
10118 }
10119
10120
10121 /* A subroutine of lower_omp_single.  Expand the simple form of
10122    a GIMPLE_OMP_SINGLE, with a copyprivate clause:
10123
10124         #pragma omp single copyprivate (a, b, c)
10125
10126    Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
10127
10128       {
10129         if ((copyout_p = GOMP_single_copy_start ()) == NULL)
10130           {
10131             BODY;
10132             copyout.a = a;
10133             copyout.b = b;
10134             copyout.c = c;
10135             GOMP_single_copy_end (&copyout);
10136           }
10137         else
10138           {
10139             a = copyout_p->a;
10140             b = copyout_p->b;
10141             c = copyout_p->c;
10142           }
10143         GOMP_barrier ();
10144       }
10145
10146   FIXME.  It may be better to delay expanding the logic of this until
10147   pass_expand_omp.  The expanded logic may make the job more difficult
10148   to a synchronization analysis pass.  */
10149
10150 static void
10151 lower_omp_single_copy (gomp_single *single_stmt, gimple_seq *pre_p,
10152                        omp_context *ctx)
10153 {
10154   tree ptr_type, t, l0, l1, l2, bfn_decl;
10155   gimple_seq copyin_seq;
10156   location_t loc = gimple_location (single_stmt);
10157
10158   ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
10159
10160   ptr_type = build_pointer_type (ctx->record_type);
10161   ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
10162
10163   l0 = create_artificial_label (loc);
10164   l1 = create_artificial_label (loc);
10165   l2 = create_artificial_label (loc);
10166
10167   bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START);
10168   t = build_call_expr_loc (loc, bfn_decl, 0);
10169   t = fold_convert_loc (loc, ptr_type, t);
10170   gimplify_assign (ctx->receiver_decl, t, pre_p);
10171
10172   t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
10173               build_int_cst (ptr_type, 0));
10174   t = build3 (COND_EXPR, void_type_node, t,
10175               build_and_jump (&l0), build_and_jump (&l1));
10176   gimplify_and_add (t, pre_p);
10177
10178   gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
10179
10180   gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
10181
10182   copyin_seq = NULL;
10183   lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
10184                               &copyin_seq, ctx);
10185
10186   t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
10187   bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END);
10188   t = build_call_expr_loc (loc, bfn_decl, 1, t);
10189   gimplify_and_add (t, pre_p);
10190
10191   t = build_and_jump (&l2);
10192   gimplify_and_add (t, pre_p);
10193
10194   gimple_seq_add_stmt (pre_p, gimple_build_label (l1));
10195
10196   gimple_seq_add_seq (pre_p, copyin_seq);
10197
10198   gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
10199 }
10200
10201
10202 /* Expand code for an OpenMP single directive.  */
10203
10204 static void
10205 lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
10206 {
10207   tree block;
10208   gimple t;
10209   gomp_single *single_stmt = as_a <gomp_single *> (gsi_stmt (*gsi_p));
10210   gbind *bind;
10211   gimple_seq bind_body, bind_body_tail = NULL, dlist;
10212
10213   push_gimplify_context ();
10214
10215   block = make_node (BLOCK);
10216   bind = gimple_build_bind (NULL, NULL, block);
10217   gsi_replace (gsi_p, bind, true);
10218   bind_body = NULL;
10219   dlist = NULL;
10220   lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
10221                            &bind_body, &dlist, ctx, NULL);
10222   lower_omp (gimple_omp_body_ptr (single_stmt), ctx);
10223
10224   gimple_seq_add_stmt (&bind_body, single_stmt);
10225
10226   if (ctx->record_type)
10227     lower_omp_single_copy (single_stmt, &bind_body, ctx);
10228   else
10229     lower_omp_single_simple (single_stmt, &bind_body);
10230
10231   gimple_omp_set_body (single_stmt, NULL);
10232
10233   gimple_seq_add_seq (&bind_body, dlist);
10234
10235   bind_body = maybe_catch_exception (bind_body);
10236
10237   t = gimple_build_omp_return
10238         (!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
10239                             OMP_CLAUSE_NOWAIT));
10240   gimple_seq_add_stmt (&bind_body_tail, t);
10241   maybe_add_implicit_barrier_cancel (ctx, &bind_body_tail);
10242   if (ctx->record_type)
10243     {
10244       gimple_stmt_iterator gsi = gsi_start (bind_body_tail);
10245       tree clobber = build_constructor (ctx->record_type, NULL);
10246       TREE_THIS_VOLATILE (clobber) = 1;
10247       gsi_insert_after (&gsi, gimple_build_assign (ctx->sender_decl,
10248                                                    clobber), GSI_SAME_STMT);
10249     }
10250   gimple_seq_add_seq (&bind_body, bind_body_tail);
10251   gimple_bind_set_body (bind, bind_body);
10252
10253   pop_gimplify_context (bind);
10254
10255   gimple_bind_append_vars (bind, ctx->block_vars);
10256   BLOCK_VARS (block) = ctx->block_vars;
10257   if (BLOCK_VARS (block))
10258     TREE_USED (block) = 1;
10259 }
10260
10261
10262 /* Expand code for an OpenMP master directive.  */
10263
10264 static void
10265 lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
10266 {
10267   tree block, lab = NULL, x, bfn_decl;
10268   gimple stmt = gsi_stmt (*gsi_p);
10269   gbind *bind;
10270   location_t loc = gimple_location (stmt);
10271   gimple_seq tseq;
10272
10273   push_gimplify_context ();
10274
10275   block = make_node (BLOCK);
10276   bind = gimple_build_bind (NULL, NULL, block);
10277   gsi_replace (gsi_p, bind, true);
10278   gimple_bind_add_stmt (bind, stmt);
10279
10280   bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
10281   x = build_call_expr_loc (loc, bfn_decl, 0);
10282   x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
10283   x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
10284   tseq = NULL;
10285   gimplify_and_add (x, &tseq);
10286   gimple_bind_add_seq (bind, tseq);
10287
10288   lower_omp (gimple_omp_body_ptr (stmt), ctx);
10289   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
10290   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
10291   gimple_omp_set_body (stmt, NULL);
10292
10293   gimple_bind_add_stmt (bind, gimple_build_label (lab));
10294
10295   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
10296
10297   pop_gimplify_context (bind);
10298
10299   gimple_bind_append_vars (bind, ctx->block_vars);
10300   BLOCK_VARS (block) = ctx->block_vars;
10301 }
10302
10303
10304 /* Expand code for an OpenMP taskgroup directive.  */
10305
10306 static void
10307 lower_omp_taskgroup (gimple_stmt_iterator *gsi_p, omp_context *ctx)
10308 {
10309   gimple stmt = gsi_stmt (*gsi_p);
10310   gcall *x;
10311   gbind *bind;
10312   tree block = make_node (BLOCK);
10313
10314   bind = gimple_build_bind (NULL, NULL, block);
10315   gsi_replace (gsi_p, bind, true);
10316   gimple_bind_add_stmt (bind, stmt);
10317
10318   x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_START),
10319                          0);
10320   gimple_bind_add_stmt (bind, x);
10321
10322   lower_omp (gimple_omp_body_ptr (stmt), ctx);
10323   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
10324   gimple_omp_set_body (stmt, NULL);
10325
10326   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
10327
10328   gimple_bind_append_vars (bind, ctx->block_vars);
10329   BLOCK_VARS (block) = ctx->block_vars;
10330 }
10331
10332
10333 /* Expand code for an OpenMP ordered directive.  */
10334
10335 static void
10336 lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
10337 {
10338   tree block;
10339   gimple stmt = gsi_stmt (*gsi_p);
10340   gcall *x;
10341   gbind *bind;
10342
10343   push_gimplify_context ();
10344
10345   block = make_node (BLOCK);
10346   bind = gimple_build_bind (NULL, NULL, block);
10347   gsi_replace (gsi_p, bind, true);
10348   gimple_bind_add_stmt (bind, stmt);
10349
10350   x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
10351                          0);
10352   gimple_bind_add_stmt (bind, x);
10353
10354   lower_omp (gimple_omp_body_ptr (stmt), ctx);
10355   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
10356   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
10357   gimple_omp_set_body (stmt, NULL);
10358
10359   x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END), 0);
10360   gimple_bind_add_stmt (bind, x);
10361
10362   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
10363
10364   pop_gimplify_context (bind);
10365
10366   gimple_bind_append_vars (bind, ctx->block_vars);
10367   BLOCK_VARS (block) = gimple_bind_vars (bind);
10368 }
10369
10370
10371 /* Gimplify a GIMPLE_OMP_CRITICAL statement.  This is a relatively simple
10372    substitution of a couple of function calls.  But in the NAMED case,
10373    requires that languages coordinate a symbol name.  It is therefore
10374    best put here in common code.  */
10375
10376 static GTY(()) hash_map<tree, tree> *critical_name_mutexes;
10377
10378 static void
10379 lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
10380 {
10381   tree block;
10382   tree name, lock, unlock;
10383   gomp_critical *stmt = as_a <gomp_critical *> (gsi_stmt (*gsi_p));
10384   gbind *bind;
10385   location_t loc = gimple_location (stmt);
10386   gimple_seq tbody;
10387
10388   name = gimple_omp_critical_name (stmt);
10389   if (name)
10390     {
10391       tree decl;
10392
10393       if (!critical_name_mutexes)
10394         critical_name_mutexes = hash_map<tree, tree>::create_ggc (10);
10395
10396       tree *n = critical_name_mutexes->get (name);
10397       if (n == NULL)
10398         {
10399           char *new_str;
10400
10401           decl = create_tmp_var_raw (ptr_type_node);
10402
10403           new_str = ACONCAT ((".gomp_critical_user_",
10404                               IDENTIFIER_POINTER (name), NULL));
10405           DECL_NAME (decl) = get_identifier (new_str);
10406           TREE_PUBLIC (decl) = 1;
10407           TREE_STATIC (decl) = 1;
10408           DECL_COMMON (decl) = 1;
10409           DECL_ARTIFICIAL (decl) = 1;
10410           DECL_IGNORED_P (decl) = 1;
10411
10412           varpool_node::finalize_decl (decl);
10413
10414           critical_name_mutexes->put (name, decl);
10415         }
10416       else
10417         decl = *n;
10418
10419       /* If '#pragma omp critical' is inside offloaded region or
10420          inside function marked as offloadable, the symbol must be
10421          marked as offloadable too.  */
10422       omp_context *octx;
10423       if (cgraph_node::get (current_function_decl)->offloadable)
10424         varpool_node::get_create (decl)->offloadable = 1;
10425       else
10426         for (octx = ctx->outer; octx; octx = octx->outer)
10427           if (is_gimple_omp_offloaded (octx->stmt))
10428             {
10429               varpool_node::get_create (decl)->offloadable = 1;
10430               break;
10431             }
10432
10433       lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START);
10434       lock = build_call_expr_loc (loc, lock, 1, build_fold_addr_expr_loc (loc, decl));
10435
10436       unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END);
10437       unlock = build_call_expr_loc (loc, unlock, 1,
10438                                 build_fold_addr_expr_loc (loc, decl));
10439     }
10440   else
10441     {
10442       lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START);
10443       lock = build_call_expr_loc (loc, lock, 0);
10444
10445       unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END);
10446       unlock = build_call_expr_loc (loc, unlock, 0);
10447     }
10448
10449   push_gimplify_context ();
10450
10451   block = make_node (BLOCK);
10452   bind = gimple_build_bind (NULL, NULL, block);
10453   gsi_replace (gsi_p, bind, true);
10454   gimple_bind_add_stmt (bind, stmt);
10455
10456   tbody = gimple_bind_body (bind);
10457   gimplify_and_add (lock, &tbody);
10458   gimple_bind_set_body (bind, tbody);
10459
10460   lower_omp (gimple_omp_body_ptr (stmt), ctx);
10461   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
10462   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
10463   gimple_omp_set_body (stmt, NULL);
10464
10465   tbody = gimple_bind_body (bind);
10466   gimplify_and_add (unlock, &tbody);
10467   gimple_bind_set_body (bind, tbody);
10468
10469   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
10470
10471   pop_gimplify_context (bind);
10472   gimple_bind_append_vars (bind, ctx->block_vars);
10473   BLOCK_VARS (block) = gimple_bind_vars (bind);
10474 }
10475
10476
10477 /* A subroutine of lower_omp_for.  Generate code to emit the predicate
10478    for a lastprivate clause.  Given a loop control predicate of (V
10479    cond N2), we gate the clause on (!(V cond N2)).  The lowered form
10480    is appended to *DLIST, iterator initialization is appended to
10481    *BODY_P.  */
10482
10483 static void
10484 lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
10485                            gimple_seq *dlist, struct omp_context *ctx)
10486 {
10487   tree clauses, cond, vinit;
10488   enum tree_code cond_code;
10489   gimple_seq stmts;
10490
10491   cond_code = fd->loop.cond_code;
10492   cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
10493
10494   /* When possible, use a strict equality expression.  This can let VRP
10495      type optimizations deduce the value and remove a copy.  */
10496   if (tree_fits_shwi_p (fd->loop.step))
10497     {
10498       HOST_WIDE_INT step = tree_to_shwi (fd->loop.step);
10499       if (step == 1 || step == -1)
10500         cond_code = EQ_EXPR;
10501     }
10502
10503   cond = build2 (cond_code, boolean_type_node, fd->loop.v, fd->loop.n2);
10504
10505   clauses = gimple_omp_for_clauses (fd->for_stmt);
10506   stmts = NULL;
10507   lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
10508   if (!gimple_seq_empty_p (stmts))
10509     {
10510       gimple_seq_add_seq (&stmts, *dlist);
10511       *dlist = stmts;
10512
10513       /* Optimize: v = 0; is usually cheaper than v = some_other_constant.  */
10514       vinit = fd->loop.n1;
10515       if (cond_code == EQ_EXPR
10516           && tree_fits_shwi_p (fd->loop.n2)
10517           && ! integer_zerop (fd->loop.n2))
10518         vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
10519       else
10520         vinit = unshare_expr (vinit);
10521
10522       /* Initialize the iterator variable, so that threads that don't execute
10523          any iterations don't execute the lastprivate clauses by accident.  */
10524       gimplify_assign (fd->loop.v, vinit, body_p);
10525     }
10526 }
10527
10528
10529 /* Lower code for an OMP loop directive.  */
10530
10531 static void
10532 lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
10533 {
10534   tree *rhs_p, block;
10535   struct omp_for_data fd, *fdp = NULL;
10536   gomp_for *stmt = as_a <gomp_for *> (gsi_stmt (*gsi_p));
10537   gbind *new_stmt;
10538   gimple_seq omp_for_body, body, dlist;
10539   size_t i;
10540
10541   push_gimplify_context ();
10542
10543   lower_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
10544
10545   block = make_node (BLOCK);
10546   new_stmt = gimple_build_bind (NULL, NULL, block);
10547   /* Replace at gsi right away, so that 'stmt' is no member
10548      of a sequence anymore as we're going to add to to a different
10549      one below.  */
10550   gsi_replace (gsi_p, new_stmt, true);
10551
10552   /* Move declaration of temporaries in the loop body before we make
10553      it go away.  */
10554   omp_for_body = gimple_omp_body (stmt);
10555   if (!gimple_seq_empty_p (omp_for_body)
10556       && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
10557     {
10558       gbind *inner_bind
10559         = as_a <gbind *> (gimple_seq_first_stmt (omp_for_body));
10560       tree vars = gimple_bind_vars (inner_bind);
10561       gimple_bind_append_vars (new_stmt, vars);
10562       /* bind_vars/BLOCK_VARS are being moved to new_stmt/block, don't
10563          keep them on the inner_bind and it's block.  */
10564       gimple_bind_set_vars (inner_bind, NULL_TREE);
10565       if (gimple_bind_block (inner_bind))
10566         BLOCK_VARS (gimple_bind_block (inner_bind)) = NULL_TREE;
10567     }
10568
10569   if (gimple_omp_for_combined_into_p (stmt))
10570     {
10571       extract_omp_for_data (stmt, &fd, NULL);
10572       fdp = &fd;
10573
10574       /* We need two temporaries with fd.loop.v type (istart/iend)
10575          and then (fd.collapse - 1) temporaries with the same
10576          type for count2 ... countN-1 vars if not constant.  */
10577       size_t count = 2;
10578       tree type = fd.iter_type;
10579       if (fd.collapse > 1
10580           && TREE_CODE (fd.loop.n2) != INTEGER_CST)
10581         count += fd.collapse - 1;
10582       bool parallel_for = gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR;
10583       tree outerc = NULL, *pc = gimple_omp_for_clauses_ptr (stmt);
10584       tree clauses = *pc;
10585       if (parallel_for)
10586         outerc
10587           = find_omp_clause (gimple_omp_parallel_clauses (ctx->outer->stmt),
10588                              OMP_CLAUSE__LOOPTEMP_);
10589       for (i = 0; i < count; i++)
10590         {
10591           tree temp;
10592           if (parallel_for)
10593             {
10594               gcc_assert (outerc);
10595               temp = lookup_decl (OMP_CLAUSE_DECL (outerc), ctx->outer);
10596               outerc = find_omp_clause (OMP_CLAUSE_CHAIN (outerc),
10597                                         OMP_CLAUSE__LOOPTEMP_);
10598             }
10599           else
10600             {
10601               temp = create_tmp_var (type);
10602               insert_decl_map (&ctx->outer->cb, temp, temp);
10603             }
10604           *pc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__LOOPTEMP_);
10605           OMP_CLAUSE_DECL (*pc) = temp;
10606           pc = &OMP_CLAUSE_CHAIN (*pc);
10607         }
10608       *pc = clauses;
10609     }
10610
10611   /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR.  */
10612   dlist = NULL;
10613   body = NULL;
10614   lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx,
10615                            fdp);
10616   gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
10617
10618   lower_omp (gimple_omp_body_ptr (stmt), ctx);
10619
10620   /* Lower the header expressions.  At this point, we can assume that
10621      the header is of the form:
10622
10623         #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
10624
10625      We just need to make sure that VAL1, VAL2 and VAL3 are lowered
10626      using the .omp_data_s mapping, if needed.  */
10627   for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
10628     {
10629       rhs_p = gimple_omp_for_initial_ptr (stmt, i);
10630       if (!is_gimple_min_invariant (*rhs_p))
10631         *rhs_p = get_formal_tmp_var (*rhs_p, &body);
10632
10633       rhs_p = gimple_omp_for_final_ptr (stmt, i);
10634       if (!is_gimple_min_invariant (*rhs_p))
10635         *rhs_p = get_formal_tmp_var (*rhs_p, &body);
10636
10637       rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
10638       if (!is_gimple_min_invariant (*rhs_p))
10639         *rhs_p = get_formal_tmp_var (*rhs_p, &body);
10640     }
10641
10642   /* Once lowered, extract the bounds and clauses.  */
10643   extract_omp_for_data (stmt, &fd, NULL);
10644
10645   lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
10646
10647   gimple_seq_add_stmt (&body, stmt);
10648   gimple_seq_add_seq (&body, gimple_omp_body (stmt));
10649
10650   gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
10651                                                          fd.loop.v));
10652
10653   /* After the loop, add exit clauses.  */
10654   lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, ctx);
10655
10656   if (ctx->cancellable)
10657     gimple_seq_add_stmt (&body, gimple_build_label (ctx->cancel_label));
10658
10659   gimple_seq_add_seq (&body, dlist);
10660
10661   body = maybe_catch_exception (body);
10662
10663   /* Region exit marker goes at the end of the loop body.  */
10664   gimple_seq_add_stmt (&body, gimple_build_omp_return (fd.have_nowait));
10665   maybe_add_implicit_barrier_cancel (ctx, &body);
10666   pop_gimplify_context (new_stmt);
10667
10668   gimple_bind_append_vars (new_stmt, ctx->block_vars);
10669   BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
10670   if (BLOCK_VARS (block))
10671     TREE_USED (block) = 1;
10672
10673   gimple_bind_set_body (new_stmt, body);
10674   gimple_omp_set_body (stmt, NULL);
10675   gimple_omp_for_set_pre_body (stmt, NULL);
10676 }
10677
10678 /* Callback for walk_stmts.  Check if the current statement only contains
10679    GIMPLE_OMP_FOR or GIMPLE_OMP_SECTIONS.  */
10680
10681 static tree
10682 check_combined_parallel (gimple_stmt_iterator *gsi_p,
10683                          bool *handled_ops_p,
10684                          struct walk_stmt_info *wi)
10685 {
10686   int *info = (int *) wi->info;
10687   gimple stmt = gsi_stmt (*gsi_p);
10688
10689   *handled_ops_p = true;
10690   switch (gimple_code (stmt))
10691     {
10692     WALK_SUBSTMTS;
10693
10694     case GIMPLE_OMP_FOR:
10695     case GIMPLE_OMP_SECTIONS:
10696       *info = *info == 0 ? 1 : -1;
10697       break;
10698     default:
10699       *info = -1;
10700       break;
10701     }
10702   return NULL;
10703 }
10704
10705 struct omp_taskcopy_context
10706 {
10707   /* This field must be at the beginning, as we do "inheritance": Some
10708      callback functions for tree-inline.c (e.g., omp_copy_decl)
10709      receive a copy_body_data pointer that is up-casted to an
10710      omp_context pointer.  */
10711   copy_body_data cb;
10712   omp_context *ctx;
10713 };
10714
10715 static tree
10716 task_copyfn_copy_decl (tree var, copy_body_data *cb)
10717 {
10718   struct omp_taskcopy_context *tcctx = (struct omp_taskcopy_context *) cb;
10719
10720   if (splay_tree_lookup (tcctx->ctx->sfield_map, (splay_tree_key) var))
10721     return create_tmp_var (TREE_TYPE (var));
10722
10723   return var;
10724 }
10725
10726 static tree
10727 task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
10728 {
10729   tree name, new_fields = NULL, type, f;
10730
10731   type = lang_hooks.types.make_type (RECORD_TYPE);
10732   name = DECL_NAME (TYPE_NAME (orig_type));
10733   name = build_decl (gimple_location (tcctx->ctx->stmt),
10734                      TYPE_DECL, name, type);
10735   TYPE_NAME (type) = name;
10736
10737   for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
10738     {
10739       tree new_f = copy_node (f);
10740       DECL_CONTEXT (new_f) = type;
10741       TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
10742       TREE_CHAIN (new_f) = new_fields;
10743       walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
10744       walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
10745       walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
10746                  &tcctx->cb, NULL);
10747       new_fields = new_f;
10748       tcctx->cb.decl_map->put (f, new_f);
10749     }
10750   TYPE_FIELDS (type) = nreverse (new_fields);
10751   layout_type (type);
10752   return type;
10753 }
10754
10755 /* Create task copyfn.  */
10756
10757 static void
10758 create_task_copyfn (gomp_task *task_stmt, omp_context *ctx)
10759 {
10760   struct function *child_cfun;
10761   tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
10762   tree record_type, srecord_type, bind, list;
10763   bool record_needs_remap = false, srecord_needs_remap = false;
10764   splay_tree_node n;
10765   struct omp_taskcopy_context tcctx;
10766   location_t loc = gimple_location (task_stmt);
10767
10768   child_fn = gimple_omp_task_copy_fn (task_stmt);
10769   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
10770   gcc_assert (child_cfun->cfg == NULL);
10771   DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();
10772
10773   /* Reset DECL_CONTEXT on function arguments.  */
10774   for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
10775     DECL_CONTEXT (t) = child_fn;
10776
10777   /* Populate the function.  */
10778   push_gimplify_context ();
10779   push_cfun (child_cfun);
10780
10781   bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
10782   TREE_SIDE_EFFECTS (bind) = 1;
10783   list = NULL;
10784   DECL_SAVED_TREE (child_fn) = bind;
10785   DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);
10786
10787   /* Remap src and dst argument types if needed.  */
10788   record_type = ctx->record_type;
10789   srecord_type = ctx->srecord_type;
10790   for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
10791     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
10792       {
10793         record_needs_remap = true;
10794         break;
10795       }
10796   for (f = TYPE_FIELDS (srecord_type); f ; f = DECL_CHAIN (f))
10797     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
10798       {
10799         srecord_needs_remap = true;
10800         break;
10801       }
10802
10803   if (record_needs_remap || srecord_needs_remap)
10804     {
10805       memset (&tcctx, '\0', sizeof (tcctx));
10806       tcctx.cb.src_fn = ctx->cb.src_fn;
10807       tcctx.cb.dst_fn = child_fn;
10808       tcctx.cb.src_node = cgraph_node::get (tcctx.cb.src_fn);
10809       gcc_checking_assert (tcctx.cb.src_node);
10810       tcctx.cb.dst_node = tcctx.cb.src_node;
10811       tcctx.cb.src_cfun = ctx->cb.src_cfun;
10812       tcctx.cb.copy_decl = task_copyfn_copy_decl;
10813       tcctx.cb.eh_lp_nr = 0;
10814       tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
10815       tcctx.cb.decl_map = new hash_map<tree, tree>;
10816       tcctx.ctx = ctx;
10817
10818       if (record_needs_remap)
10819         record_type = task_copyfn_remap_type (&tcctx, record_type);
10820       if (srecord_needs_remap)
10821         srecord_type = task_copyfn_remap_type (&tcctx, srecord_type);
10822     }
10823   else
10824     tcctx.cb.decl_map = NULL;
10825
10826   arg = DECL_ARGUMENTS (child_fn);
10827   TREE_TYPE (arg) = build_pointer_type (record_type);
10828   sarg = DECL_CHAIN (arg);
10829   TREE_TYPE (sarg) = build_pointer_type (srecord_type);
10830
10831   /* First pass: initialize temporaries used in record_type and srecord_type
10832      sizes and field offsets.  */
10833   if (tcctx.cb.decl_map)
10834     for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
10835       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
10836         {
10837           tree *p;
10838
10839           decl = OMP_CLAUSE_DECL (c);
10840           p = tcctx.cb.decl_map->get (decl);
10841           if (p == NULL)
10842             continue;
10843           n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
10844           sf = (tree) n->value;
10845           sf = *tcctx.cb.decl_map->get (sf);
10846           src = build_simple_mem_ref_loc (loc, sarg);
10847           src = omp_build_component_ref (src, sf);
10848           t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
10849           append_to_statement_list (t, &list);
10850         }
10851
10852   /* Second pass: copy shared var pointers and copy construct non-VLA
10853      firstprivate vars.  */
10854   for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
10855     switch (OMP_CLAUSE_CODE (c))
10856       {
10857       case OMP_CLAUSE_SHARED:
10858         decl = OMP_CLAUSE_DECL (c);
10859         n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
10860         if (n == NULL)
10861           break;
10862         f = (tree) n->value;
10863         if (tcctx.cb.decl_map)
10864           f = *tcctx.cb.decl_map->get (f);
10865         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
10866         sf = (tree) n->value;
10867         if (tcctx.cb.decl_map)
10868           sf = *tcctx.cb.decl_map->get (sf);
10869         src = build_simple_mem_ref_loc (loc, sarg);
10870         src = omp_build_component_ref (src, sf);
10871         dst = build_simple_mem_ref_loc (loc, arg);
10872         dst = omp_build_component_ref (dst, f);
10873         t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
10874         append_to_statement_list (t, &list);
10875         break;
10876       case OMP_CLAUSE_FIRSTPRIVATE:
10877         decl = OMP_CLAUSE_DECL (c);
10878         if (is_variable_sized (decl))
10879           break;
10880         n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
10881         if (n == NULL)
10882           break;
10883         f = (tree) n->value;
10884         if (tcctx.cb.decl_map)
10885           f = *tcctx.cb.decl_map->get (f);
10886         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
10887         if (n != NULL)
10888           {
10889             sf = (tree) n->value;
10890             if (tcctx.cb.decl_map)
10891               sf = *tcctx.cb.decl_map->get (sf);
10892             src = build_simple_mem_ref_loc (loc, sarg);
10893             src = omp_build_component_ref (src, sf);
10894             if (use_pointer_for_field (decl, NULL) || is_reference (decl))
10895               src = build_simple_mem_ref_loc (loc, src);
10896           }
10897         else
10898           src = decl;
10899         dst = build_simple_mem_ref_loc (loc, arg);
10900         dst = omp_build_component_ref (dst, f);
10901         t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
10902         append_to_statement_list (t, &list);
10903         break;
10904       case OMP_CLAUSE_PRIVATE:
10905         if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c))
10906           break;
10907         decl = OMP_CLAUSE_DECL (c);
10908         n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
10909         f = (tree) n->value;
10910         if (tcctx.cb.decl_map)
10911           f = *tcctx.cb.decl_map->get (f);
10912         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
10913         if (n != NULL)
10914           {
10915             sf = (tree) n->value;
10916             if (tcctx.cb.decl_map)
10917               sf = *tcctx.cb.decl_map->get (sf);
10918             src = build_simple_mem_ref_loc (loc, sarg);
10919             src = omp_build_component_ref (src, sf);
10920             if (use_pointer_for_field (decl, NULL))
10921               src = build_simple_mem_ref_loc (loc, src);
10922           }
10923         else
10924           src = decl;
10925         dst = build_simple_mem_ref_loc (loc, arg);
10926         dst = omp_build_component_ref (dst, f);
10927         t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
10928         append_to_statement_list (t, &list);
10929         break;
10930       default:
10931         break;
10932       }
10933
10934   /* Last pass: handle VLA firstprivates.  */
10935   if (tcctx.cb.decl_map)
10936     for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
10937       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
10938         {
10939           tree ind, ptr, df;
10940
10941           decl = OMP_CLAUSE_DECL (c);
10942           if (!is_variable_sized (decl))
10943             continue;
10944           n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
10945           if (n == NULL)
10946             continue;
10947           f = (tree) n->value;
10948           f = *tcctx.cb.decl_map->get (f);
10949           gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
10950           ind = DECL_VALUE_EXPR (decl);
10951           gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
10952           gcc_assert (DECL_P (TREE_OPERAND (ind, 0)));
10953           n = splay_tree_lookup (ctx->sfield_map,
10954                                  (splay_tree_key) TREE_OPERAND (ind, 0));
10955           sf = (tree) n->value;
10956           sf = *tcctx.cb.decl_map->get (sf);
10957           src = build_simple_mem_ref_loc (loc, sarg);
10958           src = omp_build_component_ref (src, sf);
10959           src = build_simple_mem_ref_loc (loc, src);
10960           dst = build_simple_mem_ref_loc (loc, arg);
10961           dst = omp_build_component_ref (dst, f);
10962           t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
10963           append_to_statement_list (t, &list);
10964           n = splay_tree_lookup (ctx->field_map,
10965                                  (splay_tree_key) TREE_OPERAND (ind, 0));
10966           df = (tree) n->value;
10967           df = *tcctx.cb.decl_map->get (df);
10968           ptr = build_simple_mem_ref_loc (loc, arg);
10969           ptr = omp_build_component_ref (ptr, df);
10970           t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
10971                       build_fold_addr_expr_loc (loc, dst));
10972           append_to_statement_list (t, &list);
10973         }
10974
10975   t = build1 (RETURN_EXPR, void_type_node, NULL);
10976   append_to_statement_list (t, &list);
10977
10978   if (tcctx.cb.decl_map)
10979     delete tcctx.cb.decl_map;
10980   pop_gimplify_context (NULL);
10981   BIND_EXPR_BODY (bind) = list;
10982   pop_cfun ();
10983 }
10984
10985 static void
10986 lower_depend_clauses (gimple stmt, gimple_seq *iseq, gimple_seq *oseq)
10987 {
10988   tree c, clauses;
10989   gimple g;
10990   size_t n_in = 0, n_out = 0, idx = 2, i;
10991
10992   clauses = find_omp_clause (gimple_omp_task_clauses (stmt),
10993                              OMP_CLAUSE_DEPEND);
10994   gcc_assert (clauses);
10995   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
10996     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
10997       switch (OMP_CLAUSE_DEPEND_KIND (c))
10998         {
10999         case OMP_CLAUSE_DEPEND_IN:
11000           n_in++;
11001           break;
11002         case OMP_CLAUSE_DEPEND_OUT:
11003         case OMP_CLAUSE_DEPEND_INOUT:
11004           n_out++;
11005           break;
11006         default:
11007           gcc_unreachable ();
11008         }
11009   tree type = build_array_type_nelts (ptr_type_node, n_in + n_out + 2);
11010   tree array = create_tmp_var (type);
11011   tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
11012                    NULL_TREE);
11013   g = gimple_build_assign (r, build_int_cst (ptr_type_node, n_in + n_out));
11014   gimple_seq_add_stmt (iseq, g);
11015   r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
11016               NULL_TREE);
11017   g = gimple_build_assign (r, build_int_cst (ptr_type_node, n_out));
11018   gimple_seq_add_stmt (iseq, g);
11019   for (i = 0; i < 2; i++)
11020     {
11021       if ((i ? n_in : n_out) == 0)
11022         continue;
11023       for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
11024         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
11025             && ((OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_IN) ^ i))
11026           {
11027             tree t = OMP_CLAUSE_DECL (c);
11028             t = fold_convert (ptr_type_node, t);
11029             gimplify_expr (&t, iseq, NULL, is_gimple_val, fb_rvalue);
11030             r = build4 (ARRAY_REF, ptr_type_node, array, size_int (idx++),
11031                         NULL_TREE, NULL_TREE);
11032             g = gimple_build_assign (r, t);
11033             gimple_seq_add_stmt (iseq, g);
11034           }
11035     }
11036   tree *p = gimple_omp_task_clauses_ptr (stmt);
11037   c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
11038   OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
11039   OMP_CLAUSE_CHAIN (c) = *p;
11040   *p = c;
11041   tree clobber = build_constructor (type, NULL);
11042   TREE_THIS_VOLATILE (clobber) = 1;
11043   g = gimple_build_assign (array, clobber);
11044   gimple_seq_add_stmt (oseq, g);
11045 }
11046
11047 /* Lower the OpenMP parallel or task directive in the current statement
11048    in GSI_P.  CTX holds context information for the directive.  */
11049
11050 static void
11051 lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
11052 {
11053   tree clauses;
11054   tree child_fn, t;
11055   gimple stmt = gsi_stmt (*gsi_p);
11056   gbind *par_bind, *bind, *dep_bind = NULL;
11057   gimple_seq par_body, olist, ilist, par_olist, par_rlist, par_ilist, new_body;
11058   location_t loc = gimple_location (stmt);
11059
11060   clauses = gimple_omp_taskreg_clauses (stmt);
11061   par_bind
11062     = as_a <gbind *> (gimple_seq_first_stmt (gimple_omp_body (stmt)));
11063   par_body = gimple_bind_body (par_bind);
11064   child_fn = ctx->cb.dst_fn;
11065   if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
11066       && !gimple_omp_parallel_combined_p (stmt))
11067     {
11068       struct walk_stmt_info wi;
11069       int ws_num = 0;
11070
11071       memset (&wi, 0, sizeof (wi));
11072       wi.info = &ws_num;
11073       wi.val_only = true;
11074       walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
11075       if (ws_num == 1)
11076         gimple_omp_parallel_set_combined_p (stmt, true);
11077     }
11078   gimple_seq dep_ilist = NULL;
11079   gimple_seq dep_olist = NULL;
11080   if (gimple_code (stmt) == GIMPLE_OMP_TASK
11081       && find_omp_clause (clauses, OMP_CLAUSE_DEPEND))
11082     {
11083       push_gimplify_context ();
11084       dep_bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
11085       lower_depend_clauses (stmt, &dep_ilist, &dep_olist);
11086     }
11087
11088   if (ctx->srecord_type)
11089     create_task_copyfn (as_a <gomp_task *> (stmt), ctx);
11090
11091   push_gimplify_context ();
11092
11093   par_olist = NULL;
11094   par_ilist = NULL;
11095   par_rlist = NULL;
11096   lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx, NULL);
11097   lower_omp (&par_body, ctx);
11098   if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
11099     lower_reduction_clauses (clauses, &par_rlist, ctx);
11100
11101   /* Declare all the variables created by mapping and the variables
11102      declared in the scope of the parallel body.  */
11103   record_vars_into (ctx->block_vars, child_fn);
11104   record_vars_into (gimple_bind_vars (par_bind), child_fn);
11105
11106   if (ctx->record_type)
11107     {
11108       ctx->sender_decl
11109         = create_tmp_var (ctx->srecord_type ? ctx->srecord_type
11110                           : ctx->record_type, ".omp_data_o");
11111       DECL_NAMELESS (ctx->sender_decl) = 1;
11112       TREE_ADDRESSABLE (ctx->sender_decl) = 1;
11113       gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
11114     }
11115
11116   olist = NULL;
11117   ilist = NULL;
11118   lower_send_clauses (clauses, &ilist, &olist, ctx);
11119   lower_send_shared_vars (&ilist, &olist, ctx);
11120
11121   if (ctx->record_type)
11122     {
11123       tree clobber = build_constructor (TREE_TYPE (ctx->sender_decl), NULL);
11124       TREE_THIS_VOLATILE (clobber) = 1;
11125       gimple_seq_add_stmt (&olist, gimple_build_assign (ctx->sender_decl,
11126                                                         clobber));
11127     }
11128
11129   /* Once all the expansions are done, sequence all the different
11130      fragments inside gimple_omp_body.  */
11131
11132   new_body = NULL;
11133
11134   if (ctx->record_type)
11135     {
11136       t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
11137       /* fixup_child_record_type might have changed receiver_decl's type.  */
11138       t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
11139       gimple_seq_add_stmt (&new_body,
11140                            gimple_build_assign (ctx->receiver_decl, t));
11141     }
11142
11143   gimple_seq_add_seq (&new_body, par_ilist);
11144   gimple_seq_add_seq (&new_body, par_body);
11145   gimple_seq_add_seq (&new_body, par_rlist);
11146   if (ctx->cancellable)
11147     gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
11148   gimple_seq_add_seq (&new_body, par_olist);
11149   new_body = maybe_catch_exception (new_body);
11150   gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
11151   gimple_omp_set_body (stmt, new_body);
11152
11153   bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
11154   gsi_replace (gsi_p, dep_bind ? dep_bind : bind, true);
11155   gimple_bind_add_seq (bind, ilist);
11156   gimple_bind_add_stmt (bind, stmt);
11157   gimple_bind_add_seq (bind, olist);
11158
11159   pop_gimplify_context (NULL);
11160
11161   if (dep_bind)
11162     {
11163       gimple_bind_add_seq (dep_bind, dep_ilist);
11164       gimple_bind_add_stmt (dep_bind, bind);
11165       gimple_bind_add_seq (dep_bind, dep_olist);
11166       pop_gimplify_context (dep_bind);
11167     }
11168 }
11169
11170 /* Lower the GIMPLE_OMP_TARGET in the current statement
11171    in GSI_P.  CTX holds context information for the directive.  */
11172
11173 static void
11174 lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
11175 {
11176   tree clauses;
11177   tree child_fn, t, c;
11178   gomp_target *stmt = as_a <gomp_target *> (gsi_stmt (*gsi_p));
11179   gbind *tgt_bind, *bind;
11180   gimple_seq tgt_body, olist, ilist, orlist, irlist, new_body;
11181   location_t loc = gimple_location (stmt);
11182   bool offloaded, data_region;
11183   unsigned int map_cnt = 0;
11184
11185   offloaded = is_gimple_omp_offloaded (stmt);
11186   switch (gimple_omp_target_kind (stmt))
11187     {
11188     case GF_OMP_TARGET_KIND_REGION:
11189     case GF_OMP_TARGET_KIND_UPDATE:
11190     case GF_OMP_TARGET_KIND_OACC_PARALLEL:
11191     case GF_OMP_TARGET_KIND_OACC_KERNELS:
11192     case GF_OMP_TARGET_KIND_OACC_UPDATE:
11193     case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
11194       data_region = false;
11195       break;
11196     case GF_OMP_TARGET_KIND_DATA:
11197     case GF_OMP_TARGET_KIND_OACC_DATA:
11198       data_region = true;
11199       break;
11200     default:
11201       gcc_unreachable ();
11202     }
11203
11204   clauses = gimple_omp_target_clauses (stmt);
11205
11206   tgt_bind = NULL;
11207   tgt_body = NULL;
11208   if (offloaded)
11209     {
11210       tgt_bind = gimple_seq_first_stmt_as_a_bind (gimple_omp_body (stmt));
11211       tgt_body = gimple_bind_body (tgt_bind);
11212     }
11213   else if (data_region)
11214     tgt_body = gimple_omp_body (stmt);
11215   child_fn = ctx->cb.dst_fn;
11216
11217   push_gimplify_context ();
11218
11219   irlist = NULL;
11220   orlist = NULL;
11221   if (offloaded
11222       && is_gimple_omp_oacc (stmt))
11223     oacc_process_reduction_data (&tgt_body, &irlist, &orlist, ctx);
11224
11225   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
11226     switch (OMP_CLAUSE_CODE (c))
11227       {
11228         tree var, x;
11229
11230       default:
11231         break;
11232       case OMP_CLAUSE_MAP:
11233 #ifdef ENABLE_CHECKING
11234         /* First check what we're prepared to handle in the following.  */
11235         switch (OMP_CLAUSE_MAP_KIND (c))
11236           {
11237           case GOMP_MAP_ALLOC:
11238           case GOMP_MAP_TO:
11239           case GOMP_MAP_FROM:
11240           case GOMP_MAP_TOFROM:
11241           case GOMP_MAP_POINTER:
11242           case GOMP_MAP_TO_PSET:
11243             break;
11244           case GOMP_MAP_FORCE_ALLOC:
11245           case GOMP_MAP_FORCE_TO:
11246           case GOMP_MAP_FORCE_FROM:
11247           case GOMP_MAP_FORCE_TOFROM:
11248           case GOMP_MAP_FORCE_PRESENT:
11249           case GOMP_MAP_FORCE_DEALLOC:
11250           case GOMP_MAP_FORCE_DEVICEPTR:
11251             gcc_assert (is_gimple_omp_oacc (stmt));
11252             break;
11253           default:
11254             gcc_unreachable ();
11255           }
11256 #endif
11257           /* FALLTHRU */
11258       case OMP_CLAUSE_TO:
11259       case OMP_CLAUSE_FROM:
11260         var = OMP_CLAUSE_DECL (c);
11261         if (!DECL_P (var))
11262           {
11263             if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
11264                 || !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
11265               map_cnt++;
11266             continue;
11267           }
11268
11269         if (DECL_SIZE (var)
11270             && TREE_CODE (DECL_SIZE (var)) != INTEGER_CST)
11271           {
11272             tree var2 = DECL_VALUE_EXPR (var);
11273             gcc_assert (TREE_CODE (var2) == INDIRECT_REF);
11274             var2 = TREE_OPERAND (var2, 0);
11275             gcc_assert (DECL_P (var2));
11276             var = var2;
11277           }
11278
11279         if (!maybe_lookup_field (var, ctx))
11280           continue;
11281
11282         if (offloaded)
11283           {
11284             x = build_receiver_ref (var, true, ctx);
11285             tree new_var = lookup_decl (var, ctx);
11286             if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
11287                 && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
11288                 && TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
11289               x = build_simple_mem_ref (x);
11290             SET_DECL_VALUE_EXPR (new_var, x);
11291             DECL_HAS_VALUE_EXPR_P (new_var) = 1;
11292           }
11293         map_cnt++;
11294       }
11295
11296   if (offloaded)
11297     {
11298       target_nesting_level++;
11299       lower_omp (&tgt_body, ctx);
11300       target_nesting_level--;
11301     }
11302   else if (data_region)
11303     lower_omp (&tgt_body, ctx);
11304
11305   if (offloaded)
11306     {
11307       /* Declare all the variables created by mapping and the variables
11308          declared in the scope of the target body.  */
11309       record_vars_into (ctx->block_vars, child_fn);
11310       record_vars_into (gimple_bind_vars (tgt_bind), child_fn);
11311     }
11312
11313   olist = NULL;
11314   ilist = NULL;
11315   if (ctx->record_type)
11316     {
11317       ctx->sender_decl
11318         = create_tmp_var (ctx->record_type, ".omp_data_arr");
11319       DECL_NAMELESS (ctx->sender_decl) = 1;
11320       TREE_ADDRESSABLE (ctx->sender_decl) = 1;
11321       t = make_tree_vec (3);
11322       TREE_VEC_ELT (t, 0) = ctx->sender_decl;
11323       TREE_VEC_ELT (t, 1)
11324         = create_tmp_var (build_array_type_nelts (size_type_node, map_cnt),
11325                           ".omp_data_sizes");
11326       DECL_NAMELESS (TREE_VEC_ELT (t, 1)) = 1;
11327       TREE_ADDRESSABLE (TREE_VEC_ELT (t, 1)) = 1;
11328       TREE_STATIC (TREE_VEC_ELT (t, 1)) = 1;
11329       tree tkind_type;
11330       int talign_shift;
11331       if (is_gimple_omp_oacc (stmt))
11332         {
11333           tkind_type = short_unsigned_type_node;
11334           talign_shift = 8;
11335         }
11336       else
11337         {
11338           tkind_type = unsigned_char_type_node;
11339           talign_shift = 3;
11340         }
11341       TREE_VEC_ELT (t, 2)
11342         = create_tmp_var (build_array_type_nelts (tkind_type, map_cnt),
11343                           ".omp_data_kinds");
11344       DECL_NAMELESS (TREE_VEC_ELT (t, 2)) = 1;
11345       TREE_ADDRESSABLE (TREE_VEC_ELT (t, 2)) = 1;
11346       TREE_STATIC (TREE_VEC_ELT (t, 2)) = 1;
11347       gimple_omp_target_set_data_arg (stmt, t);
11348
11349       vec<constructor_elt, va_gc> *vsize;
11350       vec<constructor_elt, va_gc> *vkind;
11351       vec_alloc (vsize, map_cnt);
11352       vec_alloc (vkind, map_cnt);
11353       unsigned int map_idx = 0;
11354
11355       for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
11356         switch (OMP_CLAUSE_CODE (c))
11357           {
11358             tree ovar, nc;
11359
11360           default:
11361             break;
11362           case OMP_CLAUSE_MAP:
11363           case OMP_CLAUSE_TO:
11364           case OMP_CLAUSE_FROM:
11365             nc = c;
11366             ovar = OMP_CLAUSE_DECL (c);
11367             if (!DECL_P (ovar))
11368               {
11369                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
11370                     && OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
11371                   {
11372                     gcc_checking_assert (OMP_CLAUSE_DECL (OMP_CLAUSE_CHAIN (c))
11373                                          == get_base_address (ovar));
11374                     nc = OMP_CLAUSE_CHAIN (c);
11375                     ovar = OMP_CLAUSE_DECL (nc);
11376                   }
11377                 else
11378                   {
11379                     tree x = build_sender_ref (ovar, ctx);
11380                     tree v
11381                       = build_fold_addr_expr_with_type (ovar, ptr_type_node);
11382                     gimplify_assign (x, v, &ilist);
11383                     nc = NULL_TREE;
11384                   }
11385               }
11386             else
11387               {
11388                 if (DECL_SIZE (ovar)
11389                     && TREE_CODE (DECL_SIZE (ovar)) != INTEGER_CST)
11390                   {
11391                     tree ovar2 = DECL_VALUE_EXPR (ovar);
11392                     gcc_assert (TREE_CODE (ovar2) == INDIRECT_REF);
11393                     ovar2 = TREE_OPERAND (ovar2, 0);
11394                     gcc_assert (DECL_P (ovar2));
11395                     ovar = ovar2;
11396                   }
11397                 if (!maybe_lookup_field (ovar, ctx))
11398                   continue;
11399               }
11400
11401             unsigned int talign = TYPE_ALIGN_UNIT (TREE_TYPE (ovar));
11402             if (DECL_P (ovar) && DECL_ALIGN_UNIT (ovar) > talign)
11403               talign = DECL_ALIGN_UNIT (ovar);
11404             if (nc)
11405               {
11406                 tree var = lookup_decl_in_outer_ctx (ovar, ctx);
11407                 tree x = build_sender_ref (ovar, ctx);
11408                 if (maybe_lookup_oacc_reduction (var, ctx))
11409                   {
11410                     gcc_checking_assert (offloaded
11411                                          && is_gimple_omp_oacc (stmt));
11412                     gimplify_assign (x, var, &ilist);
11413                   }
11414                 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
11415                          && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
11416                          && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
11417                          && TREE_CODE (TREE_TYPE (ovar)) == ARRAY_TYPE)
11418                   {
11419                     gcc_assert (offloaded);
11420                     tree avar
11421                       = create_tmp_var (TREE_TYPE (TREE_TYPE (x)));
11422                     mark_addressable (avar);
11423                     gimplify_assign (avar, build_fold_addr_expr (var), &ilist);
11424                     talign = DECL_ALIGN_UNIT (avar);
11425                     avar = build_fold_addr_expr (avar);
11426                     gimplify_assign (x, avar, &ilist);
11427                   }
11428                 else if (is_gimple_reg (var))
11429                   {
11430                     gcc_assert (offloaded);
11431                     tree avar = create_tmp_var (TREE_TYPE (var));
11432                     mark_addressable (avar);
11433                     enum gomp_map_kind map_kind = OMP_CLAUSE_MAP_KIND (c);
11434                     if (GOMP_MAP_COPY_TO_P (map_kind)
11435                         || map_kind == GOMP_MAP_POINTER
11436                         || map_kind == GOMP_MAP_TO_PSET
11437                         || map_kind == GOMP_MAP_FORCE_DEVICEPTR)
11438                       gimplify_assign (avar, var, &ilist);
11439                     avar = build_fold_addr_expr (avar);
11440                     gimplify_assign (x, avar, &ilist);
11441                     if ((GOMP_MAP_COPY_FROM_P (map_kind)
11442                          || map_kind == GOMP_MAP_FORCE_DEVICEPTR)
11443                         && !TYPE_READONLY (TREE_TYPE (var)))
11444                       {
11445                         x = build_sender_ref (ovar, ctx);
11446                         x = build_simple_mem_ref (x);
11447                         gimplify_assign (var, x, &olist);
11448                       }
11449                   }
11450                 else
11451                   {
11452                     var = build_fold_addr_expr (var);
11453                     gimplify_assign (x, var, &ilist);
11454                   }
11455               }
11456             tree s = OMP_CLAUSE_SIZE (c);
11457             if (s == NULL_TREE)
11458               s = TYPE_SIZE_UNIT (TREE_TYPE (ovar));
11459             s = fold_convert (size_type_node, s);
11460             tree purpose = size_int (map_idx++);
11461             CONSTRUCTOR_APPEND_ELT (vsize, purpose, s);
11462             if (TREE_CODE (s) != INTEGER_CST)
11463               TREE_STATIC (TREE_VEC_ELT (t, 1)) = 0;
11464
11465             unsigned HOST_WIDE_INT tkind;
11466             switch (OMP_CLAUSE_CODE (c))
11467               {
11468               case OMP_CLAUSE_MAP:
11469                 tkind = OMP_CLAUSE_MAP_KIND (c);
11470                 break;
11471               case OMP_CLAUSE_TO:
11472                 tkind = GOMP_MAP_TO;
11473                 break;
11474               case OMP_CLAUSE_FROM:
11475                 tkind = GOMP_MAP_FROM;
11476                 break;
11477               default:
11478                 gcc_unreachable ();
11479               }
11480             gcc_checking_assert (tkind
11481                                  < (HOST_WIDE_INT_C (1U) << talign_shift));
11482             talign = ceil_log2 (talign);
11483             tkind |= talign << talign_shift;
11484             gcc_checking_assert (tkind
11485                                  <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
11486             CONSTRUCTOR_APPEND_ELT (vkind, purpose,
11487                                     build_int_cstu (tkind_type, tkind));
11488             if (nc && nc != c)
11489               c = nc;
11490           }
11491
11492       gcc_assert (map_idx == map_cnt);
11493
11494       DECL_INITIAL (TREE_VEC_ELT (t, 1))
11495         = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 1)), vsize);
11496       DECL_INITIAL (TREE_VEC_ELT (t, 2))
11497         = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 2)), vkind);
11498       if (!TREE_STATIC (TREE_VEC_ELT (t, 1)))
11499         {
11500           gimple_seq initlist = NULL;
11501           force_gimple_operand (build1 (DECL_EXPR, void_type_node,
11502                                         TREE_VEC_ELT (t, 1)),
11503                                 &initlist, true, NULL_TREE);
11504           gimple_seq_add_seq (&ilist, initlist);
11505
11506           tree clobber = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 1)),
11507                                             NULL);
11508           TREE_THIS_VOLATILE (clobber) = 1;
11509           gimple_seq_add_stmt (&olist,
11510                                gimple_build_assign (TREE_VEC_ELT (t, 1),
11511                                                     clobber));
11512         }
11513
11514       tree clobber = build_constructor (ctx->record_type, NULL);
11515       TREE_THIS_VOLATILE (clobber) = 1;
11516       gimple_seq_add_stmt (&olist, gimple_build_assign (ctx->sender_decl,
11517                                                         clobber));
11518     }
11519
11520   /* Once all the expansions are done, sequence all the different
11521      fragments inside gimple_omp_body.  */
11522
11523   new_body = NULL;
11524
11525   if (offloaded
11526       && ctx->record_type)
11527     {
11528       t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
11529       /* fixup_child_record_type might have changed receiver_decl's type.  */
11530       t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
11531       gimple_seq_add_stmt (&new_body,
11532                            gimple_build_assign (ctx->receiver_decl, t));
11533     }
11534
11535   if (offloaded)
11536     {
11537       gimple_seq_add_seq (&new_body, tgt_body);
11538       new_body = maybe_catch_exception (new_body);
11539     }
11540   else if (data_region)
11541     new_body = tgt_body;
11542   if (offloaded || data_region)
11543     {
11544       gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
11545       gimple_omp_set_body (stmt, new_body);
11546     }
11547
11548   bind = gimple_build_bind (NULL, NULL,
11549                             tgt_bind ? gimple_bind_block (tgt_bind)
11550                                      : NULL_TREE);
11551   gsi_replace (gsi_p, bind, true);
11552   gimple_bind_add_seq (bind, irlist);
11553   gimple_bind_add_seq (bind, ilist);
11554   gimple_bind_add_stmt (bind, stmt);
11555   gimple_bind_add_seq (bind, olist);
11556   gimple_bind_add_seq (bind, orlist);
11557
11558   pop_gimplify_context (NULL);
11559 }
11560
11561 /* Expand code for an OpenMP teams directive.  */
11562
11563 static void
11564 lower_omp_teams (gimple_stmt_iterator *gsi_p, omp_context *ctx)
11565 {
11566   gomp_teams *teams_stmt = as_a <gomp_teams *> (gsi_stmt (*gsi_p));
11567   push_gimplify_context ();
11568
11569   tree block = make_node (BLOCK);
11570   gbind *bind = gimple_build_bind (NULL, NULL, block);
11571   gsi_replace (gsi_p, bind, true);
11572   gimple_seq bind_body = NULL;
11573   gimple_seq dlist = NULL;
11574   gimple_seq olist = NULL;
11575
11576   tree num_teams = find_omp_clause (gimple_omp_teams_clauses (teams_stmt),
11577                                     OMP_CLAUSE_NUM_TEAMS);
11578   if (num_teams == NULL_TREE)
11579     num_teams = build_int_cst (unsigned_type_node, 0);
11580   else
11581     {
11582       num_teams = OMP_CLAUSE_NUM_TEAMS_EXPR (num_teams);
11583       num_teams = fold_convert (unsigned_type_node, num_teams);
11584       gimplify_expr (&num_teams, &bind_body, NULL, is_gimple_val, fb_rvalue);
11585     }
11586   tree thread_limit = find_omp_clause (gimple_omp_teams_clauses (teams_stmt),
11587                                        OMP_CLAUSE_THREAD_LIMIT);
11588   if (thread_limit == NULL_TREE)
11589     thread_limit = build_int_cst (unsigned_type_node, 0);
11590   else
11591     {
11592       thread_limit = OMP_CLAUSE_THREAD_LIMIT_EXPR (thread_limit);
11593       thread_limit = fold_convert (unsigned_type_node, thread_limit);
11594       gimplify_expr (&thread_limit, &bind_body, NULL, is_gimple_val,
11595                      fb_rvalue);
11596     }
11597
11598   lower_rec_input_clauses (gimple_omp_teams_clauses (teams_stmt),
11599                            &bind_body, &dlist, ctx, NULL);
11600   lower_omp (gimple_omp_body_ptr (teams_stmt), ctx);
11601   lower_reduction_clauses (gimple_omp_teams_clauses (teams_stmt), &olist, ctx);
11602   gimple_seq_add_stmt (&bind_body, teams_stmt);
11603
11604   location_t loc = gimple_location (teams_stmt);
11605   tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TEAMS);
11606   gimple call = gimple_build_call (decl, 2, num_teams, thread_limit);
11607   gimple_set_location (call, loc);
11608   gimple_seq_add_stmt (&bind_body, call);
11609
11610   gimple_seq_add_seq (&bind_body, gimple_omp_body (teams_stmt));
11611   gimple_omp_set_body (teams_stmt, NULL);
11612   gimple_seq_add_seq (&bind_body, olist);
11613   gimple_seq_add_seq (&bind_body, dlist);
11614   gimple_seq_add_stmt (&bind_body, gimple_build_omp_return (true));
11615   gimple_bind_set_body (bind, bind_body);
11616
11617   pop_gimplify_context (bind);
11618
11619   gimple_bind_append_vars (bind, ctx->block_vars);
11620   BLOCK_VARS (block) = ctx->block_vars;
11621   if (BLOCK_VARS (block))
11622     TREE_USED (block) = 1;
11623 }
11624
11625
11626 /* Callback for lower_omp_1.  Return non-NULL if *tp needs to be
11627    regimplified.  If DATA is non-NULL, lower_omp_1 is outside
11628    of OMP context, but with task_shared_vars set.  */
11629
11630 static tree
11631 lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
11632                         void *data)
11633 {
11634   tree t = *tp;
11635
11636   /* Any variable with DECL_VALUE_EXPR needs to be regimplified.  */
11637   if (TREE_CODE (t) == VAR_DECL && data == NULL && DECL_HAS_VALUE_EXPR_P (t))
11638     return t;
11639
11640   if (task_shared_vars
11641       && DECL_P (t)
11642       && bitmap_bit_p (task_shared_vars, DECL_UID (t)))
11643     return t;
11644
11645   /* If a global variable has been privatized, TREE_CONSTANT on
11646      ADDR_EXPR might be wrong.  */
11647   if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
11648     recompute_tree_invariant_for_addr_expr (t);
11649
11650   *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
11651   return NULL_TREE;
11652 }
11653
11654 static void
11655 lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
11656 {
11657   gimple stmt = gsi_stmt (*gsi_p);
11658   struct walk_stmt_info wi;
11659   gcall *call_stmt;
11660
11661   if (gimple_has_location (stmt))
11662     input_location = gimple_location (stmt);
11663
11664   if (task_shared_vars)
11665     memset (&wi, '\0', sizeof (wi));
11666
11667   /* If we have issued syntax errors, avoid doing any heavy lifting.
11668      Just replace the OMP directives with a NOP to avoid
11669      confusing RTL expansion.  */
11670   if (seen_error () && is_gimple_omp (stmt))
11671     {
11672       gsi_replace (gsi_p, gimple_build_nop (), true);
11673       return;
11674     }
11675
11676   switch (gimple_code (stmt))
11677     {
11678     case GIMPLE_COND:
11679       {
11680         gcond *cond_stmt = as_a <gcond *> (stmt);
11681         if ((ctx || task_shared_vars)
11682             && (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
11683                            lower_omp_regimplify_p,
11684                            ctx ? NULL : &wi, NULL)
11685                 || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
11686                               lower_omp_regimplify_p,
11687                               ctx ? NULL : &wi, NULL)))
11688           gimple_regimplify_operands (cond_stmt, gsi_p);
11689       }
11690       break;
11691     case GIMPLE_CATCH:
11692       lower_omp (gimple_catch_handler_ptr (as_a <gcatch *> (stmt)), ctx);
11693       break;
11694     case GIMPLE_EH_FILTER:
11695       lower_omp (gimple_eh_filter_failure_ptr (stmt), ctx);
11696       break;
11697     case GIMPLE_TRY:
11698       lower_omp (gimple_try_eval_ptr (stmt), ctx);
11699       lower_omp (gimple_try_cleanup_ptr (stmt), ctx);
11700       break;
11701     case GIMPLE_TRANSACTION:
11702       lower_omp (gimple_transaction_body_ptr (
11703                    as_a <gtransaction *> (stmt)),
11704                  ctx);
11705       break;
11706     case GIMPLE_BIND:
11707       lower_omp (gimple_bind_body_ptr (as_a <gbind *> (stmt)), ctx);
11708       break;
11709     case GIMPLE_OMP_PARALLEL:
11710     case GIMPLE_OMP_TASK:
11711       ctx = maybe_lookup_ctx (stmt);
11712       gcc_assert (ctx);
11713       if (ctx->cancellable)
11714         ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
11715       lower_omp_taskreg (gsi_p, ctx);
11716       break;
11717     case GIMPLE_OMP_FOR:
11718       ctx = maybe_lookup_ctx (stmt);
11719       gcc_assert (ctx);
11720       if (ctx->cancellable)
11721         ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
11722       lower_omp_for (gsi_p, ctx);
11723       break;
11724     case GIMPLE_OMP_SECTIONS:
11725       ctx = maybe_lookup_ctx (stmt);
11726       gcc_assert (ctx);
11727       if (ctx->cancellable)
11728         ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
11729       lower_omp_sections (gsi_p, ctx);
11730       break;
11731     case GIMPLE_OMP_SINGLE:
11732       ctx = maybe_lookup_ctx (stmt);
11733       gcc_assert (ctx);
11734       lower_omp_single (gsi_p, ctx);
11735       break;
11736     case GIMPLE_OMP_MASTER:
11737       ctx = maybe_lookup_ctx (stmt);
11738       gcc_assert (ctx);
11739       lower_omp_master (gsi_p, ctx);
11740       break;
11741     case GIMPLE_OMP_TASKGROUP:
11742       ctx = maybe_lookup_ctx (stmt);
11743       gcc_assert (ctx);
11744       lower_omp_taskgroup (gsi_p, ctx);
11745       break;
11746     case GIMPLE_OMP_ORDERED:
11747       ctx = maybe_lookup_ctx (stmt);
11748       gcc_assert (ctx);
11749       lower_omp_ordered (gsi_p, ctx);
11750       break;
11751     case GIMPLE_OMP_CRITICAL:
11752       ctx = maybe_lookup_ctx (stmt);
11753       gcc_assert (ctx);
11754       lower_omp_critical (gsi_p, ctx);
11755       break;
11756     case GIMPLE_OMP_ATOMIC_LOAD:
11757       if ((ctx || task_shared_vars)
11758           && walk_tree (gimple_omp_atomic_load_rhs_ptr (
11759                           as_a <gomp_atomic_load *> (stmt)),
11760                         lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
11761         gimple_regimplify_operands (stmt, gsi_p);
11762       break;
11763     case GIMPLE_OMP_TARGET:
11764       ctx = maybe_lookup_ctx (stmt);
11765       gcc_assert (ctx);
11766       lower_omp_target (gsi_p, ctx);
11767       break;
11768     case GIMPLE_OMP_TEAMS:
11769       ctx = maybe_lookup_ctx (stmt);
11770       gcc_assert (ctx);
11771       lower_omp_teams (gsi_p, ctx);
11772       break;
11773     case GIMPLE_CALL:
11774       tree fndecl;
11775       call_stmt = as_a <gcall *> (stmt);
11776       fndecl = gimple_call_fndecl (call_stmt);
11777       if (fndecl
11778           && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
11779         switch (DECL_FUNCTION_CODE (fndecl))
11780           {
11781           case BUILT_IN_GOMP_BARRIER:
11782             if (ctx == NULL)
11783               break;
11784             /* FALLTHRU */
11785           case BUILT_IN_GOMP_CANCEL:
11786           case BUILT_IN_GOMP_CANCELLATION_POINT:
11787             omp_context *cctx;
11788             cctx = ctx;
11789             if (gimple_code (cctx->stmt) == GIMPLE_OMP_SECTION)
11790               cctx = cctx->outer;
11791             gcc_assert (gimple_call_lhs (call_stmt) == NULL_TREE);
11792             if (!cctx->cancellable)
11793               {
11794                 if (DECL_FUNCTION_CODE (fndecl)
11795                     == BUILT_IN_GOMP_CANCELLATION_POINT)
11796                   {
11797                     stmt = gimple_build_nop ();
11798                     gsi_replace (gsi_p, stmt, false);
11799                   }
11800                 break;
11801               }
11802             if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER)
11803               {
11804                 fndecl = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER_CANCEL);
11805                 gimple_call_set_fndecl (call_stmt, fndecl);
11806                 gimple_call_set_fntype (call_stmt, TREE_TYPE (fndecl));
11807               }
11808             tree lhs;
11809             lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (fndecl)));
11810             gimple_call_set_lhs (call_stmt, lhs);
11811             tree fallthru_label;
11812             fallthru_label = create_artificial_label (UNKNOWN_LOCATION);
11813             gimple g;
11814             g = gimple_build_label (fallthru_label);
11815             gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
11816             g = gimple_build_cond (NE_EXPR, lhs,
11817                                    fold_convert (TREE_TYPE (lhs),
11818                                                  boolean_false_node),
11819                                    cctx->cancel_label, fallthru_label);
11820             gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
11821             break;
11822           default:
11823             break;
11824           }
11825       /* FALLTHRU */
11826     default:
11827       if ((ctx || task_shared_vars)
11828           && walk_gimple_op (stmt, lower_omp_regimplify_p,
11829                              ctx ? NULL : &wi))
11830         {
11831           /* Just remove clobbers, this should happen only if we have
11832              "privatized" local addressable variables in SIMD regions,
11833              the clobber isn't needed in that case and gimplifying address
11834              of the ARRAY_REF into a pointer and creating MEM_REF based
11835              clobber would create worse code than we get with the clobber
11836              dropped.  */
11837           if (gimple_clobber_p (stmt))
11838             {
11839               gsi_replace (gsi_p, gimple_build_nop (), true);
11840               break;
11841             }
11842           gimple_regimplify_operands (stmt, gsi_p);
11843         }
11844       break;
11845     }
11846 }
11847
11848 static void
11849 lower_omp (gimple_seq *body, omp_context *ctx)
11850 {
11851   location_t saved_location = input_location;
11852   gimple_stmt_iterator gsi;
11853   for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
11854     lower_omp_1 (&gsi, ctx);
11855   /* During gimplification, we haven't folded statments inside offloading
11856      regions (gimplify.c:maybe_fold_stmt); do that now.  */
11857   if (target_nesting_level)
11858     for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
11859       fold_stmt (&gsi);
11860   input_location = saved_location;
11861 }
11862 \f
11863 /* Main entry point.  */
11864
11865 static unsigned int
11866 execute_lower_omp (void)
11867 {
11868   gimple_seq body;
11869   int i;
11870   omp_context *ctx;
11871
11872   /* This pass always runs, to provide PROP_gimple_lomp.
11873      But often, there is nothing to do.  */
11874   if (flag_cilkplus == 0 && flag_openacc == 0 && flag_openmp == 0
11875       && flag_openmp_simd == 0)
11876     return 0;
11877
11878   all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
11879                                  delete_omp_context);
11880
11881   body = gimple_body (current_function_decl);
11882   scan_omp (&body, NULL);
11883   gcc_assert (taskreg_nesting_level == 0);
11884   FOR_EACH_VEC_ELT (taskreg_contexts, i, ctx)
11885     finish_taskreg_scan (ctx);
11886   taskreg_contexts.release ();
11887
11888   if (all_contexts->root)
11889     {
11890       if (task_shared_vars)
11891         push_gimplify_context ();
11892       lower_omp (&body, NULL);
11893       if (task_shared_vars)
11894         pop_gimplify_context (NULL);
11895     }
11896
11897   if (all_contexts)
11898     {
11899       splay_tree_delete (all_contexts);
11900       all_contexts = NULL;
11901     }
11902   BITMAP_FREE (task_shared_vars);
11903   return 0;
11904 }
11905
11906 namespace {
11907
11908 const pass_data pass_data_lower_omp =
11909 {
11910   GIMPLE_PASS, /* type */
11911   "omplower", /* name */
11912   OPTGROUP_NONE, /* optinfo_flags */
11913   TV_NONE, /* tv_id */
11914   PROP_gimple_any, /* properties_required */
11915   PROP_gimple_lomp, /* properties_provided */
11916   0, /* properties_destroyed */
11917   0, /* todo_flags_start */
11918   0, /* todo_flags_finish */
11919 };
11920
11921 class pass_lower_omp : public gimple_opt_pass
11922 {
11923 public:
11924   pass_lower_omp (gcc::context *ctxt)
11925     : gimple_opt_pass (pass_data_lower_omp, ctxt)
11926   {}
11927
11928   /* opt_pass methods: */
11929   virtual unsigned int execute (function *) { return execute_lower_omp (); }
11930
11931 }; // class pass_lower_omp
11932
11933 } // anon namespace
11934
11935 gimple_opt_pass *
11936 make_pass_lower_omp (gcc::context *ctxt)
11937 {
11938   return new pass_lower_omp (ctxt);
11939 }
11940 \f
11941 /* The following is a utility to diagnose structured block violations.
11942    It is not part of the "omplower" pass, as that's invoked too late.  It
11943    should be invoked by the respective front ends after gimplification.  */
11944
11945 static splay_tree all_labels;
11946
11947 /* Check for mismatched contexts and generate an error if needed.  Return
11948    true if an error is detected.  */
11949
11950 static bool
11951 diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
11952                gimple branch_ctx, gimple label_ctx)
11953 {
11954   gcc_checking_assert (!branch_ctx || is_gimple_omp (branch_ctx));
11955   gcc_checking_assert (!label_ctx || is_gimple_omp (label_ctx));
11956
11957   if (label_ctx == branch_ctx)
11958     return false;
11959
11960   const char* kind = NULL;
11961
11962   if (flag_cilkplus)
11963     {
11964       if ((branch_ctx
11965            && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
11966            && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
11967           || (label_ctx
11968               && gimple_code (label_ctx) == GIMPLE_OMP_FOR
11969               && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
11970         kind = "Cilk Plus";
11971     }
11972   if (flag_openacc)
11973     {
11974       if ((branch_ctx && is_gimple_omp_oacc (branch_ctx))
11975           || (label_ctx && is_gimple_omp_oacc (label_ctx)))
11976         {
11977           gcc_checking_assert (kind == NULL);
11978           kind = "OpenACC";
11979         }
11980     }
11981   if (kind == NULL)
11982     {
11983       gcc_checking_assert (flag_openmp);
11984       kind = "OpenMP";
11985     }
11986
11987   /*
11988      Previously we kept track of the label's entire context in diagnose_sb_[12]
11989      so we could traverse it and issue a correct "exit" or "enter" error
11990      message upon a structured block violation.
11991
11992      We built the context by building a list with tree_cons'ing, but there is
11993      no easy counterpart in gimple tuples.  It seems like far too much work
11994      for issuing exit/enter error messages.  If someone really misses the
11995      distinct error message... patches welcome.
11996    */
11997
11998 #if 0
11999   /* Try to avoid confusing the user by producing and error message
12000      with correct "exit" or "enter" verbiage.  We prefer "exit"
12001      unless we can show that LABEL_CTX is nested within BRANCH_CTX.  */
12002   if (branch_ctx == NULL)
12003     exit_p = false;
12004   else
12005     {
12006       while (label_ctx)
12007         {
12008           if (TREE_VALUE (label_ctx) == branch_ctx)
12009             {
12010               exit_p = false;
12011               break;
12012             }
12013           label_ctx = TREE_CHAIN (label_ctx);
12014         }
12015     }
12016
12017   if (exit_p)
12018     error ("invalid exit from %s structured block", kind);
12019   else
12020     error ("invalid entry to %s structured block", kind);
12021 #endif
12022
12023   /* If it's obvious we have an invalid entry, be specific about the error.  */
12024   if (branch_ctx == NULL)
12025     error ("invalid entry to %s structured block", kind);
12026   else
12027     {
12028       /* Otherwise, be vague and lazy, but efficient.  */
12029       error ("invalid branch to/from %s structured block", kind);
12030     }
12031
12032   gsi_replace (gsi_p, gimple_build_nop (), false);
12033   return true;
12034 }
12035
12036 /* Pass 1: Create a minimal tree of structured blocks, and record
12037    where each label is found.  */
12038
12039 static tree
12040 diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
12041                struct walk_stmt_info *wi)
12042 {
12043   gimple context = (gimple) wi->info;
12044   gimple inner_context;
12045   gimple stmt = gsi_stmt (*gsi_p);
12046
12047   *handled_ops_p = true;
12048
12049   switch (gimple_code (stmt))
12050     {
12051     WALK_SUBSTMTS;
12052
12053     case GIMPLE_OMP_PARALLEL:
12054     case GIMPLE_OMP_TASK:
12055     case GIMPLE_OMP_SECTIONS:
12056     case GIMPLE_OMP_SINGLE:
12057     case GIMPLE_OMP_SECTION:
12058     case GIMPLE_OMP_MASTER:
12059     case GIMPLE_OMP_ORDERED:
12060     case GIMPLE_OMP_CRITICAL:
12061     case GIMPLE_OMP_TARGET:
12062     case GIMPLE_OMP_TEAMS:
12063     case GIMPLE_OMP_TASKGROUP:
12064       /* The minimal context here is just the current OMP construct.  */
12065       inner_context = stmt;
12066       wi->info = inner_context;
12067       walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
12068       wi->info = context;
12069       break;
12070
12071     case GIMPLE_OMP_FOR:
12072       inner_context = stmt;
12073       wi->info = inner_context;
12074       /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
12075          walk them.  */
12076       walk_gimple_seq (gimple_omp_for_pre_body (stmt),
12077                        diagnose_sb_1, NULL, wi);
12078       walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
12079       wi->info = context;
12080       break;
12081
12082     case GIMPLE_LABEL:
12083       splay_tree_insert (all_labels,
12084                          (splay_tree_key) gimple_label_label (
12085                                             as_a <glabel *> (stmt)),
12086                          (splay_tree_value) context);
12087       break;
12088
12089     default:
12090       break;
12091     }
12092
12093   return NULL_TREE;
12094 }
12095
12096 /* Pass 2: Check each branch and see if its context differs from that of
12097    the destination label's context.  */
12098
12099 static tree
12100 diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
12101                struct walk_stmt_info *wi)
12102 {
12103   gimple context = (gimple) wi->info;
12104   splay_tree_node n;
12105   gimple stmt = gsi_stmt (*gsi_p);
12106
12107   *handled_ops_p = true;
12108
12109   switch (gimple_code (stmt))
12110     {
12111     WALK_SUBSTMTS;
12112
12113     case GIMPLE_OMP_PARALLEL:
12114     case GIMPLE_OMP_TASK:
12115     case GIMPLE_OMP_SECTIONS:
12116     case GIMPLE_OMP_SINGLE:
12117     case GIMPLE_OMP_SECTION:
12118     case GIMPLE_OMP_MASTER:
12119     case GIMPLE_OMP_ORDERED:
12120     case GIMPLE_OMP_CRITICAL:
12121     case GIMPLE_OMP_TARGET:
12122     case GIMPLE_OMP_TEAMS:
12123     case GIMPLE_OMP_TASKGROUP:
12124       wi->info = stmt;
12125       walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
12126       wi->info = context;
12127       break;
12128
12129     case GIMPLE_OMP_FOR:
12130       wi->info = stmt;
12131       /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
12132          walk them.  */
12133       walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt),
12134                            diagnose_sb_2, NULL, wi);
12135       walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
12136       wi->info = context;
12137       break;
12138
12139     case GIMPLE_COND:
12140         {
12141           gcond *cond_stmt = as_a <gcond *> (stmt);
12142           tree lab = gimple_cond_true_label (cond_stmt);
12143           if (lab)
12144             {
12145               n = splay_tree_lookup (all_labels,
12146                                      (splay_tree_key) lab);
12147               diagnose_sb_0 (gsi_p, context,
12148                              n ? (gimple) n->value : NULL);
12149             }
12150           lab = gimple_cond_false_label (cond_stmt);
12151           if (lab)
12152             {
12153               n = splay_tree_lookup (all_labels,
12154                                      (splay_tree_key) lab);
12155               diagnose_sb_0 (gsi_p, context,
12156                              n ? (gimple) n->value : NULL);
12157             }
12158         }
12159       break;
12160
12161     case GIMPLE_GOTO:
12162       {
12163         tree lab = gimple_goto_dest (stmt);
12164         if (TREE_CODE (lab) != LABEL_DECL)
12165           break;
12166
12167         n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
12168         diagnose_sb_0 (gsi_p, context, n ? (gimple) n->value : NULL);
12169       }
12170       break;
12171
12172     case GIMPLE_SWITCH:
12173       {
12174         gswitch *switch_stmt = as_a <gswitch *> (stmt);
12175         unsigned int i;
12176         for (i = 0; i < gimple_switch_num_labels (switch_stmt); ++i)
12177           {
12178             tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i));
12179             n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
12180             if (n && diagnose_sb_0 (gsi_p, context, (gimple) n->value))
12181               break;
12182           }
12183       }
12184       break;
12185
12186     case GIMPLE_RETURN:
12187       diagnose_sb_0 (gsi_p, context, NULL);
12188       break;
12189
12190     default:
12191       break;
12192     }
12193
12194   return NULL_TREE;
12195 }
12196
12197 /* Called from tree-cfg.c::make_edges to create cfg edges for all relevant
12198    GIMPLE_* codes.  */
12199 bool
12200 make_gimple_omp_edges (basic_block bb, struct omp_region **region,
12201                        int *region_idx)
12202 {
12203   gimple last = last_stmt (bb);
12204   enum gimple_code code = gimple_code (last);
12205   struct omp_region *cur_region = *region;
12206   bool fallthru = false;
12207
12208   switch (code)
12209     {
12210     case GIMPLE_OMP_PARALLEL:
12211     case GIMPLE_OMP_TASK:
12212     case GIMPLE_OMP_FOR:
12213     case GIMPLE_OMP_SINGLE:
12214     case GIMPLE_OMP_TEAMS:
12215     case GIMPLE_OMP_MASTER:
12216     case GIMPLE_OMP_TASKGROUP:
12217     case GIMPLE_OMP_ORDERED:
12218     case GIMPLE_OMP_CRITICAL:
12219     case GIMPLE_OMP_SECTION:
12220       cur_region = new_omp_region (bb, code, cur_region);
12221       fallthru = true;
12222       break;
12223
12224     case GIMPLE_OMP_TARGET:
12225       cur_region = new_omp_region (bb, code, cur_region);
12226       fallthru = true;
12227       switch (gimple_omp_target_kind (last))
12228         {
12229         case GF_OMP_TARGET_KIND_REGION:
12230         case GF_OMP_TARGET_KIND_DATA:
12231         case GF_OMP_TARGET_KIND_OACC_PARALLEL:
12232         case GF_OMP_TARGET_KIND_OACC_KERNELS:
12233         case GF_OMP_TARGET_KIND_OACC_DATA:
12234           break;
12235         case GF_OMP_TARGET_KIND_UPDATE:
12236         case GF_OMP_TARGET_KIND_OACC_UPDATE:
12237         case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
12238           cur_region = cur_region->outer;
12239           break;
12240         default:
12241           gcc_unreachable ();
12242         }
12243       break;
12244
12245     case GIMPLE_OMP_SECTIONS:
12246       cur_region = new_omp_region (bb, code, cur_region);
12247       fallthru = true;
12248       break;
12249
12250     case GIMPLE_OMP_SECTIONS_SWITCH:
12251       fallthru = false;
12252       break;
12253
12254     case GIMPLE_OMP_ATOMIC_LOAD:
12255     case GIMPLE_OMP_ATOMIC_STORE:
12256        fallthru = true;
12257        break;
12258
12259     case GIMPLE_OMP_RETURN:
12260       /* In the case of a GIMPLE_OMP_SECTION, the edge will go
12261          somewhere other than the next block.  This will be
12262          created later.  */
12263       cur_region->exit = bb;
12264       fallthru = cur_region->type != GIMPLE_OMP_SECTION;
12265       cur_region = cur_region->outer;
12266       break;
12267
12268     case GIMPLE_OMP_CONTINUE:
12269       cur_region->cont = bb;
12270       switch (cur_region->type)
12271         {
12272         case GIMPLE_OMP_FOR:
12273           /* Mark all GIMPLE_OMP_FOR and GIMPLE_OMP_CONTINUE
12274              succs edges as abnormal to prevent splitting
12275              them.  */
12276           single_succ_edge (cur_region->entry)->flags |= EDGE_ABNORMAL;
12277           /* Make the loopback edge.  */
12278           make_edge (bb, single_succ (cur_region->entry),
12279                      EDGE_ABNORMAL);
12280
12281           /* Create an edge from GIMPLE_OMP_FOR to exit, which
12282              corresponds to the case that the body of the loop
12283              is not executed at all.  */
12284           make_edge (cur_region->entry, bb->next_bb, EDGE_ABNORMAL);
12285           make_edge (bb, bb->next_bb, EDGE_FALLTHRU | EDGE_ABNORMAL);
12286           fallthru = false;
12287           break;
12288
12289         case GIMPLE_OMP_SECTIONS:
12290           /* Wire up the edges into and out of the nested sections.  */
12291           {
12292             basic_block switch_bb = single_succ (cur_region->entry);
12293
12294             struct omp_region *i;
12295             for (i = cur_region->inner; i ; i = i->next)
12296               {
12297                 gcc_assert (i->type == GIMPLE_OMP_SECTION);
12298                 make_edge (switch_bb, i->entry, 0);
12299                 make_edge (i->exit, bb, EDGE_FALLTHRU);
12300               }
12301
12302             /* Make the loopback edge to the block with
12303                GIMPLE_OMP_SECTIONS_SWITCH.  */
12304             make_edge (bb, switch_bb, 0);
12305
12306             /* Make the edge from the switch to exit.  */
12307             make_edge (switch_bb, bb->next_bb, 0);
12308             fallthru = false;
12309           }
12310           break;
12311
12312         default:
12313           gcc_unreachable ();
12314         }
12315       break;
12316
12317     default:
12318       gcc_unreachable ();
12319     }
12320
12321   if (*region != cur_region)
12322     {
12323       *region = cur_region;
12324       if (cur_region)
12325         *region_idx = cur_region->entry->index;
12326       else
12327         *region_idx = 0;
12328     }
12329
12330   return fallthru;
12331 }
12332
12333 static unsigned int
12334 diagnose_omp_structured_block_errors (void)
12335 {
12336   struct walk_stmt_info wi;
12337   gimple_seq body = gimple_body (current_function_decl);
12338
12339   all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
12340
12341   memset (&wi, 0, sizeof (wi));
12342   walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);
12343
12344   memset (&wi, 0, sizeof (wi));
12345   wi.want_locations = true;
12346   walk_gimple_seq_mod (&body, diagnose_sb_2, NULL, &wi);
12347
12348   gimple_set_body (current_function_decl, body);
12349
12350   splay_tree_delete (all_labels);
12351   all_labels = NULL;
12352
12353   return 0;
12354 }
12355
12356 namespace {
12357
12358 const pass_data pass_data_diagnose_omp_blocks =
12359 {
12360   GIMPLE_PASS, /* type */
12361   "*diagnose_omp_blocks", /* name */
12362   OPTGROUP_NONE, /* optinfo_flags */
12363   TV_NONE, /* tv_id */
12364   PROP_gimple_any, /* properties_required */
12365   0, /* properties_provided */
12366   0, /* properties_destroyed */
12367   0, /* todo_flags_start */
12368   0, /* todo_flags_finish */
12369 };
12370
12371 class pass_diagnose_omp_blocks : public gimple_opt_pass
12372 {
12373 public:
12374   pass_diagnose_omp_blocks (gcc::context *ctxt)
12375     : gimple_opt_pass (pass_data_diagnose_omp_blocks, ctxt)
12376   {}
12377
12378   /* opt_pass methods: */
12379   virtual bool gate (function *)
12380   {
12381     return flag_cilkplus || flag_openacc || flag_openmp;
12382   }
12383   virtual unsigned int execute (function *)
12384     {
12385       return diagnose_omp_structured_block_errors ();
12386     }
12387
12388 }; // class pass_diagnose_omp_blocks
12389
12390 } // anon namespace
12391
12392 gimple_opt_pass *
12393 make_pass_diagnose_omp_blocks (gcc::context *ctxt)
12394 {
12395   return new pass_diagnose_omp_blocks (ctxt);
12396 }
12397 \f
12398 /* SIMD clone supporting code.  */
12399
12400 /* Allocate a fresh `simd_clone' and return it.  NARGS is the number
12401    of arguments to reserve space for.  */
12402
12403 static struct cgraph_simd_clone *
12404 simd_clone_struct_alloc (int nargs)
12405 {
12406   struct cgraph_simd_clone *clone_info;
12407   size_t len = (sizeof (struct cgraph_simd_clone)
12408                 + nargs * sizeof (struct cgraph_simd_clone_arg));
12409   clone_info = (struct cgraph_simd_clone *)
12410                ggc_internal_cleared_alloc (len);
12411   return clone_info;
12412 }
12413
12414 /* Make a copy of the `struct cgraph_simd_clone' in FROM to TO.  */
12415
12416 static inline void
12417 simd_clone_struct_copy (struct cgraph_simd_clone *to,
12418                         struct cgraph_simd_clone *from)
12419 {
12420   memcpy (to, from, (sizeof (struct cgraph_simd_clone)
12421                      + ((from->nargs - from->inbranch)
12422                         * sizeof (struct cgraph_simd_clone_arg))));
12423 }
12424
12425 /* Return vector of parameter types of function FNDECL.  This uses
12426    TYPE_ARG_TYPES if available, otherwise falls back to types of
12427    DECL_ARGUMENTS types.  */
12428
12429 vec<tree>
12430 simd_clone_vector_of_formal_parm_types (tree fndecl)
12431 {
12432   if (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
12433     return ipa_get_vector_of_formal_parm_types (TREE_TYPE (fndecl));
12434   vec<tree> args = ipa_get_vector_of_formal_parms (fndecl);
12435   unsigned int i;
12436   tree arg;
12437   FOR_EACH_VEC_ELT (args, i, arg)
12438     args[i] = TREE_TYPE (args[i]);
12439   return args;
12440 }
12441
12442 /* Given a simd function in NODE, extract the simd specific
12443    information from the OMP clauses passed in CLAUSES, and return
12444    the struct cgraph_simd_clone * if it should be cloned.  *INBRANCH_SPECIFIED
12445    is set to TRUE if the `inbranch' or `notinbranch' clause specified,
12446    otherwise set to FALSE.  */
12447
12448 static struct cgraph_simd_clone *
12449 simd_clone_clauses_extract (struct cgraph_node *node, tree clauses,
12450                             bool *inbranch_specified)
12451 {
12452   vec<tree> args = simd_clone_vector_of_formal_parm_types (node->decl);
12453   tree t;
12454   int n;
12455   *inbranch_specified = false;
12456
12457   n = args.length ();
12458   if (n > 0 && args.last () == void_type_node)
12459     n--;
12460
12461   /* To distinguish from an OpenMP simd clone, Cilk Plus functions to
12462      be cloned have a distinctive artificial label in addition to "omp
12463      declare simd".  */
12464   bool cilk_clone
12465     = (flag_cilkplus
12466        && lookup_attribute ("cilk simd function",
12467                             DECL_ATTRIBUTES (node->decl)));
12468
12469   /* Allocate one more than needed just in case this is an in-branch
12470      clone which will require a mask argument.  */
12471   struct cgraph_simd_clone *clone_info = simd_clone_struct_alloc (n + 1);
12472   clone_info->nargs = n;
12473   clone_info->cilk_elemental = cilk_clone;
12474
12475   if (!clauses)
12476     {
12477       args.release ();
12478       return clone_info;
12479     }
12480   clauses = TREE_VALUE (clauses);
12481   if (!clauses || TREE_CODE (clauses) != OMP_CLAUSE)
12482     return clone_info;
12483
12484   for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
12485     {
12486       switch (OMP_CLAUSE_CODE (t))
12487         {
12488         case OMP_CLAUSE_INBRANCH:
12489           clone_info->inbranch = 1;
12490           *inbranch_specified = true;
12491           break;
12492         case OMP_CLAUSE_NOTINBRANCH:
12493           clone_info->inbranch = 0;
12494           *inbranch_specified = true;
12495           break;
12496         case OMP_CLAUSE_SIMDLEN:
12497           clone_info->simdlen
12498             = TREE_INT_CST_LOW (OMP_CLAUSE_SIMDLEN_EXPR (t));
12499           break;
12500         case OMP_CLAUSE_LINEAR:
12501           {
12502             tree decl = OMP_CLAUSE_DECL (t);
12503             tree step = OMP_CLAUSE_LINEAR_STEP (t);
12504             int argno = TREE_INT_CST_LOW (decl);
12505             if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (t))
12506               {
12507                 clone_info->args[argno].arg_type
12508                   = SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP;
12509                 clone_info->args[argno].linear_step = tree_to_shwi (step);
12510                 gcc_assert (clone_info->args[argno].linear_step >= 0
12511                             && clone_info->args[argno].linear_step < n);
12512               }
12513             else
12514               {
12515                 if (POINTER_TYPE_P (args[argno]))
12516                   step = fold_convert (ssizetype, step);
12517                 if (!tree_fits_shwi_p (step))
12518                   {
12519                     warning_at (OMP_CLAUSE_LOCATION (t), 0,
12520                                 "ignoring large linear step");
12521                     args.release ();
12522                     return NULL;
12523                   }
12524                 else if (integer_zerop (step))
12525                   {
12526                     warning_at (OMP_CLAUSE_LOCATION (t), 0,
12527                                 "ignoring zero linear step");
12528                     args.release ();
12529                     return NULL;
12530                   }
12531                 else
12532                   {
12533                     clone_info->args[argno].arg_type
12534                       = SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP;
12535                     clone_info->args[argno].linear_step = tree_to_shwi (step);
12536                   }
12537               }
12538             break;
12539           }
12540         case OMP_CLAUSE_UNIFORM:
12541           {
12542             tree decl = OMP_CLAUSE_DECL (t);
12543             int argno = tree_to_uhwi (decl);
12544             clone_info->args[argno].arg_type
12545               = SIMD_CLONE_ARG_TYPE_UNIFORM;
12546             break;
12547           }
12548         case OMP_CLAUSE_ALIGNED:
12549           {
12550             tree decl = OMP_CLAUSE_DECL (t);
12551             int argno = tree_to_uhwi (decl);
12552             clone_info->args[argno].alignment
12553               = TREE_INT_CST_LOW (OMP_CLAUSE_ALIGNED_ALIGNMENT (t));
12554             break;
12555           }
12556         default:
12557           break;
12558         }
12559     }
12560   args.release ();
12561   return clone_info;
12562 }
12563
12564 /* Given a SIMD clone in NODE, calculate the characteristic data
12565    type and return the coresponding type.  The characteristic data
12566    type is computed as described in the Intel Vector ABI.  */
12567
12568 static tree
12569 simd_clone_compute_base_data_type (struct cgraph_node *node,
12570                                    struct cgraph_simd_clone *clone_info)
12571 {
12572   tree type = integer_type_node;
12573   tree fndecl = node->decl;
12574
12575   /* a) For non-void function, the characteristic data type is the
12576         return type.  */
12577   if (TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE)
12578     type = TREE_TYPE (TREE_TYPE (fndecl));
12579
12580   /* b) If the function has any non-uniform, non-linear parameters,
12581         then the characteristic data type is the type of the first
12582         such parameter.  */
12583   else
12584     {
12585       vec<tree> map = simd_clone_vector_of_formal_parm_types (fndecl);
12586       for (unsigned int i = 0; i < clone_info->nargs; ++i)
12587         if (clone_info->args[i].arg_type == SIMD_CLONE_ARG_TYPE_VECTOR)
12588           {
12589             type = map[i];
12590             break;
12591           }
12592       map.release ();
12593     }
12594
12595   /* c) If the characteristic data type determined by a) or b) above
12596         is struct, union, or class type which is pass-by-value (except
12597         for the type that maps to the built-in complex data type), the
12598         characteristic data type is int.  */
12599   if (RECORD_OR_UNION_TYPE_P (type)
12600       && !aggregate_value_p (type, NULL)
12601       && TREE_CODE (type) != COMPLEX_TYPE)
12602     return integer_type_node;
12603
12604   /* d) If none of the above three classes is applicable, the
12605         characteristic data type is int.  */
12606
12607   return type;
12608
12609   /* e) For Intel Xeon Phi native and offload compilation, if the
12610         resulting characteristic data type is 8-bit or 16-bit integer
12611         data type, the characteristic data type is int.  */
12612   /* Well, we don't handle Xeon Phi yet.  */
12613 }
12614
12615 static tree
12616 simd_clone_mangle (struct cgraph_node *node,
12617                    struct cgraph_simd_clone *clone_info)
12618 {
12619   char vecsize_mangle = clone_info->vecsize_mangle;
12620   char mask = clone_info->inbranch ? 'M' : 'N';
12621   unsigned int simdlen = clone_info->simdlen;
12622   unsigned int n;
12623   pretty_printer pp;
12624
12625   gcc_assert (vecsize_mangle && simdlen);
12626
12627   pp_string (&pp, "_ZGV");
12628   pp_character (&pp, vecsize_mangle);
12629   pp_character (&pp, mask);
12630   pp_decimal_int (&pp, simdlen);
12631
12632   for (n = 0; n < clone_info->nargs; ++n)
12633     {
12634       struct cgraph_simd_clone_arg arg = clone_info->args[n];
12635
12636       if (arg.arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM)
12637         pp_character (&pp, 'u');
12638       else if (arg.arg_type == SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP)
12639         {
12640           gcc_assert (arg.linear_step != 0);
12641           pp_character (&pp, 'l');
12642           if (arg.linear_step > 1)
12643             pp_unsigned_wide_integer (&pp, arg.linear_step);
12644           else if (arg.linear_step < 0)
12645             {
12646               pp_character (&pp, 'n');
12647               pp_unsigned_wide_integer (&pp, (-(unsigned HOST_WIDE_INT)
12648                                               arg.linear_step));
12649             }
12650         }
12651       else if (arg.arg_type == SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP)
12652         {
12653           pp_character (&pp, 's');
12654           pp_unsigned_wide_integer (&pp, arg.linear_step);
12655         }
12656       else
12657         pp_character (&pp, 'v');
12658       if (arg.alignment)
12659         {
12660           pp_character (&pp, 'a');
12661           pp_decimal_int (&pp, arg.alignment);
12662         }
12663     }
12664
12665   pp_underscore (&pp);
12666   const char *str = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl));
12667   if (*str == '*')
12668     ++str;
12669   pp_string (&pp, str);
12670   str = pp_formatted_text (&pp);
12671
12672   /* If there already is a SIMD clone with the same mangled name, don't
12673      add another one.  This can happen e.g. for
12674      #pragma omp declare simd
12675      #pragma omp declare simd simdlen(8)
12676      int foo (int, int);
12677      if the simdlen is assumed to be 8 for the first one, etc.  */
12678   for (struct cgraph_node *clone = node->simd_clones; clone;
12679        clone = clone->simdclone->next_clone)
12680     if (strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (clone->decl)),
12681                 str) == 0)
12682       return NULL_TREE;
12683
12684   return get_identifier (str);
12685 }
12686
12687 /* Create a simd clone of OLD_NODE and return it.  */
12688
12689 static struct cgraph_node *
12690 simd_clone_create (struct cgraph_node *old_node)
12691 {
12692   struct cgraph_node *new_node;
12693   if (old_node->definition)
12694     {
12695       if (!old_node->has_gimple_body_p ())
12696         return NULL;
12697       old_node->get_body ();
12698       new_node = old_node->create_version_clone_with_body (vNULL, NULL, NULL,
12699                                                            false, NULL, NULL,
12700                                                            "simdclone");
12701     }
12702   else
12703     {
12704       tree old_decl = old_node->decl;
12705       tree new_decl = copy_node (old_node->decl);
12706       DECL_NAME (new_decl) = clone_function_name (old_decl, "simdclone");
12707       SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
12708       SET_DECL_RTL (new_decl, NULL);
12709       DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
12710       DECL_STATIC_DESTRUCTOR (new_decl) = 0;
12711       new_node = old_node->create_version_clone (new_decl, vNULL, NULL);
12712       symtab->call_cgraph_insertion_hooks (new_node);
12713     }
12714   if (new_node == NULL)
12715     return new_node;
12716
12717   TREE_PUBLIC (new_node->decl) = TREE_PUBLIC (old_node->decl);
12718
12719   /* The function cgraph_function_versioning () will force the new
12720      symbol local.  Undo this, and inherit external visability from
12721      the old node.  */
12722   new_node->local.local = old_node->local.local;
12723   new_node->externally_visible = old_node->externally_visible;
12724
12725   return new_node;
12726 }
12727
12728 /* Adjust the return type of the given function to its appropriate
12729    vector counterpart.  Returns a simd array to be used throughout the
12730    function as a return value.  */
12731
12732 static tree
12733 simd_clone_adjust_return_type (struct cgraph_node *node)
12734 {
12735   tree fndecl = node->decl;
12736   tree orig_rettype = TREE_TYPE (TREE_TYPE (fndecl));
12737   unsigned int veclen;
12738   tree t;
12739
12740   /* Adjust the function return type.  */
12741   if (orig_rettype == void_type_node)
12742     return NULL_TREE;
12743   TREE_TYPE (fndecl) = build_distinct_type_copy (TREE_TYPE (fndecl));
12744   t = TREE_TYPE (TREE_TYPE (fndecl));
12745   if (INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
12746     veclen = node->simdclone->vecsize_int;
12747   else
12748     veclen = node->simdclone->vecsize_float;
12749   veclen /= GET_MODE_BITSIZE (TYPE_MODE (t));
12750   if (veclen > node->simdclone->simdlen)
12751     veclen = node->simdclone->simdlen;
12752   if (POINTER_TYPE_P (t))
12753     t = pointer_sized_int_node;
12754   if (veclen == node->simdclone->simdlen)
12755     t = build_vector_type (t, node->simdclone->simdlen);
12756   else
12757     {
12758       t = build_vector_type (t, veclen);
12759       t = build_array_type_nelts (t, node->simdclone->simdlen / veclen);
12760     }
12761   TREE_TYPE (TREE_TYPE (fndecl)) = t;
12762   if (!node->definition)
12763     return NULL_TREE;
12764
12765   t = DECL_RESULT (fndecl);
12766   /* Adjust the DECL_RESULT.  */
12767   gcc_assert (TREE_TYPE (t) != void_type_node);
12768   TREE_TYPE (t) = TREE_TYPE (TREE_TYPE (fndecl));
12769   relayout_decl (t);
12770
12771   tree atype = build_array_type_nelts (orig_rettype,
12772                                        node->simdclone->simdlen);
12773   if (veclen != node->simdclone->simdlen)
12774     return build1 (VIEW_CONVERT_EXPR, atype, t);
12775
12776   /* Set up a SIMD array to use as the return value.  */
12777   tree retval = create_tmp_var_raw (atype, "retval");
12778   gimple_add_tmp_var (retval);
12779   return retval;
12780 }
12781
12782 /* Each vector argument has a corresponding array to be used locally
12783    as part of the eventual loop.  Create such temporary array and
12784    return it.
12785
12786    PREFIX is the prefix to be used for the temporary.
12787
12788    TYPE is the inner element type.
12789
12790    SIMDLEN is the number of elements.  */
12791
12792 static tree
12793 create_tmp_simd_array (const char *prefix, tree type, int simdlen)
12794 {
12795   tree atype = build_array_type_nelts (type, simdlen);
12796   tree avar = create_tmp_var_raw (atype, prefix);
12797   gimple_add_tmp_var (avar);
12798   return avar;
12799 }
12800
12801 /* Modify the function argument types to their corresponding vector
12802    counterparts if appropriate.  Also, create one array for each simd
12803    argument to be used locally when using the function arguments as
12804    part of the loop.
12805
12806    NODE is the function whose arguments are to be adjusted.
12807
12808    Returns an adjustment vector that will be filled describing how the
12809    argument types will be adjusted.  */
12810
12811 static ipa_parm_adjustment_vec
12812 simd_clone_adjust_argument_types (struct cgraph_node *node)
12813 {
12814   vec<tree> args;
12815   ipa_parm_adjustment_vec adjustments;
12816
12817   if (node->definition)
12818     args = ipa_get_vector_of_formal_parms (node->decl);
12819   else
12820     args = simd_clone_vector_of_formal_parm_types (node->decl);
12821   adjustments.create (args.length ());
12822   unsigned i, j, veclen;
12823   struct ipa_parm_adjustment adj;
12824   for (i = 0; i < node->simdclone->nargs; ++i)
12825     {
12826       memset (&adj, 0, sizeof (adj));
12827       tree parm = args[i];
12828       tree parm_type = node->definition ? TREE_TYPE (parm) : parm;
12829       adj.base_index = i;
12830       adj.base = parm;
12831
12832       node->simdclone->args[i].orig_arg = node->definition ? parm : NULL_TREE;
12833       node->simdclone->args[i].orig_type = parm_type;
12834
12835       if (node->simdclone->args[i].arg_type != SIMD_CLONE_ARG_TYPE_VECTOR)
12836         {
12837           /* No adjustment necessary for scalar arguments.  */
12838           adj.op = IPA_PARM_OP_COPY;
12839         }
12840       else
12841         {
12842           if (INTEGRAL_TYPE_P (parm_type) || POINTER_TYPE_P (parm_type))
12843             veclen = node->simdclone->vecsize_int;
12844           else
12845             veclen = node->simdclone->vecsize_float;
12846           veclen /= GET_MODE_BITSIZE (TYPE_MODE (parm_type));
12847           if (veclen > node->simdclone->simdlen)
12848             veclen = node->simdclone->simdlen;
12849           adj.arg_prefix = "simd";
12850           if (POINTER_TYPE_P (parm_type))
12851             adj.type = build_vector_type (pointer_sized_int_node, veclen);
12852           else
12853             adj.type = build_vector_type (parm_type, veclen);
12854           node->simdclone->args[i].vector_type = adj.type;
12855           for (j = veclen; j < node->simdclone->simdlen; j += veclen)
12856             {
12857               adjustments.safe_push (adj);
12858               if (j == veclen)
12859                 {
12860                   memset (&adj, 0, sizeof (adj));
12861                   adj.op = IPA_PARM_OP_NEW;
12862                   adj.arg_prefix = "simd";
12863                   adj.base_index = i;
12864                   adj.type = node->simdclone->args[i].vector_type;
12865                 }
12866             }
12867
12868           if (node->definition)
12869             node->simdclone->args[i].simd_array
12870               = create_tmp_simd_array (IDENTIFIER_POINTER (DECL_NAME (parm)),
12871                                        parm_type, node->simdclone->simdlen);
12872         }
12873       adjustments.safe_push (adj);
12874     }
12875
12876   if (node->simdclone->inbranch)
12877     {
12878       tree base_type
12879         = simd_clone_compute_base_data_type (node->simdclone->origin,
12880                                              node->simdclone);
12881
12882       memset (&adj, 0, sizeof (adj));
12883       adj.op = IPA_PARM_OP_NEW;
12884       adj.arg_prefix = "mask";
12885
12886       adj.base_index = i;
12887       if (INTEGRAL_TYPE_P (base_type) || POINTER_TYPE_P (base_type))
12888         veclen = node->simdclone->vecsize_int;
12889       else
12890         veclen = node->simdclone->vecsize_float;
12891       veclen /= GET_MODE_BITSIZE (TYPE_MODE (base_type));
12892       if (veclen > node->simdclone->simdlen)
12893         veclen = node->simdclone->simdlen;
12894       if (POINTER_TYPE_P (base_type))
12895         adj.type = build_vector_type (pointer_sized_int_node, veclen);
12896       else
12897         adj.type = build_vector_type (base_type, veclen);
12898       adjustments.safe_push (adj);
12899
12900       for (j = veclen; j < node->simdclone->simdlen; j += veclen)
12901         adjustments.safe_push (adj);
12902
12903       /* We have previously allocated one extra entry for the mask.  Use
12904          it and fill it.  */
12905       struct cgraph_simd_clone *sc = node->simdclone;
12906       sc->nargs++;
12907       if (node->definition)
12908         {
12909           sc->args[i].orig_arg
12910             = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL, base_type);
12911           sc->args[i].simd_array
12912             = create_tmp_simd_array ("mask", base_type, sc->simdlen);
12913         }
12914       sc->args[i].orig_type = base_type;
12915       sc->args[i].arg_type = SIMD_CLONE_ARG_TYPE_MASK;
12916     }
12917
12918   if (node->definition)
12919     ipa_modify_formal_parameters (node->decl, adjustments);
12920   else
12921     {
12922       tree new_arg_types = NULL_TREE, new_reversed;
12923       bool last_parm_void = false;
12924       if (args.length () > 0 && args.last () == void_type_node)
12925         last_parm_void = true;
12926
12927       gcc_assert (TYPE_ARG_TYPES (TREE_TYPE (node->decl)));
12928       j = adjustments.length ();
12929       for (i = 0; i < j; i++)
12930         {
12931           struct ipa_parm_adjustment *adj = &adjustments[i];
12932           tree ptype;
12933           if (adj->op == IPA_PARM_OP_COPY)
12934             ptype = args[adj->base_index];
12935           else
12936             ptype = adj->type;
12937           new_arg_types = tree_cons (NULL_TREE, ptype, new_arg_types);
12938         }
12939       new_reversed = nreverse (new_arg_types);
12940       if (last_parm_void)
12941         {
12942           if (new_reversed)
12943             TREE_CHAIN (new_arg_types) = void_list_node;
12944           else
12945             new_reversed = void_list_node;
12946         }
12947
12948       tree new_type = build_distinct_type_copy (TREE_TYPE (node->decl));
12949       TYPE_ARG_TYPES (new_type) = new_reversed;
12950       TREE_TYPE (node->decl) = new_type;
12951
12952       adjustments.release ();
12953     }
12954   args.release ();
12955   return adjustments;
12956 }
12957
12958 /* Initialize and copy the function arguments in NODE to their
12959    corresponding local simd arrays.  Returns a fresh gimple_seq with
12960    the instruction sequence generated.  */
12961
12962 static gimple_seq
12963 simd_clone_init_simd_arrays (struct cgraph_node *node,
12964                              ipa_parm_adjustment_vec adjustments)
12965 {
12966   gimple_seq seq = NULL;
12967   unsigned i = 0, j = 0, k;
12968
12969   for (tree arg = DECL_ARGUMENTS (node->decl);
12970        arg;
12971        arg = DECL_CHAIN (arg), i++, j++)
12972     {
12973       if (adjustments[j].op == IPA_PARM_OP_COPY)
12974         continue;
12975
12976       node->simdclone->args[i].vector_arg = arg;
12977
12978       tree array = node->simdclone->args[i].simd_array;
12979       if (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg)) == node->simdclone->simdlen)
12980         {
12981           tree ptype = build_pointer_type (TREE_TYPE (TREE_TYPE (array)));
12982           tree ptr = build_fold_addr_expr (array);
12983           tree t = build2 (MEM_REF, TREE_TYPE (arg), ptr,
12984                            build_int_cst (ptype, 0));
12985           t = build2 (MODIFY_EXPR, TREE_TYPE (t), t, arg);
12986           gimplify_and_add (t, &seq);
12987         }
12988       else
12989         {
12990           unsigned int simdlen = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg));
12991           tree ptype = build_pointer_type (TREE_TYPE (TREE_TYPE (array)));
12992           for (k = 0; k < node->simdclone->simdlen; k += simdlen)
12993             {
12994               tree ptr = build_fold_addr_expr (array);
12995               int elemsize;
12996               if (k)
12997                 {
12998                   arg = DECL_CHAIN (arg);
12999                   j++;
13000                 }
13001               elemsize
13002                 = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))));
13003               tree t = build2 (MEM_REF, TREE_TYPE (arg), ptr,
13004                                build_int_cst (ptype, k * elemsize));
13005               t = build2 (MODIFY_EXPR, TREE_TYPE (t), t, arg);
13006               gimplify_and_add (t, &seq);
13007             }
13008         }
13009     }
13010   return seq;
13011 }
13012
13013 /* Callback info for ipa_simd_modify_stmt_ops below.  */
13014
13015 struct modify_stmt_info {
13016   ipa_parm_adjustment_vec adjustments;
13017   gimple stmt;
13018   /* True if the parent statement was modified by
13019      ipa_simd_modify_stmt_ops.  */
13020   bool modified;
13021 };
13022
13023 /* Callback for walk_gimple_op.
13024
13025    Adjust operands from a given statement as specified in the
13026    adjustments vector in the callback data.  */
13027
13028 static tree
13029 ipa_simd_modify_stmt_ops (tree *tp, int *walk_subtrees, void *data)
13030 {
13031   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
13032   struct modify_stmt_info *info = (struct modify_stmt_info *) wi->info;
13033   tree *orig_tp = tp;
13034   if (TREE_CODE (*tp) == ADDR_EXPR)
13035     tp = &TREE_OPERAND (*tp, 0);
13036   struct ipa_parm_adjustment *cand = NULL;
13037   if (TREE_CODE (*tp) == PARM_DECL)
13038     cand = ipa_get_adjustment_candidate (&tp, NULL, info->adjustments, true);
13039   else
13040     {
13041       if (TYPE_P (*tp))
13042         *walk_subtrees = 0;
13043     }
13044
13045   tree repl = NULL_TREE;
13046   if (cand)
13047     repl = unshare_expr (cand->new_decl);
13048   else
13049     {
13050       if (tp != orig_tp)
13051         {
13052           *walk_subtrees = 0;
13053           bool modified = info->modified;
13054           info->modified = false;
13055           walk_tree (tp, ipa_simd_modify_stmt_ops, wi, wi->pset);
13056           if (!info->modified)
13057             {
13058               info->modified = modified;
13059               return NULL_TREE;
13060             }
13061           info->modified = modified;
13062           repl = *tp;
13063         }
13064       else
13065         return NULL_TREE;
13066     }
13067
13068   if (tp != orig_tp)
13069     {
13070       repl = build_fold_addr_expr (repl);
13071       gimple stmt;
13072       if (is_gimple_debug (info->stmt))
13073         {
13074           tree vexpr = make_node (DEBUG_EXPR_DECL);
13075           stmt = gimple_build_debug_source_bind (vexpr, repl, NULL);
13076           DECL_ARTIFICIAL (vexpr) = 1;
13077           TREE_TYPE (vexpr) = TREE_TYPE (repl);
13078           DECL_MODE (vexpr) = TYPE_MODE (TREE_TYPE (repl));
13079           repl = vexpr;
13080         }
13081       else
13082         {
13083           stmt = gimple_build_assign (make_ssa_name (TREE_TYPE (repl)), repl);
13084           repl = gimple_assign_lhs (stmt);
13085         }
13086       gimple_stmt_iterator gsi = gsi_for_stmt (info->stmt);
13087       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
13088       *orig_tp = repl;
13089     }
13090   else if (!useless_type_conversion_p (TREE_TYPE (*tp), TREE_TYPE (repl)))
13091     {
13092       tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*tp), repl);
13093       *tp = vce;
13094     }
13095   else
13096     *tp = repl;
13097
13098   info->modified = true;
13099   return NULL_TREE;
13100 }
13101
13102 /* Traverse the function body and perform all modifications as
13103    described in ADJUSTMENTS.  At function return, ADJUSTMENTS will be
13104    modified such that the replacement/reduction value will now be an
13105    offset into the corresponding simd_array.
13106
13107    This function will replace all function argument uses with their
13108    corresponding simd array elements, and ajust the return values
13109    accordingly.  */
13110
13111 static void
13112 ipa_simd_modify_function_body (struct cgraph_node *node,
13113                                ipa_parm_adjustment_vec adjustments,
13114                                tree retval_array, tree iter)
13115 {
13116   basic_block bb;
13117   unsigned int i, j, l;
13118
13119   /* Re-use the adjustments array, but this time use it to replace
13120      every function argument use to an offset into the corresponding
13121      simd_array.  */
13122   for (i = 0, j = 0; i < node->simdclone->nargs; ++i, ++j)
13123     {
13124       if (!node->simdclone->args[i].vector_arg)
13125         continue;
13126
13127       tree basetype = TREE_TYPE (node->simdclone->args[i].orig_arg);
13128       tree vectype = TREE_TYPE (node->simdclone->args[i].vector_arg);
13129       adjustments[j].new_decl
13130         = build4 (ARRAY_REF,
13131                   basetype,
13132                   node->simdclone->args[i].simd_array,
13133                   iter,
13134                   NULL_TREE, NULL_TREE);
13135       if (adjustments[j].op == IPA_PARM_OP_NONE
13136           && TYPE_VECTOR_SUBPARTS (vectype) < node->simdclone->simdlen)
13137         j += node->simdclone->simdlen / TYPE_VECTOR_SUBPARTS (vectype) - 1;
13138     }
13139
13140   l = adjustments.length ();
13141   for (i = 1; i < num_ssa_names; i++)
13142     {
13143       tree name = ssa_name (i);
13144       if (name
13145           && SSA_NAME_VAR (name)
13146           && TREE_CODE (SSA_NAME_VAR (name)) == PARM_DECL)
13147         {
13148           for (j = 0; j < l; j++)
13149             if (SSA_NAME_VAR (name) == adjustments[j].base
13150                 && adjustments[j].new_decl)
13151               {
13152                 tree base_var;
13153                 if (adjustments[j].new_ssa_base == NULL_TREE)
13154                   {
13155                     base_var
13156                       = copy_var_decl (adjustments[j].base,
13157                                        DECL_NAME (adjustments[j].base),
13158                                        TREE_TYPE (adjustments[j].base));
13159                     adjustments[j].new_ssa_base = base_var;
13160                   }
13161                 else
13162                   base_var = adjustments[j].new_ssa_base;
13163                 if (SSA_NAME_IS_DEFAULT_DEF (name))
13164                   {
13165                     bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
13166                     gimple_stmt_iterator gsi = gsi_after_labels (bb);
13167                     tree new_decl = unshare_expr (adjustments[j].new_decl);
13168                     set_ssa_default_def (cfun, adjustments[j].base, NULL_TREE);
13169                     SET_SSA_NAME_VAR_OR_IDENTIFIER (name, base_var);
13170                     SSA_NAME_IS_DEFAULT_DEF (name) = 0;
13171                     gimple stmt = gimple_build_assign (name, new_decl);
13172                     gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
13173                   }
13174                 else
13175                   SET_SSA_NAME_VAR_OR_IDENTIFIER (name, base_var);
13176               }
13177         }
13178     }
13179
13180   struct modify_stmt_info info;
13181   info.adjustments = adjustments;
13182
13183   FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
13184     {
13185       gimple_stmt_iterator gsi;
13186
13187       gsi = gsi_start_bb (bb);
13188       while (!gsi_end_p (gsi))
13189         {
13190           gimple stmt = gsi_stmt (gsi);
13191           info.stmt = stmt;
13192           struct walk_stmt_info wi;
13193
13194           memset (&wi, 0, sizeof (wi));
13195           info.modified = false;
13196           wi.info = &info;
13197           walk_gimple_op (stmt, ipa_simd_modify_stmt_ops, &wi);
13198
13199           if (greturn *return_stmt = dyn_cast <greturn *> (stmt))
13200             {
13201               tree retval = gimple_return_retval (return_stmt);
13202               if (!retval)
13203                 {
13204                   gsi_remove (&gsi, true);
13205                   continue;
13206                 }
13207
13208               /* Replace `return foo' with `retval_array[iter] = foo'.  */
13209               tree ref = build4 (ARRAY_REF, TREE_TYPE (retval),
13210                                  retval_array, iter, NULL, NULL);
13211               stmt = gimple_build_assign (ref, retval);
13212               gsi_replace (&gsi, stmt, true);
13213               info.modified = true;
13214             }
13215
13216           if (info.modified)
13217             {
13218               update_stmt (stmt);
13219               if (maybe_clean_eh_stmt (stmt))
13220                 gimple_purge_dead_eh_edges (gimple_bb (stmt));
13221             }
13222           gsi_next (&gsi);
13223         }
13224     }
13225 }
13226
13227 /* Adjust the argument types in NODE to their appropriate vector
13228    counterparts.  */
13229
13230 static void
13231 simd_clone_adjust (struct cgraph_node *node)
13232 {
13233   push_cfun (DECL_STRUCT_FUNCTION (node->decl));
13234
13235   targetm.simd_clone.adjust (node);
13236
13237   tree retval = simd_clone_adjust_return_type (node);
13238   ipa_parm_adjustment_vec adjustments
13239     = simd_clone_adjust_argument_types (node);
13240
13241   push_gimplify_context ();
13242
13243   gimple_seq seq = simd_clone_init_simd_arrays (node, adjustments);
13244
13245   /* Adjust all uses of vector arguments accordingly.  Adjust all
13246      return values accordingly.  */
13247   tree iter = create_tmp_var (unsigned_type_node, "iter");
13248   tree iter1 = make_ssa_name (iter);
13249   tree iter2 = make_ssa_name (iter);
13250   ipa_simd_modify_function_body (node, adjustments, retval, iter1);
13251
13252   /* Initialize the iteration variable.  */
13253   basic_block entry_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
13254   basic_block body_bb = split_block_after_labels (entry_bb)->dest;
13255   gimple_stmt_iterator gsi = gsi_after_labels (entry_bb);
13256   /* Insert the SIMD array and iv initialization at function
13257      entry.  */
13258   gsi_insert_seq_before (&gsi, seq, GSI_NEW_STMT);
13259
13260   pop_gimplify_context (NULL);
13261
13262   /* Create a new BB right before the original exit BB, to hold the
13263      iteration increment and the condition/branch.  */
13264   basic_block orig_exit = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), 0)->src;
13265   basic_block incr_bb = create_empty_bb (orig_exit);
13266   add_bb_to_loop (incr_bb, body_bb->loop_father);
13267   /* The succ of orig_exit was EXIT_BLOCK_PTR_FOR_FN (cfun), with an empty
13268      flag.  Set it now to be a FALLTHRU_EDGE.  */
13269   gcc_assert (EDGE_COUNT (orig_exit->succs) == 1);
13270   EDGE_SUCC (orig_exit, 0)->flags |= EDGE_FALLTHRU;
13271   for (unsigned i = 0;
13272        i < EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds); ++i)
13273     {
13274       edge e = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), i);
13275       redirect_edge_succ (e, incr_bb);
13276     }
13277   edge e = make_edge (incr_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
13278   e->probability = REG_BR_PROB_BASE;
13279   gsi = gsi_last_bb (incr_bb);
13280   gimple g = gimple_build_assign (iter2, PLUS_EXPR, iter1,
13281                                   build_int_cst (unsigned_type_node, 1));
13282   gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
13283
13284   /* Mostly annotate the loop for the vectorizer (the rest is done below).  */
13285   struct loop *loop = alloc_loop ();
13286   cfun->has_force_vectorize_loops = true;
13287   loop->safelen = node->simdclone->simdlen;
13288   loop->force_vectorize = true;
13289   loop->header = body_bb;
13290
13291   /* Branch around the body if the mask applies.  */
13292   if (node->simdclone->inbranch)
13293     {
13294       gimple_stmt_iterator gsi = gsi_last_bb (loop->header);
13295       tree mask_array
13296         = node->simdclone->args[node->simdclone->nargs - 1].simd_array;
13297       tree mask = make_ssa_name (TREE_TYPE (TREE_TYPE (mask_array)));
13298       tree aref = build4 (ARRAY_REF,
13299                           TREE_TYPE (TREE_TYPE (mask_array)),
13300                           mask_array, iter1,
13301                           NULL, NULL);
13302       g = gimple_build_assign (mask, aref);
13303       gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
13304       int bitsize = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (aref)));
13305       if (!INTEGRAL_TYPE_P (TREE_TYPE (aref)))
13306         {
13307           aref = build1 (VIEW_CONVERT_EXPR,
13308                          build_nonstandard_integer_type (bitsize, 0), mask);
13309           mask = make_ssa_name (TREE_TYPE (aref));
13310           g = gimple_build_assign (mask, aref);
13311           gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
13312         }
13313
13314       g = gimple_build_cond (EQ_EXPR, mask, build_zero_cst (TREE_TYPE (mask)),
13315                              NULL, NULL);
13316       gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
13317       make_edge (loop->header, incr_bb, EDGE_TRUE_VALUE);
13318       FALLTHRU_EDGE (loop->header)->flags = EDGE_FALSE_VALUE;
13319     }
13320
13321   /* Generate the condition.  */
13322   g = gimple_build_cond (LT_EXPR,
13323                          iter2,
13324                          build_int_cst (unsigned_type_node,
13325                                         node->simdclone->simdlen),
13326                          NULL, NULL);
13327   gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
13328   e = split_block (incr_bb, gsi_stmt (gsi));
13329   basic_block latch_bb = e->dest;
13330   basic_block new_exit_bb;
13331   new_exit_bb = split_block (latch_bb, NULL)->dest;
13332   loop->latch = latch_bb;
13333
13334   redirect_edge_succ (FALLTHRU_EDGE (latch_bb), body_bb);
13335
13336   make_edge (incr_bb, new_exit_bb, EDGE_FALSE_VALUE);
13337   /* The successor of incr_bb is already pointing to latch_bb; just
13338      change the flags.
13339      make_edge (incr_bb, latch_bb, EDGE_TRUE_VALUE);  */
13340   FALLTHRU_EDGE (incr_bb)->flags = EDGE_TRUE_VALUE;
13341
13342   gphi *phi = create_phi_node (iter1, body_bb);
13343   edge preheader_edge = find_edge (entry_bb, body_bb);
13344   edge latch_edge = single_succ_edge (latch_bb);
13345   add_phi_arg (phi, build_zero_cst (unsigned_type_node), preheader_edge,
13346                UNKNOWN_LOCATION);
13347   add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
13348
13349   /* Generate the new return.  */
13350   gsi = gsi_last_bb (new_exit_bb);
13351   if (retval
13352       && TREE_CODE (retval) == VIEW_CONVERT_EXPR
13353       && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
13354     retval = TREE_OPERAND (retval, 0);
13355   else if (retval)
13356     {
13357       retval = build1 (VIEW_CONVERT_EXPR,
13358                        TREE_TYPE (TREE_TYPE (node->decl)),
13359                        retval);
13360       retval = force_gimple_operand_gsi (&gsi, retval, true, NULL,
13361                                          false, GSI_CONTINUE_LINKING);
13362     }
13363   g = gimple_build_return (retval);
13364   gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
13365
13366   /* Handle aligned clauses by replacing default defs of the aligned
13367      uniform args with __builtin_assume_aligned (arg_N(D), alignment)
13368      lhs.  Handle linear by adding PHIs.  */
13369   for (unsigned i = 0; i < node->simdclone->nargs; i++)
13370     if (node->simdclone->args[i].alignment
13371         && node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM
13372         && (node->simdclone->args[i].alignment
13373             & (node->simdclone->args[i].alignment - 1)) == 0
13374         && TREE_CODE (TREE_TYPE (node->simdclone->args[i].orig_arg))
13375            == POINTER_TYPE)
13376       {
13377         unsigned int alignment = node->simdclone->args[i].alignment;
13378         tree orig_arg = node->simdclone->args[i].orig_arg;
13379         tree def = ssa_default_def (cfun, orig_arg);
13380         if (def && !has_zero_uses (def))
13381           {
13382             tree fn = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
13383             gimple_seq seq = NULL;
13384             bool need_cvt = false;
13385             gcall *call
13386               = gimple_build_call (fn, 2, def, size_int (alignment));
13387             g = call;
13388             if (!useless_type_conversion_p (TREE_TYPE (orig_arg),
13389                                             ptr_type_node))
13390               need_cvt = true;
13391             tree t = make_ssa_name (need_cvt ? ptr_type_node : orig_arg);
13392             gimple_call_set_lhs (g, t);
13393             gimple_seq_add_stmt_without_update (&seq, g);
13394             if (need_cvt)
13395               {
13396                 t = make_ssa_name (orig_arg);
13397                 g = gimple_build_assign (t, NOP_EXPR, gimple_call_lhs (g));
13398                 gimple_seq_add_stmt_without_update (&seq, g);
13399               }
13400             gsi_insert_seq_on_edge_immediate
13401               (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
13402
13403             entry_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
13404             int freq = compute_call_stmt_bb_frequency (current_function_decl,
13405                                                        entry_bb);
13406             node->create_edge (cgraph_node::get_create (fn),
13407                                call, entry_bb->count, freq);
13408
13409             imm_use_iterator iter;
13410             use_operand_p use_p;
13411             gimple use_stmt;
13412             tree repl = gimple_get_lhs (g);
13413             FOR_EACH_IMM_USE_STMT (use_stmt, iter, def)
13414               if (is_gimple_debug (use_stmt) || use_stmt == call)
13415                 continue;
13416               else
13417                 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
13418                   SET_USE (use_p, repl);
13419           }
13420       }
13421     else if (node->simdclone->args[i].arg_type
13422              == SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP)
13423       {
13424         tree orig_arg = node->simdclone->args[i].orig_arg;
13425         tree def = ssa_default_def (cfun, orig_arg);
13426         gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
13427                     || POINTER_TYPE_P (TREE_TYPE (orig_arg)));
13428         if (def && !has_zero_uses (def))
13429           {
13430             iter1 = make_ssa_name (orig_arg);
13431             iter2 = make_ssa_name (orig_arg);
13432             phi = create_phi_node (iter1, body_bb);
13433             add_phi_arg (phi, def, preheader_edge, UNKNOWN_LOCATION);
13434             add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
13435             enum tree_code code = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
13436                                   ? PLUS_EXPR : POINTER_PLUS_EXPR;
13437             tree addtype = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
13438                            ? TREE_TYPE (orig_arg) : sizetype;
13439             tree addcst
13440               = build_int_cst (addtype, node->simdclone->args[i].linear_step);
13441             g = gimple_build_assign (iter2, code, iter1, addcst);
13442             gsi = gsi_last_bb (incr_bb);
13443             gsi_insert_before (&gsi, g, GSI_SAME_STMT);
13444
13445             imm_use_iterator iter;
13446             use_operand_p use_p;
13447             gimple use_stmt;
13448             FOR_EACH_IMM_USE_STMT (use_stmt, iter, def)
13449               if (use_stmt == phi)
13450                 continue;
13451               else
13452                 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
13453                   SET_USE (use_p, iter1);
13454           }
13455       }
13456
13457   calculate_dominance_info (CDI_DOMINATORS);
13458   add_loop (loop, loop->header->loop_father);
13459   update_ssa (TODO_update_ssa);
13460
13461   pop_cfun ();
13462 }
13463
13464 /* If the function in NODE is tagged as an elemental SIMD function,
13465    create the appropriate SIMD clones.  */
13466
13467 static void
13468 expand_simd_clones (struct cgraph_node *node)
13469 {
13470   tree attr = lookup_attribute ("omp declare simd",
13471                                 DECL_ATTRIBUTES (node->decl));
13472   if (attr == NULL_TREE
13473       || node->global.inlined_to
13474       || lookup_attribute ("noclone", DECL_ATTRIBUTES (node->decl)))
13475     return;
13476
13477   /* Ignore
13478      #pragma omp declare simd
13479      extern int foo ();
13480      in C, there we don't know the argument types at all.  */
13481   if (!node->definition
13482       && TYPE_ARG_TYPES (TREE_TYPE (node->decl)) == NULL_TREE)
13483     return;
13484
13485   do
13486     {
13487       /* Start with parsing the "omp declare simd" attribute(s).  */
13488       bool inbranch_clause_specified;
13489       struct cgraph_simd_clone *clone_info
13490         = simd_clone_clauses_extract (node, TREE_VALUE (attr),
13491                                       &inbranch_clause_specified);
13492       if (clone_info == NULL)
13493         continue;
13494
13495       int orig_simdlen = clone_info->simdlen;
13496       tree base_type = simd_clone_compute_base_data_type (node, clone_info);
13497       /* The target can return 0 (no simd clones should be created),
13498          1 (just one ISA of simd clones should be created) or higher
13499          count of ISA variants.  In that case, clone_info is initialized
13500          for the first ISA variant.  */
13501       int count
13502         = targetm.simd_clone.compute_vecsize_and_simdlen (node, clone_info,
13503                                                           base_type, 0);
13504       if (count == 0)
13505         continue;
13506
13507       /* Loop over all COUNT ISA variants, and if !INBRANCH_CLAUSE_SPECIFIED,
13508          also create one inbranch and one !inbranch clone of it.  */
13509       for (int i = 0; i < count * 2; i++)
13510         {
13511           struct cgraph_simd_clone *clone = clone_info;
13512           if (inbranch_clause_specified && (i & 1) != 0)
13513             continue;
13514
13515           if (i != 0)
13516             {
13517               clone = simd_clone_struct_alloc (clone_info->nargs
13518                                                + ((i & 1) != 0));
13519               simd_clone_struct_copy (clone, clone_info);
13520               /* Undo changes targetm.simd_clone.compute_vecsize_and_simdlen
13521                  and simd_clone_adjust_argument_types did to the first
13522                  clone's info.  */
13523               clone->nargs -= clone_info->inbranch;
13524               clone->simdlen = orig_simdlen;
13525               /* And call the target hook again to get the right ISA.  */
13526               targetm.simd_clone.compute_vecsize_and_simdlen (node, clone,
13527                                                               base_type,
13528                                                               i / 2);
13529               if ((i & 1) != 0)
13530                 clone->inbranch = 1;
13531             }
13532
13533           /* simd_clone_mangle might fail if such a clone has been created
13534              already.  */
13535           tree id = simd_clone_mangle (node, clone);
13536           if (id == NULL_TREE)
13537             continue;
13538
13539           /* Only when we are sure we want to create the clone actually
13540              clone the function (or definitions) or create another
13541              extern FUNCTION_DECL (for prototypes without definitions).  */
13542           struct cgraph_node *n = simd_clone_create (node);
13543           if (n == NULL)
13544             continue;
13545
13546           n->simdclone = clone;
13547           clone->origin = node;
13548           clone->next_clone = NULL;
13549           if (node->simd_clones == NULL)
13550             {
13551               clone->prev_clone = n;
13552               node->simd_clones = n;
13553             }
13554           else
13555             {
13556               clone->prev_clone = node->simd_clones->simdclone->prev_clone;
13557               clone->prev_clone->simdclone->next_clone = n;
13558               node->simd_clones->simdclone->prev_clone = n;
13559             }
13560           symtab->change_decl_assembler_name (n->decl, id);
13561           /* And finally adjust the return type, parameters and for
13562              definitions also function body.  */
13563           if (node->definition)
13564             simd_clone_adjust (n);
13565           else
13566             {
13567               simd_clone_adjust_return_type (n);
13568               simd_clone_adjust_argument_types (n);
13569             }
13570         }
13571     }
13572   while ((attr = lookup_attribute ("omp declare simd", TREE_CHAIN (attr))));
13573 }
13574
13575 /* Entry point for IPA simd clone creation pass.  */
13576
13577 static unsigned int
13578 ipa_omp_simd_clone (void)
13579 {
13580   struct cgraph_node *node;
13581   FOR_EACH_FUNCTION (node)
13582     expand_simd_clones (node);
13583   return 0;
13584 }
13585
13586 namespace {
13587
13588 const pass_data pass_data_omp_simd_clone =
13589 {
13590   SIMPLE_IPA_PASS,              /* type */
13591   "simdclone",                  /* name */
13592   OPTGROUP_NONE,                /* optinfo_flags */
13593   TV_NONE,                      /* tv_id */
13594   ( PROP_ssa | PROP_cfg ),      /* properties_required */
13595   0,                            /* properties_provided */
13596   0,                            /* properties_destroyed */
13597   0,                            /* todo_flags_start */
13598   0,                            /* todo_flags_finish */
13599 };
13600
13601 class pass_omp_simd_clone : public simple_ipa_opt_pass
13602 {
13603 public:
13604   pass_omp_simd_clone(gcc::context *ctxt)
13605     : simple_ipa_opt_pass(pass_data_omp_simd_clone, ctxt)
13606   {}
13607
13608   /* opt_pass methods: */
13609   virtual bool gate (function *);
13610   virtual unsigned int execute (function *) { return ipa_omp_simd_clone (); }
13611 };
13612
13613 bool
13614 pass_omp_simd_clone::gate (function *)
13615 {
13616   return ((flag_openmp || flag_openmp_simd
13617            || flag_cilkplus
13618            || (in_lto_p && !flag_wpa))
13619           && (targetm.simd_clone.compute_vecsize_and_simdlen != NULL));
13620 }
13621
13622 } // anon namespace
13623
13624 simple_ipa_opt_pass *
13625 make_pass_omp_simd_clone (gcc::context *ctxt)
13626 {
13627   return new pass_omp_simd_clone (ctxt);
13628 }
13629
13630 /* Helper function for omp_finish_file routine.  Takes decls from V_DECLS and
13631    adds their addresses and sizes to constructor-vector V_CTOR.  */
13632 static void
13633 add_decls_addresses_to_decl_constructor (vec<tree, va_gc> *v_decls,
13634                                          vec<constructor_elt, va_gc> *v_ctor)
13635 {
13636   unsigned len = vec_safe_length (v_decls);
13637   for (unsigned i = 0; i < len; i++)
13638     {
13639       tree it = (*v_decls)[i];
13640       bool is_function = TREE_CODE (it) != VAR_DECL;
13641
13642       CONSTRUCTOR_APPEND_ELT (v_ctor, NULL_TREE, build_fold_addr_expr (it));
13643       if (!is_function)
13644         CONSTRUCTOR_APPEND_ELT (v_ctor, NULL_TREE,
13645                                 fold_convert (const_ptr_type_node,
13646                                               DECL_SIZE_UNIT (it)));
13647     }
13648 }
13649
13650 /* Create new symbols containing (address, size) pairs for global variables,
13651    marked with "omp declare target" attribute, as well as addresses for the
13652    functions, which are outlined offloading regions.  */
13653 void
13654 omp_finish_file (void)
13655 {
13656   unsigned num_funcs = vec_safe_length (offload_funcs);
13657   unsigned num_vars = vec_safe_length (offload_vars);
13658
13659   if (num_funcs == 0 && num_vars == 0)
13660     return;
13661
13662   if (targetm_common.have_named_sections)
13663     {
13664       vec<constructor_elt, va_gc> *v_f, *v_v;
13665       vec_alloc (v_f, num_funcs);
13666       vec_alloc (v_v, num_vars * 2);
13667
13668       add_decls_addresses_to_decl_constructor (offload_funcs, v_f);
13669       add_decls_addresses_to_decl_constructor (offload_vars, v_v);
13670
13671       tree vars_decl_type = build_array_type_nelts (pointer_sized_int_node,
13672                                                     num_vars * 2);
13673       tree funcs_decl_type = build_array_type_nelts (pointer_sized_int_node,
13674                                                      num_funcs);
13675       TYPE_ALIGN (vars_decl_type) = TYPE_ALIGN (pointer_sized_int_node);
13676       TYPE_ALIGN (funcs_decl_type) = TYPE_ALIGN (pointer_sized_int_node);
13677       tree ctor_v = build_constructor (vars_decl_type, v_v);
13678       tree ctor_f = build_constructor (funcs_decl_type, v_f);
13679       TREE_CONSTANT (ctor_v) = TREE_CONSTANT (ctor_f) = 1;
13680       TREE_STATIC (ctor_v) = TREE_STATIC (ctor_f) = 1;
13681       tree funcs_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
13682                                     get_identifier (".offload_func_table"),
13683                                     funcs_decl_type);
13684       tree vars_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
13685                                    get_identifier (".offload_var_table"),
13686                                    vars_decl_type);
13687       TREE_STATIC (funcs_decl) = TREE_STATIC (vars_decl) = 1;
13688       /* Do not align tables more than TYPE_ALIGN (pointer_sized_int_node),
13689          otherwise a joint table in a binary will contain padding between
13690          tables from multiple object files.  */
13691       DECL_USER_ALIGN (funcs_decl) = DECL_USER_ALIGN (vars_decl) = 1;
13692       DECL_ALIGN (funcs_decl) = TYPE_ALIGN (funcs_decl_type);
13693       DECL_ALIGN (vars_decl) = TYPE_ALIGN (vars_decl_type);
13694       DECL_INITIAL (funcs_decl) = ctor_f;
13695       DECL_INITIAL (vars_decl) = ctor_v;
13696       set_decl_section_name (funcs_decl, OFFLOAD_FUNC_TABLE_SECTION_NAME);
13697       set_decl_section_name (vars_decl, OFFLOAD_VAR_TABLE_SECTION_NAME);
13698
13699       varpool_node::finalize_decl (vars_decl);
13700       varpool_node::finalize_decl (funcs_decl);
13701     }
13702   else
13703     {
13704       for (unsigned i = 0; i < num_funcs; i++)
13705         {
13706           tree it = (*offload_funcs)[i];
13707           targetm.record_offload_symbol (it);
13708         }
13709       for (unsigned i = 0; i < num_vars; i++)
13710         {
13711           tree it = (*offload_vars)[i];
13712           targetm.record_offload_symbol (it);
13713         }
13714     }
13715 }
13716
13717 #include "gt-omp-low.h"