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