OSDN Git Service

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