OSDN Git Service

2012-12-15 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / omp-low.c
1 /* Lowering pass for OpenMP directives.  Converts OpenMP directives
2    into explicit calls to the runtime library (libgomp) and data
3    marshalling to implement data sharing and copying clauses.
4    Contributed by Diego Novillo <dnovillo@redhat.com>
5
6    Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
7    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 "tree.h"
30 #include "rtl.h"
31 #include "gimple.h"
32 #include "tree-iterator.h"
33 #include "tree-inline.h"
34 #include "langhooks.h"
35 #include "diagnostic-core.h"
36 #include "tree-flow.h"
37 #include "timevar.h"
38 #include "flags.h"
39 #include "function.h"
40 #include "expr.h"
41 #include "tree-pass.h"
42 #include "ggc.h"
43 #include "except.h"
44 #include "splay-tree.h"
45 #include "optabs.h"
46 #include "cfgloop.h"
47
48
49 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
50    phases.  The first phase scans the function looking for OMP statements
51    and then for variables that must be replaced to satisfy data sharing
52    clauses.  The second phase expands code for the constructs, as well as
53    re-gimplifying things when variables have been replaced with complex
54    expressions.
55
56    Final code generation is done by pass_expand_omp.  The flowgraph is
57    scanned for parallel regions which are then moved to a new
58    function, to be invoked by the thread library.  */
59
60 /* Context structure.  Used to store information about each parallel
61    directive in the code.  */
62
63 typedef struct omp_context
64 {
65   /* This field must be at the beginning, as we do "inheritance": Some
66      callback functions for tree-inline.c (e.g., omp_copy_decl)
67      receive a copy_body_data pointer that is up-casted to an
68      omp_context pointer.  */
69   copy_body_data cb;
70
71   /* The tree of contexts corresponding to the encountered constructs.  */
72   struct omp_context *outer;
73   gimple stmt;
74
75   /* Map variables to fields in a structure that allows communication
76      between sending and receiving threads.  */
77   splay_tree field_map;
78   tree record_type;
79   tree sender_decl;
80   tree receiver_decl;
81
82   /* These are used just by task contexts, if task firstprivate fn is
83      needed.  srecord_type is used to communicate from the thread
84      that encountered the task construct to task firstprivate fn,
85      record_type is allocated by GOMP_task, initialized by task firstprivate
86      fn and passed to the task body fn.  */
87   splay_tree sfield_map;
88   tree srecord_type;
89
90   /* A chain of variables to add to the top-level block surrounding the
91      construct.  In the case of a parallel, this is in the child function.  */
92   tree block_vars;
93
94   /* What to do with variables with implicitly determined sharing
95      attributes.  */
96   enum omp_clause_default_kind default_kind;
97
98   /* Nesting depth of this context.  Used to beautify error messages re
99      invalid gotos.  The outermost ctx is depth 1, with depth 0 being
100      reserved for the main body of the function.  */
101   int depth;
102
103   /* True if this parallel directive is nested within another.  */
104   bool is_nested;
105 } omp_context;
106
107
108 struct omp_for_data_loop
109 {
110   tree v, n1, n2, step;
111   enum tree_code cond_code;
112 };
113
114 /* A structure describing the main elements of a parallel loop.  */
115
116 struct omp_for_data
117 {
118   struct omp_for_data_loop loop;
119   tree chunk_size;
120   gimple for_stmt;
121   tree pre, iter_type;
122   int collapse;
123   bool have_nowait, have_ordered;
124   enum omp_clause_schedule_kind sched_kind;
125   struct omp_for_data_loop *loops;
126 };
127
128
129 static splay_tree all_contexts;
130 static int taskreg_nesting_level;
131 struct omp_region *root_omp_region;
132 static bitmap task_shared_vars;
133
134 static void scan_omp (gimple_seq, omp_context *);
135 static tree scan_omp_1_op (tree *, int *, void *);
136
137 #define WALK_SUBSTMTS  \
138     case GIMPLE_BIND: \
139     case GIMPLE_TRY: \
140     case GIMPLE_CATCH: \
141     case GIMPLE_EH_FILTER: \
142     case GIMPLE_TRANSACTION: \
143       /* The sub-statements for these should be walked.  */ \
144       *handled_ops_p = false; \
145       break;
146
147 /* Convenience function for calling scan_omp_1_op on tree operands.  */
148
149 static inline tree
150 scan_omp_op (tree *tp, omp_context *ctx)
151 {
152   struct walk_stmt_info wi;
153
154   memset (&wi, 0, sizeof (wi));
155   wi.info = ctx;
156   wi.want_locations = true;
157
158   return walk_tree (tp, scan_omp_1_op, &wi, NULL);
159 }
160
161 static void lower_omp (gimple_seq, omp_context *);
162 static tree lookup_decl_in_outer_ctx (tree, omp_context *);
163 static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
164
165 /* Find an OpenMP clause of type KIND within CLAUSES.  */
166
167 tree
168 find_omp_clause (tree clauses, enum omp_clause_code kind)
169 {
170   for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
171     if (OMP_CLAUSE_CODE (clauses) == kind)
172       return clauses;
173
174   return NULL_TREE;
175 }
176
177 /* Return true if CTX is for an omp parallel.  */
178
179 static inline bool
180 is_parallel_ctx (omp_context *ctx)
181 {
182   return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL;
183 }
184
185
186 /* Return true if CTX is for an omp task.  */
187
188 static inline bool
189 is_task_ctx (omp_context *ctx)
190 {
191   return gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
192 }
193
194
195 /* Return true if CTX is for an omp parallel or omp task.  */
196
197 static inline bool
198 is_taskreg_ctx (omp_context *ctx)
199 {
200   return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL
201          || gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
202 }
203
204
205 /* Return true if REGION is a combined parallel+workshare region.  */
206
207 static inline bool
208 is_combined_parallel (struct omp_region *region)
209 {
210   return region->is_combined_parallel;
211 }
212
213
214 /* Extract the header elements of parallel loop FOR_STMT and store
215    them into *FD.  */
216
217 static void
218 extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
219                       struct omp_for_data_loop *loops)
220 {
221   tree t, var, *collapse_iter, *collapse_count;
222   tree count = NULL_TREE, iter_type = long_integer_type_node;
223   struct omp_for_data_loop *loop;
224   int i;
225   struct omp_for_data_loop dummy_loop;
226   location_t loc = gimple_location (for_stmt);
227
228   fd->for_stmt = for_stmt;
229   fd->pre = NULL;
230   fd->collapse = gimple_omp_for_collapse (for_stmt);
231   if (fd->collapse > 1)
232     fd->loops = loops;
233   else
234     fd->loops = &fd->loop;
235
236   fd->have_nowait = fd->have_ordered = false;
237   fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
238   fd->chunk_size = NULL_TREE;
239   collapse_iter = NULL;
240   collapse_count = NULL;
241
242   for (t = gimple_omp_for_clauses (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
243     switch (OMP_CLAUSE_CODE (t))
244       {
245       case OMP_CLAUSE_NOWAIT:
246         fd->have_nowait = true;
247         break;
248       case OMP_CLAUSE_ORDERED:
249         fd->have_ordered = true;
250         break;
251       case OMP_CLAUSE_SCHEDULE:
252         fd->sched_kind = OMP_CLAUSE_SCHEDULE_KIND (t);
253         fd->chunk_size = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t);
254         break;
255       case OMP_CLAUSE_COLLAPSE:
256         if (fd->collapse > 1)
257           {
258             collapse_iter = &OMP_CLAUSE_COLLAPSE_ITERVAR (t);
259             collapse_count = &OMP_CLAUSE_COLLAPSE_COUNT (t);
260           }
261       default:
262         break;
263       }
264
265   /* FIXME: for now map schedule(auto) to schedule(static).
266      There should be analysis to determine whether all iterations
267      are approximately the same amount of work (then schedule(static)
268      is best) or if it varies (then schedule(dynamic,N) is better).  */
269   if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_AUTO)
270     {
271       fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
272       gcc_assert (fd->chunk_size == NULL);
273     }
274   gcc_assert (fd->collapse == 1 || collapse_iter != NULL);
275   if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
276     gcc_assert (fd->chunk_size == NULL);
277   else if (fd->chunk_size == NULL)
278     {
279       /* We only need to compute a default chunk size for ordered
280          static loops and dynamic loops.  */
281       if (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
282           || fd->have_ordered
283           || fd->collapse > 1)
284         fd->chunk_size = (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
285                          ? integer_zero_node : integer_one_node;
286     }
287
288   for (i = 0; i < fd->collapse; i++)
289     {
290       if (fd->collapse == 1)
291         loop = &fd->loop;
292       else if (loops != NULL)
293         loop = loops + i;
294       else
295         loop = &dummy_loop;
296
297
298       loop->v = gimple_omp_for_index (for_stmt, i);
299       gcc_assert (SSA_VAR_P (loop->v));
300       gcc_assert (TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
301                   || TREE_CODE (TREE_TYPE (loop->v)) == POINTER_TYPE);
302       var = TREE_CODE (loop->v) == SSA_NAME ? SSA_NAME_VAR (loop->v) : loop->v;
303       loop->n1 = gimple_omp_for_initial (for_stmt, i);
304
305       loop->cond_code = gimple_omp_for_cond (for_stmt, i);
306       loop->n2 = gimple_omp_for_final (for_stmt, i);
307       switch (loop->cond_code)
308         {
309         case LT_EXPR:
310         case GT_EXPR:
311           break;
312         case LE_EXPR:
313           if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
314             loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, 1);
315           else
316             loop->n2 = fold_build2_loc (loc,
317                                     PLUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
318                                     build_int_cst (TREE_TYPE (loop->n2), 1));
319           loop->cond_code = LT_EXPR;
320           break;
321         case GE_EXPR:
322           if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
323             loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, -1);
324           else
325             loop->n2 = fold_build2_loc (loc,
326                                     MINUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
327                                     build_int_cst (TREE_TYPE (loop->n2), 1));
328           loop->cond_code = GT_EXPR;
329           break;
330         default:
331           gcc_unreachable ();
332         }
333
334       t = gimple_omp_for_incr (for_stmt, i);
335       gcc_assert (TREE_OPERAND (t, 0) == var);
336       switch (TREE_CODE (t))
337         {
338         case PLUS_EXPR:
339         case POINTER_PLUS_EXPR:
340           loop->step = TREE_OPERAND (t, 1);
341           break;
342         case MINUS_EXPR:
343           loop->step = TREE_OPERAND (t, 1);
344           loop->step = fold_build1_loc (loc,
345                                     NEGATE_EXPR, TREE_TYPE (loop->step),
346                                     loop->step);
347           break;
348         default:
349           gcc_unreachable ();
350         }
351
352       if (iter_type != long_long_unsigned_type_node)
353         {
354           if (POINTER_TYPE_P (TREE_TYPE (loop->v)))
355             iter_type = long_long_unsigned_type_node;
356           else if (TYPE_UNSIGNED (TREE_TYPE (loop->v))
357                    && TYPE_PRECISION (TREE_TYPE (loop->v))
358                       >= TYPE_PRECISION (iter_type))
359             {
360               tree n;
361
362               if (loop->cond_code == LT_EXPR)
363                 n = fold_build2_loc (loc,
364                                  PLUS_EXPR, TREE_TYPE (loop->v),
365                                  loop->n2, loop->step);
366               else
367                 n = loop->n1;
368               if (TREE_CODE (n) != INTEGER_CST
369                   || tree_int_cst_lt (TYPE_MAX_VALUE (iter_type), n))
370                 iter_type = long_long_unsigned_type_node;
371             }
372           else if (TYPE_PRECISION (TREE_TYPE (loop->v))
373                    > TYPE_PRECISION (iter_type))
374             {
375               tree n1, n2;
376
377               if (loop->cond_code == LT_EXPR)
378                 {
379                   n1 = loop->n1;
380                   n2 = fold_build2_loc (loc,
381                                     PLUS_EXPR, TREE_TYPE (loop->v),
382                                     loop->n2, loop->step);
383                 }
384               else
385                 {
386                   n1 = fold_build2_loc (loc,
387                                     MINUS_EXPR, TREE_TYPE (loop->v),
388                                     loop->n2, loop->step);
389                   n2 = loop->n1;
390                 }
391               if (TREE_CODE (n1) != INTEGER_CST
392                   || TREE_CODE (n2) != INTEGER_CST
393                   || !tree_int_cst_lt (TYPE_MIN_VALUE (iter_type), n1)
394                   || !tree_int_cst_lt (n2, TYPE_MAX_VALUE (iter_type)))
395                 iter_type = long_long_unsigned_type_node;
396             }
397         }
398
399       if (collapse_count && *collapse_count == NULL)
400         {
401           if ((i == 0 || count != NULL_TREE)
402               && TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
403               && TREE_CONSTANT (loop->n1)
404               && TREE_CONSTANT (loop->n2)
405               && TREE_CODE (loop->step) == INTEGER_CST)
406             {
407               tree itype = TREE_TYPE (loop->v);
408
409               if (POINTER_TYPE_P (itype))
410                 itype
411                   = lang_hooks.types.type_for_size (TYPE_PRECISION (itype), 0);
412               t = build_int_cst (itype, (loop->cond_code == LT_EXPR ? -1 : 1));
413               t = fold_build2_loc (loc,
414                                PLUS_EXPR, itype,
415                                fold_convert_loc (loc, itype, loop->step), t);
416               t = fold_build2_loc (loc, PLUS_EXPR, itype, t,
417                                fold_convert_loc (loc, itype, loop->n2));
418               t = fold_build2_loc (loc, MINUS_EXPR, itype, t,
419                                fold_convert_loc (loc, itype, loop->n1));
420               if (TYPE_UNSIGNED (itype) && loop->cond_code == GT_EXPR)
421                 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
422                                  fold_build1_loc (loc, NEGATE_EXPR, itype, t),
423                                  fold_build1_loc (loc, NEGATE_EXPR, itype,
424                                               fold_convert_loc (loc, itype,
425                                                                 loop->step)));
426               else
427                 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
428                                  fold_convert_loc (loc, itype, loop->step));
429               t = fold_convert_loc (loc, long_long_unsigned_type_node, t);
430               if (count != NULL_TREE)
431                 count = fold_build2_loc (loc,
432                                      MULT_EXPR, long_long_unsigned_type_node,
433                                      count, t);
434               else
435                 count = t;
436               if (TREE_CODE (count) != INTEGER_CST)
437                 count = NULL_TREE;
438             }
439           else
440             count = NULL_TREE;
441         }
442     }
443
444   if (count)
445     {
446       if (!tree_int_cst_lt (count, TYPE_MAX_VALUE (long_integer_type_node)))
447         iter_type = long_long_unsigned_type_node;
448       else
449         iter_type = long_integer_type_node;
450     }
451   else if (collapse_iter && *collapse_iter != NULL)
452     iter_type = TREE_TYPE (*collapse_iter);
453   fd->iter_type = iter_type;
454   if (collapse_iter && *collapse_iter == NULL)
455     *collapse_iter = create_tmp_var (iter_type, ".iter");
456   if (collapse_count && *collapse_count == NULL)
457     {
458       if (count)
459         *collapse_count = fold_convert_loc (loc, iter_type, count);
460       else
461         *collapse_count = create_tmp_var (iter_type, ".count");
462     }
463
464   if (fd->collapse > 1)
465     {
466       fd->loop.v = *collapse_iter;
467       fd->loop.n1 = build_int_cst (TREE_TYPE (fd->loop.v), 0);
468       fd->loop.n2 = *collapse_count;
469       fd->loop.step = build_int_cst (TREE_TYPE (fd->loop.v), 1);
470       fd->loop.cond_code = LT_EXPR;
471     }
472 }
473
474
475 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
476    is the immediate dominator of PAR_ENTRY_BB, return true if there
477    are no data dependencies that would prevent expanding the parallel
478    directive at PAR_ENTRY_BB as a combined parallel+workshare region.
479
480    When expanding a combined parallel+workshare region, the call to
481    the child function may need additional arguments in the case of
482    GIMPLE_OMP_FOR regions.  In some cases, these arguments are
483    computed out of variables passed in from the parent to the child
484    via 'struct .omp_data_s'.  For instance:
485
486         #pragma omp parallel for schedule (guided, i * 4)
487         for (j ...)
488
489    Is lowered into:
490
491         # BLOCK 2 (PAR_ENTRY_BB)
492         .omp_data_o.i = i;
493         #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
494
495         # BLOCK 3 (WS_ENTRY_BB)
496         .omp_data_i = &.omp_data_o;
497         D.1667 = .omp_data_i->i;
498         D.1598 = D.1667 * 4;
499         #pragma omp for schedule (guided, D.1598)
500
501    When we outline the parallel region, the call to the child function
502    'bar.omp_fn.0' will need the value D.1598 in its argument list, but
503    that value is computed *after* the call site.  So, in principle we
504    cannot do the transformation.
505
506    To see whether the code in WS_ENTRY_BB blocks the combined
507    parallel+workshare call, we collect all the variables used in the
508    GIMPLE_OMP_FOR header check whether they appear on the LHS of any
509    statement in WS_ENTRY_BB.  If so, then we cannot emit the combined
510    call.
511
512    FIXME.  If we had the SSA form built at this point, we could merely
513    hoist the code in block 3 into block 2 and be done with it.  But at
514    this point we don't have dataflow information and though we could
515    hack something up here, it is really not worth the aggravation.  */
516
517 static bool
518 workshare_safe_to_combine_p (basic_block ws_entry_bb)
519 {
520   struct omp_for_data fd;
521   gimple ws_stmt = last_stmt (ws_entry_bb);
522
523   if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
524     return true;
525
526   gcc_assert (gimple_code (ws_stmt) == GIMPLE_OMP_FOR);
527
528   extract_omp_for_data (ws_stmt, &fd, NULL);
529
530   if (fd.collapse > 1 && TREE_CODE (fd.loop.n2) != INTEGER_CST)
531     return false;
532   if (fd.iter_type != long_integer_type_node)
533     return false;
534
535   /* FIXME.  We give up too easily here.  If any of these arguments
536      are not constants, they will likely involve variables that have
537      been mapped into fields of .omp_data_s for sharing with the child
538      function.  With appropriate data flow, it would be possible to
539      see through this.  */
540   if (!is_gimple_min_invariant (fd.loop.n1)
541       || !is_gimple_min_invariant (fd.loop.n2)
542       || !is_gimple_min_invariant (fd.loop.step)
543       || (fd.chunk_size && !is_gimple_min_invariant (fd.chunk_size)))
544     return false;
545
546   return true;
547 }
548
549
550 /* Collect additional arguments needed to emit a combined
551    parallel+workshare call.  WS_STMT is the workshare directive being
552    expanded.  */
553
554 static VEC(tree,gc) *
555 get_ws_args_for (gimple ws_stmt)
556 {
557   tree t;
558   location_t loc = gimple_location (ws_stmt);
559   VEC(tree,gc) *ws_args;
560
561   if (gimple_code (ws_stmt) == GIMPLE_OMP_FOR)
562     {
563       struct omp_for_data fd;
564
565       extract_omp_for_data (ws_stmt, &fd, NULL);
566
567       ws_args = VEC_alloc (tree, gc, 3 + (fd.chunk_size != 0));
568
569       t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n1);
570       VEC_quick_push (tree, ws_args, t);
571
572       t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n2);
573       VEC_quick_push (tree, ws_args, t);
574
575       t = fold_convert_loc (loc, long_integer_type_node, fd.loop.step);
576       VEC_quick_push (tree, ws_args, t);
577
578       if (fd.chunk_size)
579         {
580           t = fold_convert_loc (loc, long_integer_type_node, fd.chunk_size);
581           VEC_quick_push (tree, ws_args, t);
582         }
583
584       return ws_args;
585     }
586   else if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
587     {
588       /* Number of sections is equal to the number of edges from the
589          GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
590          the exit of the sections region.  */
591       basic_block bb = single_succ (gimple_bb (ws_stmt));
592       t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
593       ws_args = VEC_alloc (tree, gc, 1);
594       VEC_quick_push (tree, ws_args, t);
595       return ws_args;
596     }
597
598   gcc_unreachable ();
599 }
600
601
602 /* Discover whether REGION is a combined parallel+workshare region.  */
603
604 static void
605 determine_parallel_type (struct omp_region *region)
606 {
607   basic_block par_entry_bb, par_exit_bb;
608   basic_block ws_entry_bb, ws_exit_bb;
609
610   if (region == NULL || region->inner == NULL
611       || region->exit == NULL || region->inner->exit == NULL
612       || region->inner->cont == NULL)
613     return;
614
615   /* We only support parallel+for and parallel+sections.  */
616   if (region->type != GIMPLE_OMP_PARALLEL
617       || (region->inner->type != GIMPLE_OMP_FOR
618           && region->inner->type != GIMPLE_OMP_SECTIONS))
619     return;
620
621   /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
622      WS_EXIT_BB -> PAR_EXIT_BB.  */
623   par_entry_bb = region->entry;
624   par_exit_bb = region->exit;
625   ws_entry_bb = region->inner->entry;
626   ws_exit_bb = region->inner->exit;
627
628   if (single_succ (par_entry_bb) == ws_entry_bb
629       && single_succ (ws_exit_bb) == par_exit_bb
630       && workshare_safe_to_combine_p (ws_entry_bb)
631       && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb))
632           || (last_and_only_stmt (ws_entry_bb)
633               && last_and_only_stmt (par_exit_bb))))
634     {
635       gimple ws_stmt = last_stmt (ws_entry_bb);
636
637       if (region->inner->type == GIMPLE_OMP_FOR)
638         {
639           /* If this is a combined parallel loop, we need to determine
640              whether or not to use the combined library calls.  There
641              are two cases where we do not apply the transformation:
642              static loops and any kind of ordered loop.  In the first
643              case, we already open code the loop so there is no need
644              to do anything else.  In the latter case, the combined
645              parallel loop call would still need extra synchronization
646              to implement ordered semantics, so there would not be any
647              gain in using the combined call.  */
648           tree clauses = gimple_omp_for_clauses (ws_stmt);
649           tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
650           if (c == NULL
651               || OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_STATIC
652               || find_omp_clause (clauses, OMP_CLAUSE_ORDERED))
653             {
654               region->is_combined_parallel = false;
655               region->inner->is_combined_parallel = false;
656               return;
657             }
658         }
659
660       region->is_combined_parallel = true;
661       region->inner->is_combined_parallel = true;
662       region->ws_args = get_ws_args_for (ws_stmt);
663     }
664 }
665
666
667 /* Return true if EXPR is variable sized.  */
668
669 static inline bool
670 is_variable_sized (const_tree expr)
671 {
672   return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
673 }
674
675 /* Return true if DECL is a reference type.  */
676
677 static inline bool
678 is_reference (tree decl)
679 {
680   return lang_hooks.decls.omp_privatize_by_reference (decl);
681 }
682
683 /* Lookup variables in the decl or field splay trees.  The "maybe" form
684    allows for the variable form to not have been entered, otherwise we
685    assert that the variable must have been entered.  */
686
687 static inline tree
688 lookup_decl (tree var, omp_context *ctx)
689 {
690   tree *n;
691   n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
692   return *n;
693 }
694
695 static inline tree
696 maybe_lookup_decl (const_tree var, omp_context *ctx)
697 {
698   tree *n;
699   n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
700   return n ? *n : NULL_TREE;
701 }
702
703 static inline tree
704 lookup_field (tree var, omp_context *ctx)
705 {
706   splay_tree_node n;
707   n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
708   return (tree) n->value;
709 }
710
711 static inline tree
712 lookup_sfield (tree var, omp_context *ctx)
713 {
714   splay_tree_node n;
715   n = splay_tree_lookup (ctx->sfield_map
716                          ? ctx->sfield_map : ctx->field_map,
717                          (splay_tree_key) var);
718   return (tree) n->value;
719 }
720
721 static inline tree
722 maybe_lookup_field (tree var, omp_context *ctx)
723 {
724   splay_tree_node n;
725   n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
726   return n ? (tree) n->value : NULL_TREE;
727 }
728
729 /* Return true if DECL should be copied by pointer.  SHARED_CTX is
730    the parallel context if DECL is to be shared.  */
731
732 static bool
733 use_pointer_for_field (tree decl, omp_context *shared_ctx)
734 {
735   if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
736     return true;
737
738   /* We can only use copy-in/copy-out semantics for shared variables
739      when we know the value is not accessible from an outer scope.  */
740   if (shared_ctx)
741     {
742       /* ??? Trivially accessible from anywhere.  But why would we even
743          be passing an address in this case?  Should we simply assert
744          this to be false, or should we have a cleanup pass that removes
745          these from the list of mappings?  */
746       if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
747         return true;
748
749       /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
750          without analyzing the expression whether or not its location
751          is accessible to anyone else.  In the case of nested parallel
752          regions it certainly may be.  */
753       if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
754         return true;
755
756       /* Do not use copy-in/copy-out for variables that have their
757          address taken.  */
758       if (TREE_ADDRESSABLE (decl))
759         return true;
760
761       /* Disallow copy-in/out in nested parallel if
762          decl is shared in outer parallel, otherwise
763          each thread could store the shared variable
764          in its own copy-in location, making the
765          variable no longer really shared.  */
766       if (!TREE_READONLY (decl) && shared_ctx->is_nested)
767         {
768           omp_context *up;
769
770           for (up = shared_ctx->outer; up; up = up->outer)
771             if (is_taskreg_ctx (up) && maybe_lookup_decl (decl, up))
772               break;
773
774           if (up)
775             {
776               tree c;
777
778               for (c = gimple_omp_taskreg_clauses (up->stmt);
779                    c; c = OMP_CLAUSE_CHAIN (c))
780                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
781                     && OMP_CLAUSE_DECL (c) == decl)
782                   break;
783
784               if (c)
785                 goto maybe_mark_addressable_and_ret;
786             }
787         }
788
789       /* For tasks avoid using copy-in/out, unless they are readonly
790          (in which case just copy-in is used).  As tasks can be
791          deferred or executed in different thread, when GOMP_task
792          returns, the task hasn't necessarily terminated.  */
793       if (!TREE_READONLY (decl) && is_task_ctx (shared_ctx))
794         {
795           tree outer;
796         maybe_mark_addressable_and_ret:
797           outer = maybe_lookup_decl_in_outer_ctx (decl, shared_ctx);
798           if (is_gimple_reg (outer))
799             {
800               /* Taking address of OUTER in lower_send_shared_vars
801                  might need regimplification of everything that uses the
802                  variable.  */
803               if (!task_shared_vars)
804                 task_shared_vars = BITMAP_ALLOC (NULL);
805               bitmap_set_bit (task_shared_vars, DECL_UID (outer));
806               TREE_ADDRESSABLE (outer) = 1;
807             }
808           return true;
809         }
810     }
811
812   return false;
813 }
814
815 /* Create a new VAR_DECL and copy information from VAR to it.  */
816
817 tree
818 copy_var_decl (tree var, tree name, tree type)
819 {
820   tree copy = build_decl (DECL_SOURCE_LOCATION (var), VAR_DECL, name, type);
821
822   TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
823   TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (var);
824   DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
825   DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
826   DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
827   DECL_CONTEXT (copy) = DECL_CONTEXT (var);
828   TREE_USED (copy) = 1;
829   DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
830
831   return copy;
832 }
833
834 /* Construct a new automatic decl similar to VAR.  */
835
836 static tree
837 omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
838 {
839   tree copy = copy_var_decl (var, name, type);
840
841   DECL_CONTEXT (copy) = current_function_decl;
842   DECL_CHAIN (copy) = ctx->block_vars;
843   ctx->block_vars = copy;
844
845   return copy;
846 }
847
848 static tree
849 omp_copy_decl_1 (tree var, omp_context *ctx)
850 {
851   return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
852 }
853
854 /* Build tree nodes to access the field for VAR on the receiver side.  */
855
856 static tree
857 build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
858 {
859   tree x, field = lookup_field (var, ctx);
860
861   /* If the receiver record type was remapped in the child function,
862      remap the field into the new record type.  */
863   x = maybe_lookup_field (field, ctx);
864   if (x != NULL)
865     field = x;
866
867   x = build_simple_mem_ref (ctx->receiver_decl);
868   x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL);
869   if (by_ref)
870     x = build_simple_mem_ref (x);
871
872   return x;
873 }
874
875 /* Build tree nodes to access VAR in the scope outer to CTX.  In the case
876    of a parallel, this is a component reference; for workshare constructs
877    this is some variable.  */
878
879 static tree
880 build_outer_var_ref (tree var, omp_context *ctx)
881 {
882   tree x;
883
884   if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
885     x = var;
886   else if (is_variable_sized (var))
887     {
888       x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
889       x = build_outer_var_ref (x, ctx);
890       x = build_simple_mem_ref (x);
891     }
892   else if (is_taskreg_ctx (ctx))
893     {
894       bool by_ref = use_pointer_for_field (var, NULL);
895       x = build_receiver_ref (var, by_ref, ctx);
896     }
897   else if (ctx->outer)
898     x = lookup_decl (var, ctx->outer);
899   else if (is_reference (var))
900     /* This can happen with orphaned constructs.  If var is reference, it is
901        possible it is shared and as such valid.  */
902     x = var;
903   else
904     gcc_unreachable ();
905
906   if (is_reference (var))
907     x = build_simple_mem_ref (x);
908
909   return x;
910 }
911
912 /* Build tree nodes to access the field for VAR on the sender side.  */
913
914 static tree
915 build_sender_ref (tree var, omp_context *ctx)
916 {
917   tree field = lookup_sfield (var, ctx);
918   return build3 (COMPONENT_REF, TREE_TYPE (field),
919                  ctx->sender_decl, field, NULL);
920 }
921
922 /* Add a new field for VAR inside the structure CTX->SENDER_DECL.  */
923
924 static void
925 install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
926 {
927   tree field, type, sfield = NULL_TREE;
928
929   gcc_assert ((mask & 1) == 0
930               || !splay_tree_lookup (ctx->field_map, (splay_tree_key) var));
931   gcc_assert ((mask & 2) == 0 || !ctx->sfield_map
932               || !splay_tree_lookup (ctx->sfield_map, (splay_tree_key) var));
933
934   type = TREE_TYPE (var);
935   if (by_ref)
936     type = build_pointer_type (type);
937   else if ((mask & 3) == 1 && is_reference (var))
938     type = TREE_TYPE (type);
939
940   field = build_decl (DECL_SOURCE_LOCATION (var),
941                       FIELD_DECL, DECL_NAME (var), type);
942
943   /* Remember what variable this field was created for.  This does have a
944      side effect of making dwarf2out ignore this member, so for helpful
945      debugging we clear it later in delete_omp_context.  */
946   DECL_ABSTRACT_ORIGIN (field) = var;
947   if (type == TREE_TYPE (var))
948     {
949       DECL_ALIGN (field) = DECL_ALIGN (var);
950       DECL_USER_ALIGN (field) = DECL_USER_ALIGN (var);
951       TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (var);
952     }
953   else
954     DECL_ALIGN (field) = TYPE_ALIGN (type);
955
956   if ((mask & 3) == 3)
957     {
958       insert_field_into_struct (ctx->record_type, field);
959       if (ctx->srecord_type)
960         {
961           sfield = build_decl (DECL_SOURCE_LOCATION (var),
962                                FIELD_DECL, DECL_NAME (var), type);
963           DECL_ABSTRACT_ORIGIN (sfield) = var;
964           DECL_ALIGN (sfield) = DECL_ALIGN (field);
965           DECL_USER_ALIGN (sfield) = DECL_USER_ALIGN (field);
966           TREE_THIS_VOLATILE (sfield) = TREE_THIS_VOLATILE (field);
967           insert_field_into_struct (ctx->srecord_type, sfield);
968         }
969     }
970   else
971     {
972       if (ctx->srecord_type == NULL_TREE)
973         {
974           tree t;
975
976           ctx->srecord_type = lang_hooks.types.make_type (RECORD_TYPE);
977           ctx->sfield_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
978           for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
979             {
980               sfield = build_decl (DECL_SOURCE_LOCATION (var),
981                                    FIELD_DECL, DECL_NAME (t), TREE_TYPE (t));
982               DECL_ABSTRACT_ORIGIN (sfield) = DECL_ABSTRACT_ORIGIN (t);
983               insert_field_into_struct (ctx->srecord_type, sfield);
984               splay_tree_insert (ctx->sfield_map,
985                                  (splay_tree_key) DECL_ABSTRACT_ORIGIN (t),
986                                  (splay_tree_value) sfield);
987             }
988         }
989       sfield = field;
990       insert_field_into_struct ((mask & 1) ? ctx->record_type
991                                 : ctx->srecord_type, field);
992     }
993
994   if (mask & 1)
995     splay_tree_insert (ctx->field_map, (splay_tree_key) var,
996                        (splay_tree_value) field);
997   if ((mask & 2) && ctx->sfield_map)
998     splay_tree_insert (ctx->sfield_map, (splay_tree_key) var,
999                        (splay_tree_value) sfield);
1000 }
1001
1002 static tree
1003 install_var_local (tree var, omp_context *ctx)
1004 {
1005   tree new_var = omp_copy_decl_1 (var, ctx);
1006   insert_decl_map (&ctx->cb, var, new_var);
1007   return new_var;
1008 }
1009
1010 /* Adjust the replacement for DECL in CTX for the new context.  This means
1011    copying the DECL_VALUE_EXPR, and fixing up the type.  */
1012
1013 static void
1014 fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
1015 {
1016   tree new_decl, size;
1017
1018   new_decl = lookup_decl (decl, ctx);
1019
1020   TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
1021
1022   if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
1023       && DECL_HAS_VALUE_EXPR_P (decl))
1024     {
1025       tree ve = DECL_VALUE_EXPR (decl);
1026       walk_tree (&ve, copy_tree_body_r, &ctx->cb, NULL);
1027       SET_DECL_VALUE_EXPR (new_decl, ve);
1028       DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
1029     }
1030
1031   if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
1032     {
1033       size = remap_decl (DECL_SIZE (decl), &ctx->cb);
1034       if (size == error_mark_node)
1035         size = TYPE_SIZE (TREE_TYPE (new_decl));
1036       DECL_SIZE (new_decl) = size;
1037
1038       size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
1039       if (size == error_mark_node)
1040         size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
1041       DECL_SIZE_UNIT (new_decl) = size;
1042     }
1043 }
1044
1045 /* The callback for remap_decl.  Search all containing contexts for a
1046    mapping of the variable; this avoids having to duplicate the splay
1047    tree ahead of time.  We know a mapping doesn't already exist in the
1048    given context.  Create new mappings to implement default semantics.  */
1049
1050 static tree
1051 omp_copy_decl (tree var, copy_body_data *cb)
1052 {
1053   omp_context *ctx = (omp_context *) cb;
1054   tree new_var;
1055
1056   if (TREE_CODE (var) == LABEL_DECL)
1057     {
1058       new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
1059       DECL_CONTEXT (new_var) = current_function_decl;
1060       insert_decl_map (&ctx->cb, var, new_var);
1061       return new_var;
1062     }
1063
1064   while (!is_taskreg_ctx (ctx))
1065     {
1066       ctx = ctx->outer;
1067       if (ctx == NULL)
1068         return var;
1069       new_var = maybe_lookup_decl (var, ctx);
1070       if (new_var)
1071         return new_var;
1072     }
1073
1074   if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
1075     return var;
1076
1077   return error_mark_node;
1078 }
1079
1080
1081 /* Return the parallel region associated with STMT.  */
1082
1083 /* Debugging dumps for parallel regions.  */
1084 void dump_omp_region (FILE *, struct omp_region *, int);
1085 void debug_omp_region (struct omp_region *);
1086 void debug_all_omp_regions (void);
1087
1088 /* Dump the parallel region tree rooted at REGION.  */
1089
1090 void
1091 dump_omp_region (FILE *file, struct omp_region *region, int indent)
1092 {
1093   fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
1094            gimple_code_name[region->type]);
1095
1096   if (region->inner)
1097     dump_omp_region (file, region->inner, indent + 4);
1098
1099   if (region->cont)
1100     {
1101       fprintf (file, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent, "",
1102                region->cont->index);
1103     }
1104
1105   if (region->exit)
1106     fprintf (file, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent, "",
1107              region->exit->index);
1108   else
1109     fprintf (file, "%*s[no exit marker]\n", indent, "");
1110
1111   if (region->next)
1112     dump_omp_region (file, region->next, indent);
1113 }
1114
1115 DEBUG_FUNCTION void
1116 debug_omp_region (struct omp_region *region)
1117 {
1118   dump_omp_region (stderr, region, 0);
1119 }
1120
1121 DEBUG_FUNCTION void
1122 debug_all_omp_regions (void)
1123 {
1124   dump_omp_region (stderr, root_omp_region, 0);
1125 }
1126
1127
1128 /* Create a new parallel region starting at STMT inside region PARENT.  */
1129
1130 struct omp_region *
1131 new_omp_region (basic_block bb, enum gimple_code type,
1132                 struct omp_region *parent)
1133 {
1134   struct omp_region *region = XCNEW (struct omp_region);
1135
1136   region->outer = parent;
1137   region->entry = bb;
1138   region->type = type;
1139
1140   if (parent)
1141     {
1142       /* This is a nested region.  Add it to the list of inner
1143          regions in PARENT.  */
1144       region->next = parent->inner;
1145       parent->inner = region;
1146     }
1147   else
1148     {
1149       /* This is a toplevel region.  Add it to the list of toplevel
1150          regions in ROOT_OMP_REGION.  */
1151       region->next = root_omp_region;
1152       root_omp_region = region;
1153     }
1154
1155   return region;
1156 }
1157
1158 /* Release the memory associated with the region tree rooted at REGION.  */
1159
1160 static void
1161 free_omp_region_1 (struct omp_region *region)
1162 {
1163   struct omp_region *i, *n;
1164
1165   for (i = region->inner; i ; i = n)
1166     {
1167       n = i->next;
1168       free_omp_region_1 (i);
1169     }
1170
1171   free (region);
1172 }
1173
1174 /* Release the memory for the entire omp region tree.  */
1175
1176 void
1177 free_omp_regions (void)
1178 {
1179   struct omp_region *r, *n;
1180   for (r = root_omp_region; r ; r = n)
1181     {
1182       n = r->next;
1183       free_omp_region_1 (r);
1184     }
1185   root_omp_region = NULL;
1186 }
1187
1188
1189 /* Create a new context, with OUTER_CTX being the surrounding context.  */
1190
1191 static omp_context *
1192 new_omp_context (gimple stmt, omp_context *outer_ctx)
1193 {
1194   omp_context *ctx = XCNEW (omp_context);
1195
1196   splay_tree_insert (all_contexts, (splay_tree_key) stmt,
1197                      (splay_tree_value) ctx);
1198   ctx->stmt = stmt;
1199
1200   if (outer_ctx)
1201     {
1202       ctx->outer = outer_ctx;
1203       ctx->cb = outer_ctx->cb;
1204       ctx->cb.block = NULL;
1205       ctx->depth = outer_ctx->depth + 1;
1206     }
1207   else
1208     {
1209       ctx->cb.src_fn = current_function_decl;
1210       ctx->cb.dst_fn = current_function_decl;
1211       ctx->cb.src_node = cgraph_get_node (current_function_decl);
1212       gcc_checking_assert (ctx->cb.src_node);
1213       ctx->cb.dst_node = ctx->cb.src_node;
1214       ctx->cb.src_cfun = cfun;
1215       ctx->cb.copy_decl = omp_copy_decl;
1216       ctx->cb.eh_lp_nr = 0;
1217       ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
1218       ctx->depth = 1;
1219     }
1220
1221   ctx->cb.decl_map = pointer_map_create ();
1222
1223   return ctx;
1224 }
1225
1226 static gimple_seq maybe_catch_exception (gimple_seq);
1227
1228 /* Finalize task copyfn.  */
1229
1230 static void
1231 finalize_task_copyfn (gimple task_stmt)
1232 {
1233   struct function *child_cfun;
1234   tree child_fn, old_fn;
1235   gimple_seq seq, new_seq;
1236   gimple bind;
1237
1238   child_fn = gimple_omp_task_copy_fn (task_stmt);
1239   if (child_fn == NULL_TREE)
1240     return;
1241
1242   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
1243
1244   /* Inform the callgraph about the new function.  */
1245   DECL_STRUCT_FUNCTION (child_fn)->curr_properties
1246     = cfun->curr_properties;
1247
1248   old_fn = current_function_decl;
1249   push_cfun (child_cfun);
1250   current_function_decl = child_fn;
1251   bind = gimplify_body (&DECL_SAVED_TREE (child_fn), child_fn, false);
1252   seq = gimple_seq_alloc ();
1253   gimple_seq_add_stmt (&seq, bind);
1254   new_seq = maybe_catch_exception (seq);
1255   if (new_seq != seq)
1256     {
1257       bind = gimple_build_bind (NULL, new_seq, NULL);
1258       seq = gimple_seq_alloc ();
1259       gimple_seq_add_stmt (&seq, bind);
1260     }
1261   gimple_set_body (child_fn, seq);
1262   pop_cfun ();
1263   current_function_decl = old_fn;
1264
1265   cgraph_add_new_function (child_fn, false);
1266 }
1267
1268 /* Destroy a omp_context data structures.  Called through the splay tree
1269    value delete callback.  */
1270
1271 static void
1272 delete_omp_context (splay_tree_value value)
1273 {
1274   omp_context *ctx = (omp_context *) value;
1275
1276   pointer_map_destroy (ctx->cb.decl_map);
1277
1278   if (ctx->field_map)
1279     splay_tree_delete (ctx->field_map);
1280   if (ctx->sfield_map)
1281     splay_tree_delete (ctx->sfield_map);
1282
1283   /* We hijacked DECL_ABSTRACT_ORIGIN earlier.  We need to clear it before
1284      it produces corrupt debug information.  */
1285   if (ctx->record_type)
1286     {
1287       tree t;
1288       for (t = TYPE_FIELDS (ctx->record_type); t ; t = DECL_CHAIN (t))
1289         DECL_ABSTRACT_ORIGIN (t) = NULL;
1290     }
1291   if (ctx->srecord_type)
1292     {
1293       tree t;
1294       for (t = TYPE_FIELDS (ctx->srecord_type); t ; t = DECL_CHAIN (t))
1295         DECL_ABSTRACT_ORIGIN (t) = NULL;
1296     }
1297
1298   if (is_task_ctx (ctx))
1299     finalize_task_copyfn (ctx->stmt);
1300
1301   XDELETE (ctx);
1302 }
1303
1304 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
1305    context.  */
1306
1307 static void
1308 fixup_child_record_type (omp_context *ctx)
1309 {
1310   tree f, type = ctx->record_type;
1311
1312   /* ??? It isn't sufficient to just call remap_type here, because
1313      variably_modified_type_p doesn't work the way we expect for
1314      record types.  Testing each field for whether it needs remapping
1315      and creating a new record by hand works, however.  */
1316   for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
1317     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
1318       break;
1319   if (f)
1320     {
1321       tree name, new_fields = NULL;
1322
1323       type = lang_hooks.types.make_type (RECORD_TYPE);
1324       name = DECL_NAME (TYPE_NAME (ctx->record_type));
1325       name = build_decl (DECL_SOURCE_LOCATION (ctx->receiver_decl),
1326                          TYPE_DECL, name, type);
1327       TYPE_NAME (type) = name;
1328
1329       for (f = TYPE_FIELDS (ctx->record_type); f ; f = DECL_CHAIN (f))
1330         {
1331           tree new_f = copy_node (f);
1332           DECL_CONTEXT (new_f) = type;
1333           TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
1334           DECL_CHAIN (new_f) = new_fields;
1335           walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &ctx->cb, NULL);
1336           walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r,
1337                      &ctx->cb, NULL);
1338           walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
1339                      &ctx->cb, NULL);
1340           new_fields = new_f;
1341
1342           /* Arrange to be able to look up the receiver field
1343              given the sender field.  */
1344           splay_tree_insert (ctx->field_map, (splay_tree_key) f,
1345                              (splay_tree_value) new_f);
1346         }
1347       TYPE_FIELDS (type) = nreverse (new_fields);
1348       layout_type (type);
1349     }
1350
1351   TREE_TYPE (ctx->receiver_decl) = build_pointer_type (type);
1352 }
1353
1354 /* Instantiate decls as necessary in CTX to satisfy the data sharing
1355    specified by CLAUSES.  */
1356
1357 static void
1358 scan_sharing_clauses (tree clauses, omp_context *ctx)
1359 {
1360   tree c, decl;
1361   bool scan_array_reductions = false;
1362
1363   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1364     {
1365       bool by_ref;
1366
1367       switch (OMP_CLAUSE_CODE (c))
1368         {
1369         case OMP_CLAUSE_PRIVATE:
1370           decl = OMP_CLAUSE_DECL (c);
1371           if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
1372             goto do_private;
1373           else if (!is_variable_sized (decl))
1374             install_var_local (decl, ctx);
1375           break;
1376
1377         case OMP_CLAUSE_SHARED:
1378           gcc_assert (is_taskreg_ctx (ctx));
1379           decl = OMP_CLAUSE_DECL (c);
1380           gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl))
1381                       || !is_variable_sized (decl));
1382           /* Global variables don't need to be copied,
1383              the receiver side will use them directly.  */
1384           if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1385             break;
1386           by_ref = use_pointer_for_field (decl, ctx);
1387           if (! TREE_READONLY (decl)
1388               || TREE_ADDRESSABLE (decl)
1389               || by_ref
1390               || is_reference (decl))
1391             {
1392               install_var_field (decl, by_ref, 3, ctx);
1393               install_var_local (decl, ctx);
1394               break;
1395             }
1396           /* We don't need to copy const scalar vars back.  */
1397           OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
1398           goto do_private;
1399
1400         case OMP_CLAUSE_LASTPRIVATE:
1401           /* Let the corresponding firstprivate clause create
1402              the variable.  */
1403           if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1404             break;
1405           /* FALLTHRU */
1406
1407         case OMP_CLAUSE_FIRSTPRIVATE:
1408         case OMP_CLAUSE_REDUCTION:
1409           decl = OMP_CLAUSE_DECL (c);
1410         do_private:
1411           if (is_variable_sized (decl))
1412             {
1413               if (is_task_ctx (ctx))
1414                 install_var_field (decl, false, 1, ctx);
1415               break;
1416             }
1417           else if (is_taskreg_ctx (ctx))
1418             {
1419               bool global
1420                 = is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx));
1421               by_ref = use_pointer_for_field (decl, NULL);
1422
1423               if (is_task_ctx (ctx)
1424                   && (global || by_ref || is_reference (decl)))
1425                 {
1426                   install_var_field (decl, false, 1, ctx);
1427                   if (!global)
1428                     install_var_field (decl, by_ref, 2, ctx);
1429                 }
1430               else if (!global)
1431                 install_var_field (decl, by_ref, 3, ctx);
1432             }
1433           install_var_local (decl, ctx);
1434           break;
1435
1436         case OMP_CLAUSE_COPYPRIVATE:
1437         case OMP_CLAUSE_COPYIN:
1438           decl = OMP_CLAUSE_DECL (c);
1439           by_ref = use_pointer_for_field (decl, NULL);
1440           install_var_field (decl, by_ref, 3, ctx);
1441           break;
1442
1443         case OMP_CLAUSE_DEFAULT:
1444           ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
1445           break;
1446
1447         case OMP_CLAUSE_FINAL:
1448         case OMP_CLAUSE_IF:
1449         case OMP_CLAUSE_NUM_THREADS:
1450         case OMP_CLAUSE_SCHEDULE:
1451           if (ctx->outer)
1452             scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
1453           break;
1454
1455         case OMP_CLAUSE_NOWAIT:
1456         case OMP_CLAUSE_ORDERED:
1457         case OMP_CLAUSE_COLLAPSE:
1458         case OMP_CLAUSE_UNTIED:
1459         case OMP_CLAUSE_MERGEABLE:
1460           break;
1461
1462         default:
1463           gcc_unreachable ();
1464         }
1465     }
1466
1467   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1468     {
1469       switch (OMP_CLAUSE_CODE (c))
1470         {
1471         case OMP_CLAUSE_LASTPRIVATE:
1472           /* Let the corresponding firstprivate clause create
1473              the variable.  */
1474           if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
1475             scan_array_reductions = true;
1476           if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1477             break;
1478           /* FALLTHRU */
1479
1480         case OMP_CLAUSE_PRIVATE:
1481         case OMP_CLAUSE_FIRSTPRIVATE:
1482         case OMP_CLAUSE_REDUCTION:
1483           decl = OMP_CLAUSE_DECL (c);
1484           if (is_variable_sized (decl))
1485             install_var_local (decl, ctx);
1486           fixup_remapped_decl (decl, ctx,
1487                                OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
1488                                && OMP_CLAUSE_PRIVATE_DEBUG (c));
1489           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1490               && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1491             scan_array_reductions = true;
1492           break;
1493
1494         case OMP_CLAUSE_SHARED:
1495           decl = OMP_CLAUSE_DECL (c);
1496           if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1497             fixup_remapped_decl (decl, ctx, false);
1498           break;
1499
1500         case OMP_CLAUSE_COPYPRIVATE:
1501         case OMP_CLAUSE_COPYIN:
1502         case OMP_CLAUSE_DEFAULT:
1503         case OMP_CLAUSE_IF:
1504         case OMP_CLAUSE_NUM_THREADS:
1505         case OMP_CLAUSE_SCHEDULE:
1506         case OMP_CLAUSE_NOWAIT:
1507         case OMP_CLAUSE_ORDERED:
1508         case OMP_CLAUSE_COLLAPSE:
1509         case OMP_CLAUSE_UNTIED:
1510         case OMP_CLAUSE_FINAL:
1511         case OMP_CLAUSE_MERGEABLE:
1512           break;
1513
1514         default:
1515           gcc_unreachable ();
1516         }
1517     }
1518
1519   if (scan_array_reductions)
1520     for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1521       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1522           && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1523         {
1524           scan_omp (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
1525           scan_omp (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
1526         }
1527       else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
1528                && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
1529         scan_omp (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
1530 }
1531
1532 /* Create a new name for omp child function.  Returns an identifier.  */
1533
1534 static GTY(()) unsigned int tmp_ompfn_id_num;
1535
1536 static tree
1537 create_omp_child_function_name (bool task_copy)
1538 {
1539   return (clone_function_name (current_function_decl,
1540                                task_copy ? "_omp_cpyfn" : "_omp_fn"));
1541 }
1542
1543 /* Build a decl for the omp child function.  It'll not contain a body
1544    yet, just the bare decl.  */
1545
1546 static void
1547 create_omp_child_function (omp_context *ctx, bool task_copy)
1548 {
1549   tree decl, type, name, t;
1550
1551   name = create_omp_child_function_name (task_copy);
1552   if (task_copy)
1553     type = build_function_type_list (void_type_node, ptr_type_node,
1554                                      ptr_type_node, NULL_TREE);
1555   else
1556     type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
1557
1558   decl = build_decl (gimple_location (ctx->stmt),
1559                      FUNCTION_DECL, name, type);
1560
1561   if (!task_copy)
1562     ctx->cb.dst_fn = decl;
1563   else
1564     gimple_omp_task_set_copy_fn (ctx->stmt, decl);
1565
1566   TREE_STATIC (decl) = 1;
1567   TREE_USED (decl) = 1;
1568   DECL_ARTIFICIAL (decl) = 1;
1569   DECL_NAMELESS (decl) = 1;
1570   DECL_IGNORED_P (decl) = 0;
1571   TREE_PUBLIC (decl) = 0;
1572   DECL_UNINLINABLE (decl) = 1;
1573   DECL_EXTERNAL (decl) = 0;
1574   DECL_CONTEXT (decl) = NULL_TREE;
1575   DECL_INITIAL (decl) = make_node (BLOCK);
1576
1577   t = build_decl (DECL_SOURCE_LOCATION (decl),
1578                   RESULT_DECL, NULL_TREE, void_type_node);
1579   DECL_ARTIFICIAL (t) = 1;
1580   DECL_IGNORED_P (t) = 1;
1581   DECL_CONTEXT (t) = decl;
1582   DECL_RESULT (decl) = t;
1583
1584   t = build_decl (DECL_SOURCE_LOCATION (decl),
1585                   PARM_DECL, get_identifier (".omp_data_i"), ptr_type_node);
1586   DECL_ARTIFICIAL (t) = 1;
1587   DECL_NAMELESS (t) = 1;
1588   DECL_ARG_TYPE (t) = ptr_type_node;
1589   DECL_CONTEXT (t) = current_function_decl;
1590   TREE_USED (t) = 1;
1591   DECL_ARGUMENTS (decl) = t;
1592   if (!task_copy)
1593     ctx->receiver_decl = t;
1594   else
1595     {
1596       t = build_decl (DECL_SOURCE_LOCATION (decl),
1597                       PARM_DECL, get_identifier (".omp_data_o"),
1598                       ptr_type_node);
1599       DECL_ARTIFICIAL (t) = 1;
1600       DECL_NAMELESS (t) = 1;
1601       DECL_ARG_TYPE (t) = ptr_type_node;
1602       DECL_CONTEXT (t) = current_function_decl;
1603       TREE_USED (t) = 1;
1604       TREE_ADDRESSABLE (t) = 1;
1605       DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
1606       DECL_ARGUMENTS (decl) = t;
1607     }
1608
1609   /* Allocate memory for the function structure.  The call to
1610      allocate_struct_function clobbers CFUN, so we need to restore
1611      it afterward.  */
1612   push_struct_function (decl);
1613   cfun->function_end_locus = gimple_location (ctx->stmt);
1614   pop_cfun ();
1615 }
1616
1617
1618 /* Scan an OpenMP parallel directive.  */
1619
1620 static void
1621 scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
1622 {
1623   omp_context *ctx;
1624   tree name;
1625   gimple stmt = gsi_stmt (*gsi);
1626
1627   /* Ignore parallel directives with empty bodies, unless there
1628      are copyin clauses.  */
1629   if (optimize > 0
1630       && empty_body_p (gimple_omp_body (stmt))
1631       && find_omp_clause (gimple_omp_parallel_clauses (stmt),
1632                           OMP_CLAUSE_COPYIN) == NULL)
1633     {
1634       gsi_replace (gsi, gimple_build_nop (), false);
1635       return;
1636     }
1637
1638   ctx = new_omp_context (stmt, outer_ctx);
1639   if (taskreg_nesting_level > 1)
1640     ctx->is_nested = true;
1641   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1642   ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
1643   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1644   name = create_tmp_var_name (".omp_data_s");
1645   name = build_decl (gimple_location (stmt),
1646                      TYPE_DECL, name, ctx->record_type);
1647   DECL_ARTIFICIAL (name) = 1;
1648   DECL_NAMELESS (name) = 1;
1649   TYPE_NAME (ctx->record_type) = name;
1650   create_omp_child_function (ctx, false);
1651   gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
1652
1653   scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
1654   scan_omp (gimple_omp_body (stmt), ctx);
1655
1656   if (TYPE_FIELDS (ctx->record_type) == NULL)
1657     ctx->record_type = ctx->receiver_decl = NULL;
1658   else
1659     {
1660       layout_type (ctx->record_type);
1661       fixup_child_record_type (ctx);
1662     }
1663 }
1664
1665 /* Scan an OpenMP task directive.  */
1666
1667 static void
1668 scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
1669 {
1670   omp_context *ctx;
1671   tree name, t;
1672   gimple stmt = gsi_stmt (*gsi);
1673   location_t loc = gimple_location (stmt);
1674
1675   /* Ignore task directives with empty bodies.  */
1676   if (optimize > 0
1677       && empty_body_p (gimple_omp_body (stmt)))
1678     {
1679       gsi_replace (gsi, gimple_build_nop (), false);
1680       return;
1681     }
1682
1683   ctx = new_omp_context (stmt, outer_ctx);
1684   if (taskreg_nesting_level > 1)
1685     ctx->is_nested = true;
1686   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1687   ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
1688   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1689   name = create_tmp_var_name (".omp_data_s");
1690   name = build_decl (gimple_location (stmt),
1691                      TYPE_DECL, name, ctx->record_type);
1692   DECL_ARTIFICIAL (name) = 1;
1693   DECL_NAMELESS (name) = 1;
1694   TYPE_NAME (ctx->record_type) = name;
1695   create_omp_child_function (ctx, false);
1696   gimple_omp_task_set_child_fn (stmt, ctx->cb.dst_fn);
1697
1698   scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);
1699
1700   if (ctx->srecord_type)
1701     {
1702       name = create_tmp_var_name (".omp_data_a");
1703       name = build_decl (gimple_location (stmt),
1704                          TYPE_DECL, name, ctx->srecord_type);
1705       DECL_ARTIFICIAL (name) = 1;
1706       DECL_NAMELESS (name) = 1;
1707       TYPE_NAME (ctx->srecord_type) = name;
1708       create_omp_child_function (ctx, true);
1709     }
1710
1711   scan_omp (gimple_omp_body (stmt), ctx);
1712
1713   if (TYPE_FIELDS (ctx->record_type) == NULL)
1714     {
1715       ctx->record_type = ctx->receiver_decl = NULL;
1716       t = build_int_cst (long_integer_type_node, 0);
1717       gimple_omp_task_set_arg_size (stmt, t);
1718       t = build_int_cst (long_integer_type_node, 1);
1719       gimple_omp_task_set_arg_align (stmt, t);
1720     }
1721   else
1722     {
1723       tree *p, vla_fields = NULL_TREE, *q = &vla_fields;
1724       /* Move VLA fields to the end.  */
1725       p = &TYPE_FIELDS (ctx->record_type);
1726       while (*p)
1727         if (!TYPE_SIZE_UNIT (TREE_TYPE (*p))
1728             || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p))))
1729           {
1730             *q = *p;
1731             *p = TREE_CHAIN (*p);
1732             TREE_CHAIN (*q) = NULL_TREE;
1733             q = &TREE_CHAIN (*q);
1734           }
1735         else
1736           p = &DECL_CHAIN (*p);
1737       *p = vla_fields;
1738       layout_type (ctx->record_type);
1739       fixup_child_record_type (ctx);
1740       if (ctx->srecord_type)
1741         layout_type (ctx->srecord_type);
1742       t = fold_convert_loc (loc, long_integer_type_node,
1743                         TYPE_SIZE_UNIT (ctx->record_type));
1744       gimple_omp_task_set_arg_size (stmt, t);
1745       t = build_int_cst (long_integer_type_node,
1746                          TYPE_ALIGN_UNIT (ctx->record_type));
1747       gimple_omp_task_set_arg_align (stmt, t);
1748     }
1749 }
1750
1751
1752 /* Scan an OpenMP loop directive.  */
1753
1754 static void
1755 scan_omp_for (gimple stmt, omp_context *outer_ctx)
1756 {
1757   omp_context *ctx;
1758   size_t i;
1759
1760   ctx = new_omp_context (stmt, outer_ctx);
1761
1762   scan_sharing_clauses (gimple_omp_for_clauses (stmt), ctx);
1763
1764   scan_omp (gimple_omp_for_pre_body (stmt), ctx);
1765   for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
1766     {
1767       scan_omp_op (gimple_omp_for_index_ptr (stmt, i), ctx);
1768       scan_omp_op (gimple_omp_for_initial_ptr (stmt, i), ctx);
1769       scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
1770       scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
1771     }
1772   scan_omp (gimple_omp_body (stmt), ctx);
1773 }
1774
1775 /* Scan an OpenMP sections directive.  */
1776
1777 static void
1778 scan_omp_sections (gimple stmt, omp_context *outer_ctx)
1779 {
1780   omp_context *ctx;
1781
1782   ctx = new_omp_context (stmt, outer_ctx);
1783   scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
1784   scan_omp (gimple_omp_body (stmt), ctx);
1785 }
1786
1787 /* Scan an OpenMP single directive.  */
1788
1789 static void
1790 scan_omp_single (gimple stmt, omp_context *outer_ctx)
1791 {
1792   omp_context *ctx;
1793   tree name;
1794
1795   ctx = new_omp_context (stmt, outer_ctx);
1796   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1797   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1798   name = create_tmp_var_name (".omp_copy_s");
1799   name = build_decl (gimple_location (stmt),
1800                      TYPE_DECL, name, ctx->record_type);
1801   TYPE_NAME (ctx->record_type) = name;
1802
1803   scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
1804   scan_omp (gimple_omp_body (stmt), ctx);
1805
1806   if (TYPE_FIELDS (ctx->record_type) == NULL)
1807     ctx->record_type = NULL;
1808   else
1809     layout_type (ctx->record_type);
1810 }
1811
1812
1813 /* Check OpenMP nesting restrictions.  */
1814 static void
1815 check_omp_nesting_restrictions (gimple  stmt, omp_context *ctx)
1816 {
1817   switch (gimple_code (stmt))
1818     {
1819     case GIMPLE_OMP_FOR:
1820     case GIMPLE_OMP_SECTIONS:
1821     case GIMPLE_OMP_SINGLE:
1822     case GIMPLE_CALL:
1823       for (; ctx != NULL; ctx = ctx->outer)
1824         switch (gimple_code (ctx->stmt))
1825           {
1826           case GIMPLE_OMP_FOR:
1827           case GIMPLE_OMP_SECTIONS:
1828           case GIMPLE_OMP_SINGLE:
1829           case GIMPLE_OMP_ORDERED:
1830           case GIMPLE_OMP_MASTER:
1831           case GIMPLE_OMP_TASK:
1832             if (is_gimple_call (stmt))
1833               {
1834                 warning (0, "barrier region may not be closely nested inside "
1835                             "of work-sharing, critical, ordered, master or "
1836                             "explicit task region");
1837                 return;
1838               }
1839             warning (0, "work-sharing region may not be closely nested inside "
1840                         "of work-sharing, critical, ordered, master or explicit "
1841                         "task region");
1842             return;
1843           case GIMPLE_OMP_PARALLEL:
1844             return;
1845           default:
1846             break;
1847           }
1848       break;
1849     case GIMPLE_OMP_MASTER:
1850       for (; ctx != NULL; ctx = ctx->outer)
1851         switch (gimple_code (ctx->stmt))
1852           {
1853           case GIMPLE_OMP_FOR:
1854           case GIMPLE_OMP_SECTIONS:
1855           case GIMPLE_OMP_SINGLE:
1856           case GIMPLE_OMP_TASK:
1857             warning (0, "master region may not be closely nested inside "
1858                         "of work-sharing or explicit task region");
1859             return;
1860           case GIMPLE_OMP_PARALLEL:
1861             return;
1862           default:
1863             break;
1864           }
1865       break;
1866     case GIMPLE_OMP_ORDERED:
1867       for (; ctx != NULL; ctx = ctx->outer)
1868         switch (gimple_code (ctx->stmt))
1869           {
1870           case GIMPLE_OMP_CRITICAL:
1871           case GIMPLE_OMP_TASK:
1872             warning (0, "ordered region may not be closely nested inside "
1873                         "of critical or explicit task region");
1874             return;
1875           case GIMPLE_OMP_FOR:
1876             if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
1877                                  OMP_CLAUSE_ORDERED) == NULL)
1878               warning (0, "ordered region must be closely nested inside "
1879                           "a loop region with an ordered clause");
1880             return;
1881           case GIMPLE_OMP_PARALLEL:
1882             return;
1883           default:
1884             break;
1885           }
1886       break;
1887     case GIMPLE_OMP_CRITICAL:
1888       for (; ctx != NULL; ctx = ctx->outer)
1889         if (gimple_code (ctx->stmt) == GIMPLE_OMP_CRITICAL
1890             && (gimple_omp_critical_name (stmt)
1891                 == gimple_omp_critical_name (ctx->stmt)))
1892           {
1893             warning (0, "critical region may not be nested inside a critical "
1894                         "region with the same name");
1895             return;
1896           }
1897       break;
1898     default:
1899       break;
1900     }
1901 }
1902
1903
1904 /* Helper function scan_omp.
1905
1906    Callback for walk_tree or operators in walk_gimple_stmt used to
1907    scan for OpenMP directives in TP.  */
1908
1909 static tree
1910 scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
1911 {
1912   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
1913   omp_context *ctx = (omp_context *) wi->info;
1914   tree t = *tp;
1915
1916   switch (TREE_CODE (t))
1917     {
1918     case VAR_DECL:
1919     case PARM_DECL:
1920     case LABEL_DECL:
1921     case RESULT_DECL:
1922       if (ctx)
1923         *tp = remap_decl (t, &ctx->cb);
1924       break;
1925
1926     default:
1927       if (ctx && TYPE_P (t))
1928         *tp = remap_type (t, &ctx->cb);
1929       else if (!DECL_P (t))
1930         {
1931           *walk_subtrees = 1;
1932           if (ctx)
1933             {
1934               tree tem = remap_type (TREE_TYPE (t), &ctx->cb);
1935               if (tem != TREE_TYPE (t))
1936                 {
1937                   if (TREE_CODE (t) == INTEGER_CST)
1938                     *tp = build_int_cst_wide (tem,
1939                                               TREE_INT_CST_LOW (t),
1940                                               TREE_INT_CST_HIGH (t));
1941                   else
1942                     TREE_TYPE (t) = tem;
1943                 }
1944             }
1945         }
1946       break;
1947     }
1948
1949   return NULL_TREE;
1950 }
1951
1952
1953 /* Helper function for scan_omp.
1954
1955    Callback for walk_gimple_stmt used to scan for OpenMP directives in
1956    the current statement in GSI.  */
1957
1958 static tree
1959 scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
1960                  struct walk_stmt_info *wi)
1961 {
1962   gimple stmt = gsi_stmt (*gsi);
1963   omp_context *ctx = (omp_context *) wi->info;
1964
1965   if (gimple_has_location (stmt))
1966     input_location = gimple_location (stmt);
1967
1968   /* Check the OpenMP nesting restrictions.  */
1969   if (ctx != NULL)
1970     {
1971       if (is_gimple_omp (stmt))
1972         check_omp_nesting_restrictions (stmt, ctx);
1973       else if (is_gimple_call (stmt))
1974         {
1975           tree fndecl = gimple_call_fndecl (stmt);
1976           if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
1977               && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER)
1978             check_omp_nesting_restrictions (stmt, ctx);
1979         }
1980     }
1981
1982   *handled_ops_p = true;
1983
1984   switch (gimple_code (stmt))
1985     {
1986     case GIMPLE_OMP_PARALLEL:
1987       taskreg_nesting_level++;
1988       scan_omp_parallel (gsi, ctx);
1989       taskreg_nesting_level--;
1990       break;
1991
1992     case GIMPLE_OMP_TASK:
1993       taskreg_nesting_level++;
1994       scan_omp_task (gsi, ctx);
1995       taskreg_nesting_level--;
1996       break;
1997
1998     case GIMPLE_OMP_FOR:
1999       scan_omp_for (stmt, ctx);
2000       break;
2001
2002     case GIMPLE_OMP_SECTIONS:
2003       scan_omp_sections (stmt, ctx);
2004       break;
2005
2006     case GIMPLE_OMP_SINGLE:
2007       scan_omp_single (stmt, ctx);
2008       break;
2009
2010     case GIMPLE_OMP_SECTION:
2011     case GIMPLE_OMP_MASTER:
2012     case GIMPLE_OMP_ORDERED:
2013     case GIMPLE_OMP_CRITICAL:
2014       ctx = new_omp_context (stmt, ctx);
2015       scan_omp (gimple_omp_body (stmt), ctx);
2016       break;
2017
2018     case GIMPLE_BIND:
2019       {
2020         tree var;
2021
2022         *handled_ops_p = false;
2023         if (ctx)
2024           for (var = gimple_bind_vars (stmt); var ; var = DECL_CHAIN (var))
2025             insert_decl_map (&ctx->cb, var, var);
2026       }
2027       break;
2028     default:
2029       *handled_ops_p = false;
2030       break;
2031     }
2032
2033   return NULL_TREE;
2034 }
2035
2036
2037 /* Scan all the statements starting at the current statement.  CTX
2038    contains context information about the OpenMP directives and
2039    clauses found during the scan.  */
2040
2041 static void
2042 scan_omp (gimple_seq body, omp_context *ctx)
2043 {
2044   location_t saved_location;
2045   struct walk_stmt_info wi;
2046
2047   memset (&wi, 0, sizeof (wi));
2048   wi.info = ctx;
2049   wi.want_locations = true;
2050
2051   saved_location = input_location;
2052   walk_gimple_seq (body, scan_omp_1_stmt, scan_omp_1_op, &wi);
2053   input_location = saved_location;
2054 }
2055 \f
2056 /* Re-gimplification and code generation routines.  */
2057
2058 /* Build a call to GOMP_barrier.  */
2059
2060 static tree
2061 build_omp_barrier (void)
2062 {
2063   return build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_BARRIER), 0);
2064 }
2065
2066 /* If a context was created for STMT when it was scanned, return it.  */
2067
2068 static omp_context *
2069 maybe_lookup_ctx (gimple stmt)
2070 {
2071   splay_tree_node n;
2072   n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
2073   return n ? (omp_context *) n->value : NULL;
2074 }
2075
2076
2077 /* Find the mapping for DECL in CTX or the immediately enclosing
2078    context that has a mapping for DECL.
2079
2080    If CTX is a nested parallel directive, we may have to use the decl
2081    mappings created in CTX's parent context.  Suppose that we have the
2082    following parallel nesting (variable UIDs showed for clarity):
2083
2084         iD.1562 = 0;
2085         #omp parallel shared(iD.1562)           -> outer parallel
2086           iD.1562 = iD.1562 + 1;
2087
2088           #omp parallel shared (iD.1562)        -> inner parallel
2089              iD.1562 = iD.1562 - 1;
2090
2091    Each parallel structure will create a distinct .omp_data_s structure
2092    for copying iD.1562 in/out of the directive:
2093
2094         outer parallel          .omp_data_s.1.i -> iD.1562
2095         inner parallel          .omp_data_s.2.i -> iD.1562
2096
2097    A shared variable mapping will produce a copy-out operation before
2098    the parallel directive and a copy-in operation after it.  So, in
2099    this case we would have:
2100
2101         iD.1562 = 0;
2102         .omp_data_o.1.i = iD.1562;
2103         #omp parallel shared(iD.1562)           -> outer parallel
2104           .omp_data_i.1 = &.omp_data_o.1
2105           .omp_data_i.1->i = .omp_data_i.1->i + 1;
2106
2107           .omp_data_o.2.i = iD.1562;            -> **
2108           #omp parallel shared(iD.1562)         -> inner parallel
2109             .omp_data_i.2 = &.omp_data_o.2
2110             .omp_data_i.2->i = .omp_data_i.2->i - 1;
2111
2112
2113     ** This is a problem.  The symbol iD.1562 cannot be referenced
2114        inside the body of the outer parallel region.  But since we are
2115        emitting this copy operation while expanding the inner parallel
2116        directive, we need to access the CTX structure of the outer
2117        parallel directive to get the correct mapping:
2118
2119           .omp_data_o.2.i = .omp_data_i.1->i
2120
2121     Since there may be other workshare or parallel directives enclosing
2122     the parallel directive, it may be necessary to walk up the context
2123     parent chain.  This is not a problem in general because nested
2124     parallelism happens only rarely.  */
2125
2126 static tree
2127 lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
2128 {
2129   tree t;
2130   omp_context *up;
2131
2132   for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
2133     t = maybe_lookup_decl (decl, up);
2134
2135   gcc_assert (!ctx->is_nested || t || is_global_var (decl));
2136
2137   return t ? t : decl;
2138 }
2139
2140
2141 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
2142    in outer contexts.  */
2143
2144 static tree
2145 maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
2146 {
2147   tree t = NULL;
2148   omp_context *up;
2149
2150   for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
2151     t = maybe_lookup_decl (decl, up);
2152
2153   return t ? t : decl;
2154 }
2155
2156
2157 /* Construct the initialization value for reduction CLAUSE.  */
2158
2159 tree
2160 omp_reduction_init (tree clause, tree type)
2161 {
2162   location_t loc = OMP_CLAUSE_LOCATION (clause);
2163   switch (OMP_CLAUSE_REDUCTION_CODE (clause))
2164     {
2165     case PLUS_EXPR:
2166     case MINUS_EXPR:
2167     case BIT_IOR_EXPR:
2168     case BIT_XOR_EXPR:
2169     case TRUTH_OR_EXPR:
2170     case TRUTH_ORIF_EXPR:
2171     case TRUTH_XOR_EXPR:
2172     case NE_EXPR:
2173       return build_zero_cst (type);
2174
2175     case MULT_EXPR:
2176     case TRUTH_AND_EXPR:
2177     case TRUTH_ANDIF_EXPR:
2178     case EQ_EXPR:
2179       return fold_convert_loc (loc, type, integer_one_node);
2180
2181     case BIT_AND_EXPR:
2182       return fold_convert_loc (loc, type, integer_minus_one_node);
2183
2184     case MAX_EXPR:
2185       if (SCALAR_FLOAT_TYPE_P (type))
2186         {
2187           REAL_VALUE_TYPE max, min;
2188           if (HONOR_INFINITIES (TYPE_MODE (type)))
2189             {
2190               real_inf (&max);
2191               real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
2192             }
2193           else
2194             real_maxval (&min, 1, TYPE_MODE (type));
2195           return build_real (type, min);
2196         }
2197       else
2198         {
2199           gcc_assert (INTEGRAL_TYPE_P (type));
2200           return TYPE_MIN_VALUE (type);
2201         }
2202
2203     case MIN_EXPR:
2204       if (SCALAR_FLOAT_TYPE_P (type))
2205         {
2206           REAL_VALUE_TYPE max;
2207           if (HONOR_INFINITIES (TYPE_MODE (type)))
2208             real_inf (&max);
2209           else
2210             real_maxval (&max, 0, TYPE_MODE (type));
2211           return build_real (type, max);
2212         }
2213       else
2214         {
2215           gcc_assert (INTEGRAL_TYPE_P (type));
2216           return TYPE_MAX_VALUE (type);
2217         }
2218
2219     default:
2220       gcc_unreachable ();
2221     }
2222 }
2223
2224 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
2225    from the receiver (aka child) side and initializers for REFERENCE_TYPE
2226    private variables.  Initialization statements go in ILIST, while calls
2227    to destructors go in DLIST.  */
2228
2229 static void
2230 lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
2231                          omp_context *ctx)
2232 {
2233   gimple_stmt_iterator diter;
2234   tree c, dtor, copyin_seq, x, ptr;
2235   bool copyin_by_ref = false;
2236   bool lastprivate_firstprivate = false;
2237   int pass;
2238
2239   *dlist = gimple_seq_alloc ();
2240   diter = gsi_start (*dlist);
2241   copyin_seq = NULL;
2242
2243   /* Do all the fixed sized types in the first pass, and the variable sized
2244      types in the second pass.  This makes sure that the scalar arguments to
2245      the variable sized types are processed before we use them in the
2246      variable sized operations.  */
2247   for (pass = 0; pass < 2; ++pass)
2248     {
2249       for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2250         {
2251           enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
2252           tree var, new_var;
2253           bool by_ref;
2254           location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2255
2256           switch (c_kind)
2257             {
2258             case OMP_CLAUSE_PRIVATE:
2259               if (OMP_CLAUSE_PRIVATE_DEBUG (c))
2260                 continue;
2261               break;
2262             case OMP_CLAUSE_SHARED:
2263               if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
2264                 {
2265                   gcc_assert (is_global_var (OMP_CLAUSE_DECL (c)));
2266                   continue;
2267                 }
2268             case OMP_CLAUSE_FIRSTPRIVATE:
2269             case OMP_CLAUSE_COPYIN:
2270             case OMP_CLAUSE_REDUCTION:
2271               break;
2272             case OMP_CLAUSE_LASTPRIVATE:
2273               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2274                 {
2275                   lastprivate_firstprivate = true;
2276                   if (pass != 0)
2277                     continue;
2278                 }
2279               break;
2280             default:
2281               continue;
2282             }
2283
2284           new_var = var = OMP_CLAUSE_DECL (c);
2285           if (c_kind != OMP_CLAUSE_COPYIN)
2286             new_var = lookup_decl (var, ctx);
2287
2288           if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
2289             {
2290               if (pass != 0)
2291                 continue;
2292             }
2293           else if (is_variable_sized (var))
2294             {
2295               /* For variable sized types, we need to allocate the
2296                  actual storage here.  Call alloca and store the
2297                  result in the pointer decl that we created elsewhere.  */
2298               if (pass == 0)
2299                 continue;
2300
2301               if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
2302                 {
2303                   gimple stmt;
2304                   tree tmp, atmp;
2305
2306                   ptr = DECL_VALUE_EXPR (new_var);
2307                   gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
2308                   ptr = TREE_OPERAND (ptr, 0);
2309                   gcc_assert (DECL_P (ptr));
2310                   x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
2311
2312                   /* void *tmp = __builtin_alloca */
2313                   atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
2314                   stmt = gimple_build_call (atmp, 1, x);
2315                   tmp = create_tmp_var_raw (ptr_type_node, NULL);
2316                   gimple_add_tmp_var (tmp);
2317                   gimple_call_set_lhs (stmt, tmp);
2318
2319                   gimple_seq_add_stmt (ilist, stmt);
2320
2321                   x = fold_convert_loc (clause_loc, TREE_TYPE (ptr), tmp);
2322                   gimplify_assign (ptr, x, ilist);
2323                 }
2324             }
2325           else if (is_reference (var))
2326             {
2327               /* For references that are being privatized for Fortran,
2328                  allocate new backing storage for the new pointer
2329                  variable.  This allows us to avoid changing all the
2330                  code that expects a pointer to something that expects
2331                  a direct variable.  Note that this doesn't apply to
2332                  C++, since reference types are disallowed in data
2333                  sharing clauses there, except for NRV optimized
2334                  return values.  */
2335               if (pass == 0)
2336                 continue;
2337
2338               x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
2339               if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
2340                 {
2341                   x = build_receiver_ref (var, false, ctx);
2342                   x = build_fold_addr_expr_loc (clause_loc, x);
2343                 }
2344               else if (TREE_CONSTANT (x))
2345                 {
2346                   const char *name = NULL;
2347                   if (DECL_NAME (var))
2348                     name = IDENTIFIER_POINTER (DECL_NAME (new_var));
2349
2350                   x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
2351                                           name);
2352                   gimple_add_tmp_var (x);
2353                   TREE_ADDRESSABLE (x) = 1;
2354                   x = build_fold_addr_expr_loc (clause_loc, x);
2355                 }
2356               else
2357                 {
2358                   tree atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
2359                   x = build_call_expr_loc (clause_loc, atmp, 1, x);
2360                 }
2361
2362               x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
2363               gimplify_assign (new_var, x, ilist);
2364
2365               new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2366             }
2367           else if (c_kind == OMP_CLAUSE_REDUCTION
2368                    && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2369             {
2370               if (pass == 0)
2371                 continue;
2372             }
2373           else if (pass != 0)
2374             continue;
2375
2376           switch (OMP_CLAUSE_CODE (c))
2377             {
2378             case OMP_CLAUSE_SHARED:
2379               /* Shared global vars are just accessed directly.  */
2380               if (is_global_var (new_var))
2381                 break;
2382               /* Set up the DECL_VALUE_EXPR for shared variables now.  This
2383                  needs to be delayed until after fixup_child_record_type so
2384                  that we get the correct type during the dereference.  */
2385               by_ref = use_pointer_for_field (var, ctx);
2386               x = build_receiver_ref (var, by_ref, ctx);
2387               SET_DECL_VALUE_EXPR (new_var, x);
2388               DECL_HAS_VALUE_EXPR_P (new_var) = 1;
2389
2390               /* ??? If VAR is not passed by reference, and the variable
2391                  hasn't been initialized yet, then we'll get a warning for
2392                  the store into the omp_data_s structure.  Ideally, we'd be
2393                  able to notice this and not store anything at all, but
2394                  we're generating code too early.  Suppress the warning.  */
2395               if (!by_ref)
2396                 TREE_NO_WARNING (var) = 1;
2397               break;
2398
2399             case OMP_CLAUSE_LASTPRIVATE:
2400               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2401                 break;
2402               /* FALLTHRU */
2403
2404             case OMP_CLAUSE_PRIVATE:
2405               if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE)
2406                 x = build_outer_var_ref (var, ctx);
2407               else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
2408                 {
2409                   if (is_task_ctx (ctx))
2410                     x = build_receiver_ref (var, false, ctx);
2411                   else
2412                     x = build_outer_var_ref (var, ctx);
2413                 }
2414               else
2415                 x = NULL;
2416               x = lang_hooks.decls.omp_clause_default_ctor (c, new_var, x);
2417               if (x)
2418                 gimplify_and_add (x, ilist);
2419               /* FALLTHRU */
2420
2421             do_dtor:
2422               x = lang_hooks.decls.omp_clause_dtor (c, new_var);
2423               if (x)
2424                 {
2425                   gimple_seq tseq = NULL;
2426
2427                   dtor = x;
2428                   gimplify_stmt (&dtor, &tseq);
2429                   gsi_insert_seq_before (&diter, tseq, GSI_SAME_STMT);
2430                 }
2431               break;
2432
2433             case OMP_CLAUSE_FIRSTPRIVATE:
2434               if (is_task_ctx (ctx))
2435                 {
2436                   if (is_reference (var) || is_variable_sized (var))
2437                     goto do_dtor;
2438                   else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var,
2439                                                                           ctx))
2440                            || use_pointer_for_field (var, NULL))
2441                     {
2442                       x = build_receiver_ref (var, false, ctx);
2443                       SET_DECL_VALUE_EXPR (new_var, x);
2444                       DECL_HAS_VALUE_EXPR_P (new_var) = 1;
2445                       goto do_dtor;
2446                     }
2447                 }
2448               x = build_outer_var_ref (var, ctx);
2449               x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
2450               gimplify_and_add (x, ilist);
2451               goto do_dtor;
2452               break;
2453
2454             case OMP_CLAUSE_COPYIN:
2455               by_ref = use_pointer_for_field (var, NULL);
2456               x = build_receiver_ref (var, by_ref, ctx);
2457               x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
2458               append_to_statement_list (x, &copyin_seq);
2459               copyin_by_ref |= by_ref;
2460               break;
2461
2462             case OMP_CLAUSE_REDUCTION:
2463               if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2464                 {
2465                   tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
2466                   x = build_outer_var_ref (var, ctx);
2467
2468                   if (is_reference (var))
2469                     x = build_fold_addr_expr_loc (clause_loc, x);
2470                   SET_DECL_VALUE_EXPR (placeholder, x);
2471                   DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
2472                   lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
2473                   gimple_seq_add_seq (ilist,
2474                                       OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
2475                   OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
2476                   DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
2477                 }
2478               else
2479                 {
2480                   x = omp_reduction_init (c, TREE_TYPE (new_var));
2481                   gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
2482                   gimplify_assign (new_var, x, ilist);
2483                 }
2484               break;
2485
2486             default:
2487               gcc_unreachable ();
2488             }
2489         }
2490     }
2491
2492   /* The copyin sequence is not to be executed by the main thread, since
2493      that would result in self-copies.  Perhaps not visible to scalars,
2494      but it certainly is to C++ operator=.  */
2495   if (copyin_seq)
2496     {
2497       x = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM),
2498                            0);
2499       x = build2 (NE_EXPR, boolean_type_node, x,
2500                   build_int_cst (TREE_TYPE (x), 0));
2501       x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
2502       gimplify_and_add (x, ilist);
2503     }
2504
2505   /* If any copyin variable is passed by reference, we must ensure the
2506      master thread doesn't modify it before it is copied over in all
2507      threads.  Similarly for variables in both firstprivate and
2508      lastprivate clauses we need to ensure the lastprivate copying
2509      happens after firstprivate copying in all threads.  */
2510   if (copyin_by_ref || lastprivate_firstprivate)
2511     gimplify_and_add (build_omp_barrier (), ilist);
2512 }
2513
2514
2515 /* Generate code to implement the LASTPRIVATE clauses.  This is used for
2516    both parallel and workshare constructs.  PREDICATE may be NULL if it's
2517    always true.   */
2518
2519 static void
2520 lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
2521                             omp_context *ctx)
2522 {
2523   tree x, c, label = NULL;
2524   bool par_clauses = false;
2525
2526   /* Early exit if there are no lastprivate clauses.  */
2527   clauses = find_omp_clause (clauses, OMP_CLAUSE_LASTPRIVATE);
2528   if (clauses == NULL)
2529     {
2530       /* If this was a workshare clause, see if it had been combined
2531          with its parallel.  In that case, look for the clauses on the
2532          parallel statement itself.  */
2533       if (is_parallel_ctx (ctx))
2534         return;
2535
2536       ctx = ctx->outer;
2537       if (ctx == NULL || !is_parallel_ctx (ctx))
2538         return;
2539
2540       clauses = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2541                                  OMP_CLAUSE_LASTPRIVATE);
2542       if (clauses == NULL)
2543         return;
2544       par_clauses = true;
2545     }
2546
2547   if (predicate)
2548     {
2549       gimple stmt;
2550       tree label_true, arm1, arm2;
2551
2552       label = create_artificial_label (UNKNOWN_LOCATION);
2553       label_true = create_artificial_label (UNKNOWN_LOCATION);
2554       arm1 = TREE_OPERAND (predicate, 0);
2555       arm2 = TREE_OPERAND (predicate, 1);
2556       gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
2557       gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
2558       stmt = gimple_build_cond (TREE_CODE (predicate), arm1, arm2,
2559                                 label_true, label);
2560       gimple_seq_add_stmt (stmt_list, stmt);
2561       gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
2562     }
2563
2564   for (c = clauses; c ;)
2565     {
2566       tree var, new_var;
2567       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2568
2569       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
2570         {
2571           var = OMP_CLAUSE_DECL (c);
2572           new_var = lookup_decl (var, ctx);
2573
2574           if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
2575             {
2576               lower_omp (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
2577               gimple_seq_add_seq (stmt_list,
2578                                   OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
2579             }
2580           OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
2581
2582           x = build_outer_var_ref (var, ctx);
2583           if (is_reference (var))
2584             new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2585           x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
2586           gimplify_and_add (x, stmt_list);
2587         }
2588       c = OMP_CLAUSE_CHAIN (c);
2589       if (c == NULL && !par_clauses)
2590         {
2591           /* If this was a workshare clause, see if it had been combined
2592              with its parallel.  In that case, continue looking for the
2593              clauses also on the parallel statement itself.  */
2594           if (is_parallel_ctx (ctx))
2595             break;
2596
2597           ctx = ctx->outer;
2598           if (ctx == NULL || !is_parallel_ctx (ctx))
2599             break;
2600
2601           c = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2602                                OMP_CLAUSE_LASTPRIVATE);
2603           par_clauses = true;
2604         }
2605     }
2606
2607   if (label)
2608     gimple_seq_add_stmt (stmt_list, gimple_build_label (label));
2609 }
2610
2611
2612 /* Generate code to implement the REDUCTION clauses.  */
2613
2614 static void
2615 lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
2616 {
2617   gimple_seq sub_seq = NULL;
2618   gimple stmt;
2619   tree x, c;
2620   int count = 0;
2621
2622   /* First see if there is exactly one reduction clause.  Use OMP_ATOMIC
2623      update in that case, otherwise use a lock.  */
2624   for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
2625     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
2626       {
2627         if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2628           {
2629             /* Never use OMP_ATOMIC for array reductions.  */
2630             count = -1;
2631             break;
2632           }
2633         count++;
2634       }
2635
2636   if (count == 0)
2637     return;
2638
2639   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2640     {
2641       tree var, ref, new_var;
2642       enum tree_code code;
2643       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2644
2645       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
2646         continue;
2647
2648       var = OMP_CLAUSE_DECL (c);
2649       new_var = lookup_decl (var, ctx);
2650       if (is_reference (var))
2651         new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2652       ref = build_outer_var_ref (var, ctx);
2653       code = OMP_CLAUSE_REDUCTION_CODE (c);
2654
2655       /* reduction(-:var) sums up the partial results, so it acts
2656          identically to reduction(+:var).  */
2657       if (code == MINUS_EXPR)
2658         code = PLUS_EXPR;
2659
2660       if (count == 1)
2661         {
2662           tree addr = build_fold_addr_expr_loc (clause_loc, ref);
2663
2664           addr = save_expr (addr);
2665           ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
2666           x = fold_build2_loc (clause_loc, code, TREE_TYPE (ref), ref, new_var);
2667           x = build2 (OMP_ATOMIC, void_type_node, addr, x);
2668           gimplify_and_add (x, stmt_seqp);
2669           return;
2670         }
2671
2672       if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2673         {
2674           tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
2675
2676           if (is_reference (var))
2677             ref = build_fold_addr_expr_loc (clause_loc, ref);
2678           SET_DECL_VALUE_EXPR (placeholder, ref);
2679           DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
2680           lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
2681           gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
2682           OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
2683           OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
2684         }
2685       else
2686         {
2687           x = build2 (code, TREE_TYPE (ref), ref, new_var);
2688           ref = build_outer_var_ref (var, ctx);
2689           gimplify_assign (ref, x, &sub_seq);
2690         }
2691     }
2692
2693   stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START),
2694                             0);
2695   gimple_seq_add_stmt (stmt_seqp, stmt);
2696
2697   gimple_seq_add_seq (stmt_seqp, sub_seq);
2698
2699   stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END),
2700                             0);
2701   gimple_seq_add_stmt (stmt_seqp, stmt);
2702 }
2703
2704
2705 /* Generate code to implement the COPYPRIVATE clauses.  */
2706
2707 static void
2708 lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist,
2709                             omp_context *ctx)
2710 {
2711   tree c;
2712
2713   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2714     {
2715       tree var, new_var, ref, x;
2716       bool by_ref;
2717       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2718
2719       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
2720         continue;
2721
2722       var = OMP_CLAUSE_DECL (c);
2723       by_ref = use_pointer_for_field (var, NULL);
2724
2725       ref = build_sender_ref (var, ctx);
2726       x = new_var = lookup_decl_in_outer_ctx (var, ctx);
2727       if (by_ref)
2728         {
2729           x = build_fold_addr_expr_loc (clause_loc, new_var);
2730           x = fold_convert_loc (clause_loc, TREE_TYPE (ref), x);
2731         }
2732       gimplify_assign (ref, x, slist);
2733
2734       ref = build_receiver_ref (var, false, ctx);
2735       if (by_ref)
2736         {
2737           ref = fold_convert_loc (clause_loc,
2738                                   build_pointer_type (TREE_TYPE (new_var)),
2739                                   ref);
2740           ref = build_fold_indirect_ref_loc (clause_loc, ref);
2741         }
2742       if (is_reference (var))
2743         {
2744           ref = fold_convert_loc (clause_loc, TREE_TYPE (new_var), ref);
2745           ref = build_simple_mem_ref_loc (clause_loc, ref);
2746           new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2747         }
2748       x = lang_hooks.decls.omp_clause_assign_op (c, new_var, ref);
2749       gimplify_and_add (x, rlist);
2750     }
2751 }
2752
2753
2754 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
2755    and REDUCTION from the sender (aka parent) side.  */
2756
2757 static void
2758 lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist,
2759                     omp_context *ctx)
2760 {
2761   tree c;
2762
2763   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2764     {
2765       tree val, ref, x, var;
2766       bool by_ref, do_in = false, do_out = false;
2767       location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2768
2769       switch (OMP_CLAUSE_CODE (c))
2770         {
2771         case OMP_CLAUSE_PRIVATE:
2772           if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
2773             break;
2774           continue;
2775         case OMP_CLAUSE_FIRSTPRIVATE:
2776         case OMP_CLAUSE_COPYIN:
2777         case OMP_CLAUSE_LASTPRIVATE:
2778         case OMP_CLAUSE_REDUCTION:
2779           break;
2780         default:
2781           continue;
2782         }
2783
2784       val = OMP_CLAUSE_DECL (c);
2785       var = lookup_decl_in_outer_ctx (val, ctx);
2786
2787       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
2788           && is_global_var (var))
2789         continue;
2790       if (is_variable_sized (val))
2791         continue;
2792       by_ref = use_pointer_for_field (val, NULL);
2793
2794       switch (OMP_CLAUSE_CODE (c))
2795         {
2796         case OMP_CLAUSE_PRIVATE:
2797         case OMP_CLAUSE_FIRSTPRIVATE:
2798         case OMP_CLAUSE_COPYIN:
2799           do_in = true;
2800           break;
2801
2802         case OMP_CLAUSE_LASTPRIVATE:
2803           if (by_ref || is_reference (val))
2804             {
2805               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2806                 continue;
2807               do_in = true;
2808             }
2809           else
2810             {
2811               do_out = true;
2812               if (lang_hooks.decls.omp_private_outer_ref (val))
2813                 do_in = true;
2814             }
2815           break;
2816
2817         case OMP_CLAUSE_REDUCTION:
2818           do_in = true;
2819           do_out = !(by_ref || is_reference (val));
2820           break;
2821
2822         default:
2823           gcc_unreachable ();
2824         }
2825
2826       if (do_in)
2827         {
2828           ref = build_sender_ref (val, ctx);
2829           x = by_ref ? build_fold_addr_expr_loc (clause_loc, var) : var;
2830           gimplify_assign (ref, x, ilist);
2831           if (is_task_ctx (ctx))
2832             DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref, 1)) = NULL;
2833         }
2834
2835       if (do_out)
2836         {
2837           ref = build_sender_ref (val, ctx);
2838           gimplify_assign (var, ref, olist);
2839         }
2840     }
2841 }
2842
2843 /* Generate code to implement SHARED from the sender (aka parent)
2844    side.  This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
2845    list things that got automatically shared.  */
2846
2847 static void
2848 lower_send_shared_vars (gimple_seq *ilist, gimple_seq *olist, omp_context *ctx)
2849 {
2850   tree var, ovar, nvar, f, x, record_type;
2851
2852   if (ctx->record_type == NULL)
2853     return;
2854
2855   record_type = ctx->srecord_type ? ctx->srecord_type : ctx->record_type;
2856   for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
2857     {
2858       ovar = DECL_ABSTRACT_ORIGIN (f);
2859       nvar = maybe_lookup_decl (ovar, ctx);
2860       if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
2861         continue;
2862
2863       /* If CTX is a nested parallel directive.  Find the immediately
2864          enclosing parallel or workshare construct that contains a
2865          mapping for OVAR.  */
2866       var = lookup_decl_in_outer_ctx (ovar, ctx);
2867
2868       if (use_pointer_for_field (ovar, ctx))
2869         {
2870           x = build_sender_ref (ovar, ctx);
2871           var = build_fold_addr_expr (var);
2872           gimplify_assign (x, var, ilist);
2873         }
2874       else
2875         {
2876           x = build_sender_ref (ovar, ctx);
2877           gimplify_assign (x, var, ilist);
2878
2879           if (!TREE_READONLY (var)
2880               /* We don't need to receive a new reference to a result
2881                  or parm decl.  In fact we may not store to it as we will
2882                  invalidate any pending RSO and generate wrong gimple
2883                  during inlining.  */
2884               && !((TREE_CODE (var) == RESULT_DECL
2885                     || TREE_CODE (var) == PARM_DECL)
2886                    && DECL_BY_REFERENCE (var)))
2887             {
2888               x = build_sender_ref (ovar, ctx);
2889               gimplify_assign (var, x, olist);
2890             }
2891         }
2892     }
2893 }
2894
2895
2896 /* A convenience function to build an empty GIMPLE_COND with just the
2897    condition.  */
2898
2899 static gimple
2900 gimple_build_cond_empty (tree cond)
2901 {
2902   enum tree_code pred_code;
2903   tree lhs, rhs;
2904
2905   gimple_cond_get_ops_from_tree (cond, &pred_code, &lhs, &rhs);
2906   return gimple_build_cond (pred_code, lhs, rhs, NULL_TREE, NULL_TREE);
2907 }
2908
2909
2910 /* Build the function calls to GOMP_parallel_start etc to actually
2911    generate the parallel operation.  REGION is the parallel region
2912    being expanded.  BB is the block where to insert the code.  WS_ARGS
2913    will be set if this is a call to a combined parallel+workshare
2914    construct, it contains the list of additional arguments needed by
2915    the workshare construct.  */
2916
2917 static void
2918 expand_parallel_call (struct omp_region *region, basic_block bb,
2919                       gimple entry_stmt, VEC(tree,gc) *ws_args)
2920 {
2921   tree t, t1, t2, val, cond, c, clauses;
2922   gimple_stmt_iterator gsi;
2923   gimple stmt;
2924   enum built_in_function start_ix;
2925   int start_ix2;
2926   location_t clause_loc;
2927   VEC(tree,gc) *args;
2928
2929   clauses = gimple_omp_parallel_clauses (entry_stmt);
2930
2931   /* Determine what flavor of GOMP_parallel_start we will be
2932      emitting.  */
2933   start_ix = BUILT_IN_GOMP_PARALLEL_START;
2934   if (is_combined_parallel (region))
2935     {
2936       switch (region->inner->type)
2937         {
2938         case GIMPLE_OMP_FOR:
2939           gcc_assert (region->inner->sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
2940           start_ix2 = ((int)BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
2941                        + (region->inner->sched_kind
2942                           == OMP_CLAUSE_SCHEDULE_RUNTIME
2943                           ? 3 : region->inner->sched_kind));
2944           start_ix = (enum built_in_function)start_ix2;
2945           break;
2946         case GIMPLE_OMP_SECTIONS:
2947           start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS_START;
2948           break;
2949         default:
2950           gcc_unreachable ();
2951         }
2952     }
2953
2954   /* By default, the value of NUM_THREADS is zero (selected at run time)
2955      and there is no conditional.  */
2956   cond = NULL_TREE;
2957   val = build_int_cst (unsigned_type_node, 0);
2958
2959   c = find_omp_clause (clauses, OMP_CLAUSE_IF);
2960   if (c)
2961     cond = OMP_CLAUSE_IF_EXPR (c);
2962
2963   c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
2964   if (c)
2965     {
2966       val = OMP_CLAUSE_NUM_THREADS_EXPR (c);
2967       clause_loc = OMP_CLAUSE_LOCATION (c);
2968     }
2969   else
2970     clause_loc = gimple_location (entry_stmt);
2971
2972   /* Ensure 'val' is of the correct type.  */
2973   val = fold_convert_loc (clause_loc, unsigned_type_node, val);
2974
2975   /* If we found the clause 'if (cond)', build either
2976      (cond != 0) or (cond ? val : 1u).  */
2977   if (cond)
2978     {
2979       gimple_stmt_iterator gsi;
2980
2981       cond = gimple_boolify (cond);
2982
2983       if (integer_zerop (val))
2984         val = fold_build2_loc (clause_loc,
2985                            EQ_EXPR, unsigned_type_node, cond,
2986                            build_int_cst (TREE_TYPE (cond), 0));
2987       else
2988         {
2989           basic_block cond_bb, then_bb, else_bb;
2990           edge e, e_then, e_else;
2991           tree tmp_then, tmp_else, tmp_join, tmp_var;
2992
2993           tmp_var = create_tmp_var (TREE_TYPE (val), NULL);
2994           if (gimple_in_ssa_p (cfun))
2995             {
2996               tmp_then = make_ssa_name (tmp_var, NULL);
2997               tmp_else = make_ssa_name (tmp_var, NULL);
2998               tmp_join = make_ssa_name (tmp_var, NULL);
2999             }
3000           else
3001             {
3002               tmp_then = tmp_var;
3003               tmp_else = tmp_var;
3004               tmp_join = tmp_var;
3005             }
3006
3007           e = split_block (bb, NULL);
3008           cond_bb = e->src;
3009           bb = e->dest;
3010           remove_edge (e);
3011
3012           then_bb = create_empty_bb (cond_bb);
3013           else_bb = create_empty_bb (then_bb);
3014           set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
3015           set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
3016
3017           stmt = gimple_build_cond_empty (cond);
3018           gsi = gsi_start_bb (cond_bb);
3019           gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3020
3021           gsi = gsi_start_bb (then_bb);
3022           stmt = gimple_build_assign (tmp_then, val);
3023           gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3024
3025           gsi = gsi_start_bb (else_bb);
3026           stmt = gimple_build_assign
3027                    (tmp_else, build_int_cst (unsigned_type_node, 1));
3028           gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3029
3030           make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
3031           make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
3032           e_then = make_edge (then_bb, bb, EDGE_FALLTHRU);
3033           e_else = make_edge (else_bb, bb, EDGE_FALLTHRU);
3034
3035           if (gimple_in_ssa_p (cfun))
3036             {
3037               gimple phi = create_phi_node (tmp_join, bb);
3038               SSA_NAME_DEF_STMT (tmp_join) = phi;
3039               add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION);
3040               add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION);
3041             }
3042
3043           val = tmp_join;
3044         }
3045
3046       gsi = gsi_start_bb (bb);
3047       val = force_gimple_operand_gsi (&gsi, val, true, NULL_TREE,
3048                                       false, GSI_CONTINUE_LINKING);
3049     }
3050
3051   gsi = gsi_last_bb (bb);
3052   t = gimple_omp_parallel_data_arg (entry_stmt);
3053   if (t == NULL)
3054     t1 = null_pointer_node;
3055   else
3056     t1 = build_fold_addr_expr (t);
3057   t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
3058
3059   args = VEC_alloc (tree, gc, 3 + VEC_length (tree, ws_args));
3060   VEC_quick_push (tree, args, t2);
3061   VEC_quick_push (tree, args, t1);
3062   VEC_quick_push (tree, args, val);
3063   VEC_splice (tree, args, ws_args);
3064
3065   t = build_call_expr_loc_vec (UNKNOWN_LOCATION,
3066                                builtin_decl_explicit (start_ix), args);
3067
3068   force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3069                             false, GSI_CONTINUE_LINKING);
3070
3071   t = gimple_omp_parallel_data_arg (entry_stmt);
3072   if (t == NULL)
3073     t = null_pointer_node;
3074   else
3075     t = build_fold_addr_expr (t);
3076   t = build_call_expr_loc (gimple_location (entry_stmt),
3077                            gimple_omp_parallel_child_fn (entry_stmt), 1, t);
3078   force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3079                             false, GSI_CONTINUE_LINKING);
3080
3081   t = build_call_expr_loc (gimple_location (entry_stmt),
3082                            builtin_decl_explicit (BUILT_IN_GOMP_PARALLEL_END),
3083                            0);
3084   force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3085                             false, GSI_CONTINUE_LINKING);
3086 }
3087
3088
3089 /* Build the function call to GOMP_task to actually
3090    generate the task operation.  BB is the block where to insert the code.  */
3091
3092 static void
3093 expand_task_call (basic_block bb, gimple entry_stmt)
3094 {
3095   tree t, t1, t2, t3, flags, cond, c, c2, clauses;
3096   gimple_stmt_iterator gsi;
3097   location_t loc = gimple_location (entry_stmt);
3098
3099   clauses = gimple_omp_task_clauses (entry_stmt);
3100
3101   c = find_omp_clause (clauses, OMP_CLAUSE_IF);
3102   if (c)
3103     cond = gimple_boolify (OMP_CLAUSE_IF_EXPR (c));
3104   else
3105     cond = boolean_true_node;
3106
3107   c = find_omp_clause (clauses, OMP_CLAUSE_UNTIED);
3108   c2 = find_omp_clause (clauses, OMP_CLAUSE_MERGEABLE);
3109   flags = build_int_cst (unsigned_type_node,
3110                          (c ? 1 : 0) + (c2 ? 4 : 0));
3111
3112   c = find_omp_clause (clauses, OMP_CLAUSE_FINAL);
3113   if (c)
3114     {
3115       c = gimple_boolify (OMP_CLAUSE_FINAL_EXPR (c));
3116       c = fold_build3_loc (loc, COND_EXPR, unsigned_type_node, c,
3117                            build_int_cst (unsigned_type_node, 2),
3118                            build_int_cst (unsigned_type_node, 0));
3119       flags = fold_build2_loc (loc, PLUS_EXPR, unsigned_type_node, flags, c);
3120     }
3121
3122   gsi = gsi_last_bb (bb);
3123   t = gimple_omp_task_data_arg (entry_stmt);
3124   if (t == NULL)
3125     t2 = null_pointer_node;
3126   else
3127     t2 = build_fold_addr_expr_loc (loc, t);
3128   t1 = build_fold_addr_expr_loc (loc, gimple_omp_task_child_fn (entry_stmt));
3129   t = gimple_omp_task_copy_fn (entry_stmt);
3130   if (t == NULL)
3131     t3 = null_pointer_node;
3132   else
3133     t3 = build_fold_addr_expr_loc (loc, t);
3134
3135   t = build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_TASK),
3136                        7, t1, t2, t3,
3137                        gimple_omp_task_arg_size (entry_stmt),
3138                        gimple_omp_task_arg_align (entry_stmt), cond, flags);
3139
3140   force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3141                             false, GSI_CONTINUE_LINKING);
3142 }
3143
3144
3145 /* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
3146    catch handler and return it.  This prevents programs from violating the
3147    structured block semantics with throws.  */
3148
3149 static gimple_seq
3150 maybe_catch_exception (gimple_seq body)
3151 {
3152   gimple g;
3153   tree decl;
3154
3155   if (!flag_exceptions)
3156     return body;
3157
3158   if (lang_hooks.eh_protect_cleanup_actions != NULL)
3159     decl = lang_hooks.eh_protect_cleanup_actions ();
3160   else
3161     decl = builtin_decl_explicit (BUILT_IN_TRAP);
3162
3163   g = gimple_build_eh_must_not_throw (decl);
3164   g = gimple_build_try (body, gimple_seq_alloc_with_stmt (g),
3165                         GIMPLE_TRY_CATCH);
3166
3167  return gimple_seq_alloc_with_stmt (g);
3168 }
3169
3170 /* Chain all the DECLs in LIST by their TREE_CHAIN fields.  */
3171
3172 static tree
3173 vec2chain (VEC(tree,gc) *v)
3174 {
3175   tree chain = NULL_TREE, t;
3176   unsigned ix;
3177
3178   FOR_EACH_VEC_ELT_REVERSE (tree, v, ix, t)
3179     {
3180       DECL_CHAIN (t) = chain;
3181       chain = t;
3182     }
3183
3184   return chain;
3185 }
3186
3187
3188 /* Remove barriers in REGION->EXIT's block.  Note that this is only
3189    valid for GIMPLE_OMP_PARALLEL regions.  Since the end of a parallel region
3190    is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
3191    left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
3192    removed.  */
3193
3194 static void
3195 remove_exit_barrier (struct omp_region *region)
3196 {
3197   gimple_stmt_iterator gsi;
3198   basic_block exit_bb;
3199   edge_iterator ei;
3200   edge e;
3201   gimple stmt;
3202   int any_addressable_vars = -1;
3203
3204   exit_bb = region->exit;
3205
3206   /* If the parallel region doesn't return, we don't have REGION->EXIT
3207      block at all.  */
3208   if (! exit_bb)
3209     return;
3210
3211   /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN.  The
3212      workshare's GIMPLE_OMP_RETURN will be in a preceding block.  The kinds of
3213      statements that can appear in between are extremely limited -- no
3214      memory operations at all.  Here, we allow nothing at all, so the
3215      only thing we allow to precede this GIMPLE_OMP_RETURN is a label.  */
3216   gsi = gsi_last_bb (exit_bb);
3217   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
3218   gsi_prev (&gsi);
3219   if (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
3220     return;
3221
3222   FOR_EACH_EDGE (e, ei, exit_bb->preds)
3223     {
3224       gsi = gsi_last_bb (e->src);
3225       if (gsi_end_p (gsi))
3226         continue;
3227       stmt = gsi_stmt (gsi);
3228       if (gimple_code (stmt) == GIMPLE_OMP_RETURN
3229           && !gimple_omp_return_nowait_p (stmt))
3230         {
3231           /* OpenMP 3.0 tasks unfortunately prevent this optimization
3232              in many cases.  If there could be tasks queued, the barrier
3233              might be needed to let the tasks run before some local
3234              variable of the parallel that the task uses as shared
3235              runs out of scope.  The task can be spawned either
3236              from within current function (this would be easy to check)
3237              or from some function it calls and gets passed an address
3238              of such a variable.  */
3239           if (any_addressable_vars < 0)
3240             {
3241               gimple parallel_stmt = last_stmt (region->entry);
3242               tree child_fun = gimple_omp_parallel_child_fn (parallel_stmt);
3243               tree local_decls, block, decl;
3244               unsigned ix;
3245
3246               any_addressable_vars = 0;
3247               FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (child_fun), ix, decl)
3248                 if (TREE_ADDRESSABLE (decl))
3249                   {
3250                     any_addressable_vars = 1;
3251                     break;
3252                   }
3253               for (block = gimple_block (stmt);
3254                    !any_addressable_vars
3255                    && block
3256                    && TREE_CODE (block) == BLOCK;
3257                    block = BLOCK_SUPERCONTEXT (block))
3258                 {
3259                   for (local_decls = BLOCK_VARS (block);
3260                        local_decls;
3261                        local_decls = DECL_CHAIN (local_decls))
3262                     if (TREE_ADDRESSABLE (local_decls))
3263                       {
3264                         any_addressable_vars = 1;
3265                         break;
3266                       }
3267                   if (block == gimple_block (parallel_stmt))
3268                     break;
3269                 }
3270             }
3271           if (!any_addressable_vars)
3272             gimple_omp_return_set_nowait (stmt);
3273         }
3274     }
3275 }
3276
3277 static void
3278 remove_exit_barriers (struct omp_region *region)
3279 {
3280   if (region->type == GIMPLE_OMP_PARALLEL)
3281     remove_exit_barrier (region);
3282
3283   if (region->inner)
3284     {
3285       region = region->inner;
3286       remove_exit_barriers (region);
3287       while (region->next)
3288         {
3289           region = region->next;
3290           remove_exit_barriers (region);
3291         }
3292     }
3293 }
3294
3295 /* Optimize omp_get_thread_num () and omp_get_num_threads ()
3296    calls.  These can't be declared as const functions, but
3297    within one parallel body they are constant, so they can be
3298    transformed there into __builtin_omp_get_{thread_num,num_threads} ()
3299    which are declared const.  Similarly for task body, except
3300    that in untied task omp_get_thread_num () can change at any task
3301    scheduling point.  */
3302
3303 static void
3304 optimize_omp_library_calls (gimple entry_stmt)
3305 {
3306   basic_block bb;
3307   gimple_stmt_iterator gsi;
3308   tree thr_num_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
3309   tree thr_num_id = DECL_ASSEMBLER_NAME (thr_num_tree);
3310   tree num_thr_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
3311   tree num_thr_id = DECL_ASSEMBLER_NAME (num_thr_tree);
3312   bool untied_task = (gimple_code (entry_stmt) == GIMPLE_OMP_TASK
3313                       && find_omp_clause (gimple_omp_task_clauses (entry_stmt),
3314                                           OMP_CLAUSE_UNTIED) != NULL);
3315
3316   FOR_EACH_BB (bb)
3317     for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3318       {
3319         gimple call = gsi_stmt (gsi);
3320         tree decl;
3321
3322         if (is_gimple_call (call)
3323             && (decl = gimple_call_fndecl (call))
3324             && DECL_EXTERNAL (decl)
3325             && TREE_PUBLIC (decl)
3326             && DECL_INITIAL (decl) == NULL)
3327           {
3328             tree built_in;
3329
3330             if (DECL_NAME (decl) == thr_num_id)
3331               {
3332                 /* In #pragma omp task untied omp_get_thread_num () can change
3333                    during the execution of the task region.  */
3334                 if (untied_task)
3335                   continue;
3336                 built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
3337               }
3338             else if (DECL_NAME (decl) == num_thr_id)
3339               built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
3340             else
3341               continue;
3342
3343             if (DECL_ASSEMBLER_NAME (decl) != DECL_ASSEMBLER_NAME (built_in)
3344                 || gimple_call_num_args (call) != 0)
3345               continue;
3346
3347             if (flag_exceptions && !TREE_NOTHROW (decl))
3348               continue;
3349
3350             if (TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE
3351                 || !types_compatible_p (TREE_TYPE (TREE_TYPE (decl)),
3352                                         TREE_TYPE (TREE_TYPE (built_in))))
3353               continue;
3354
3355             gimple_call_set_fndecl (call, built_in);
3356           }
3357       }
3358 }
3359
3360 /* Expand the OpenMP parallel or task directive starting at REGION.  */
3361
3362 static void
3363 expand_omp_taskreg (struct omp_region *region)
3364 {
3365   basic_block entry_bb, exit_bb, new_bb;
3366   struct function *child_cfun;
3367   tree child_fn, block, t;
3368   tree save_current;
3369   gimple_stmt_iterator gsi;
3370   gimple entry_stmt, stmt;
3371   edge e;
3372   VEC(tree,gc) *ws_args;
3373
3374   entry_stmt = last_stmt (region->entry);
3375   child_fn = gimple_omp_taskreg_child_fn (entry_stmt);
3376   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
3377   /* If this function has been already instrumented, make sure
3378      the child function isn't instrumented again.  */
3379   child_cfun->after_tree_profile = cfun->after_tree_profile;
3380
3381   entry_bb = region->entry;
3382   exit_bb = region->exit;
3383
3384   if (is_combined_parallel (region))
3385     ws_args = region->ws_args;
3386   else
3387     ws_args = NULL;
3388
3389   if (child_cfun->cfg)
3390     {
3391       /* Due to inlining, it may happen that we have already outlined
3392          the region, in which case all we need to do is make the
3393          sub-graph unreachable and emit the parallel call.  */
3394       edge entry_succ_e, exit_succ_e;
3395       gimple_stmt_iterator gsi;
3396
3397       entry_succ_e = single_succ_edge (entry_bb);
3398
3399       gsi = gsi_last_bb (entry_bb);
3400       gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_PARALLEL
3401                   || gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_TASK);
3402       gsi_remove (&gsi, true);
3403
3404       new_bb = entry_bb;
3405       if (exit_bb)
3406         {
3407           exit_succ_e = single_succ_edge (exit_bb);
3408           make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
3409         }
3410       remove_edge_and_dominated_blocks (entry_succ_e);
3411     }
3412   else
3413     {
3414       unsigned srcidx, dstidx, num;
3415
3416       /* If the parallel region needs data sent from the parent
3417          function, then the very first statement (except possible
3418          tree profile counter updates) of the parallel body
3419          is a copy assignment .OMP_DATA_I = &.OMP_DATA_O.  Since
3420          &.OMP_DATA_O is passed as an argument to the child function,
3421          we need to replace it with the argument as seen by the child
3422          function.
3423
3424          In most cases, this will end up being the identity assignment
3425          .OMP_DATA_I = .OMP_DATA_I.  However, if the parallel body had
3426          a function call that has been inlined, the original PARM_DECL
3427          .OMP_DATA_I may have been converted into a different local
3428          variable.  In which case, we need to keep the assignment.  */
3429       if (gimple_omp_taskreg_data_arg (entry_stmt))
3430         {
3431           basic_block entry_succ_bb = single_succ (entry_bb);
3432           gimple_stmt_iterator gsi;
3433           tree arg, narg;
3434           gimple parcopy_stmt = NULL;
3435
3436           for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
3437             {
3438               gimple stmt;
3439
3440               gcc_assert (!gsi_end_p (gsi));
3441               stmt = gsi_stmt (gsi);
3442               if (gimple_code (stmt) != GIMPLE_ASSIGN)
3443                 continue;
3444
3445               if (gimple_num_ops (stmt) == 2)
3446                 {
3447                   tree arg = gimple_assign_rhs1 (stmt);
3448
3449                   /* We're ignore the subcode because we're
3450                      effectively doing a STRIP_NOPS.  */
3451
3452                   if (TREE_CODE (arg) == ADDR_EXPR
3453                       && TREE_OPERAND (arg, 0)
3454                         == gimple_omp_taskreg_data_arg (entry_stmt))
3455                     {
3456                       parcopy_stmt = stmt;
3457                       break;
3458                     }
3459                 }
3460             }
3461
3462           gcc_assert (parcopy_stmt != NULL);
3463           arg = DECL_ARGUMENTS (child_fn);
3464
3465           if (!gimple_in_ssa_p (cfun))
3466             {
3467               if (gimple_assign_lhs (parcopy_stmt) == arg)
3468                 gsi_remove (&gsi, true);
3469               else
3470                 {
3471                   /* ?? Is setting the subcode really necessary ??  */
3472                   gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (arg));
3473                   gimple_assign_set_rhs1 (parcopy_stmt, arg);
3474                 }
3475             }
3476           else
3477             {
3478               /* If we are in ssa form, we must load the value from the default
3479                  definition of the argument.  That should not be defined now,
3480                  since the argument is not used uninitialized.  */
3481               gcc_assert (gimple_default_def (cfun, arg) == NULL);
3482               narg = make_ssa_name (arg, gimple_build_nop ());
3483               set_default_def (arg, narg);
3484               /* ?? Is setting the subcode really necessary ??  */
3485               gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (narg));
3486               gimple_assign_set_rhs1 (parcopy_stmt, narg);
3487               update_stmt (parcopy_stmt);
3488             }
3489         }
3490
3491       /* Declare local variables needed in CHILD_CFUN.  */
3492       block = DECL_INITIAL (child_fn);
3493       BLOCK_VARS (block) = vec2chain (child_cfun->local_decls);
3494       /* The gimplifier could record temporaries in parallel/task block
3495          rather than in containing function's local_decls chain,
3496          which would mean cgraph missed finalizing them.  Do it now.  */
3497       for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
3498         if (TREE_CODE (t) == VAR_DECL
3499             && TREE_STATIC (t)
3500             && !DECL_EXTERNAL (t))
3501           varpool_finalize_decl (t);
3502       DECL_SAVED_TREE (child_fn) = NULL;
3503       gimple_set_body (child_fn, bb_seq (single_succ (entry_bb)));
3504       TREE_USED (block) = 1;
3505
3506       /* Reset DECL_CONTEXT on function arguments.  */
3507       for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
3508         DECL_CONTEXT (t) = child_fn;
3509
3510       /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
3511          so that it can be moved to the child function.  */
3512       gsi = gsi_last_bb (entry_bb);
3513       stmt = gsi_stmt (gsi);
3514       gcc_assert (stmt && (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
3515                            || gimple_code (stmt) == GIMPLE_OMP_TASK));
3516       gsi_remove (&gsi, true);
3517       e = split_block (entry_bb, stmt);
3518       entry_bb = e->dest;
3519       single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3520
3521       /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR.  */
3522       if (exit_bb)
3523         {
3524           gsi = gsi_last_bb (exit_bb);
3525           gcc_assert (!gsi_end_p (gsi)
3526                       && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
3527           stmt = gimple_build_return (NULL);
3528           gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
3529           gsi_remove (&gsi, true);
3530         }
3531
3532       /* Move the parallel region into CHILD_CFUN.  */
3533
3534       if (gimple_in_ssa_p (cfun))
3535         {
3536           push_cfun (child_cfun);
3537           init_tree_ssa (child_cfun);
3538           init_ssa_operands ();
3539           cfun->gimple_df->in_ssa_p = true;
3540           pop_cfun ();
3541           block = NULL_TREE;
3542         }
3543       else
3544         block = gimple_block (entry_stmt);
3545
3546       new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
3547       if (exit_bb)
3548         single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
3549
3550       /* Remove non-local VAR_DECLs from child_cfun->local_decls list.  */
3551       num = VEC_length (tree, child_cfun->local_decls);
3552       for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
3553         {
3554           t = VEC_index (tree, child_cfun->local_decls, srcidx);
3555           if (DECL_CONTEXT (t) == cfun->decl)
3556             continue;
3557           if (srcidx != dstidx)
3558             VEC_replace (tree, child_cfun->local_decls, dstidx, t);
3559           dstidx++;
3560         }
3561       if (dstidx != num)
3562         VEC_truncate (tree, child_cfun->local_decls, dstidx);
3563
3564       /* Inform the callgraph about the new function.  */
3565       DECL_STRUCT_FUNCTION (child_fn)->curr_properties
3566         = cfun->curr_properties;
3567       cgraph_add_new_function (child_fn, true);
3568
3569       /* Fix the callgraph edges for child_cfun.  Those for cfun will be
3570          fixed in a following pass.  */
3571       push_cfun (child_cfun);
3572       save_current = current_function_decl;
3573       current_function_decl = child_fn;
3574       if (optimize)
3575         optimize_omp_library_calls (entry_stmt);
3576       rebuild_cgraph_edges ();
3577
3578       /* Some EH regions might become dead, see PR34608.  If
3579          pass_cleanup_cfg isn't the first pass to happen with the
3580          new child, these dead EH edges might cause problems.
3581          Clean them up now.  */
3582       if (flag_exceptions)
3583         {
3584           basic_block bb;
3585           bool changed = false;
3586
3587           FOR_EACH_BB (bb)
3588             changed |= gimple_purge_dead_eh_edges (bb);
3589           if (changed)
3590             cleanup_tree_cfg ();
3591         }
3592       if (gimple_in_ssa_p (cfun))
3593         update_ssa (TODO_update_ssa);
3594       current_function_decl = save_current;
3595       pop_cfun ();
3596     }
3597
3598   /* Emit a library call to launch the children threads.  */
3599   if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
3600     expand_parallel_call (region, new_bb, entry_stmt, ws_args);
3601   else
3602     expand_task_call (new_bb, entry_stmt);
3603   update_ssa (TODO_update_ssa_only_virtuals);
3604 }
3605
3606
3607 /* A subroutine of expand_omp_for.  Generate code for a parallel
3608    loop with any schedule.  Given parameters:
3609
3610         for (V = N1; V cond N2; V += STEP) BODY;
3611
3612    where COND is "<" or ">", we generate pseudocode
3613
3614         more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
3615         if (more) goto L0; else goto L3;
3616     L0:
3617         V = istart0;
3618         iend = iend0;
3619     L1:
3620         BODY;
3621         V += STEP;
3622         if (V cond iend) goto L1; else goto L2;
3623     L2:
3624         if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3625     L3:
3626
3627     If this is a combined omp parallel loop, instead of the call to
3628     GOMP_loop_foo_start, we call GOMP_loop_foo_next.
3629
3630     For collapsed loops, given parameters:
3631       collapse(3)
3632       for (V1 = N11; V1 cond1 N12; V1 += STEP1)
3633         for (V2 = N21; V2 cond2 N22; V2 += STEP2)
3634           for (V3 = N31; V3 cond3 N32; V3 += STEP3)
3635             BODY;
3636
3637     we generate pseudocode
3638
3639         if (cond3 is <)
3640           adj = STEP3 - 1;
3641         else
3642           adj = STEP3 + 1;
3643         count3 = (adj + N32 - N31) / STEP3;
3644         if (cond2 is <)
3645           adj = STEP2 - 1;
3646         else
3647           adj = STEP2 + 1;
3648         count2 = (adj + N22 - N21) / STEP2;
3649         if (cond1 is <)
3650           adj = STEP1 - 1;
3651         else
3652           adj = STEP1 + 1;
3653         count1 = (adj + N12 - N11) / STEP1;
3654         count = count1 * count2 * count3;
3655         more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
3656         if (more) goto L0; else goto L3;
3657     L0:
3658         V = istart0;
3659         T = V;
3660         V3 = N31 + (T % count3) * STEP3;
3661         T = T / count3;
3662         V2 = N21 + (T % count2) * STEP2;
3663         T = T / count2;
3664         V1 = N11 + T * STEP1;
3665         iend = iend0;
3666     L1:
3667         BODY;
3668         V += 1;
3669         if (V < iend) goto L10; else goto L2;
3670     L10:
3671         V3 += STEP3;
3672         if (V3 cond3 N32) goto L1; else goto L11;
3673     L11:
3674         V3 = N31;
3675         V2 += STEP2;
3676         if (V2 cond2 N22) goto L1; else goto L12;
3677     L12:
3678         V2 = N21;
3679         V1 += STEP1;
3680         goto L1;
3681     L2:
3682         if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3683     L3:
3684
3685       */
3686
3687 static void
3688 expand_omp_for_generic (struct omp_region *region,
3689                         struct omp_for_data *fd,
3690                         enum built_in_function start_fn,
3691                         enum built_in_function next_fn)
3692 {
3693   tree type, istart0, iend0, iend;
3694   tree t, vmain, vback, bias = NULL_TREE;
3695   basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, collapse_bb;
3696   basic_block l2_bb = NULL, l3_bb = NULL;
3697   gimple_stmt_iterator gsi;
3698   gimple stmt;
3699   bool in_combined_parallel = is_combined_parallel (region);
3700   bool broken_loop = region->cont == NULL;
3701   edge e, ne;
3702   tree *counts = NULL;
3703   int i;
3704
3705   gcc_assert (!broken_loop || !in_combined_parallel);
3706   gcc_assert (fd->iter_type == long_integer_type_node
3707               || !in_combined_parallel);
3708
3709   type = TREE_TYPE (fd->loop.v);
3710   istart0 = create_tmp_var (fd->iter_type, ".istart0");
3711   iend0 = create_tmp_var (fd->iter_type, ".iend0");
3712   TREE_ADDRESSABLE (istart0) = 1;
3713   TREE_ADDRESSABLE (iend0) = 1;
3714   if (gimple_in_ssa_p (cfun))
3715     {
3716       add_referenced_var (istart0);
3717       add_referenced_var (iend0);
3718     }
3719
3720   /* See if we need to bias by LLONG_MIN.  */
3721   if (fd->iter_type == long_long_unsigned_type_node
3722       && TREE_CODE (type) == INTEGER_TYPE
3723       && !TYPE_UNSIGNED (type))
3724     {
3725       tree n1, n2;
3726
3727       if (fd->loop.cond_code == LT_EXPR)
3728         {
3729           n1 = fd->loop.n1;
3730           n2 = fold_build2 (PLUS_EXPR, type, fd->loop.n2, fd->loop.step);
3731         }
3732       else
3733         {
3734           n1 = fold_build2 (MINUS_EXPR, type, fd->loop.n2, fd->loop.step);
3735           n2 = fd->loop.n1;
3736         }
3737       if (TREE_CODE (n1) != INTEGER_CST
3738           || TREE_CODE (n2) != INTEGER_CST
3739           || ((tree_int_cst_sgn (n1) < 0) ^ (tree_int_cst_sgn (n2) < 0)))
3740         bias = fold_convert (fd->iter_type, TYPE_MIN_VALUE (type));
3741     }
3742
3743   entry_bb = region->entry;
3744   cont_bb = region->cont;
3745   collapse_bb = NULL;
3746   gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
3747   gcc_assert (broken_loop
3748               || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
3749   l0_bb = split_edge (FALLTHRU_EDGE (entry_bb));
3750   l1_bb = single_succ (l0_bb);
3751   if (!broken_loop)
3752     {
3753       l2_bb = create_empty_bb (cont_bb);
3754       gcc_assert (BRANCH_EDGE (cont_bb)->dest == l1_bb);
3755       gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
3756     }
3757   else
3758     l2_bb = NULL;
3759   l3_bb = BRANCH_EDGE (entry_bb)->dest;
3760   exit_bb = region->exit;
3761
3762   gsi = gsi_last_bb (entry_bb);
3763
3764   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
3765   if (fd->collapse > 1)
3766     {
3767       /* collapsed loops need work for expansion in SSA form.  */
3768       gcc_assert (!gimple_in_ssa_p (cfun));
3769       counts = (tree *) alloca (fd->collapse * sizeof (tree));
3770       for (i = 0; i < fd->collapse; i++)
3771         {
3772           tree itype = TREE_TYPE (fd->loops[i].v);
3773
3774           if (POINTER_TYPE_P (itype))
3775             itype = lang_hooks.types.type_for_size (TYPE_PRECISION (itype), 0);
3776           t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR
3777                                      ? -1 : 1));
3778           t = fold_build2 (PLUS_EXPR, itype,
3779                            fold_convert (itype, fd->loops[i].step), t);
3780           t = fold_build2 (PLUS_EXPR, itype, t,
3781                            fold_convert (itype, fd->loops[i].n2));
3782           t = fold_build2 (MINUS_EXPR, itype, t,
3783                            fold_convert (itype, fd->loops[i].n1));
3784           if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
3785             t = fold_build2 (TRUNC_DIV_EXPR, itype,
3786                              fold_build1 (NEGATE_EXPR, itype, t),
3787                              fold_build1 (NEGATE_EXPR, itype,
3788                                           fold_convert (itype,
3789                                                         fd->loops[i].step)));
3790           else
3791             t = fold_build2 (TRUNC_DIV_EXPR, itype, t,
3792                              fold_convert (itype, fd->loops[i].step));
3793           t = fold_convert (type, t);
3794           if (TREE_CODE (t) == INTEGER_CST)
3795             counts[i] = t;
3796           else
3797             {
3798               counts[i] = create_tmp_var (type, ".count");
3799               t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3800                                             true, GSI_SAME_STMT);
3801               stmt = gimple_build_assign (counts[i], t);
3802               gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3803             }
3804           if (SSA_VAR_P (fd->loop.n2))
3805             {
3806               if (i == 0)
3807                 t = counts[0];
3808               else
3809                 {
3810                   t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
3811                   t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3812                                                 true, GSI_SAME_STMT);
3813                 }
3814               stmt = gimple_build_assign (fd->loop.n2, t);
3815               gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3816             }
3817         }
3818     }
3819   if (in_combined_parallel)
3820     {
3821       /* In a combined parallel loop, emit a call to
3822          GOMP_loop_foo_next.  */
3823       t = build_call_expr (builtin_decl_explicit (next_fn), 2,
3824                            build_fold_addr_expr (istart0),
3825                            build_fold_addr_expr (iend0));
3826     }
3827   else
3828     {
3829       tree t0, t1, t2, t3, t4;
3830       /* If this is not a combined parallel loop, emit a call to
3831          GOMP_loop_foo_start in ENTRY_BB.  */
3832       t4 = build_fold_addr_expr (iend0);
3833       t3 = build_fold_addr_expr (istart0);
3834       t2 = fold_convert (fd->iter_type, fd->loop.step);
3835       if (POINTER_TYPE_P (type)
3836           && TYPE_PRECISION (type) != TYPE_PRECISION (fd->iter_type))
3837         {
3838           /* Avoid casting pointers to integer of a different size.  */
3839           tree itype
3840             = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
3841           t1 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n2));
3842           t0 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n1));
3843         }
3844       else
3845         {
3846           t1 = fold_convert (fd->iter_type, fd->loop.n2);
3847           t0 = fold_convert (fd->iter_type, fd->loop.n1);
3848         }
3849       if (bias)
3850         {
3851           t1 = fold_build2 (PLUS_EXPR, fd->iter_type, t1, bias);
3852           t0 = fold_build2 (PLUS_EXPR, fd->iter_type, t0, bias);
3853         }
3854       if (fd->iter_type == long_integer_type_node)
3855         {
3856           if (fd->chunk_size)
3857             {
3858               t = fold_convert (fd->iter_type, fd->chunk_size);
3859               t = build_call_expr (builtin_decl_explicit (start_fn),
3860                                    6, t0, t1, t2, t, t3, t4);
3861             }
3862           else
3863             t = build_call_expr (builtin_decl_explicit (start_fn),
3864                                  5, t0, t1, t2, t3, t4);
3865         }
3866       else
3867         {
3868           tree t5;
3869           tree c_bool_type;
3870           tree bfn_decl;
3871
3872           /* The GOMP_loop_ull_*start functions have additional boolean
3873              argument, true for < loops and false for > loops.
3874              In Fortran, the C bool type can be different from
3875              boolean_type_node.  */
3876           bfn_decl = builtin_decl_explicit (start_fn);
3877           c_bool_type = TREE_TYPE (TREE_TYPE (bfn_decl));
3878           t5 = build_int_cst (c_bool_type,
3879                               fd->loop.cond_code == LT_EXPR ? 1 : 0);
3880           if (fd->chunk_size)
3881             {
3882               tree bfn_decl = builtin_decl_explicit (start_fn);
3883               t = fold_convert (fd->iter_type, fd->chunk_size);
3884               t = build_call_expr (bfn_decl, 7, t5, t0, t1, t2, t, t3, t4);
3885             }
3886           else
3887             t = build_call_expr (builtin_decl_explicit (start_fn),
3888                                  6, t5, t0, t1, t2, t3, t4);
3889         }
3890     }
3891   if (TREE_TYPE (t) != boolean_type_node)
3892     t = fold_build2 (NE_EXPR, boolean_type_node,
3893                      t, build_int_cst (TREE_TYPE (t), 0));
3894   t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3895                                 true, GSI_SAME_STMT);
3896   gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
3897
3898   /* Remove the GIMPLE_OMP_FOR statement.  */
3899   gsi_remove (&gsi, true);
3900
3901   /* Iteration setup for sequential loop goes in L0_BB.  */
3902   gsi = gsi_start_bb (l0_bb);
3903   t = istart0;
3904   if (bias)
3905     t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
3906   if (POINTER_TYPE_P (type))
3907     t = fold_convert (lang_hooks.types.type_for_size (TYPE_PRECISION (type),
3908                                                       0), t);
3909   t = fold_convert (type, t);
3910   t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3911                                 false, GSI_CONTINUE_LINKING);
3912   stmt = gimple_build_assign (fd->loop.v, t);
3913   gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3914
3915   t = iend0;
3916   if (bias)
3917     t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
3918   if (POINTER_TYPE_P (type))
3919     t = fold_convert (lang_hooks.types.type_for_size (TYPE_PRECISION (type),
3920                                                       0), t);
3921   t = fold_convert (type, t);
3922   iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3923                                    false, GSI_CONTINUE_LINKING);
3924   if (fd->collapse > 1)
3925     {
3926       tree tem = create_tmp_var (type, ".tem");
3927
3928       stmt = gimple_build_assign (tem, fd->loop.v);
3929       gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3930       for (i = fd->collapse - 1; i >= 0; i--)
3931         {
3932           tree vtype = TREE_TYPE (fd->loops[i].v), itype;
3933           itype = vtype;
3934           if (POINTER_TYPE_P (vtype))
3935             itype = lang_hooks.types.type_for_size (TYPE_PRECISION (vtype), 0);
3936           t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
3937           t = fold_convert (itype, t);
3938           t = fold_build2 (MULT_EXPR, itype, t,
3939                            fold_convert (itype, fd->loops[i].step));
3940           if (POINTER_TYPE_P (vtype))
3941             t = fold_build_pointer_plus (fd->loops[i].n1, t);
3942           else
3943             t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
3944           t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3945                                         false, GSI_CONTINUE_LINKING);
3946           stmt = gimple_build_assign (fd->loops[i].v, t);
3947           gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3948           if (i != 0)
3949             {
3950               t = fold_build2 (TRUNC_DIV_EXPR, type, tem, counts[i]);
3951               t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3952                                             false, GSI_CONTINUE_LINKING);
3953               stmt = gimple_build_assign (tem, t);
3954               gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3955             }
3956         }
3957     }
3958
3959   if (!broken_loop)
3960     {
3961       /* Code to control the increment and predicate for the sequential
3962          loop goes in the CONT_BB.  */
3963       gsi = gsi_last_bb (cont_bb);
3964       stmt = gsi_stmt (gsi);
3965       gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
3966       vmain = gimple_omp_continue_control_use (stmt);
3967       vback = gimple_omp_continue_control_def (stmt);
3968
3969       if (POINTER_TYPE_P (type))
3970         t = fold_build_pointer_plus (vmain, fd->loop.step);
3971       else
3972         t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
3973       t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3974                                     true, GSI_SAME_STMT);
3975       stmt = gimple_build_assign (vback, t);
3976       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3977
3978       t = build2 (fd->loop.cond_code, boolean_type_node, vback, iend);
3979       stmt = gimple_build_cond_empty (t);
3980       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3981
3982       /* Remove GIMPLE_OMP_CONTINUE.  */
3983       gsi_remove (&gsi, true);
3984
3985       if (fd->collapse > 1)
3986         {
3987           basic_block last_bb, bb;
3988
3989           last_bb = cont_bb;
3990           for (i = fd->collapse - 1; i >= 0; i--)
3991             {
3992               tree vtype = TREE_TYPE (fd->loops[i].v);
3993
3994               bb = create_empty_bb (last_bb);
3995               gsi = gsi_start_bb (bb);
3996
3997               if (i < fd->collapse - 1)
3998                 {
3999                   e = make_edge (last_bb, bb, EDGE_FALSE_VALUE);
4000                   e->probability = REG_BR_PROB_BASE / 8;
4001
4002                   t = fd->loops[i + 1].n1;
4003                   t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4004                                                 false, GSI_CONTINUE_LINKING);
4005                   stmt = gimple_build_assign (fd->loops[i + 1].v, t);
4006                   gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4007                 }
4008               else
4009                 collapse_bb = bb;
4010
4011               set_immediate_dominator (CDI_DOMINATORS, bb, last_bb);
4012
4013               if (POINTER_TYPE_P (vtype))
4014                 t = fold_build_pointer_plus (fd->loops[i].v, fd->loops[i].step);
4015               else
4016                 t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v,
4017                                  fd->loops[i].step);
4018               t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4019                                             false, GSI_CONTINUE_LINKING);
4020               stmt = gimple_build_assign (fd->loops[i].v, t);
4021               gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4022
4023               if (i > 0)
4024                 {
4025                   t = fd->loops[i].n2;
4026                   t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4027                                                 false, GSI_CONTINUE_LINKING);
4028                   t = fold_build2 (fd->loops[i].cond_code, boolean_type_node,
4029                                    fd->loops[i].v, t);
4030                   stmt = gimple_build_cond_empty (t);
4031                   gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4032                   e = make_edge (bb, l1_bb, EDGE_TRUE_VALUE);
4033                   e->probability = REG_BR_PROB_BASE * 7 / 8;
4034                 }
4035               else
4036                 make_edge (bb, l1_bb, EDGE_FALLTHRU);
4037               last_bb = bb;
4038             }
4039         }
4040
4041       /* Emit code to get the next parallel iteration in L2_BB.  */
4042       gsi = gsi_start_bb (l2_bb);
4043
4044       t = build_call_expr (builtin_decl_explicit (next_fn), 2,
4045                            build_fold_addr_expr (istart0),
4046                            build_fold_addr_expr (iend0));
4047       t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4048                                     false, GSI_CONTINUE_LINKING);
4049       if (TREE_TYPE (t) != boolean_type_node)
4050         t = fold_build2 (NE_EXPR, boolean_type_node,
4051                          t, build_int_cst (TREE_TYPE (t), 0));
4052       stmt = gimple_build_cond_empty (t);
4053       gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4054     }
4055
4056   /* Add the loop cleanup function.  */
4057   gsi = gsi_last_bb (exit_bb);
4058   if (gimple_omp_return_nowait_p (gsi_stmt (gsi)))
4059     t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_NOWAIT);
4060   else
4061     t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END);
4062   stmt = gimple_build_call (t, 0);
4063   gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
4064   gsi_remove (&gsi, true);
4065
4066   /* Connect the new blocks.  */
4067   find_edge (entry_bb, l0_bb)->flags = EDGE_TRUE_VALUE;
4068   find_edge (entry_bb, l3_bb)->flags = EDGE_FALSE_VALUE;
4069
4070   if (!broken_loop)
4071     {
4072       gimple_seq phis;
4073
4074       e = find_edge (cont_bb, l3_bb);
4075       ne = make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
4076
4077       phis = phi_nodes (l3_bb);
4078       for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
4079         {
4080           gimple phi = gsi_stmt (gsi);
4081           SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, ne),
4082                    PHI_ARG_DEF_FROM_EDGE (phi, e));
4083         }
4084       remove_edge (e);
4085
4086       make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
4087       if (fd->collapse > 1)
4088         {
4089           e = find_edge (cont_bb, l1_bb);
4090           remove_edge (e);
4091           e = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
4092         }
4093       else
4094         {
4095           e = find_edge (cont_bb, l1_bb);
4096           e->flags = EDGE_TRUE_VALUE;
4097         }
4098       e->probability = REG_BR_PROB_BASE * 7 / 8;
4099       find_edge (cont_bb, l2_bb)->probability = REG_BR_PROB_BASE / 8;
4100       make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
4101
4102       set_immediate_dominator (CDI_DOMINATORS, l2_bb,
4103                                recompute_dominator (CDI_DOMINATORS, l2_bb));
4104       set_immediate_dominator (CDI_DOMINATORS, l3_bb,
4105                                recompute_dominator (CDI_DOMINATORS, l3_bb));
4106       set_immediate_dominator (CDI_DOMINATORS, l0_bb,
4107                                recompute_dominator (CDI_DOMINATORS, l0_bb));
4108       set_immediate_dominator (CDI_DOMINATORS, l1_bb,
4109                                recompute_dominator (CDI_DOMINATORS, l1_bb));
4110     }
4111 }
4112
4113
4114 /* A subroutine of expand_omp_for.  Generate code for a parallel
4115    loop with static schedule and no specified chunk size.  Given
4116    parameters:
4117
4118         for (V = N1; V cond N2; V += STEP) BODY;
4119
4120    where COND is "<" or ">", we generate pseudocode
4121
4122         if (cond is <)
4123           adj = STEP - 1;
4124         else
4125           adj = STEP + 1;
4126         if ((__typeof (V)) -1 > 0 && cond is >)
4127           n = -(adj + N2 - N1) / -STEP;
4128         else
4129           n = (adj + N2 - N1) / STEP;
4130         q = n / nthreads;
4131         tt = n % nthreads;
4132         if (threadid < tt) goto L3; else goto L4;
4133     L3:
4134         tt = 0;
4135         q = q + 1;
4136     L4:
4137         s0 = q * threadid + tt;
4138         e0 = s0 + q;
4139         V = s0 * STEP + N1;
4140         if (s0 >= e0) goto L2; else goto L0;
4141     L0:
4142         e = e0 * STEP + N1;
4143     L1:
4144         BODY;
4145         V += STEP;
4146         if (V cond e) goto L1;
4147     L2:
4148 */
4149
4150 static void
4151 expand_omp_for_static_nochunk (struct omp_region *region,
4152                                struct omp_for_data *fd)
4153 {
4154   tree n, q, s0, e0, e, t, tt, nthreads, threadid;
4155   tree type, itype, vmain, vback;
4156   basic_block entry_bb, second_bb, third_bb, exit_bb, seq_start_bb;
4157   basic_block body_bb, cont_bb;
4158   basic_block fin_bb;
4159   gimple_stmt_iterator gsi;
4160   gimple stmt;
4161   edge ep;
4162
4163   itype = type = TREE_TYPE (fd->loop.v);
4164   if (POINTER_TYPE_P (type))
4165     itype = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
4166
4167   entry_bb = region->entry;
4168   cont_bb = region->cont;
4169   gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
4170   gcc_assert (BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
4171   seq_start_bb = split_edge (FALLTHRU_EDGE (entry_bb));
4172   body_bb = single_succ (seq_start_bb);
4173   gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
4174   gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
4175   fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
4176   exit_bb = region->exit;
4177
4178   /* Iteration space partitioning goes in ENTRY_BB.  */
4179   gsi = gsi_last_bb (entry_bb);
4180   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
4181
4182   t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS), 0);
4183   t = fold_convert (itype, t);
4184   nthreads = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4185                                        true, GSI_SAME_STMT);
4186
4187   t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM), 0);
4188   t = fold_convert (itype, t);
4189   threadid = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4190                                        true, GSI_SAME_STMT);
4191
4192   fd->loop.n1
4193     = force_gimple_operand_gsi (&gsi, fold_convert (type, fd->loop.n1),
4194                                 true, NULL_TREE, true, GSI_SAME_STMT);
4195   fd->loop.n2
4196     = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->loop.n2),
4197                                 true, NULL_TREE, true, GSI_SAME_STMT);
4198   fd->loop.step
4199     = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->loop.step),
4200                                 true, NULL_TREE, true, GSI_SAME_STMT);
4201
4202   t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
4203   t = fold_build2 (PLUS_EXPR, itype, fd->loop.step, t);
4204   t = fold_build2 (PLUS_EXPR, itype, t, fd->loop.n2);
4205   t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, fd->loop.n1));
4206   if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
4207     t = fold_build2 (TRUNC_DIV_EXPR, itype,
4208                      fold_build1 (NEGATE_EXPR, itype, t),
4209                      fold_build1 (NEGATE_EXPR, itype, fd->loop.step));
4210   else
4211     t = fold_build2 (TRUNC_DIV_EXPR, itype, t, fd->loop.step);
4212   t = fold_convert (itype, t);
4213   n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4214
4215   q = create_tmp_var (itype, "q");
4216   t = fold_build2 (TRUNC_DIV_EXPR, itype, n, nthreads);
4217   t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
4218   gsi_insert_before (&gsi, gimple_build_assign (q, t), GSI_SAME_STMT);
4219
4220   tt = create_tmp_var (itype, "tt");
4221   t = fold_build2 (TRUNC_MOD_EXPR, itype, n, nthreads);
4222   t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
4223   gsi_insert_before (&gsi, gimple_build_assign (tt, t), GSI_SAME_STMT);
4224
4225   t = build2 (LT_EXPR, boolean_type_node, threadid, tt);
4226   stmt = gimple_build_cond_empty (t);
4227   gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4228
4229   second_bb = split_block (entry_bb, stmt)->dest;
4230   gsi = gsi_last_bb (second_bb);
4231   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
4232
4233   gsi_insert_before (&gsi, gimple_build_assign (tt, build_int_cst (itype, 0)),
4234                      GSI_SAME_STMT);
4235   stmt = gimple_build_assign_with_ops (PLUS_EXPR, q, q,
4236                                        build_int_cst (itype, 1));
4237   gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4238
4239   third_bb = split_block (second_bb, stmt)->dest;
4240   gsi = gsi_last_bb (third_bb);
4241   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
4242
4243   t = build2 (MULT_EXPR, itype, q, threadid);
4244   t = build2 (PLUS_EXPR, itype, t, tt);
4245   s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4246
4247   t = fold_build2 (PLUS_EXPR, itype, s0, q);
4248   e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4249
4250   t = build2 (GE_EXPR, boolean_type_node, s0, e0);
4251   gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
4252
4253   /* Remove the GIMPLE_OMP_FOR statement.  */
4254   gsi_remove (&gsi, true);
4255
4256   /* Setup code for sequential iteration goes in SEQ_START_BB.  */
4257   gsi = gsi_start_bb (seq_start_bb);
4258
4259   t = fold_convert (itype, s0);
4260   t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4261   if (POINTER_TYPE_P (type))
4262     t = fold_build_pointer_plus (fd->loop.n1, t);
4263   else
4264     t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4265   t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4266                                 false, GSI_CONTINUE_LINKING);
4267   stmt = gimple_build_assign (fd->loop.v, t);
4268   gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4269
4270   t = fold_convert (itype, e0);
4271   t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4272   if (POINTER_TYPE_P (type))
4273     t = fold_build_pointer_plus (fd->loop.n1, t);
4274   else
4275     t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4276   e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4277                                 false, GSI_CONTINUE_LINKING);
4278
4279   /* The code controlling the sequential loop replaces the
4280      GIMPLE_OMP_CONTINUE.  */
4281   gsi = gsi_last_bb (cont_bb);
4282   stmt = gsi_stmt (gsi);
4283   gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
4284   vmain = gimple_omp_continue_control_use (stmt);
4285   vback = gimple_omp_continue_control_def (stmt);
4286
4287   if (POINTER_TYPE_P (type))
4288     t = fold_build_pointer_plus (vmain, fd->loop.step);
4289   else
4290     t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
4291   t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4292                                 true, GSI_SAME_STMT);
4293   stmt = gimple_build_assign (vback, t);
4294   gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4295
4296   t = build2 (fd->loop.cond_code, boolean_type_node, vback, e);
4297   gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
4298
4299   /* Remove the GIMPLE_OMP_CONTINUE statement.  */
4300   gsi_remove (&gsi, true);
4301
4302   /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing.  */
4303   gsi = gsi_last_bb (exit_bb);
4304   if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
4305     force_gimple_operand_gsi (&gsi, build_omp_barrier (), false, NULL_TREE,
4306                               false, GSI_SAME_STMT);
4307   gsi_remove (&gsi, true);
4308
4309   /* Connect all the blocks.  */
4310   ep = make_edge (entry_bb, third_bb, EDGE_FALSE_VALUE);
4311   ep->probability = REG_BR_PROB_BASE / 4 * 3;
4312   ep = find_edge (entry_bb, second_bb);
4313   ep->flags = EDGE_TRUE_VALUE;
4314   ep->probability = REG_BR_PROB_BASE / 4;
4315   find_edge (third_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
4316   find_edge (third_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
4317
4318   find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
4319   find_edge (cont_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
4320
4321   set_immediate_dominator (CDI_DOMINATORS, second_bb, entry_bb);
4322   set_immediate_dominator (CDI_DOMINATORS, third_bb, entry_bb);
4323   set_immediate_dominator (CDI_DOMINATORS, seq_start_bb, third_bb);
4324   set_immediate_dominator (CDI_DOMINATORS, body_bb,
4325                            recompute_dominator (CDI_DOMINATORS, body_bb));
4326   set_immediate_dominator (CDI_DOMINATORS, fin_bb,
4327                            recompute_dominator (CDI_DOMINATORS, fin_bb));
4328 }
4329
4330
4331 /* A subroutine of expand_omp_for.  Generate code for a parallel
4332    loop with static schedule and a specified chunk size.  Given
4333    parameters:
4334
4335         for (V = N1; V cond N2; V += STEP) BODY;
4336
4337    where COND is "<" or ">", we generate pseudocode
4338
4339         if (cond is <)
4340           adj = STEP - 1;
4341         else
4342           adj = STEP + 1;
4343         if ((__typeof (V)) -1 > 0 && cond is >)
4344           n = -(adj + N2 - N1) / -STEP;
4345         else
4346           n = (adj + N2 - N1) / STEP;
4347         trip = 0;
4348         V = threadid * CHUNK * STEP + N1;  -- this extra definition of V is
4349                                               here so that V is defined
4350                                               if the loop is not entered
4351     L0:
4352         s0 = (trip * nthreads + threadid) * CHUNK;
4353         e0 = min(s0 + CHUNK, n);
4354         if (s0 < n) goto L1; else goto L4;
4355     L1:
4356         V = s0 * STEP + N1;
4357         e = e0 * STEP + N1;
4358     L2:
4359         BODY;
4360         V += STEP;
4361         if (V cond e) goto L2; else goto L3;
4362     L3:
4363         trip += 1;
4364         goto L0;
4365     L4:
4366 */
4367
4368 static void
4369 expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
4370 {
4371   tree n, s0, e0, e, t;
4372   tree trip_var, trip_init, trip_main, trip_back, nthreads, threadid;
4373   tree type, itype, v_main, v_back, v_extra;
4374   basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
4375   basic_block trip_update_bb, cont_bb, fin_bb;
4376   gimple_stmt_iterator si;
4377   gimple stmt;
4378   edge se;
4379
4380   itype = type = TREE_TYPE (fd->loop.v);
4381   if (POINTER_TYPE_P (type))
4382     itype = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
4383
4384   entry_bb = region->entry;
4385   se = split_block (entry_bb, last_stmt (entry_bb));
4386   entry_bb = se->src;
4387   iter_part_bb = se->dest;
4388   cont_bb = region->cont;
4389   gcc_assert (EDGE_COUNT (iter_part_bb->succs) == 2);
4390   gcc_assert (BRANCH_EDGE (iter_part_bb)->dest
4391               == FALLTHRU_EDGE (cont_bb)->dest);
4392   seq_start_bb = split_edge (FALLTHRU_EDGE (iter_part_bb));
4393   body_bb = single_succ (seq_start_bb);
4394   gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
4395   gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
4396   fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
4397   trip_update_bb = split_edge (FALLTHRU_EDGE (cont_bb));
4398   exit_bb = region->exit;
4399
4400   /* Trip and adjustment setup goes in ENTRY_BB.  */
4401   si = gsi_last_bb (entry_bb);
4402   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_FOR);
4403
4404   t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS), 0);
4405   t = fold_convert (itype, t);
4406   nthreads = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4407                                        true, GSI_SAME_STMT);
4408
4409   t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM), 0);
4410   t = fold_convert (itype, t);
4411   threadid = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4412                                        true, GSI_SAME_STMT);
4413
4414   fd->loop.n1
4415     = force_gimple_operand_gsi (&si, fold_convert (type, fd->loop.n1),
4416                                 true, NULL_TREE, true, GSI_SAME_STMT);
4417   fd->loop.n2
4418     = force_gimple_operand_gsi (&si, fold_convert (itype, fd->loop.n2),
4419                                 true, NULL_TREE, true, GSI_SAME_STMT);
4420   fd->loop.step
4421     = force_gimple_operand_gsi (&si, fold_convert (itype, fd->loop.step),
4422                                 true, NULL_TREE, true, GSI_SAME_STMT);
4423   fd->chunk_size
4424     = force_gimple_operand_gsi (&si, fold_convert (itype, fd->chunk_size),
4425                                 true, NULL_TREE, true, GSI_SAME_STMT);
4426
4427   t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
4428   t = fold_build2 (PLUS_EXPR, itype, fd->loop.step, t);
4429   t = fold_build2 (PLUS_EXPR, itype, t, fd->loop.n2);
4430   t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, fd->loop.n1));
4431   if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
4432     t = fold_build2 (TRUNC_DIV_EXPR, itype,
4433                      fold_build1 (NEGATE_EXPR, itype, t),
4434                      fold_build1 (NEGATE_EXPR, itype, fd->loop.step));
4435   else
4436     t = fold_build2 (TRUNC_DIV_EXPR, itype, t, fd->loop.step);
4437   t = fold_convert (itype, t);
4438   n = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4439                                 true, GSI_SAME_STMT);
4440
4441   trip_var = create_tmp_var (itype, ".trip");
4442   if (gimple_in_ssa_p (cfun))
4443     {
4444       add_referenced_var (trip_var);
4445       trip_init = make_ssa_name (trip_var, NULL);
4446       trip_main = make_ssa_name (trip_var, NULL);
4447       trip_back = make_ssa_name (trip_var, NULL);
4448     }
4449   else
4450     {
4451       trip_init = trip_var;
4452       trip_main = trip_var;
4453       trip_back = trip_var;
4454     }
4455
4456   stmt = gimple_build_assign (trip_init, build_int_cst (itype, 0));
4457   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
4458
4459   t = fold_build2 (MULT_EXPR, itype, threadid, fd->chunk_size);
4460   t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4461   if (POINTER_TYPE_P (type))
4462     t = fold_build_pointer_plus (fd->loop.n1, t);
4463   else
4464     t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4465   v_extra = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4466                                       true, GSI_SAME_STMT);
4467
4468   /* Remove the GIMPLE_OMP_FOR.  */
4469   gsi_remove (&si, true);
4470
4471   /* Iteration space partitioning goes in ITER_PART_BB.  */
4472   si = gsi_last_bb (iter_part_bb);
4473
4474   t = fold_build2 (MULT_EXPR, itype, trip_main, nthreads);
4475   t = fold_build2 (PLUS_EXPR, itype, t, threadid);
4476   t = fold_build2 (MULT_EXPR, itype, t, fd->chunk_size);
4477   s0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4478                                  false, GSI_CONTINUE_LINKING);
4479
4480   t = fold_build2 (PLUS_EXPR, itype, s0, fd->chunk_size);
4481   t = fold_build2 (MIN_EXPR, itype, t, n);
4482   e0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4483                                  false, GSI_CONTINUE_LINKING);
4484
4485   t = build2 (LT_EXPR, boolean_type_node, s0, n);
4486   gsi_insert_after (&si, gimple_build_cond_empty (t), GSI_CONTINUE_LINKING);
4487
4488   /* Setup code for sequential iteration goes in SEQ_START_BB.  */
4489   si = gsi_start_bb (seq_start_bb);
4490
4491   t = fold_convert (itype, s0);
4492   t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4493   if (POINTER_TYPE_P (type))
4494     t = fold_build_pointer_plus (fd->loop.n1, t);
4495   else
4496     t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4497   t = force_gimple_operand_gsi (&si, t, false, NULL_TREE,
4498                                 false, GSI_CONTINUE_LINKING);
4499   stmt = gimple_build_assign (fd->loop.v, t);
4500   gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4501
4502   t = fold_convert (itype, e0);
4503   t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4504   if (POINTER_TYPE_P (type))
4505     t = fold_build_pointer_plus (fd->loop.n1, t);
4506   else
4507     t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4508   e = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4509                                 false, GSI_CONTINUE_LINKING);
4510
4511   /* The code controlling the sequential loop goes in CONT_BB,
4512      replacing the GIMPLE_OMP_CONTINUE.  */
4513   si = gsi_last_bb (cont_bb);
4514   stmt = gsi_stmt (si);
4515   gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
4516   v_main = gimple_omp_continue_control_use (stmt);
4517   v_back = gimple_omp_continue_control_def (stmt);
4518
4519   if (POINTER_TYPE_P (type))
4520     t = fold_build_pointer_plus (v_main, fd->loop.step);
4521   else
4522     t = fold_build2 (PLUS_EXPR, type, v_main, fd->loop.step);
4523   stmt = gimple_build_assign (v_back, t);
4524   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
4525
4526   t = build2 (fd->loop.cond_code, boolean_type_node, v_back, e);
4527   gsi_insert_before (&si, gimple_build_cond_empty (t), GSI_SAME_STMT);
4528
4529   /* Remove GIMPLE_OMP_CONTINUE.  */
4530   gsi_remove (&si, true);
4531
4532   /* Trip update code goes into TRIP_UPDATE_BB.  */
4533   si = gsi_start_bb (trip_update_bb);
4534
4535   t = build_int_cst (itype, 1);
4536   t = build2 (PLUS_EXPR, itype, trip_main, t);
4537   stmt = gimple_build_assign (trip_back, t);
4538   gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4539
4540   /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing.  */
4541   si = gsi_last_bb (exit_bb);
4542   if (!gimple_omp_return_nowait_p (gsi_stmt (si)))
4543     force_gimple_operand_gsi (&si, build_omp_barrier (), false, NULL_TREE,
4544                               false, GSI_SAME_STMT);
4545   gsi_remove (&si, true);
4546
4547   /* Connect the new blocks.  */
4548   find_edge (iter_part_bb, seq_start_bb)->flags = EDGE_TRUE_VALUE;
4549   find_edge (iter_part_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
4550
4551   find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
4552   find_edge (cont_bb, trip_update_bb)->flags = EDGE_FALSE_VALUE;
4553
4554   redirect_edge_and_branch (single_succ_edge (trip_update_bb), iter_part_bb);
4555
4556   if (gimple_in_ssa_p (cfun))
4557     {
4558       gimple_stmt_iterator psi;
4559       gimple phi;
4560       edge re, ene;
4561       edge_var_map_vector head;
4562       edge_var_map *vm;
4563       size_t i;
4564
4565       /* When we redirect the edge from trip_update_bb to iter_part_bb, we
4566          remove arguments of the phi nodes in fin_bb.  We need to create
4567          appropriate phi nodes in iter_part_bb instead.  */
4568       se = single_pred_edge (fin_bb);
4569       re = single_succ_edge (trip_update_bb);
4570       head = redirect_edge_var_map_vector (re);
4571       ene = single_succ_edge (entry_bb);
4572
4573       psi = gsi_start_phis (fin_bb);
4574       for (i = 0; !gsi_end_p (psi) && VEC_iterate (edge_var_map, head, i, vm);
4575            gsi_next (&psi), ++i)
4576         {
4577           gimple nphi;
4578           source_location locus;
4579
4580           phi = gsi_stmt (psi);
4581           t = gimple_phi_result (phi);
4582           gcc_assert (t == redirect_edge_var_map_result (vm));
4583           nphi = create_phi_node (t, iter_part_bb);
4584           SSA_NAME_DEF_STMT (t) = nphi;
4585
4586           t = PHI_ARG_DEF_FROM_EDGE (phi, se);
4587           locus = gimple_phi_arg_location_from_edge (phi, se);
4588
4589           /* A special case -- fd->loop.v is not yet computed in
4590              iter_part_bb, we need to use v_extra instead.  */
4591           if (t == fd->loop.v)
4592             t = v_extra;
4593           add_phi_arg (nphi, t, ene, locus);
4594           locus = redirect_edge_var_map_location (vm);
4595           add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus);
4596         }
4597       gcc_assert (!gsi_end_p (psi) && i == VEC_length (edge_var_map, head));
4598       redirect_edge_var_map_clear (re);
4599       while (1)
4600         {
4601           psi = gsi_start_phis (fin_bb);
4602           if (gsi_end_p (psi))
4603             break;
4604           remove_phi_node (&psi, false);
4605         }
4606
4607       /* Make phi node for trip.  */
4608       phi = create_phi_node (trip_main, iter_part_bb);
4609       SSA_NAME_DEF_STMT (trip_main) = phi;
4610       add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb),
4611                    UNKNOWN_LOCATION);
4612       add_phi_arg (phi, trip_init, single_succ_edge (entry_bb),
4613                    UNKNOWN_LOCATION);
4614     }
4615
4616   set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
4617   set_immediate_dominator (CDI_DOMINATORS, iter_part_bb,
4618                            recompute_dominator (CDI_DOMINATORS, iter_part_bb));
4619   set_immediate_dominator (CDI_DOMINATORS, fin_bb,
4620                            recompute_dominator (CDI_DOMINATORS, fin_bb));
4621   set_immediate_dominator (CDI_DOMINATORS, seq_start_bb,
4622                            recompute_dominator (CDI_DOMINATORS, seq_start_bb));
4623   set_immediate_dominator (CDI_DOMINATORS, body_bb,
4624                            recompute_dominator (CDI_DOMINATORS, body_bb));
4625 }
4626
4627
4628 /* Expand the OpenMP loop defined by REGION.  */
4629
4630 static void
4631 expand_omp_for (struct omp_region *region)
4632 {
4633   struct omp_for_data fd;
4634   struct omp_for_data_loop *loops;
4635
4636   loops
4637     = (struct omp_for_data_loop *)
4638       alloca (gimple_omp_for_collapse (last_stmt (region->entry))
4639               * sizeof (struct omp_for_data_loop));
4640   extract_omp_for_data (last_stmt (region->entry), &fd, loops);
4641   region->sched_kind = fd.sched_kind;
4642
4643   gcc_assert (EDGE_COUNT (region->entry->succs) == 2);
4644   BRANCH_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
4645   FALLTHRU_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
4646   if (region->cont)
4647     {
4648       gcc_assert (EDGE_COUNT (region->cont->succs) == 2);
4649       BRANCH_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
4650       FALLTHRU_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
4651     }
4652
4653   if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
4654       && !fd.have_ordered
4655       && fd.collapse == 1
4656       && region->cont != NULL)
4657     {
4658       if (fd.chunk_size == NULL)
4659         expand_omp_for_static_nochunk (region, &fd);
4660       else
4661         expand_omp_for_static_chunk (region, &fd);
4662     }
4663   else
4664     {
4665       int fn_index, start_ix, next_ix;
4666
4667       gcc_assert (fd.sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
4668       fn_index = (fd.sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
4669                   ? 3 : fd.sched_kind;
4670       fn_index += fd.have_ordered * 4;
4671       start_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_START) + fn_index;
4672       next_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_NEXT) + fn_index;
4673       if (fd.iter_type == long_long_unsigned_type_node)
4674         {
4675           start_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_START
4676                         - (int)BUILT_IN_GOMP_LOOP_STATIC_START);
4677           next_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT
4678                       - (int)BUILT_IN_GOMP_LOOP_STATIC_NEXT);
4679         }
4680       expand_omp_for_generic (region, &fd, (enum built_in_function) start_ix,
4681                               (enum built_in_function) next_ix);
4682     }
4683
4684   update_ssa (TODO_update_ssa_only_virtuals);
4685 }
4686
4687
4688 /* Expand code for an OpenMP sections directive.  In pseudo code, we generate
4689
4690         v = GOMP_sections_start (n);
4691     L0:
4692         switch (v)
4693           {
4694           case 0:
4695             goto L2;
4696           case 1:
4697             section 1;
4698             goto L1;
4699           case 2:
4700             ...
4701           case n:
4702             ...
4703           default:
4704             abort ();
4705           }
4706     L1:
4707         v = GOMP_sections_next ();
4708         goto L0;
4709     L2:
4710         reduction;
4711
4712     If this is a combined parallel sections, replace the call to
4713     GOMP_sections_start with call to GOMP_sections_next.  */
4714
4715 static void
4716 expand_omp_sections (struct omp_region *region)
4717 {
4718   tree t, u, vin = NULL, vmain, vnext, l2;
4719   VEC (tree,heap) *label_vec;
4720   unsigned len;
4721   basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
4722   gimple_stmt_iterator si, switch_si;
4723   gimple sections_stmt, stmt, cont;
4724   edge_iterator ei;
4725   edge e;
4726   struct omp_region *inner;
4727   unsigned i, casei;
4728   bool exit_reachable = region->cont != NULL;
4729
4730   gcc_assert (exit_reachable == (region->exit != NULL));
4731   entry_bb = region->entry;
4732   l0_bb = single_succ (entry_bb);
4733   l1_bb = region->cont;
4734   l2_bb = region->exit;
4735   if (exit_reachable)
4736     {
4737       if (single_pred_p (l2_bb) && single_pred (l2_bb) == l0_bb)
4738         l2 = gimple_block_label (l2_bb);
4739       else
4740         {
4741           /* This can happen if there are reductions.  */
4742           len = EDGE_COUNT (l0_bb->succs);
4743           gcc_assert (len > 0);
4744           e = EDGE_SUCC (l0_bb, len - 1);
4745           si = gsi_last_bb (e->dest);
4746           l2 = NULL_TREE;
4747           if (gsi_end_p (si)
4748               || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
4749             l2 = gimple_block_label (e->dest);
4750           else
4751             FOR_EACH_EDGE (e, ei, l0_bb->succs)
4752               {
4753                 si = gsi_last_bb (e->dest);
4754                 if (gsi_end_p (si)
4755                     || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
4756                   {
4757                     l2 = gimple_block_label (e->dest);
4758                     break;
4759                   }
4760               }
4761         }
4762       default_bb = create_empty_bb (l1_bb->prev_bb);
4763     }
4764   else
4765     {
4766       default_bb = create_empty_bb (l0_bb);
4767       l2 = gimple_block_label (default_bb);
4768     }
4769
4770   /* We will build a switch() with enough cases for all the
4771      GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
4772      and a default case to abort if something goes wrong.  */
4773   len = EDGE_COUNT (l0_bb->succs);
4774
4775   /* Use VEC_quick_push on label_vec throughout, since we know the size
4776      in advance.  */
4777   label_vec = VEC_alloc (tree, heap, len);
4778
4779   /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
4780      GIMPLE_OMP_SECTIONS statement.  */
4781   si = gsi_last_bb (entry_bb);
4782   sections_stmt = gsi_stmt (si);
4783   gcc_assert (gimple_code (sections_stmt) == GIMPLE_OMP_SECTIONS);
4784   vin = gimple_omp_sections_control (sections_stmt);
4785   if (!is_combined_parallel (region))
4786     {
4787       /* If we are not inside a combined parallel+sections region,
4788          call GOMP_sections_start.  */
4789       t = build_int_cst (unsigned_type_node,
4790                          exit_reachable ? len - 1 : len);
4791       u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START);
4792       stmt = gimple_build_call (u, 1, t);
4793     }
4794   else
4795     {
4796       /* Otherwise, call GOMP_sections_next.  */
4797       u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
4798       stmt = gimple_build_call (u, 0);
4799     }
4800   gimple_call_set_lhs (stmt, vin);
4801   gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4802   gsi_remove (&si, true);
4803
4804   /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
4805      L0_BB.  */
4806   switch_si = gsi_last_bb (l0_bb);
4807   gcc_assert (gimple_code (gsi_stmt (switch_si)) == GIMPLE_OMP_SECTIONS_SWITCH);
4808   if (exit_reachable)
4809     {
4810       cont = last_stmt (l1_bb);
4811       gcc_assert (gimple_code (cont) == GIMPLE_OMP_CONTINUE);
4812       vmain = gimple_omp_continue_control_use (cont);
4813       vnext = gimple_omp_continue_control_def (cont);
4814     }
4815   else
4816     {
4817       vmain = vin;
4818       vnext = NULL_TREE;
4819     }
4820
4821   i = 0;
4822   if (exit_reachable)
4823     {
4824       t = build_case_label (build_int_cst (unsigned_type_node, 0), NULL, l2);
4825       VEC_quick_push (tree, label_vec, t);
4826       i++;
4827     }
4828
4829   /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR.  */
4830   for (inner = region->inner, casei = 1;
4831        inner;
4832        inner = inner->next, i++, casei++)
4833     {
4834       basic_block s_entry_bb, s_exit_bb;
4835
4836       /* Skip optional reduction region.  */
4837       if (inner->type == GIMPLE_OMP_ATOMIC_LOAD)
4838         {
4839           --i;
4840           --casei;
4841           continue;
4842         }
4843
4844       s_entry_bb = inner->entry;
4845       s_exit_bb = inner->exit;
4846
4847       t = gimple_block_label (s_entry_bb);
4848       u = build_int_cst (unsigned_type_node, casei);
4849       u = build_case_label (u, NULL, t);
4850       VEC_quick_push (tree, label_vec, u);
4851
4852       si = gsi_last_bb (s_entry_bb);
4853       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SECTION);
4854       gcc_assert (i < len || gimple_omp_section_last_p (gsi_stmt (si)));
4855       gsi_remove (&si, true);
4856       single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
4857
4858       if (s_exit_bb == NULL)
4859         continue;
4860
4861       si = gsi_last_bb (s_exit_bb);
4862       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
4863       gsi_remove (&si, true);
4864
4865       single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
4866     }
4867
4868   /* Error handling code goes in DEFAULT_BB.  */
4869   t = gimple_block_label (default_bb);
4870   u = build_case_label (NULL, NULL, t);
4871   make_edge (l0_bb, default_bb, 0);
4872
4873   stmt = gimple_build_switch_vec (vmain, u, label_vec);
4874   gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
4875   gsi_remove (&switch_si, true);
4876   VEC_free (tree, heap, label_vec);
4877
4878   si = gsi_start_bb (default_bb);
4879   stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
4880   gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4881
4882   if (exit_reachable)
4883     {
4884       tree bfn_decl;
4885
4886       /* Code to get the next section goes in L1_BB.  */
4887       si = gsi_last_bb (l1_bb);
4888       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CONTINUE);
4889
4890       bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
4891       stmt = gimple_build_call (bfn_decl, 0);
4892       gimple_call_set_lhs (stmt, vnext);
4893       gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4894       gsi_remove (&si, true);
4895
4896       single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
4897
4898       /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB.  */
4899       si = gsi_last_bb (l2_bb);
4900       if (gimple_omp_return_nowait_p (gsi_stmt (si)))
4901         t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT);
4902       else
4903         t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END);
4904       stmt = gimple_build_call (t, 0);
4905       gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4906       gsi_remove (&si, true);
4907     }
4908
4909   set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb);
4910 }
4911
4912
4913 /* Expand code for an OpenMP single directive.  We've already expanded
4914    much of the code, here we simply place the GOMP_barrier call.  */
4915
4916 static void
4917 expand_omp_single (struct omp_region *region)
4918 {
4919   basic_block entry_bb, exit_bb;
4920   gimple_stmt_iterator si;
4921   bool need_barrier = false;
4922
4923   entry_bb = region->entry;
4924   exit_bb = region->exit;
4925
4926   si = gsi_last_bb (entry_bb);
4927   /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
4928      be removed.  We need to ensure that the thread that entered the single
4929      does not exit before the data is copied out by the other threads.  */
4930   if (find_omp_clause (gimple_omp_single_clauses (gsi_stmt (si)),
4931                        OMP_CLAUSE_COPYPRIVATE))
4932     need_barrier = true;
4933   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE);
4934   gsi_remove (&si, true);
4935   single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
4936
4937   si = gsi_last_bb (exit_bb);
4938   if (!gimple_omp_return_nowait_p (gsi_stmt (si)) || need_barrier)
4939     force_gimple_operand_gsi (&si, build_omp_barrier (), false, NULL_TREE,
4940                               false, GSI_SAME_STMT);
4941   gsi_remove (&si, true);
4942   single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
4943 }
4944
4945
4946 /* Generic expansion for OpenMP synchronization directives: master,
4947    ordered and critical.  All we need to do here is remove the entry
4948    and exit markers for REGION.  */
4949
4950 static void
4951 expand_omp_synch (struct omp_region *region)
4952 {
4953   basic_block entry_bb, exit_bb;
4954   gimple_stmt_iterator si;
4955
4956   entry_bb = region->entry;
4957   exit_bb = region->exit;
4958
4959   si = gsi_last_bb (entry_bb);
4960   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE
4961               || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASTER
4962               || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ORDERED
4963               || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CRITICAL);
4964   gsi_remove (&si, true);
4965   single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
4966
4967   if (exit_bb)
4968     {
4969       si = gsi_last_bb (exit_bb);
4970       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
4971       gsi_remove (&si, true);
4972       single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
4973     }
4974 }
4975
4976 /* A subroutine of expand_omp_atomic.  Attempt to implement the atomic
4977    operation as a normal volatile load.  */
4978
4979 static bool
4980 expand_omp_atomic_load (basic_block load_bb, tree addr,
4981                         tree loaded_val, int index)
4982 {
4983   enum built_in_function tmpbase;
4984   gimple_stmt_iterator gsi;
4985   basic_block store_bb;
4986   location_t loc;
4987   gimple stmt;
4988   tree decl, call, type, itype;
4989
4990   gsi = gsi_last_bb (load_bb);
4991   stmt = gsi_stmt (gsi);
4992   gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
4993   loc = gimple_location (stmt);
4994
4995   /* ??? If the target does not implement atomic_load_optab[mode], and mode
4996      is smaller than word size, then expand_atomic_load assumes that the load
4997      is atomic.  We could avoid the builtin entirely in this case.  */
4998
4999   tmpbase = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
5000   decl = builtin_decl_explicit (tmpbase);
5001   if (decl == NULL_TREE)
5002     return false;
5003
5004   type = TREE_TYPE (loaded_val);
5005   itype = TREE_TYPE (TREE_TYPE (decl));
5006
5007   call = build_call_expr_loc (loc, decl, 2, addr,
5008                               build_int_cst (NULL, MEMMODEL_RELAXED));
5009   if (!useless_type_conversion_p (type, itype))
5010     call = fold_build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
5011   call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
5012
5013   force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5014   gsi_remove (&gsi, true);
5015
5016   store_bb = single_succ (load_bb);
5017   gsi = gsi_last_bb (store_bb);
5018   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
5019   gsi_remove (&gsi, true);
5020
5021   if (gimple_in_ssa_p (cfun))
5022     update_ssa (TODO_update_ssa_no_phi);
5023
5024   return true;
5025 }
5026
5027 /* A subroutine of expand_omp_atomic.  Attempt to implement the atomic
5028    operation as a normal volatile store.  */
5029
5030 static bool
5031 expand_omp_atomic_store (basic_block load_bb, tree addr,
5032                          tree loaded_val, tree stored_val, int index)
5033 {
5034   enum built_in_function tmpbase;
5035   gimple_stmt_iterator gsi;
5036   basic_block store_bb = single_succ (load_bb);
5037   location_t loc;
5038   gimple stmt;
5039   tree decl, call, type, itype;
5040   enum machine_mode imode;
5041   bool exchange;
5042
5043   gsi = gsi_last_bb (load_bb);
5044   stmt = gsi_stmt (gsi);
5045   gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
5046
5047   /* If the load value is needed, then this isn't a store but an exchange.  */
5048   exchange = gimple_omp_atomic_need_value_p (stmt);
5049
5050   gsi = gsi_last_bb (store_bb);
5051   stmt = gsi_stmt (gsi);
5052   gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE);
5053   loc = gimple_location (stmt);
5054
5055   /* ??? If the target does not implement atomic_store_optab[mode], and mode
5056      is smaller than word size, then expand_atomic_store assumes that the store
5057      is atomic.  We could avoid the builtin entirely in this case.  */
5058
5059   tmpbase = (exchange ? BUILT_IN_ATOMIC_EXCHANGE_N : BUILT_IN_ATOMIC_STORE_N);
5060   tmpbase = (enum built_in_function) ((int) tmpbase + index + 1);
5061   decl = builtin_decl_explicit (tmpbase);
5062   if (decl == NULL_TREE)
5063     return false;
5064
5065   type = TREE_TYPE (stored_val);
5066
5067   /* Dig out the type of the function's second argument.  */
5068   itype = TREE_TYPE (decl);
5069   itype = TYPE_ARG_TYPES (itype);
5070   itype = TREE_CHAIN (itype);
5071   itype = TREE_VALUE (itype);
5072   imode = TYPE_MODE (itype);
5073
5074   if (exchange && !can_atomic_exchange_p (imode, true))
5075     return false;
5076
5077   if (!useless_type_conversion_p (itype, type))
5078     stored_val = fold_build1_loc (loc, VIEW_CONVERT_EXPR, itype, stored_val);
5079   call = build_call_expr_loc (loc, decl, 3, addr, stored_val,
5080                               build_int_cst (NULL, MEMMODEL_RELAXED));
5081   if (exchange)
5082     {
5083       if (!useless_type_conversion_p (type, itype))
5084         call = build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
5085       call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
5086     }
5087
5088   force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5089   gsi_remove (&gsi, true);
5090
5091   /* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above.  */
5092   gsi = gsi_last_bb (load_bb);
5093   gsi_remove (&gsi, true);
5094
5095   if (gimple_in_ssa_p (cfun))
5096     update_ssa (TODO_update_ssa_no_phi);
5097
5098   return true;
5099 }
5100
5101 /* A subroutine of expand_omp_atomic.  Attempt to implement the atomic
5102    operation as a __atomic_fetch_op builtin.  INDEX is log2 of the
5103    size of the data type, and thus usable to find the index of the builtin
5104    decl.  Returns false if the expression is not of the proper form.  */
5105
5106 static bool
5107 expand_omp_atomic_fetch_op (basic_block load_bb,
5108                             tree addr, tree loaded_val,
5109                             tree stored_val, int index)
5110 {
5111   enum built_in_function oldbase, newbase, tmpbase;
5112   tree decl, itype, call;
5113   tree lhs, rhs;
5114   basic_block store_bb = single_succ (load_bb);
5115   gimple_stmt_iterator gsi;
5116   gimple stmt;
5117   location_t loc;
5118   enum tree_code code;
5119   bool need_old, need_new;
5120   enum machine_mode imode;
5121
5122   /* We expect to find the following sequences:
5123
5124    load_bb:
5125        GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
5126
5127    store_bb:
5128        val = tmp OP something; (or: something OP tmp)
5129        GIMPLE_OMP_STORE (val)
5130
5131   ???FIXME: Allow a more flexible sequence.
5132   Perhaps use data flow to pick the statements.
5133
5134   */
5135
5136   gsi = gsi_after_labels (store_bb);
5137   stmt = gsi_stmt (gsi);
5138   loc = gimple_location (stmt);
5139   if (!is_gimple_assign (stmt))
5140     return false;
5141   gsi_next (&gsi);
5142   if (gimple_code (gsi_stmt (gsi)) != GIMPLE_OMP_ATOMIC_STORE)
5143     return false;
5144   need_new = gimple_omp_atomic_need_value_p (gsi_stmt (gsi));
5145   need_old = gimple_omp_atomic_need_value_p (last_stmt (load_bb));
5146   gcc_checking_assert (!need_old || !need_new);
5147
5148   if (!operand_equal_p (gimple_assign_lhs (stmt), stored_val, 0))
5149     return false;
5150
5151   /* Check for one of the supported fetch-op operations.  */
5152   code = gimple_assign_rhs_code (stmt);
5153   switch (code)
5154     {
5155     case PLUS_EXPR:
5156     case POINTER_PLUS_EXPR:
5157       oldbase = BUILT_IN_ATOMIC_FETCH_ADD_N;
5158       newbase = BUILT_IN_ATOMIC_ADD_FETCH_N;
5159       break;
5160     case MINUS_EXPR:
5161       oldbase = BUILT_IN_ATOMIC_FETCH_SUB_N;
5162       newbase = BUILT_IN_ATOMIC_SUB_FETCH_N;
5163       break;
5164     case BIT_AND_EXPR:
5165       oldbase = BUILT_IN_ATOMIC_FETCH_AND_N;
5166       newbase = BUILT_IN_ATOMIC_AND_FETCH_N;
5167       break;
5168     case BIT_IOR_EXPR:
5169       oldbase = BUILT_IN_ATOMIC_FETCH_OR_N;
5170       newbase = BUILT_IN_ATOMIC_OR_FETCH_N;
5171       break;
5172     case BIT_XOR_EXPR:
5173       oldbase = BUILT_IN_ATOMIC_FETCH_XOR_N;
5174       newbase = BUILT_IN_ATOMIC_XOR_FETCH_N;
5175       break;
5176     default:
5177       return false;
5178     }
5179
5180   /* Make sure the expression is of the proper form.  */
5181   if (operand_equal_p (gimple_assign_rhs1 (stmt), loaded_val, 0))
5182     rhs = gimple_assign_rhs2 (stmt);
5183   else if (commutative_tree_code (gimple_assign_rhs_code (stmt))
5184            && operand_equal_p (gimple_assign_rhs2 (stmt), loaded_val, 0))
5185     rhs = gimple_assign_rhs1 (stmt);
5186   else
5187     return false;
5188
5189   tmpbase = ((enum built_in_function)
5190              ((need_new ? newbase : oldbase) + index + 1));
5191   decl = builtin_decl_explicit (tmpbase);
5192   if (decl == NULL_TREE)
5193     return false;
5194   itype = TREE_TYPE (TREE_TYPE (decl));
5195   imode = TYPE_MODE (itype);
5196
5197   /* We could test all of the various optabs involved, but the fact of the
5198      matter is that (with the exception of i486 vs i586 and xadd) all targets
5199      that support any atomic operaton optab also implements compare-and-swap.
5200      Let optabs.c take care of expanding any compare-and-swap loop.  */
5201   if (!can_compare_and_swap_p (imode, true))
5202     return false;
5203
5204   gsi = gsi_last_bb (load_bb);
5205   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_LOAD);
5206
5207   /* OpenMP does not imply any barrier-like semantics on its atomic ops.
5208      It only requires that the operation happen atomically.  Thus we can
5209      use the RELAXED memory model.  */
5210   call = build_call_expr_loc (loc, decl, 3, addr,
5211                               fold_convert_loc (loc, itype, rhs),
5212                               build_int_cst (NULL, MEMMODEL_RELAXED));
5213
5214   if (need_old || need_new)
5215     {
5216       lhs = need_old ? loaded_val : stored_val;
5217       call = fold_convert_loc (loc, TREE_TYPE (lhs), call);
5218       call = build2_loc (loc, MODIFY_EXPR, void_type_node, lhs, call);
5219     }
5220   else
5221     call = fold_convert_loc (loc, void_type_node, call);
5222   force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5223   gsi_remove (&gsi, true);
5224
5225   gsi = gsi_last_bb (store_bb);
5226   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
5227   gsi_remove (&gsi, true);
5228   gsi = gsi_last_bb (store_bb);
5229   gsi_remove (&gsi, true);
5230
5231   if (gimple_in_ssa_p (cfun))
5232     update_ssa (TODO_update_ssa_no_phi);
5233
5234   return true;
5235 }
5236
5237 /* A subroutine of expand_omp_atomic.  Implement the atomic operation as:
5238
5239       oldval = *addr;
5240       repeat:
5241         newval = rhs;    // with oldval replacing *addr in rhs
5242         oldval = __sync_val_compare_and_swap (addr, oldval, newval);
5243         if (oldval != newval)
5244           goto repeat;
5245
5246    INDEX is log2 of the size of the data type, and thus usable to find the
5247    index of the builtin decl.  */
5248
5249 static bool
5250 expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
5251                             tree addr, tree loaded_val, tree stored_val,
5252                             int index)
5253 {
5254   tree loadedi, storedi, initial, new_storedi, old_vali;
5255   tree type, itype, cmpxchg, iaddr;
5256   gimple_stmt_iterator si;
5257   basic_block loop_header = single_succ (load_bb);
5258   gimple phi, stmt;
5259   edge e;
5260   enum built_in_function fncode;
5261
5262   /* ??? We need a non-pointer interface to __atomic_compare_exchange in
5263      order to use the RELAXED memory model effectively.  */
5264   fncode = (enum built_in_function)((int)BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
5265                                     + index + 1);
5266   cmpxchg = builtin_decl_explicit (fncode);
5267   if (cmpxchg == NULL_TREE)
5268     return false;
5269   type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5270   itype = TREE_TYPE (TREE_TYPE (cmpxchg));
5271
5272   if (!can_compare_and_swap_p (TYPE_MODE (itype), true))
5273     return false;
5274
5275   /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD.  */
5276   si = gsi_last_bb (load_bb);
5277   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
5278
5279   /* For floating-point values, we'll need to view-convert them to integers
5280      so that we can perform the atomic compare and swap.  Simplify the
5281      following code by always setting up the "i"ntegral variables.  */
5282   if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
5283     {
5284       tree iaddr_val;
5285
5286       iaddr = create_tmp_var (build_pointer_type_for_mode (itype, ptr_mode,
5287                                                            true), NULL);
5288       iaddr_val
5289         = force_gimple_operand_gsi (&si,
5290                                     fold_convert (TREE_TYPE (iaddr), addr),
5291                                     false, NULL_TREE, true, GSI_SAME_STMT);
5292       stmt = gimple_build_assign (iaddr, iaddr_val);
5293       gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5294       loadedi = create_tmp_var (itype, NULL);
5295       if (gimple_in_ssa_p (cfun))
5296         {
5297           add_referenced_var (iaddr);
5298           add_referenced_var (loadedi);
5299           loadedi = make_ssa_name (loadedi, NULL);
5300         }
5301     }
5302   else
5303     {
5304       iaddr = addr;
5305       loadedi = loaded_val;
5306     }
5307
5308   initial
5309     = force_gimple_operand_gsi (&si,
5310                                 build2 (MEM_REF, TREE_TYPE (TREE_TYPE (iaddr)),
5311                                         iaddr,
5312                                         build_int_cst (TREE_TYPE (iaddr), 0)),
5313                                 true, NULL_TREE, true, GSI_SAME_STMT);
5314
5315   /* Move the value to the LOADEDI temporary.  */
5316   if (gimple_in_ssa_p (cfun))
5317     {
5318       gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header)));
5319       phi = create_phi_node (loadedi, loop_header);
5320       SSA_NAME_DEF_STMT (loadedi) = phi;
5321       SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (load_bb)),
5322                initial);
5323     }
5324   else
5325     gsi_insert_before (&si,
5326                        gimple_build_assign (loadedi, initial),
5327                        GSI_SAME_STMT);
5328   if (loadedi != loaded_val)
5329     {
5330       gimple_stmt_iterator gsi2;
5331       tree x;
5332
5333       x = build1 (VIEW_CONVERT_EXPR, type, loadedi);
5334       gsi2 = gsi_start_bb (loop_header);
5335       if (gimple_in_ssa_p (cfun))
5336         {
5337           gimple stmt;
5338           x = force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
5339                                         true, GSI_SAME_STMT);
5340           stmt = gimple_build_assign (loaded_val, x);
5341           gsi_insert_before (&gsi2, stmt, GSI_SAME_STMT);
5342         }
5343       else
5344         {
5345           x = build2 (MODIFY_EXPR, TREE_TYPE (loaded_val), loaded_val, x);
5346           force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
5347                                     true, GSI_SAME_STMT);
5348         }
5349     }
5350   gsi_remove (&si, true);
5351
5352   si = gsi_last_bb (store_bb);
5353   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
5354
5355   if (iaddr == addr)
5356     storedi = stored_val;
5357   else
5358     storedi =
5359       force_gimple_operand_gsi (&si,
5360                                 build1 (VIEW_CONVERT_EXPR, itype,
5361                                         stored_val), true, NULL_TREE, true,
5362                                 GSI_SAME_STMT);
5363
5364   /* Build the compare&swap statement.  */
5365   new_storedi = build_call_expr (cmpxchg, 3, iaddr, loadedi, storedi);
5366   new_storedi = force_gimple_operand_gsi (&si,
5367                                           fold_convert (TREE_TYPE (loadedi),
5368                                                         new_storedi),
5369                                           true, NULL_TREE,
5370                                           true, GSI_SAME_STMT);
5371
5372   if (gimple_in_ssa_p (cfun))
5373     old_vali = loadedi;
5374   else
5375     {
5376       old_vali = create_tmp_var (TREE_TYPE (loadedi), NULL);
5377       if (gimple_in_ssa_p (cfun))
5378         add_referenced_var (old_vali);
5379       stmt = gimple_build_assign (old_vali, loadedi);
5380       gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5381
5382       stmt = gimple_build_assign (loadedi, new_storedi);
5383       gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5384     }
5385
5386   /* Note that we always perform the comparison as an integer, even for
5387      floating point.  This allows the atomic operation to properly
5388      succeed even with NaNs and -0.0.  */
5389   stmt = gimple_build_cond_empty
5390            (build2 (NE_EXPR, boolean_type_node,
5391                     new_storedi, old_vali));
5392   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5393
5394   /* Update cfg.  */
5395   e = single_succ_edge (store_bb);
5396   e->flags &= ~EDGE_FALLTHRU;
5397   e->flags |= EDGE_FALSE_VALUE;
5398
5399   e = make_edge (store_bb, loop_header, EDGE_TRUE_VALUE);
5400
5401   /* Copy the new value to loadedi (we already did that before the condition
5402      if we are not in SSA).  */
5403   if (gimple_in_ssa_p (cfun))
5404     {
5405       phi = gimple_seq_first_stmt (phi_nodes (loop_header));
5406       SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), new_storedi);
5407     }
5408
5409   /* Remove GIMPLE_OMP_ATOMIC_STORE.  */
5410   gsi_remove (&si, true);
5411
5412   if (gimple_in_ssa_p (cfun))
5413     update_ssa (TODO_update_ssa_no_phi);
5414
5415   return true;
5416 }
5417
5418 /* A subroutine of expand_omp_atomic.  Implement the atomic operation as:
5419
5420                                   GOMP_atomic_start ();
5421                                   *addr = rhs;
5422                                   GOMP_atomic_end ();
5423
5424    The result is not globally atomic, but works so long as all parallel
5425    references are within #pragma omp atomic directives.  According to
5426    responses received from omp@openmp.org, appears to be within spec.
5427    Which makes sense, since that's how several other compilers handle
5428    this situation as well.
5429    LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
5430    expanding.  STORED_VAL is the operand of the matching
5431    GIMPLE_OMP_ATOMIC_STORE.
5432
5433    We replace
5434    GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
5435    loaded_val = *addr;
5436
5437    and replace
5438    GIMPLE_OMP_ATOMIC_STORE (stored_val)  with
5439    *addr = stored_val;
5440 */
5441
5442 static bool
5443 expand_omp_atomic_mutex (basic_block load_bb, basic_block store_bb,
5444                          tree addr, tree loaded_val, tree stored_val)
5445 {
5446   gimple_stmt_iterator si;
5447   gimple stmt;
5448   tree t;
5449
5450   si = gsi_last_bb (load_bb);
5451   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
5452
5453   t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
5454   t = build_call_expr (t, 0);
5455   force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
5456
5457   stmt = gimple_build_assign (loaded_val, build_simple_mem_ref (addr));
5458   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5459   gsi_remove (&si, true);
5460
5461   si = gsi_last_bb (store_bb);
5462   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
5463
5464   stmt = gimple_build_assign (build_simple_mem_ref (unshare_expr (addr)),
5465                               stored_val);
5466   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5467
5468   t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
5469   t = build_call_expr (t, 0);
5470   force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
5471   gsi_remove (&si, true);
5472
5473   if (gimple_in_ssa_p (cfun))
5474     update_ssa (TODO_update_ssa_no_phi);
5475   return true;
5476 }
5477
5478 /* Expand an GIMPLE_OMP_ATOMIC statement.  We try to expand
5479    using expand_omp_atomic_fetch_op. If it failed, we try to
5480    call expand_omp_atomic_pipeline, and if it fails too, the
5481    ultimate fallback is wrapping the operation in a mutex
5482    (expand_omp_atomic_mutex).  REGION is the atomic region built
5483    by build_omp_regions_1().  */
5484
5485 static void
5486 expand_omp_atomic (struct omp_region *region)
5487 {
5488   basic_block load_bb = region->entry, store_bb = region->exit;
5489   gimple load = last_stmt (load_bb), store = last_stmt (store_bb);
5490   tree loaded_val = gimple_omp_atomic_load_lhs (load);
5491   tree addr = gimple_omp_atomic_load_rhs (load);
5492   tree stored_val = gimple_omp_atomic_store_val (store);
5493   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5494   HOST_WIDE_INT index;
5495
5496   /* Make sure the type is one of the supported sizes.  */
5497   index = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5498   index = exact_log2 (index);
5499   if (index >= 0 && index <= 4)
5500     {
5501       unsigned int align = TYPE_ALIGN_UNIT (type);
5502
5503       /* __sync builtins require strict data alignment.  */
5504       /* ??? Assume BIGGEST_ALIGNMENT *is* aligned.  */
5505       if (exact_log2 (align) >= index
5506           || align * BITS_PER_UNIT >= BIGGEST_ALIGNMENT)
5507         {
5508           /* Atomic load.  */
5509           if (loaded_val == stored_val
5510               && (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
5511                   || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
5512               && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
5513               && expand_omp_atomic_load (load_bb, addr, loaded_val, index))
5514             return;
5515
5516           /* Atomic store.  */
5517           if ((GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
5518                || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
5519               && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
5520               && store_bb == single_succ (load_bb)
5521               && first_stmt (store_bb) == store
5522               && expand_omp_atomic_store (load_bb, addr, loaded_val,
5523                                           stored_val, index))
5524             return;
5525
5526           /* When possible, use specialized atomic update functions.  */
5527           if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
5528               && store_bb == single_succ (load_bb)
5529               && expand_omp_atomic_fetch_op (load_bb, addr,
5530                                              loaded_val, stored_val, index))
5531             return;
5532
5533           /* If we don't have specialized __sync builtins, try and implement
5534              as a compare and swap loop.  */
5535           if (expand_omp_atomic_pipeline (load_bb, store_bb, addr,
5536                                           loaded_val, stored_val, index))
5537             return;
5538         }
5539     }
5540
5541   /* The ultimate fallback is wrapping the operation in a mutex.  */
5542   expand_omp_atomic_mutex (load_bb, store_bb, addr, loaded_val, stored_val);
5543 }
5544
5545
5546 /* Expand the parallel region tree rooted at REGION.  Expansion
5547    proceeds in depth-first order.  Innermost regions are expanded
5548    first.  This way, parallel regions that require a new function to
5549    be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
5550    internal dependencies in their body.  */
5551
5552 static void
5553 expand_omp (struct omp_region *region)
5554 {
5555   while (region)
5556     {
5557       location_t saved_location;
5558
5559       /* First, determine whether this is a combined parallel+workshare
5560          region.  */
5561       if (region->type == GIMPLE_OMP_PARALLEL)
5562         determine_parallel_type (region);
5563
5564       if (region->inner)
5565         expand_omp (region->inner);
5566
5567       saved_location = input_location;
5568       if (gimple_has_location (last_stmt (region->entry)))
5569         input_location = gimple_location (last_stmt (region->entry));
5570
5571       switch (region->type)
5572         {
5573         case GIMPLE_OMP_PARALLEL:
5574         case GIMPLE_OMP_TASK:
5575           expand_omp_taskreg (region);
5576           break;
5577
5578         case GIMPLE_OMP_FOR:
5579           expand_omp_for (region);
5580           break;
5581
5582         case GIMPLE_OMP_SECTIONS:
5583           expand_omp_sections (region);
5584           break;
5585
5586         case GIMPLE_OMP_SECTION:
5587           /* Individual omp sections are handled together with their
5588              parent GIMPLE_OMP_SECTIONS region.  */
5589           break;
5590
5591         case GIMPLE_OMP_SINGLE:
5592           expand_omp_single (region);
5593           break;
5594
5595         case GIMPLE_OMP_MASTER:
5596         case GIMPLE_OMP_ORDERED:
5597         case GIMPLE_OMP_CRITICAL:
5598           expand_omp_synch (region);
5599           break;
5600
5601         case GIMPLE_OMP_ATOMIC_LOAD:
5602           expand_omp_atomic (region);
5603           break;
5604
5605         default:
5606           gcc_unreachable ();
5607         }
5608
5609       input_location = saved_location;
5610       region = region->next;
5611     }
5612 }
5613
5614
5615 /* Helper for build_omp_regions.  Scan the dominator tree starting at
5616    block BB.  PARENT is the region that contains BB.  If SINGLE_TREE is
5617    true, the function ends once a single tree is built (otherwise, whole
5618    forest of OMP constructs may be built).  */
5619
5620 static void
5621 build_omp_regions_1 (basic_block bb, struct omp_region *parent,
5622                      bool single_tree)
5623 {
5624   gimple_stmt_iterator gsi;
5625   gimple stmt;
5626   basic_block son;
5627
5628   gsi = gsi_last_bb (bb);
5629   if (!gsi_end_p (gsi) && is_gimple_omp (gsi_stmt (gsi)))
5630     {
5631       struct omp_region *region;
5632       enum gimple_code code;
5633
5634       stmt = gsi_stmt (gsi);
5635       code = gimple_code (stmt);
5636       if (code == GIMPLE_OMP_RETURN)
5637         {
5638           /* STMT is the return point out of region PARENT.  Mark it
5639              as the exit point and make PARENT the immediately
5640              enclosing region.  */
5641           gcc_assert (parent);
5642           region = parent;
5643           region->exit = bb;
5644           parent = parent->outer;
5645         }
5646       else if (code == GIMPLE_OMP_ATOMIC_STORE)
5647         {
5648           /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
5649              GIMPLE_OMP_RETURN, but matches with
5650              GIMPLE_OMP_ATOMIC_LOAD.  */
5651           gcc_assert (parent);
5652           gcc_assert (parent->type == GIMPLE_OMP_ATOMIC_LOAD);
5653           region = parent;
5654           region->exit = bb;
5655           parent = parent->outer;
5656         }
5657
5658       else if (code == GIMPLE_OMP_CONTINUE)
5659         {
5660           gcc_assert (parent);
5661           parent->cont = bb;
5662         }
5663       else if (code == GIMPLE_OMP_SECTIONS_SWITCH)
5664         {
5665           /* GIMPLE_OMP_SECTIONS_SWITCH is part of
5666              GIMPLE_OMP_SECTIONS, and we do nothing for it.  */
5667           ;
5668         }
5669       else
5670         {
5671           /* Otherwise, this directive becomes the parent for a new
5672              region.  */
5673           region = new_omp_region (bb, code, parent);
5674           parent = region;
5675         }
5676     }
5677
5678   if (single_tree && !parent)
5679     return;
5680
5681   for (son = first_dom_son (CDI_DOMINATORS, bb);
5682        son;
5683        son = next_dom_son (CDI_DOMINATORS, son))
5684     build_omp_regions_1 (son, parent, single_tree);
5685 }
5686
5687 /* Builds the tree of OMP regions rooted at ROOT, storing it to
5688    root_omp_region.  */
5689
5690 static void
5691 build_omp_regions_root (basic_block root)
5692 {
5693   gcc_assert (root_omp_region == NULL);
5694   build_omp_regions_1 (root, NULL, true);
5695   gcc_assert (root_omp_region != NULL);
5696 }
5697
5698 /* Expands omp construct (and its subconstructs) starting in HEAD.  */
5699
5700 void
5701 omp_expand_local (basic_block head)
5702 {
5703   build_omp_regions_root (head);
5704   if (dump_file && (dump_flags & TDF_DETAILS))
5705     {
5706       fprintf (dump_file, "\nOMP region tree\n\n");
5707       dump_omp_region (dump_file, root_omp_region, 0);
5708       fprintf (dump_file, "\n");
5709     }
5710
5711   remove_exit_barriers (root_omp_region);
5712   expand_omp (root_omp_region);
5713
5714   free_omp_regions ();
5715 }
5716
5717 /* Scan the CFG and build a tree of OMP regions.  Return the root of
5718    the OMP region tree.  */
5719
5720 static void
5721 build_omp_regions (void)
5722 {
5723   gcc_assert (root_omp_region == NULL);
5724   calculate_dominance_info (CDI_DOMINATORS);
5725   build_omp_regions_1 (ENTRY_BLOCK_PTR, NULL, false);
5726 }
5727
5728 /* Main entry point for expanding OMP-GIMPLE into runtime calls.  */
5729
5730 static unsigned int
5731 execute_expand_omp (void)
5732 {
5733   build_omp_regions ();
5734
5735   if (!root_omp_region)
5736     return 0;
5737
5738   if (dump_file)
5739     {
5740       fprintf (dump_file, "\nOMP region tree\n\n");
5741       dump_omp_region (dump_file, root_omp_region, 0);
5742       fprintf (dump_file, "\n");
5743     }
5744
5745   remove_exit_barriers (root_omp_region);
5746
5747   expand_omp (root_omp_region);
5748
5749   cleanup_tree_cfg ();
5750
5751   free_omp_regions ();
5752
5753   return 0;
5754 }
5755
5756 /* OMP expansion -- the default pass, run before creation of SSA form.  */
5757
5758 static bool
5759 gate_expand_omp (void)
5760 {
5761   return (flag_openmp != 0 && !seen_error ());
5762 }
5763
5764 struct gimple_opt_pass pass_expand_omp =
5765 {
5766  {
5767   GIMPLE_PASS,
5768   "ompexp",                             /* name */
5769   gate_expand_omp,                      /* gate */
5770   execute_expand_omp,                   /* execute */
5771   NULL,                                 /* sub */
5772   NULL,                                 /* next */
5773   0,                                    /* static_pass_number */
5774   TV_NONE,                              /* tv_id */
5775   PROP_gimple_any,                      /* properties_required */
5776   0,                                    /* properties_provided */
5777   0,                                    /* properties_destroyed */
5778   0,                                    /* todo_flags_start */
5779   0                                     /* todo_flags_finish */
5780  }
5781 };
5782 \f
5783 /* Routines to lower OpenMP directives into OMP-GIMPLE.  */
5784
5785 /* Lower the OpenMP sections directive in the current statement in GSI_P.
5786    CTX is the enclosing OMP context for the current statement.  */
5787
5788 static void
5789 lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
5790 {
5791   tree block, control;
5792   gimple_stmt_iterator tgsi;
5793   unsigned i, len;
5794   gimple stmt, new_stmt, bind, t;
5795   gimple_seq ilist, dlist, olist, new_body, body;
5796   struct gimplify_ctx gctx;
5797
5798   stmt = gsi_stmt (*gsi_p);
5799
5800   push_gimplify_context (&gctx);
5801
5802   dlist = NULL;
5803   ilist = NULL;
5804   lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
5805                            &ilist, &dlist, ctx);
5806
5807   tgsi = gsi_start (gimple_omp_body (stmt));
5808   for (len = 0; !gsi_end_p (tgsi); len++, gsi_next (&tgsi))
5809     continue;
5810
5811   tgsi = gsi_start (gimple_omp_body (stmt));
5812   body = NULL;
5813   for (i = 0; i < len; i++, gsi_next (&tgsi))
5814     {
5815       omp_context *sctx;
5816       gimple sec_start;
5817
5818       sec_start = gsi_stmt (tgsi);
5819       sctx = maybe_lookup_ctx (sec_start);
5820       gcc_assert (sctx);
5821
5822       gimple_seq_add_stmt (&body, sec_start);
5823
5824       lower_omp (gimple_omp_body (sec_start), sctx);
5825       gimple_seq_add_seq (&body, gimple_omp_body (sec_start));
5826       gimple_omp_set_body (sec_start, NULL);
5827
5828       if (i == len - 1)
5829         {
5830           gimple_seq l = NULL;
5831           lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
5832                                      &l, ctx);
5833           gimple_seq_add_seq (&body, l);
5834           gimple_omp_section_set_last (sec_start);
5835         }
5836
5837       gimple_seq_add_stmt (&body, gimple_build_omp_return (false));
5838     }
5839
5840   block = make_node (BLOCK);
5841   bind = gimple_build_bind (NULL, body, block);
5842
5843   olist = NULL;
5844   lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
5845
5846   block = make_node (BLOCK);
5847   new_stmt = gimple_build_bind (NULL, NULL, block);
5848
5849   pop_gimplify_context (new_stmt);
5850   gimple_bind_append_vars (new_stmt, ctx->block_vars);
5851   BLOCK_VARS (block) = gimple_bind_vars (bind);
5852   if (BLOCK_VARS (block))
5853     TREE_USED (block) = 1;
5854
5855   new_body = NULL;
5856   gimple_seq_add_seq (&new_body, ilist);
5857   gimple_seq_add_stmt (&new_body, stmt);
5858   gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
5859   gimple_seq_add_stmt (&new_body, bind);
5860
5861   control = create_tmp_var (unsigned_type_node, ".section");
5862   t = gimple_build_omp_continue (control, control);
5863   gimple_omp_sections_set_control (stmt, control);
5864   gimple_seq_add_stmt (&new_body, t);
5865
5866   gimple_seq_add_seq (&new_body, olist);
5867   gimple_seq_add_seq (&new_body, dlist);
5868
5869   new_body = maybe_catch_exception (new_body);
5870
5871   t = gimple_build_omp_return
5872         (!!find_omp_clause (gimple_omp_sections_clauses (stmt),
5873                             OMP_CLAUSE_NOWAIT));
5874   gimple_seq_add_stmt (&new_body, t);
5875
5876   gimple_bind_set_body (new_stmt, new_body);
5877   gimple_omp_set_body (stmt, NULL);
5878
5879   gsi_replace (gsi_p, new_stmt, true);
5880 }
5881
5882
5883 /* A subroutine of lower_omp_single.  Expand the simple form of
5884    a GIMPLE_OMP_SINGLE, without a copyprivate clause:
5885
5886         if (GOMP_single_start ())
5887           BODY;
5888         [ GOMP_barrier (); ]    -> unless 'nowait' is present.
5889
5890   FIXME.  It may be better to delay expanding the logic of this until
5891   pass_expand_omp.  The expanded logic may make the job more difficult
5892   to a synchronization analysis pass.  */
5893
5894 static void
5895 lower_omp_single_simple (gimple single_stmt, gimple_seq *pre_p)
5896 {
5897   location_t loc = gimple_location (single_stmt);
5898   tree tlabel = create_artificial_label (loc);
5899   tree flabel = create_artificial_label (loc);
5900   gimple call, cond;
5901   tree lhs, decl;
5902
5903   decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START);
5904   lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)), NULL);
5905   call = gimple_build_call (decl, 0);
5906   gimple_call_set_lhs (call, lhs);
5907   gimple_seq_add_stmt (pre_p, call);
5908
5909   cond = gimple_build_cond (EQ_EXPR, lhs,
5910                             fold_convert_loc (loc, TREE_TYPE (lhs),
5911                                               boolean_true_node),
5912                             tlabel, flabel);
5913   gimple_seq_add_stmt (pre_p, cond);
5914   gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
5915   gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
5916   gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
5917 }
5918
5919
5920 /* A subroutine of lower_omp_single.  Expand the simple form of
5921    a GIMPLE_OMP_SINGLE, with a copyprivate clause:
5922
5923         #pragma omp single copyprivate (a, b, c)
5924
5925    Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
5926
5927       {
5928         if ((copyout_p = GOMP_single_copy_start ()) == NULL)
5929           {
5930             BODY;
5931             copyout.a = a;
5932             copyout.b = b;
5933             copyout.c = c;
5934             GOMP_single_copy_end (&copyout);
5935           }
5936         else
5937           {
5938             a = copyout_p->a;
5939             b = copyout_p->b;
5940             c = copyout_p->c;
5941           }
5942         GOMP_barrier ();
5943       }
5944
5945   FIXME.  It may be better to delay expanding the logic of this until
5946   pass_expand_omp.  The expanded logic may make the job more difficult
5947   to a synchronization analysis pass.  */
5948
5949 static void
5950 lower_omp_single_copy (gimple single_stmt, gimple_seq *pre_p, omp_context *ctx)
5951 {
5952   tree ptr_type, t, l0, l1, l2, bfn_decl;
5953   gimple_seq copyin_seq;
5954   location_t loc = gimple_location (single_stmt);
5955
5956   ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
5957
5958   ptr_type = build_pointer_type (ctx->record_type);
5959   ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
5960
5961   l0 = create_artificial_label (loc);
5962   l1 = create_artificial_label (loc);
5963   l2 = create_artificial_label (loc);
5964
5965   bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START);
5966   t = build_call_expr_loc (loc, bfn_decl, 0);
5967   t = fold_convert_loc (loc, ptr_type, t);
5968   gimplify_assign (ctx->receiver_decl, t, pre_p);
5969
5970   t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
5971               build_int_cst (ptr_type, 0));
5972   t = build3 (COND_EXPR, void_type_node, t,
5973               build_and_jump (&l0), build_and_jump (&l1));
5974   gimplify_and_add (t, pre_p);
5975
5976   gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
5977
5978   gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
5979
5980   copyin_seq = NULL;
5981   lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
5982                               &copyin_seq, ctx);
5983
5984   t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
5985   bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END);
5986   t = build_call_expr_loc (loc, bfn_decl, 1, t);
5987   gimplify_and_add (t, pre_p);
5988
5989   t = build_and_jump (&l2);
5990   gimplify_and_add (t, pre_p);
5991
5992   gimple_seq_add_stmt (pre_p, gimple_build_label (l1));
5993
5994   gimple_seq_add_seq (pre_p, copyin_seq);
5995
5996   gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
5997 }
5998
5999
6000 /* Expand code for an OpenMP single directive.  */
6001
6002 static void
6003 lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6004 {
6005   tree block;
6006   gimple t, bind, single_stmt = gsi_stmt (*gsi_p);
6007   gimple_seq bind_body, dlist;
6008   struct gimplify_ctx gctx;
6009
6010   push_gimplify_context (&gctx);
6011
6012   bind_body = NULL;
6013   lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
6014                            &bind_body, &dlist, ctx);
6015   lower_omp (gimple_omp_body (single_stmt), ctx);
6016
6017   gimple_seq_add_stmt (&bind_body, single_stmt);
6018
6019   if (ctx->record_type)
6020     lower_omp_single_copy (single_stmt, &bind_body, ctx);
6021   else
6022     lower_omp_single_simple (single_stmt, &bind_body);
6023
6024   gimple_omp_set_body (single_stmt, NULL);
6025
6026   gimple_seq_add_seq (&bind_body, dlist);
6027
6028   bind_body = maybe_catch_exception (bind_body);
6029
6030   t = gimple_build_omp_return
6031         (!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
6032                             OMP_CLAUSE_NOWAIT));
6033   gimple_seq_add_stmt (&bind_body, t);
6034
6035   block = make_node (BLOCK);
6036   bind = gimple_build_bind (NULL, bind_body, block);
6037
6038   pop_gimplify_context (bind);
6039
6040   gimple_bind_append_vars (bind, ctx->block_vars);
6041   BLOCK_VARS (block) = ctx->block_vars;
6042   gsi_replace (gsi_p, bind, true);
6043   if (BLOCK_VARS (block))
6044     TREE_USED (block) = 1;
6045 }
6046
6047
6048 /* Expand code for an OpenMP master directive.  */
6049
6050 static void
6051 lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6052 {
6053   tree block, lab = NULL, x, bfn_decl;
6054   gimple stmt = gsi_stmt (*gsi_p), bind;
6055   location_t loc = gimple_location (stmt);
6056   gimple_seq tseq;
6057   struct gimplify_ctx gctx;
6058
6059   push_gimplify_context (&gctx);
6060
6061   block = make_node (BLOCK);
6062   bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
6063                                  block);
6064
6065   bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
6066   x = build_call_expr_loc (loc, bfn_decl, 0);
6067   x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
6068   x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
6069   tseq = NULL;
6070   gimplify_and_add (x, &tseq);
6071   gimple_bind_add_seq (bind, tseq);
6072
6073   lower_omp (gimple_omp_body (stmt), ctx);
6074   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6075   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6076   gimple_omp_set_body (stmt, NULL);
6077
6078   gimple_bind_add_stmt (bind, gimple_build_label (lab));
6079
6080   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6081
6082   pop_gimplify_context (bind);
6083
6084   gimple_bind_append_vars (bind, ctx->block_vars);
6085   BLOCK_VARS (block) = ctx->block_vars;
6086   gsi_replace (gsi_p, bind, true);
6087 }
6088
6089
6090 /* Expand code for an OpenMP ordered directive.  */
6091
6092 static void
6093 lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6094 {
6095   tree block;
6096   gimple stmt = gsi_stmt (*gsi_p), bind, x;
6097   struct gimplify_ctx gctx;
6098
6099   push_gimplify_context (&gctx);
6100
6101   block = make_node (BLOCK);
6102   bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
6103                                    block);
6104
6105   x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
6106                          0);
6107   gimple_bind_add_stmt (bind, x);
6108
6109   lower_omp (gimple_omp_body (stmt), ctx);
6110   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6111   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6112   gimple_omp_set_body (stmt, NULL);
6113
6114   x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END), 0);
6115   gimple_bind_add_stmt (bind, x);
6116
6117   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6118
6119   pop_gimplify_context (bind);
6120
6121   gimple_bind_append_vars (bind, ctx->block_vars);
6122   BLOCK_VARS (block) = gimple_bind_vars (bind);
6123   gsi_replace (gsi_p, bind, true);
6124 }
6125
6126
6127 /* Gimplify a GIMPLE_OMP_CRITICAL statement.  This is a relatively simple
6128    substitution of a couple of function calls.  But in the NAMED case,
6129    requires that languages coordinate a symbol name.  It is therefore
6130    best put here in common code.  */
6131
6132 static GTY((param1_is (tree), param2_is (tree)))
6133   splay_tree critical_name_mutexes;
6134
6135 static void
6136 lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6137 {
6138   tree block;
6139   tree name, lock, unlock;
6140   gimple stmt = gsi_stmt (*gsi_p), bind;
6141   location_t loc = gimple_location (stmt);
6142   gimple_seq tbody;
6143   struct gimplify_ctx gctx;
6144
6145   name = gimple_omp_critical_name (stmt);
6146   if (name)
6147     {
6148       tree decl;
6149       splay_tree_node n;
6150
6151       if (!critical_name_mutexes)
6152         critical_name_mutexes
6153           = splay_tree_new_ggc (splay_tree_compare_pointers,
6154                                 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_s,
6155                                 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_node_s);
6156
6157       n = splay_tree_lookup (critical_name_mutexes, (splay_tree_key) name);
6158       if (n == NULL)
6159         {
6160           char *new_str;
6161
6162           decl = create_tmp_var_raw (ptr_type_node, NULL);
6163
6164           new_str = ACONCAT ((".gomp_critical_user_",
6165                               IDENTIFIER_POINTER (name), NULL));
6166           DECL_NAME (decl) = get_identifier (new_str);
6167           TREE_PUBLIC (decl) = 1;
6168           TREE_STATIC (decl) = 1;
6169           DECL_COMMON (decl) = 1;
6170           DECL_ARTIFICIAL (decl) = 1;
6171           DECL_IGNORED_P (decl) = 1;
6172           varpool_finalize_decl (decl);
6173
6174           splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
6175                              (splay_tree_value) decl);
6176         }
6177       else
6178         decl = (tree) n->value;
6179
6180       lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START);
6181       lock = build_call_expr_loc (loc, lock, 1, build_fold_addr_expr_loc (loc, decl));
6182
6183       unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END);
6184       unlock = build_call_expr_loc (loc, unlock, 1,
6185                                 build_fold_addr_expr_loc (loc, decl));
6186     }
6187   else
6188     {
6189       lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START);
6190       lock = build_call_expr_loc (loc, lock, 0);
6191
6192       unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END);
6193       unlock = build_call_expr_loc (loc, unlock, 0);
6194     }
6195
6196   push_gimplify_context (&gctx);
6197
6198   block = make_node (BLOCK);
6199   bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt), block);
6200
6201   tbody = gimple_bind_body (bind);
6202   gimplify_and_add (lock, &tbody);
6203   gimple_bind_set_body (bind, tbody);
6204
6205   lower_omp (gimple_omp_body (stmt), ctx);
6206   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6207   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6208   gimple_omp_set_body (stmt, NULL);
6209
6210   tbody = gimple_bind_body (bind);
6211   gimplify_and_add (unlock, &tbody);
6212   gimple_bind_set_body (bind, tbody);
6213
6214   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6215
6216   pop_gimplify_context (bind);
6217   gimple_bind_append_vars (bind, ctx->block_vars);
6218   BLOCK_VARS (block) = gimple_bind_vars (bind);
6219   gsi_replace (gsi_p, bind, true);
6220 }
6221
6222
6223 /* A subroutine of lower_omp_for.  Generate code to emit the predicate
6224    for a lastprivate clause.  Given a loop control predicate of (V
6225    cond N2), we gate the clause on (!(V cond N2)).  The lowered form
6226    is appended to *DLIST, iterator initialization is appended to
6227    *BODY_P.  */
6228
6229 static void
6230 lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
6231                            gimple_seq *dlist, struct omp_context *ctx)
6232 {
6233   tree clauses, cond, vinit;
6234   enum tree_code cond_code;
6235   gimple_seq stmts;
6236
6237   cond_code = fd->loop.cond_code;
6238   cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
6239
6240   /* When possible, use a strict equality expression.  This can let VRP
6241      type optimizations deduce the value and remove a copy.  */
6242   if (host_integerp (fd->loop.step, 0))
6243     {
6244       HOST_WIDE_INT step = TREE_INT_CST_LOW (fd->loop.step);
6245       if (step == 1 || step == -1)
6246         cond_code = EQ_EXPR;
6247     }
6248
6249   cond = build2 (cond_code, boolean_type_node, fd->loop.v, fd->loop.n2);
6250
6251   clauses = gimple_omp_for_clauses (fd->for_stmt);
6252   stmts = NULL;
6253   lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
6254   if (!gimple_seq_empty_p (stmts))
6255     {
6256       gimple_seq_add_seq (&stmts, *dlist);
6257       *dlist = stmts;
6258
6259       /* Optimize: v = 0; is usually cheaper than v = some_other_constant.  */
6260       vinit = fd->loop.n1;
6261       if (cond_code == EQ_EXPR
6262           && host_integerp (fd->loop.n2, 0)
6263           && ! integer_zerop (fd->loop.n2))
6264         vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
6265
6266       /* Initialize the iterator variable, so that threads that don't execute
6267          any iterations don't execute the lastprivate clauses by accident.  */
6268       gimplify_assign (fd->loop.v, vinit, body_p);
6269     }
6270 }
6271
6272
6273 /* Lower code for an OpenMP loop directive.  */
6274
6275 static void
6276 lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6277 {
6278   tree *rhs_p, block;
6279   struct omp_for_data fd;
6280   gimple stmt = gsi_stmt (*gsi_p), new_stmt;
6281   gimple_seq omp_for_body, body, dlist;
6282   size_t i;
6283   struct gimplify_ctx gctx;
6284
6285   push_gimplify_context (&gctx);
6286
6287   lower_omp (gimple_omp_for_pre_body (stmt), ctx);
6288   lower_omp (gimple_omp_body (stmt), ctx);
6289
6290   block = make_node (BLOCK);
6291   new_stmt = gimple_build_bind (NULL, NULL, block);
6292
6293   /* Move declaration of temporaries in the loop body before we make
6294      it go away.  */
6295   omp_for_body = gimple_omp_body (stmt);
6296   if (!gimple_seq_empty_p (omp_for_body)
6297       && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
6298     {
6299       tree vars = gimple_bind_vars (gimple_seq_first_stmt (omp_for_body));
6300       gimple_bind_append_vars (new_stmt, vars);
6301     }
6302
6303   /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR.  */
6304   dlist = NULL;
6305   body = NULL;
6306   lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx);
6307   gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
6308
6309   /* Lower the header expressions.  At this point, we can assume that
6310      the header is of the form:
6311
6312         #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
6313
6314      We just need to make sure that VAL1, VAL2 and VAL3 are lowered
6315      using the .omp_data_s mapping, if needed.  */
6316   for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
6317     {
6318       rhs_p = gimple_omp_for_initial_ptr (stmt, i);
6319       if (!is_gimple_min_invariant (*rhs_p))
6320         *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6321
6322       rhs_p = gimple_omp_for_final_ptr (stmt, i);
6323       if (!is_gimple_min_invariant (*rhs_p))
6324         *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6325
6326       rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
6327       if (!is_gimple_min_invariant (*rhs_p))
6328         *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6329     }
6330
6331   /* Once lowered, extract the bounds and clauses.  */
6332   extract_omp_for_data (stmt, &fd, NULL);
6333
6334   lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
6335
6336   gimple_seq_add_stmt (&body, stmt);
6337   gimple_seq_add_seq (&body, gimple_omp_body (stmt));
6338
6339   gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
6340                                                          fd.loop.v));
6341
6342   /* After the loop, add exit clauses.  */
6343   lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, ctx);
6344   gimple_seq_add_seq (&body, dlist);
6345
6346   body = maybe_catch_exception (body);
6347
6348   /* Region exit marker goes at the end of the loop body.  */
6349   gimple_seq_add_stmt (&body, gimple_build_omp_return (fd.have_nowait));
6350
6351   pop_gimplify_context (new_stmt);
6352
6353   gimple_bind_append_vars (new_stmt, ctx->block_vars);
6354   BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
6355   if (BLOCK_VARS (block))
6356     TREE_USED (block) = 1;
6357
6358   gimple_bind_set_body (new_stmt, body);
6359   gimple_omp_set_body (stmt, NULL);
6360   gimple_omp_for_set_pre_body (stmt, NULL);
6361   gsi_replace (gsi_p, new_stmt, true);
6362 }
6363
6364 /* Callback for walk_stmts.  Check if the current statement only contains
6365    GIMPLE_OMP_FOR or GIMPLE_OMP_PARALLEL.  */
6366
6367 static tree
6368 check_combined_parallel (gimple_stmt_iterator *gsi_p,
6369                          bool *handled_ops_p,
6370                          struct walk_stmt_info *wi)
6371 {
6372   int *info = (int *) wi->info;
6373   gimple stmt = gsi_stmt (*gsi_p);
6374
6375   *handled_ops_p = true;
6376   switch (gimple_code (stmt))
6377     {
6378     WALK_SUBSTMTS;
6379
6380     case GIMPLE_OMP_FOR:
6381     case GIMPLE_OMP_SECTIONS:
6382       *info = *info == 0 ? 1 : -1;
6383       break;
6384     default:
6385       *info = -1;
6386       break;
6387     }
6388   return NULL;
6389 }
6390
6391 struct omp_taskcopy_context
6392 {
6393   /* This field must be at the beginning, as we do "inheritance": Some
6394      callback functions for tree-inline.c (e.g., omp_copy_decl)
6395      receive a copy_body_data pointer that is up-casted to an
6396      omp_context pointer.  */
6397   copy_body_data cb;
6398   omp_context *ctx;
6399 };
6400
6401 static tree
6402 task_copyfn_copy_decl (tree var, copy_body_data *cb)
6403 {
6404   struct omp_taskcopy_context *tcctx = (struct omp_taskcopy_context *) cb;
6405
6406   if (splay_tree_lookup (tcctx->ctx->sfield_map, (splay_tree_key) var))
6407     return create_tmp_var (TREE_TYPE (var), NULL);
6408
6409   return var;
6410 }
6411
6412 static tree
6413 task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
6414 {
6415   tree name, new_fields = NULL, type, f;
6416
6417   type = lang_hooks.types.make_type (RECORD_TYPE);
6418   name = DECL_NAME (TYPE_NAME (orig_type));
6419   name = build_decl (gimple_location (tcctx->ctx->stmt),
6420                      TYPE_DECL, name, type);
6421   TYPE_NAME (type) = name;
6422
6423   for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
6424     {
6425       tree new_f = copy_node (f);
6426       DECL_CONTEXT (new_f) = type;
6427       TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
6428       TREE_CHAIN (new_f) = new_fields;
6429       walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6430       walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6431       walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
6432                  &tcctx->cb, NULL);
6433       new_fields = new_f;
6434       *pointer_map_insert (tcctx->cb.decl_map, f) = new_f;
6435     }
6436   TYPE_FIELDS (type) = nreverse (new_fields);
6437   layout_type (type);
6438   return type;
6439 }
6440
6441 /* Create task copyfn.  */
6442
6443 static void
6444 create_task_copyfn (gimple task_stmt, omp_context *ctx)
6445 {
6446   struct function *child_cfun;
6447   tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
6448   tree record_type, srecord_type, bind, list;
6449   bool record_needs_remap = false, srecord_needs_remap = false;
6450   splay_tree_node n;
6451   struct omp_taskcopy_context tcctx;
6452   struct gimplify_ctx gctx;
6453   location_t loc = gimple_location (task_stmt);
6454
6455   child_fn = gimple_omp_task_copy_fn (task_stmt);
6456   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
6457   gcc_assert (child_cfun->cfg == NULL);
6458   DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();
6459
6460   /* Reset DECL_CONTEXT on function arguments.  */
6461   for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
6462     DECL_CONTEXT (t) = child_fn;
6463
6464   /* Populate the function.  */
6465   push_gimplify_context (&gctx);
6466   current_function_decl = child_fn;
6467
6468   bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
6469   TREE_SIDE_EFFECTS (bind) = 1;
6470   list = NULL;
6471   DECL_SAVED_TREE (child_fn) = bind;
6472   DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);
6473
6474   /* Remap src and dst argument types if needed.  */
6475   record_type = ctx->record_type;
6476   srecord_type = ctx->srecord_type;
6477   for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
6478     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6479       {
6480         record_needs_remap = true;
6481         break;
6482       }
6483   for (f = TYPE_FIELDS (srecord_type); f ; f = DECL_CHAIN (f))
6484     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6485       {
6486         srecord_needs_remap = true;
6487         break;
6488       }
6489
6490   if (record_needs_remap || srecord_needs_remap)
6491     {
6492       memset (&tcctx, '\0', sizeof (tcctx));
6493       tcctx.cb.src_fn = ctx->cb.src_fn;
6494       tcctx.cb.dst_fn = child_fn;
6495       tcctx.cb.src_node = cgraph_get_node (tcctx.cb.src_fn);
6496       gcc_checking_assert (tcctx.cb.src_node);
6497       tcctx.cb.dst_node = tcctx.cb.src_node;
6498       tcctx.cb.src_cfun = ctx->cb.src_cfun;
6499       tcctx.cb.copy_decl = task_copyfn_copy_decl;
6500       tcctx.cb.eh_lp_nr = 0;
6501       tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
6502       tcctx.cb.decl_map = pointer_map_create ();
6503       tcctx.ctx = ctx;
6504
6505       if (record_needs_remap)
6506         record_type = task_copyfn_remap_type (&tcctx, record_type);
6507       if (srecord_needs_remap)
6508         srecord_type = task_copyfn_remap_type (&tcctx, srecord_type);
6509     }
6510   else
6511     tcctx.cb.decl_map = NULL;
6512
6513   push_cfun (child_cfun);
6514
6515   arg = DECL_ARGUMENTS (child_fn);
6516   TREE_TYPE (arg) = build_pointer_type (record_type);
6517   sarg = DECL_CHAIN (arg);
6518   TREE_TYPE (sarg) = build_pointer_type (srecord_type);
6519
6520   /* First pass: initialize temporaries used in record_type and srecord_type
6521      sizes and field offsets.  */
6522   if (tcctx.cb.decl_map)
6523     for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6524       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6525         {
6526           tree *p;
6527
6528           decl = OMP_CLAUSE_DECL (c);
6529           p = (tree *) pointer_map_contains (tcctx.cb.decl_map, decl);
6530           if (p == NULL)
6531             continue;
6532           n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6533           sf = (tree) n->value;
6534           sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6535           src = build_simple_mem_ref_loc (loc, sarg);
6536           src = build3 (COMPONENT_REF, TREE_TYPE (sf), src, sf, NULL);
6537           t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
6538           append_to_statement_list (t, &list);
6539         }
6540
6541   /* Second pass: copy shared var pointers and copy construct non-VLA
6542      firstprivate vars.  */
6543   for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6544     switch (OMP_CLAUSE_CODE (c))
6545       {
6546       case OMP_CLAUSE_SHARED:
6547         decl = OMP_CLAUSE_DECL (c);
6548         n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6549         if (n == NULL)
6550           break;
6551         f = (tree) n->value;
6552         if (tcctx.cb.decl_map)
6553           f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6554         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6555         sf = (tree) n->value;
6556         if (tcctx.cb.decl_map)
6557           sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6558         src = build_simple_mem_ref_loc (loc, sarg);
6559         src = build3 (COMPONENT_REF, TREE_TYPE (sf), src, sf, NULL);
6560         dst = build_simple_mem_ref_loc (loc, arg);
6561         dst = build3 (COMPONENT_REF, TREE_TYPE (f), dst, f, NULL);
6562         t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6563         append_to_statement_list (t, &list);
6564         break;
6565       case OMP_CLAUSE_FIRSTPRIVATE:
6566         decl = OMP_CLAUSE_DECL (c);
6567         if (is_variable_sized (decl))
6568           break;
6569         n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6570         if (n == NULL)
6571           break;
6572         f = (tree) n->value;
6573         if (tcctx.cb.decl_map)
6574           f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6575         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6576         if (n != NULL)
6577           {
6578             sf = (tree) n->value;
6579             if (tcctx.cb.decl_map)
6580               sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6581             src = build_simple_mem_ref_loc (loc, sarg);
6582             src = build3 (COMPONENT_REF, TREE_TYPE (sf), src, sf, NULL);
6583             if (use_pointer_for_field (decl, NULL) || is_reference (decl))
6584               src = build_simple_mem_ref_loc (loc, src);
6585           }
6586         else
6587           src = decl;
6588         dst = build_simple_mem_ref_loc (loc, arg);
6589         dst = build3 (COMPONENT_REF, TREE_TYPE (f), dst, f, NULL);
6590         t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6591         append_to_statement_list (t, &list);
6592         break;
6593       case OMP_CLAUSE_PRIVATE:
6594         if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c))
6595           break;
6596         decl = OMP_CLAUSE_DECL (c);
6597         n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6598         f = (tree) n->value;
6599         if (tcctx.cb.decl_map)
6600           f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6601         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6602         if (n != NULL)
6603           {
6604             sf = (tree) n->value;
6605             if (tcctx.cb.decl_map)
6606               sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6607             src = build_simple_mem_ref_loc (loc, sarg);
6608             src = build3 (COMPONENT_REF, TREE_TYPE (sf), src, sf, NULL);
6609             if (use_pointer_for_field (decl, NULL))
6610               src = build_simple_mem_ref_loc (loc, src);
6611           }
6612         else
6613           src = decl;
6614         dst = build_simple_mem_ref_loc (loc, arg);
6615         dst = build3 (COMPONENT_REF, TREE_TYPE (f), dst, f, NULL);
6616         t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6617         append_to_statement_list (t, &list);
6618         break;
6619       default:
6620         break;
6621       }
6622
6623   /* Last pass: handle VLA firstprivates.  */
6624   if (tcctx.cb.decl_map)
6625     for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6626       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6627         {
6628           tree ind, ptr, df;
6629
6630           decl = OMP_CLAUSE_DECL (c);
6631           if (!is_variable_sized (decl))
6632             continue;
6633           n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6634           if (n == NULL)
6635             continue;
6636           f = (tree) n->value;
6637           f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6638           gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
6639           ind = DECL_VALUE_EXPR (decl);
6640           gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
6641           gcc_assert (DECL_P (TREE_OPERAND (ind, 0)));
6642           n = splay_tree_lookup (ctx->sfield_map,
6643                                  (splay_tree_key) TREE_OPERAND (ind, 0));
6644           sf = (tree) n->value;
6645           sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6646           src = build_simple_mem_ref_loc (loc, sarg);
6647           src = build3 (COMPONENT_REF, TREE_TYPE (sf), src, sf, NULL);
6648           src = build_simple_mem_ref_loc (loc, src);
6649           dst = build_simple_mem_ref_loc (loc, arg);
6650           dst = build3 (COMPONENT_REF, TREE_TYPE (f), dst, f, NULL);
6651           t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6652           append_to_statement_list (t, &list);
6653           n = splay_tree_lookup (ctx->field_map,
6654                                  (splay_tree_key) TREE_OPERAND (ind, 0));
6655           df = (tree) n->value;
6656           df = *(tree *) pointer_map_contains (tcctx.cb.decl_map, df);
6657           ptr = build_simple_mem_ref_loc (loc, arg);
6658           ptr = build3 (COMPONENT_REF, TREE_TYPE (df), ptr, df, NULL);
6659           t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
6660                       build_fold_addr_expr_loc (loc, dst));
6661           append_to_statement_list (t, &list);
6662         }
6663
6664   t = build1 (RETURN_EXPR, void_type_node, NULL);
6665   append_to_statement_list (t, &list);
6666
6667   if (tcctx.cb.decl_map)
6668     pointer_map_destroy (tcctx.cb.decl_map);
6669   pop_gimplify_context (NULL);
6670   BIND_EXPR_BODY (bind) = list;
6671   pop_cfun ();
6672   current_function_decl = ctx->cb.src_fn;
6673 }
6674
6675 /* Lower the OpenMP parallel or task directive in the current statement
6676    in GSI_P.  CTX holds context information for the directive.  */
6677
6678 static void
6679 lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6680 {
6681   tree clauses;
6682   tree child_fn, t;
6683   gimple stmt = gsi_stmt (*gsi_p);
6684   gimple par_bind, bind;
6685   gimple_seq par_body, olist, ilist, par_olist, par_ilist, new_body;
6686   struct gimplify_ctx gctx;
6687   location_t loc = gimple_location (stmt);
6688
6689   clauses = gimple_omp_taskreg_clauses (stmt);
6690   par_bind = gimple_seq_first_stmt (gimple_omp_body (stmt));
6691   par_body = gimple_bind_body (par_bind);
6692   child_fn = ctx->cb.dst_fn;
6693   if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
6694       && !gimple_omp_parallel_combined_p (stmt))
6695     {
6696       struct walk_stmt_info wi;
6697       int ws_num = 0;
6698
6699       memset (&wi, 0, sizeof (wi));
6700       wi.info = &ws_num;
6701       wi.val_only = true;
6702       walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
6703       if (ws_num == 1)
6704         gimple_omp_parallel_set_combined_p (stmt, true);
6705     }
6706   if (ctx->srecord_type)
6707     create_task_copyfn (stmt, ctx);
6708
6709   push_gimplify_context (&gctx);
6710
6711   par_olist = NULL;
6712   par_ilist = NULL;
6713   lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
6714   lower_omp (par_body, ctx);
6715   if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
6716     lower_reduction_clauses (clauses, &par_olist, ctx);
6717
6718   /* Declare all the variables created by mapping and the variables
6719      declared in the scope of the parallel body.  */
6720   record_vars_into (ctx->block_vars, child_fn);
6721   record_vars_into (gimple_bind_vars (par_bind), child_fn);
6722
6723   if (ctx->record_type)
6724     {
6725       ctx->sender_decl
6726         = create_tmp_var (ctx->srecord_type ? ctx->srecord_type
6727                           : ctx->record_type, ".omp_data_o");
6728       DECL_NAMELESS (ctx->sender_decl) = 1;
6729       TREE_ADDRESSABLE (ctx->sender_decl) = 1;
6730       gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
6731     }
6732
6733   olist = NULL;
6734   ilist = NULL;
6735   lower_send_clauses (clauses, &ilist, &olist, ctx);
6736   lower_send_shared_vars (&ilist, &olist, ctx);
6737
6738   /* Once all the expansions are done, sequence all the different
6739      fragments inside gimple_omp_body.  */
6740
6741   new_body = NULL;
6742
6743   if (ctx->record_type)
6744     {
6745       t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
6746       /* fixup_child_record_type might have changed receiver_decl's type.  */
6747       t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
6748       gimple_seq_add_stmt (&new_body,
6749                            gimple_build_assign (ctx->receiver_decl, t));
6750     }
6751
6752   gimple_seq_add_seq (&new_body, par_ilist);
6753   gimple_seq_add_seq (&new_body, par_body);
6754   gimple_seq_add_seq (&new_body, par_olist);
6755   new_body = maybe_catch_exception (new_body);
6756   gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
6757   gimple_omp_set_body (stmt, new_body);
6758
6759   bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
6760   gimple_bind_add_stmt (bind, stmt);
6761   if (ilist || olist)
6762     {
6763       gimple_seq_add_stmt (&ilist, bind);
6764       gimple_seq_add_seq (&ilist, olist);
6765       bind = gimple_build_bind (NULL, ilist, NULL);
6766     }
6767
6768   gsi_replace (gsi_p, bind, true);
6769
6770   pop_gimplify_context (NULL);
6771 }
6772
6773 /* Callback for lower_omp_1.  Return non-NULL if *tp needs to be
6774    regimplified.  If DATA is non-NULL, lower_omp_1 is outside
6775    of OpenMP context, but with task_shared_vars set.  */
6776
6777 static tree
6778 lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
6779                         void *data)
6780 {
6781   tree t = *tp;
6782
6783   /* Any variable with DECL_VALUE_EXPR needs to be regimplified.  */
6784   if (TREE_CODE (t) == VAR_DECL && data == NULL && DECL_HAS_VALUE_EXPR_P (t))
6785     return t;
6786
6787   if (task_shared_vars
6788       && DECL_P (t)
6789       && bitmap_bit_p (task_shared_vars, DECL_UID (t)))
6790     return t;
6791
6792   /* If a global variable has been privatized, TREE_CONSTANT on
6793      ADDR_EXPR might be wrong.  */
6794   if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
6795     recompute_tree_invariant_for_addr_expr (t);
6796
6797   *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
6798   return NULL_TREE;
6799 }
6800
6801 static void
6802 lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6803 {
6804   gimple stmt = gsi_stmt (*gsi_p);
6805   struct walk_stmt_info wi;
6806
6807   if (gimple_has_location (stmt))
6808     input_location = gimple_location (stmt);
6809
6810   if (task_shared_vars)
6811     memset (&wi, '\0', sizeof (wi));
6812
6813   /* If we have issued syntax errors, avoid doing any heavy lifting.
6814      Just replace the OpenMP directives with a NOP to avoid
6815      confusing RTL expansion.  */
6816   if (seen_error () && is_gimple_omp (stmt))
6817     {
6818       gsi_replace (gsi_p, gimple_build_nop (), true);
6819       return;
6820     }
6821
6822   switch (gimple_code (stmt))
6823     {
6824     case GIMPLE_COND:
6825       if ((ctx || task_shared_vars)
6826           && (walk_tree (gimple_cond_lhs_ptr (stmt), lower_omp_regimplify_p,
6827                          ctx ? NULL : &wi, NULL)
6828               || walk_tree (gimple_cond_rhs_ptr (stmt), lower_omp_regimplify_p,
6829                             ctx ? NULL : &wi, NULL)))
6830         gimple_regimplify_operands (stmt, gsi_p);
6831       break;
6832     case GIMPLE_CATCH:
6833       lower_omp (gimple_catch_handler (stmt), ctx);
6834       break;
6835     case GIMPLE_EH_FILTER:
6836       lower_omp (gimple_eh_filter_failure (stmt), ctx);
6837       break;
6838     case GIMPLE_TRY:
6839       lower_omp (gimple_try_eval (stmt), ctx);
6840       lower_omp (gimple_try_cleanup (stmt), ctx);
6841       break;
6842     case GIMPLE_BIND:
6843       lower_omp (gimple_bind_body (stmt), ctx);
6844       break;
6845     case GIMPLE_OMP_PARALLEL:
6846     case GIMPLE_OMP_TASK:
6847       ctx = maybe_lookup_ctx (stmt);
6848       lower_omp_taskreg (gsi_p, ctx);
6849       break;
6850     case GIMPLE_OMP_FOR:
6851       ctx = maybe_lookup_ctx (stmt);
6852       gcc_assert (ctx);
6853       lower_omp_for (gsi_p, ctx);
6854       break;
6855     case GIMPLE_OMP_SECTIONS:
6856       ctx = maybe_lookup_ctx (stmt);
6857       gcc_assert (ctx);
6858       lower_omp_sections (gsi_p, ctx);
6859       break;
6860     case GIMPLE_OMP_SINGLE:
6861       ctx = maybe_lookup_ctx (stmt);
6862       gcc_assert (ctx);
6863       lower_omp_single (gsi_p, ctx);
6864       break;
6865     case GIMPLE_OMP_MASTER:
6866       ctx = maybe_lookup_ctx (stmt);
6867       gcc_assert (ctx);
6868       lower_omp_master (gsi_p, ctx);
6869       break;
6870     case GIMPLE_OMP_ORDERED:
6871       ctx = maybe_lookup_ctx (stmt);
6872       gcc_assert (ctx);
6873       lower_omp_ordered (gsi_p, ctx);
6874       break;
6875     case GIMPLE_OMP_CRITICAL:
6876       ctx = maybe_lookup_ctx (stmt);
6877       gcc_assert (ctx);
6878       lower_omp_critical (gsi_p, ctx);
6879       break;
6880     case GIMPLE_OMP_ATOMIC_LOAD:
6881       if ((ctx || task_shared_vars)
6882           && walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt),
6883                         lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
6884         gimple_regimplify_operands (stmt, gsi_p);
6885       break;
6886     default:
6887       if ((ctx || task_shared_vars)
6888           && walk_gimple_op (stmt, lower_omp_regimplify_p,
6889                              ctx ? NULL : &wi))
6890         gimple_regimplify_operands (stmt, gsi_p);
6891       break;
6892     }
6893 }
6894
6895 static void
6896 lower_omp (gimple_seq body, omp_context *ctx)
6897 {
6898   location_t saved_location = input_location;
6899   gimple_stmt_iterator gsi = gsi_start (body);
6900   for (gsi = gsi_start (body); !gsi_end_p (gsi); gsi_next (&gsi))
6901     lower_omp_1 (&gsi, ctx);
6902   input_location = saved_location;
6903 }
6904 \f
6905 /* Main entry point.  */
6906
6907 static unsigned int
6908 execute_lower_omp (void)
6909 {
6910   gimple_seq body;
6911
6912   /* This pass always runs, to provide PROP_gimple_lomp.
6913      But there is nothing to do unless -fopenmp is given.  */
6914   if (flag_openmp == 0)
6915     return 0;
6916
6917   all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
6918                                  delete_omp_context);
6919
6920   body = gimple_body (current_function_decl);
6921   scan_omp (body, NULL);
6922   gcc_assert (taskreg_nesting_level == 0);
6923
6924   if (all_contexts->root)
6925     {
6926       struct gimplify_ctx gctx;
6927
6928       if (task_shared_vars)
6929         push_gimplify_context (&gctx);
6930       lower_omp (body, NULL);
6931       if (task_shared_vars)
6932         pop_gimplify_context (NULL);
6933     }
6934
6935   if (all_contexts)
6936     {
6937       splay_tree_delete (all_contexts);
6938       all_contexts = NULL;
6939     }
6940   BITMAP_FREE (task_shared_vars);
6941   return 0;
6942 }
6943
6944 struct gimple_opt_pass pass_lower_omp =
6945 {
6946  {
6947   GIMPLE_PASS,
6948   "omplower",                           /* name */
6949   NULL,                                 /* gate */
6950   execute_lower_omp,                    /* execute */
6951   NULL,                                 /* sub */
6952   NULL,                                 /* next */
6953   0,                                    /* static_pass_number */
6954   TV_NONE,                              /* tv_id */
6955   PROP_gimple_any,                      /* properties_required */
6956   PROP_gimple_lomp,                     /* properties_provided */
6957   0,                                    /* properties_destroyed */
6958   0,                                    /* todo_flags_start */
6959   0                                     /* todo_flags_finish */
6960  }
6961 };
6962 \f
6963 /* The following is a utility to diagnose OpenMP structured block violations.
6964    It is not part of the "omplower" pass, as that's invoked too late.  It
6965    should be invoked by the respective front ends after gimplification.  */
6966
6967 static splay_tree all_labels;
6968
6969 /* Check for mismatched contexts and generate an error if needed.  Return
6970    true if an error is detected.  */
6971
6972 static bool
6973 diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
6974                gimple branch_ctx, gimple label_ctx)
6975 {
6976   if (label_ctx == branch_ctx)
6977     return false;
6978
6979
6980   /*
6981      Previously we kept track of the label's entire context in diagnose_sb_[12]
6982      so we could traverse it and issue a correct "exit" or "enter" error
6983      message upon a structured block violation.
6984
6985      We built the context by building a list with tree_cons'ing, but there is
6986      no easy counterpart in gimple tuples.  It seems like far too much work
6987      for issuing exit/enter error messages.  If someone really misses the
6988      distinct error message... patches welcome.
6989    */
6990
6991 #if 0
6992   /* Try to avoid confusing the user by producing and error message
6993      with correct "exit" or "enter" verbiage.  We prefer "exit"
6994      unless we can show that LABEL_CTX is nested within BRANCH_CTX.  */
6995   if (branch_ctx == NULL)
6996     exit_p = false;
6997   else
6998     {
6999       while (label_ctx)
7000         {
7001           if (TREE_VALUE (label_ctx) == branch_ctx)
7002             {
7003               exit_p = false;
7004               break;
7005             }
7006           label_ctx = TREE_CHAIN (label_ctx);
7007         }
7008     }
7009
7010   if (exit_p)
7011     error ("invalid exit from OpenMP structured block");
7012   else
7013     error ("invalid entry to OpenMP structured block");
7014 #endif
7015
7016   /* If it's obvious we have an invalid entry, be specific about the error.  */
7017   if (branch_ctx == NULL)
7018     error ("invalid entry to OpenMP structured block");
7019   else
7020     /* Otherwise, be vague and lazy, but efficient.  */
7021     error ("invalid branch to/from an OpenMP structured block");
7022
7023   gsi_replace (gsi_p, gimple_build_nop (), false);
7024   return true;
7025 }
7026
7027 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
7028    where each label is found.  */
7029
7030 static tree
7031 diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
7032                struct walk_stmt_info *wi)
7033 {
7034   gimple context = (gimple) wi->info;
7035   gimple inner_context;
7036   gimple stmt = gsi_stmt (*gsi_p);
7037
7038   *handled_ops_p = true;
7039
7040  switch (gimple_code (stmt))
7041     {
7042     WALK_SUBSTMTS;
7043
7044     case GIMPLE_OMP_PARALLEL:
7045     case GIMPLE_OMP_TASK:
7046     case GIMPLE_OMP_SECTIONS:
7047     case GIMPLE_OMP_SINGLE:
7048     case GIMPLE_OMP_SECTION:
7049     case GIMPLE_OMP_MASTER:
7050     case GIMPLE_OMP_ORDERED:
7051     case GIMPLE_OMP_CRITICAL:
7052       /* The minimal context here is just the current OMP construct.  */
7053       inner_context = stmt;
7054       wi->info = inner_context;
7055       walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
7056       wi->info = context;
7057       break;
7058
7059     case GIMPLE_OMP_FOR:
7060       inner_context = stmt;
7061       wi->info = inner_context;
7062       /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7063          walk them.  */
7064       walk_gimple_seq (gimple_omp_for_pre_body (stmt),
7065                        diagnose_sb_1, NULL, wi);
7066       walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
7067       wi->info = context;
7068       break;
7069
7070     case GIMPLE_LABEL:
7071       splay_tree_insert (all_labels, (splay_tree_key) gimple_label_label (stmt),
7072                          (splay_tree_value) context);
7073       break;
7074
7075     default:
7076       break;
7077     }
7078
7079   return NULL_TREE;
7080 }
7081
7082 /* Pass 2: Check each branch and see if its context differs from that of
7083    the destination label's context.  */
7084
7085 static tree
7086 diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
7087                struct walk_stmt_info *wi)
7088 {
7089   gimple context = (gimple) wi->info;
7090   splay_tree_node n;
7091   gimple stmt = gsi_stmt (*gsi_p);
7092
7093   *handled_ops_p = true;
7094
7095   switch (gimple_code (stmt))
7096     {
7097     WALK_SUBSTMTS;
7098
7099     case GIMPLE_OMP_PARALLEL:
7100     case GIMPLE_OMP_TASK:
7101     case GIMPLE_OMP_SECTIONS:
7102     case GIMPLE_OMP_SINGLE:
7103     case GIMPLE_OMP_SECTION:
7104     case GIMPLE_OMP_MASTER:
7105     case GIMPLE_OMP_ORDERED:
7106     case GIMPLE_OMP_CRITICAL:
7107       wi->info = stmt;
7108       walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
7109       wi->info = context;
7110       break;
7111
7112     case GIMPLE_OMP_FOR:
7113       wi->info = stmt;
7114       /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7115          walk them.  */
7116       walk_gimple_seq (gimple_omp_for_pre_body (stmt),
7117                        diagnose_sb_2, NULL, wi);
7118       walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
7119       wi->info = context;
7120       break;
7121
7122     case GIMPLE_COND:
7123         {
7124           tree lab = gimple_cond_true_label (stmt);
7125           if (lab)
7126             {
7127               n = splay_tree_lookup (all_labels,
7128                                      (splay_tree_key) lab);
7129               diagnose_sb_0 (gsi_p, context,
7130                              n ? (gimple) n->value : NULL);
7131             }
7132           lab = gimple_cond_false_label (stmt);
7133           if (lab)
7134             {
7135               n = splay_tree_lookup (all_labels,
7136                                      (splay_tree_key) lab);
7137               diagnose_sb_0 (gsi_p, context,
7138                              n ? (gimple) n->value : NULL);
7139             }
7140         }
7141       break;
7142
7143     case GIMPLE_GOTO:
7144       {
7145         tree lab = gimple_goto_dest (stmt);
7146         if (TREE_CODE (lab) != LABEL_DECL)
7147           break;
7148
7149         n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
7150         diagnose_sb_0 (gsi_p, context, n ? (gimple) n->value : NULL);
7151       }
7152       break;
7153
7154     case GIMPLE_SWITCH:
7155       {
7156         unsigned int i;
7157         for (i = 0; i < gimple_switch_num_labels (stmt); ++i)
7158           {
7159             tree lab = CASE_LABEL (gimple_switch_label (stmt, i));
7160             n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
7161             if (n && diagnose_sb_0 (gsi_p, context, (gimple) n->value))
7162               break;
7163           }
7164       }
7165       break;
7166
7167     case GIMPLE_RETURN:
7168       diagnose_sb_0 (gsi_p, context, NULL);
7169       break;
7170
7171     default:
7172       break;
7173     }
7174
7175   return NULL_TREE;
7176 }
7177
7178 static unsigned int
7179 diagnose_omp_structured_block_errors (void)
7180 {
7181   struct walk_stmt_info wi;
7182   gimple_seq body = gimple_body (current_function_decl);
7183
7184   all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
7185
7186   memset (&wi, 0, sizeof (wi));
7187   walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);
7188
7189   memset (&wi, 0, sizeof (wi));
7190   wi.want_locations = true;
7191   walk_gimple_seq (body, diagnose_sb_2, NULL, &wi);
7192
7193   splay_tree_delete (all_labels);
7194   all_labels = NULL;
7195
7196   return 0;
7197 }
7198
7199 static bool
7200 gate_diagnose_omp_blocks (void)
7201 {
7202   return flag_openmp != 0;
7203 }
7204
7205 struct gimple_opt_pass pass_diagnose_omp_blocks =
7206 {
7207   {
7208     GIMPLE_PASS,
7209     "*diagnose_omp_blocks",             /* name */
7210     gate_diagnose_omp_blocks,           /* gate */
7211     diagnose_omp_structured_block_errors,       /* execute */
7212     NULL,                               /* sub */
7213     NULL,                               /* next */
7214     0,                                  /* static_pass_number */
7215     TV_NONE,                            /* tv_id */
7216     PROP_gimple_any,                    /* properties_required */
7217     0,                                  /* properties_provided */
7218     0,                                  /* properties_destroyed */
7219     0,                                  /* todo_flags_start */
7220     0,                                  /* todo_flags_finish */
7221   }
7222 };
7223
7224 #include "gt-omp-low.h"