OSDN Git Service

Backported from mainline
[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 (exit_reachable == (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 (exit_reachable)
4767     {
4768       if (single_pred_p (l2_bb) && single_pred (l2_bb) == l0_bb)
4769         l2 = gimple_block_label (l2_bb);
4770       else
4771         {
4772           /* This can happen if there are reductions.  */
4773           len = EDGE_COUNT (l0_bb->succs);
4774           gcc_assert (len > 0);
4775           e = EDGE_SUCC (l0_bb, len - 1);
4776           si = gsi_last_bb (e->dest);
4777           l2 = NULL_TREE;
4778           if (gsi_end_p (si)
4779               || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
4780             l2 = gimple_block_label (e->dest);
4781           else
4782             FOR_EACH_EDGE (e, ei, l0_bb->succs)
4783               {
4784                 si = gsi_last_bb (e->dest);
4785                 if (gsi_end_p (si)
4786                     || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
4787                   {
4788                     l2 = gimple_block_label (e->dest);
4789                     break;
4790                   }
4791               }
4792         }
4793       default_bb = create_empty_bb (l1_bb->prev_bb);
4794     }
4795   else
4796     {
4797       default_bb = create_empty_bb (l0_bb);
4798       l2 = gimple_block_label (default_bb);
4799     }
4800
4801   /* We will build a switch() with enough cases for all the
4802      GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
4803      and a default case to abort if something goes wrong.  */
4804   len = EDGE_COUNT (l0_bb->succs);
4805
4806   /* Use VEC_quick_push on label_vec throughout, since we know the size
4807      in advance.  */
4808   label_vec = VEC_alloc (tree, heap, len);
4809
4810   /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
4811      GIMPLE_OMP_SECTIONS statement.  */
4812   si = gsi_last_bb (entry_bb);
4813   sections_stmt = gsi_stmt (si);
4814   gcc_assert (gimple_code (sections_stmt) == GIMPLE_OMP_SECTIONS);
4815   vin = gimple_omp_sections_control (sections_stmt);
4816   if (!is_combined_parallel (region))
4817     {
4818       /* If we are not inside a combined parallel+sections region,
4819          call GOMP_sections_start.  */
4820       t = build_int_cst (unsigned_type_node,
4821                          exit_reachable ? len - 1 : len);
4822       u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START);
4823       stmt = gimple_build_call (u, 1, t);
4824     }
4825   else
4826     {
4827       /* Otherwise, call GOMP_sections_next.  */
4828       u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
4829       stmt = gimple_build_call (u, 0);
4830     }
4831   gimple_call_set_lhs (stmt, vin);
4832   gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4833   gsi_remove (&si, true);
4834
4835   /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
4836      L0_BB.  */
4837   switch_si = gsi_last_bb (l0_bb);
4838   gcc_assert (gimple_code (gsi_stmt (switch_si)) == GIMPLE_OMP_SECTIONS_SWITCH);
4839   if (exit_reachable)
4840     {
4841       cont = last_stmt (l1_bb);
4842       gcc_assert (gimple_code (cont) == GIMPLE_OMP_CONTINUE);
4843       vmain = gimple_omp_continue_control_use (cont);
4844       vnext = gimple_omp_continue_control_def (cont);
4845     }
4846   else
4847     {
4848       vmain = vin;
4849       vnext = NULL_TREE;
4850     }
4851
4852   i = 0;
4853   if (exit_reachable)
4854     {
4855       t = build_case_label (build_int_cst (unsigned_type_node, 0), NULL, l2);
4856       VEC_quick_push (tree, label_vec, t);
4857       i++;
4858     }
4859
4860   /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR.  */
4861   for (inner = region->inner, casei = 1;
4862        inner;
4863        inner = inner->next, i++, casei++)
4864     {
4865       basic_block s_entry_bb, s_exit_bb;
4866
4867       /* Skip optional reduction region.  */
4868       if (inner->type == GIMPLE_OMP_ATOMIC_LOAD)
4869         {
4870           --i;
4871           --casei;
4872           continue;
4873         }
4874
4875       s_entry_bb = inner->entry;
4876       s_exit_bb = inner->exit;
4877
4878       t = gimple_block_label (s_entry_bb);
4879       u = build_int_cst (unsigned_type_node, casei);
4880       u = build_case_label (u, NULL, t);
4881       VEC_quick_push (tree, label_vec, u);
4882
4883       si = gsi_last_bb (s_entry_bb);
4884       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SECTION);
4885       gcc_assert (i < len || gimple_omp_section_last_p (gsi_stmt (si)));
4886       gsi_remove (&si, true);
4887       single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
4888
4889       if (s_exit_bb == NULL)
4890         continue;
4891
4892       si = gsi_last_bb (s_exit_bb);
4893       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
4894       gsi_remove (&si, true);
4895
4896       single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
4897     }
4898
4899   /* Error handling code goes in DEFAULT_BB.  */
4900   t = gimple_block_label (default_bb);
4901   u = build_case_label (NULL, NULL, t);
4902   make_edge (l0_bb, default_bb, 0);
4903
4904   stmt = gimple_build_switch_vec (vmain, u, label_vec);
4905   gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
4906   gsi_remove (&switch_si, true);
4907   VEC_free (tree, heap, label_vec);
4908
4909   si = gsi_start_bb (default_bb);
4910   stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
4911   gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4912
4913   if (exit_reachable)
4914     {
4915       tree bfn_decl;
4916
4917       /* Code to get the next section goes in L1_BB.  */
4918       si = gsi_last_bb (l1_bb);
4919       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CONTINUE);
4920
4921       bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
4922       stmt = gimple_build_call (bfn_decl, 0);
4923       gimple_call_set_lhs (stmt, vnext);
4924       gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4925       gsi_remove (&si, true);
4926
4927       single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
4928
4929       /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB.  */
4930       si = gsi_last_bb (l2_bb);
4931       if (gimple_omp_return_nowait_p (gsi_stmt (si)))
4932         t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT);
4933       else
4934         t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END);
4935       stmt = gimple_build_call (t, 0);
4936       gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4937       gsi_remove (&si, true);
4938     }
4939
4940   set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb);
4941 }
4942
4943
4944 /* Expand code for an OpenMP single directive.  We've already expanded
4945    much of the code, here we simply place the GOMP_barrier call.  */
4946
4947 static void
4948 expand_omp_single (struct omp_region *region)
4949 {
4950   basic_block entry_bb, exit_bb;
4951   gimple_stmt_iterator si;
4952   bool need_barrier = false;
4953
4954   entry_bb = region->entry;
4955   exit_bb = region->exit;
4956
4957   si = gsi_last_bb (entry_bb);
4958   /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
4959      be removed.  We need to ensure that the thread that entered the single
4960      does not exit before the data is copied out by the other threads.  */
4961   if (find_omp_clause (gimple_omp_single_clauses (gsi_stmt (si)),
4962                        OMP_CLAUSE_COPYPRIVATE))
4963     need_barrier = true;
4964   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE);
4965   gsi_remove (&si, true);
4966   single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
4967
4968   si = gsi_last_bb (exit_bb);
4969   if (!gimple_omp_return_nowait_p (gsi_stmt (si)) || need_barrier)
4970     force_gimple_operand_gsi (&si, build_omp_barrier (), false, NULL_TREE,
4971                               false, GSI_SAME_STMT);
4972   gsi_remove (&si, true);
4973   single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
4974 }
4975
4976
4977 /* Generic expansion for OpenMP synchronization directives: master,
4978    ordered and critical.  All we need to do here is remove the entry
4979    and exit markers for REGION.  */
4980
4981 static void
4982 expand_omp_synch (struct omp_region *region)
4983 {
4984   basic_block entry_bb, exit_bb;
4985   gimple_stmt_iterator si;
4986
4987   entry_bb = region->entry;
4988   exit_bb = region->exit;
4989
4990   si = gsi_last_bb (entry_bb);
4991   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE
4992               || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASTER
4993               || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ORDERED
4994               || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CRITICAL);
4995   gsi_remove (&si, true);
4996   single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
4997
4998   if (exit_bb)
4999     {
5000       si = gsi_last_bb (exit_bb);
5001       gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
5002       gsi_remove (&si, true);
5003       single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
5004     }
5005 }
5006
5007 /* A subroutine of expand_omp_atomic.  Attempt to implement the atomic
5008    operation as a normal volatile load.  */
5009
5010 static bool
5011 expand_omp_atomic_load (basic_block load_bb, tree addr,
5012                         tree loaded_val, int index)
5013 {
5014   enum built_in_function tmpbase;
5015   gimple_stmt_iterator gsi;
5016   basic_block store_bb;
5017   location_t loc;
5018   gimple stmt;
5019   tree decl, call, type, itype;
5020
5021   gsi = gsi_last_bb (load_bb);
5022   stmt = gsi_stmt (gsi);
5023   gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
5024   loc = gimple_location (stmt);
5025
5026   /* ??? If the target does not implement atomic_load_optab[mode], and mode
5027      is smaller than word size, then expand_atomic_load assumes that the load
5028      is atomic.  We could avoid the builtin entirely in this case.  */
5029
5030   tmpbase = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
5031   decl = builtin_decl_explicit (tmpbase);
5032   if (decl == NULL_TREE)
5033     return false;
5034
5035   type = TREE_TYPE (loaded_val);
5036   itype = TREE_TYPE (TREE_TYPE (decl));
5037
5038   call = build_call_expr_loc (loc, decl, 2, addr,
5039                               build_int_cst (NULL, MEMMODEL_RELAXED));
5040   if (!useless_type_conversion_p (type, itype))
5041     call = fold_build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
5042   call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
5043
5044   force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5045   gsi_remove (&gsi, true);
5046
5047   store_bb = single_succ (load_bb);
5048   gsi = gsi_last_bb (store_bb);
5049   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
5050   gsi_remove (&gsi, true);
5051
5052   if (gimple_in_ssa_p (cfun))
5053     update_ssa (TODO_update_ssa_no_phi);
5054
5055   return true;
5056 }
5057
5058 /* A subroutine of expand_omp_atomic.  Attempt to implement the atomic
5059    operation as a normal volatile store.  */
5060
5061 static bool
5062 expand_omp_atomic_store (basic_block load_bb, tree addr,
5063                          tree loaded_val, tree stored_val, int index)
5064 {
5065   enum built_in_function tmpbase;
5066   gimple_stmt_iterator gsi;
5067   basic_block store_bb = single_succ (load_bb);
5068   location_t loc;
5069   gimple stmt;
5070   tree decl, call, type, itype;
5071   enum machine_mode imode;
5072   bool exchange;
5073
5074   gsi = gsi_last_bb (load_bb);
5075   stmt = gsi_stmt (gsi);
5076   gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
5077
5078   /* If the load value is needed, then this isn't a store but an exchange.  */
5079   exchange = gimple_omp_atomic_need_value_p (stmt);
5080
5081   gsi = gsi_last_bb (store_bb);
5082   stmt = gsi_stmt (gsi);
5083   gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE);
5084   loc = gimple_location (stmt);
5085
5086   /* ??? If the target does not implement atomic_store_optab[mode], and mode
5087      is smaller than word size, then expand_atomic_store assumes that the store
5088      is atomic.  We could avoid the builtin entirely in this case.  */
5089
5090   tmpbase = (exchange ? BUILT_IN_ATOMIC_EXCHANGE_N : BUILT_IN_ATOMIC_STORE_N);
5091   tmpbase = (enum built_in_function) ((int) tmpbase + index + 1);
5092   decl = builtin_decl_explicit (tmpbase);
5093   if (decl == NULL_TREE)
5094     return false;
5095
5096   type = TREE_TYPE (stored_val);
5097
5098   /* Dig out the type of the function's second argument.  */
5099   itype = TREE_TYPE (decl);
5100   itype = TYPE_ARG_TYPES (itype);
5101   itype = TREE_CHAIN (itype);
5102   itype = TREE_VALUE (itype);
5103   imode = TYPE_MODE (itype);
5104
5105   if (exchange && !can_atomic_exchange_p (imode, true))
5106     return false;
5107
5108   if (!useless_type_conversion_p (itype, type))
5109     stored_val = fold_build1_loc (loc, VIEW_CONVERT_EXPR, itype, stored_val);
5110   call = build_call_expr_loc (loc, decl, 3, addr, stored_val,
5111                               build_int_cst (NULL, MEMMODEL_RELAXED));
5112   if (exchange)
5113     {
5114       if (!useless_type_conversion_p (type, itype))
5115         call = build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
5116       call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
5117     }
5118
5119   force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5120   gsi_remove (&gsi, true);
5121
5122   /* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above.  */
5123   gsi = gsi_last_bb (load_bb);
5124   gsi_remove (&gsi, true);
5125
5126   if (gimple_in_ssa_p (cfun))
5127     update_ssa (TODO_update_ssa_no_phi);
5128
5129   return true;
5130 }
5131
5132 /* A subroutine of expand_omp_atomic.  Attempt to implement the atomic
5133    operation as a __atomic_fetch_op builtin.  INDEX is log2 of the
5134    size of the data type, and thus usable to find the index of the builtin
5135    decl.  Returns false if the expression is not of the proper form.  */
5136
5137 static bool
5138 expand_omp_atomic_fetch_op (basic_block load_bb,
5139                             tree addr, tree loaded_val,
5140                             tree stored_val, int index)
5141 {
5142   enum built_in_function oldbase, newbase, tmpbase;
5143   tree decl, itype, call;
5144   tree lhs, rhs;
5145   basic_block store_bb = single_succ (load_bb);
5146   gimple_stmt_iterator gsi;
5147   gimple stmt;
5148   location_t loc;
5149   enum tree_code code;
5150   bool need_old, need_new;
5151   enum machine_mode imode;
5152
5153   /* We expect to find the following sequences:
5154
5155    load_bb:
5156        GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
5157
5158    store_bb:
5159        val = tmp OP something; (or: something OP tmp)
5160        GIMPLE_OMP_STORE (val)
5161
5162   ???FIXME: Allow a more flexible sequence.
5163   Perhaps use data flow to pick the statements.
5164
5165   */
5166
5167   gsi = gsi_after_labels (store_bb);
5168   stmt = gsi_stmt (gsi);
5169   loc = gimple_location (stmt);
5170   if (!is_gimple_assign (stmt))
5171     return false;
5172   gsi_next (&gsi);
5173   if (gimple_code (gsi_stmt (gsi)) != GIMPLE_OMP_ATOMIC_STORE)
5174     return false;
5175   need_new = gimple_omp_atomic_need_value_p (gsi_stmt (gsi));
5176   need_old = gimple_omp_atomic_need_value_p (last_stmt (load_bb));
5177   gcc_checking_assert (!need_old || !need_new);
5178
5179   if (!operand_equal_p (gimple_assign_lhs (stmt), stored_val, 0))
5180     return false;
5181
5182   /* Check for one of the supported fetch-op operations.  */
5183   code = gimple_assign_rhs_code (stmt);
5184   switch (code)
5185     {
5186     case PLUS_EXPR:
5187     case POINTER_PLUS_EXPR:
5188       oldbase = BUILT_IN_ATOMIC_FETCH_ADD_N;
5189       newbase = BUILT_IN_ATOMIC_ADD_FETCH_N;
5190       break;
5191     case MINUS_EXPR:
5192       oldbase = BUILT_IN_ATOMIC_FETCH_SUB_N;
5193       newbase = BUILT_IN_ATOMIC_SUB_FETCH_N;
5194       break;
5195     case BIT_AND_EXPR:
5196       oldbase = BUILT_IN_ATOMIC_FETCH_AND_N;
5197       newbase = BUILT_IN_ATOMIC_AND_FETCH_N;
5198       break;
5199     case BIT_IOR_EXPR:
5200       oldbase = BUILT_IN_ATOMIC_FETCH_OR_N;
5201       newbase = BUILT_IN_ATOMIC_OR_FETCH_N;
5202       break;
5203     case BIT_XOR_EXPR:
5204       oldbase = BUILT_IN_ATOMIC_FETCH_XOR_N;
5205       newbase = BUILT_IN_ATOMIC_XOR_FETCH_N;
5206       break;
5207     default:
5208       return false;
5209     }
5210
5211   /* Make sure the expression is of the proper form.  */
5212   if (operand_equal_p (gimple_assign_rhs1 (stmt), loaded_val, 0))
5213     rhs = gimple_assign_rhs2 (stmt);
5214   else if (commutative_tree_code (gimple_assign_rhs_code (stmt))
5215            && operand_equal_p (gimple_assign_rhs2 (stmt), loaded_val, 0))
5216     rhs = gimple_assign_rhs1 (stmt);
5217   else
5218     return false;
5219
5220   tmpbase = ((enum built_in_function)
5221              ((need_new ? newbase : oldbase) + index + 1));
5222   decl = builtin_decl_explicit (tmpbase);
5223   if (decl == NULL_TREE)
5224     return false;
5225   itype = TREE_TYPE (TREE_TYPE (decl));
5226   imode = TYPE_MODE (itype);
5227
5228   /* We could test all of the various optabs involved, but the fact of the
5229      matter is that (with the exception of i486 vs i586 and xadd) all targets
5230      that support any atomic operaton optab also implements compare-and-swap.
5231      Let optabs.c take care of expanding any compare-and-swap loop.  */
5232   if (!can_compare_and_swap_p (imode, true))
5233     return false;
5234
5235   gsi = gsi_last_bb (load_bb);
5236   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_LOAD);
5237
5238   /* OpenMP does not imply any barrier-like semantics on its atomic ops.
5239      It only requires that the operation happen atomically.  Thus we can
5240      use the RELAXED memory model.  */
5241   call = build_call_expr_loc (loc, decl, 3, addr,
5242                               fold_convert_loc (loc, itype, rhs),
5243                               build_int_cst (NULL, MEMMODEL_RELAXED));
5244
5245   if (need_old || need_new)
5246     {
5247       lhs = need_old ? loaded_val : stored_val;
5248       call = fold_convert_loc (loc, TREE_TYPE (lhs), call);
5249       call = build2_loc (loc, MODIFY_EXPR, void_type_node, lhs, call);
5250     }
5251   else
5252     call = fold_convert_loc (loc, void_type_node, call);
5253   force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5254   gsi_remove (&gsi, true);
5255
5256   gsi = gsi_last_bb (store_bb);
5257   gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
5258   gsi_remove (&gsi, true);
5259   gsi = gsi_last_bb (store_bb);
5260   gsi_remove (&gsi, true);
5261
5262   if (gimple_in_ssa_p (cfun))
5263     update_ssa (TODO_update_ssa_no_phi);
5264
5265   return true;
5266 }
5267
5268 /* A subroutine of expand_omp_atomic.  Implement the atomic operation as:
5269
5270       oldval = *addr;
5271       repeat:
5272         newval = rhs;    // with oldval replacing *addr in rhs
5273         oldval = __sync_val_compare_and_swap (addr, oldval, newval);
5274         if (oldval != newval)
5275           goto repeat;
5276
5277    INDEX is log2 of the size of the data type, and thus usable to find the
5278    index of the builtin decl.  */
5279
5280 static bool
5281 expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
5282                             tree addr, tree loaded_val, tree stored_val,
5283                             int index)
5284 {
5285   tree loadedi, storedi, initial, new_storedi, old_vali;
5286   tree type, itype, cmpxchg, iaddr;
5287   gimple_stmt_iterator si;
5288   basic_block loop_header = single_succ (load_bb);
5289   gimple phi, stmt;
5290   edge e;
5291   enum built_in_function fncode;
5292
5293   /* ??? We need a non-pointer interface to __atomic_compare_exchange in
5294      order to use the RELAXED memory model effectively.  */
5295   fncode = (enum built_in_function)((int)BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
5296                                     + index + 1);
5297   cmpxchg = builtin_decl_explicit (fncode);
5298   if (cmpxchg == NULL_TREE)
5299     return false;
5300   type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5301   itype = TREE_TYPE (TREE_TYPE (cmpxchg));
5302
5303   if (!can_compare_and_swap_p (TYPE_MODE (itype), true))
5304     return false;
5305
5306   /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD.  */
5307   si = gsi_last_bb (load_bb);
5308   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
5309
5310   /* For floating-point values, we'll need to view-convert them to integers
5311      so that we can perform the atomic compare and swap.  Simplify the
5312      following code by always setting up the "i"ntegral variables.  */
5313   if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
5314     {
5315       tree iaddr_val;
5316
5317       iaddr = create_tmp_var (build_pointer_type_for_mode (itype, ptr_mode,
5318                                                            true), NULL);
5319       iaddr_val
5320         = force_gimple_operand_gsi (&si,
5321                                     fold_convert (TREE_TYPE (iaddr), addr),
5322                                     false, NULL_TREE, true, GSI_SAME_STMT);
5323       stmt = gimple_build_assign (iaddr, iaddr_val);
5324       gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5325       loadedi = create_tmp_var (itype, NULL);
5326       if (gimple_in_ssa_p (cfun))
5327         {
5328           add_referenced_var (iaddr);
5329           add_referenced_var (loadedi);
5330           loadedi = make_ssa_name (loadedi, NULL);
5331         }
5332     }
5333   else
5334     {
5335       iaddr = addr;
5336       loadedi = loaded_val;
5337     }
5338
5339   initial
5340     = force_gimple_operand_gsi (&si,
5341                                 build2 (MEM_REF, TREE_TYPE (TREE_TYPE (iaddr)),
5342                                         iaddr,
5343                                         build_int_cst (TREE_TYPE (iaddr), 0)),
5344                                 true, NULL_TREE, true, GSI_SAME_STMT);
5345
5346   /* Move the value to the LOADEDI temporary.  */
5347   if (gimple_in_ssa_p (cfun))
5348     {
5349       gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header)));
5350       phi = create_phi_node (loadedi, loop_header);
5351       SSA_NAME_DEF_STMT (loadedi) = phi;
5352       SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (load_bb)),
5353                initial);
5354     }
5355   else
5356     gsi_insert_before (&si,
5357                        gimple_build_assign (loadedi, initial),
5358                        GSI_SAME_STMT);
5359   if (loadedi != loaded_val)
5360     {
5361       gimple_stmt_iterator gsi2;
5362       tree x;
5363
5364       x = build1 (VIEW_CONVERT_EXPR, type, loadedi);
5365       gsi2 = gsi_start_bb (loop_header);
5366       if (gimple_in_ssa_p (cfun))
5367         {
5368           gimple stmt;
5369           x = force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
5370                                         true, GSI_SAME_STMT);
5371           stmt = gimple_build_assign (loaded_val, x);
5372           gsi_insert_before (&gsi2, stmt, GSI_SAME_STMT);
5373         }
5374       else
5375         {
5376           x = build2 (MODIFY_EXPR, TREE_TYPE (loaded_val), loaded_val, x);
5377           force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
5378                                     true, GSI_SAME_STMT);
5379         }
5380     }
5381   gsi_remove (&si, true);
5382
5383   si = gsi_last_bb (store_bb);
5384   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
5385
5386   if (iaddr == addr)
5387     storedi = stored_val;
5388   else
5389     storedi =
5390       force_gimple_operand_gsi (&si,
5391                                 build1 (VIEW_CONVERT_EXPR, itype,
5392                                         stored_val), true, NULL_TREE, true,
5393                                 GSI_SAME_STMT);
5394
5395   /* Build the compare&swap statement.  */
5396   new_storedi = build_call_expr (cmpxchg, 3, iaddr, loadedi, storedi);
5397   new_storedi = force_gimple_operand_gsi (&si,
5398                                           fold_convert (TREE_TYPE (loadedi),
5399                                                         new_storedi),
5400                                           true, NULL_TREE,
5401                                           true, GSI_SAME_STMT);
5402
5403   if (gimple_in_ssa_p (cfun))
5404     old_vali = loadedi;
5405   else
5406     {
5407       old_vali = create_tmp_var (TREE_TYPE (loadedi), NULL);
5408       if (gimple_in_ssa_p (cfun))
5409         add_referenced_var (old_vali);
5410       stmt = gimple_build_assign (old_vali, loadedi);
5411       gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5412
5413       stmt = gimple_build_assign (loadedi, new_storedi);
5414       gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5415     }
5416
5417   /* Note that we always perform the comparison as an integer, even for
5418      floating point.  This allows the atomic operation to properly
5419      succeed even with NaNs and -0.0.  */
5420   stmt = gimple_build_cond_empty
5421            (build2 (NE_EXPR, boolean_type_node,
5422                     new_storedi, old_vali));
5423   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5424
5425   /* Update cfg.  */
5426   e = single_succ_edge (store_bb);
5427   e->flags &= ~EDGE_FALLTHRU;
5428   e->flags |= EDGE_FALSE_VALUE;
5429
5430   e = make_edge (store_bb, loop_header, EDGE_TRUE_VALUE);
5431
5432   /* Copy the new value to loadedi (we already did that before the condition
5433      if we are not in SSA).  */
5434   if (gimple_in_ssa_p (cfun))
5435     {
5436       phi = gimple_seq_first_stmt (phi_nodes (loop_header));
5437       SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), new_storedi);
5438     }
5439
5440   /* Remove GIMPLE_OMP_ATOMIC_STORE.  */
5441   gsi_remove (&si, true);
5442
5443   if (gimple_in_ssa_p (cfun))
5444     update_ssa (TODO_update_ssa_no_phi);
5445
5446   return true;
5447 }
5448
5449 /* A subroutine of expand_omp_atomic.  Implement the atomic operation as:
5450
5451                                   GOMP_atomic_start ();
5452                                   *addr = rhs;
5453                                   GOMP_atomic_end ();
5454
5455    The result is not globally atomic, but works so long as all parallel
5456    references are within #pragma omp atomic directives.  According to
5457    responses received from omp@openmp.org, appears to be within spec.
5458    Which makes sense, since that's how several other compilers handle
5459    this situation as well.
5460    LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
5461    expanding.  STORED_VAL is the operand of the matching
5462    GIMPLE_OMP_ATOMIC_STORE.
5463
5464    We replace
5465    GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
5466    loaded_val = *addr;
5467
5468    and replace
5469    GIMPLE_OMP_ATOMIC_STORE (stored_val)  with
5470    *addr = stored_val;
5471 */
5472
5473 static bool
5474 expand_omp_atomic_mutex (basic_block load_bb, basic_block store_bb,
5475                          tree addr, tree loaded_val, tree stored_val)
5476 {
5477   gimple_stmt_iterator si;
5478   gimple stmt;
5479   tree t;
5480
5481   si = gsi_last_bb (load_bb);
5482   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
5483
5484   t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
5485   t = build_call_expr (t, 0);
5486   force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
5487
5488   stmt = gimple_build_assign (loaded_val, build_simple_mem_ref (addr));
5489   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5490   gsi_remove (&si, true);
5491
5492   si = gsi_last_bb (store_bb);
5493   gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
5494
5495   stmt = gimple_build_assign (build_simple_mem_ref (unshare_expr (addr)),
5496                               stored_val);
5497   gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5498
5499   t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
5500   t = build_call_expr (t, 0);
5501   force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
5502   gsi_remove (&si, true);
5503
5504   if (gimple_in_ssa_p (cfun))
5505     update_ssa (TODO_update_ssa_no_phi);
5506   return true;
5507 }
5508
5509 /* Expand an GIMPLE_OMP_ATOMIC statement.  We try to expand
5510    using expand_omp_atomic_fetch_op. If it failed, we try to
5511    call expand_omp_atomic_pipeline, and if it fails too, the
5512    ultimate fallback is wrapping the operation in a mutex
5513    (expand_omp_atomic_mutex).  REGION is the atomic region built
5514    by build_omp_regions_1().  */
5515
5516 static void
5517 expand_omp_atomic (struct omp_region *region)
5518 {
5519   basic_block load_bb = region->entry, store_bb = region->exit;
5520   gimple load = last_stmt (load_bb), store = last_stmt (store_bb);
5521   tree loaded_val = gimple_omp_atomic_load_lhs (load);
5522   tree addr = gimple_omp_atomic_load_rhs (load);
5523   tree stored_val = gimple_omp_atomic_store_val (store);
5524   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5525   HOST_WIDE_INT index;
5526
5527   /* Make sure the type is one of the supported sizes.  */
5528   index = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5529   index = exact_log2 (index);
5530   if (index >= 0 && index <= 4)
5531     {
5532       unsigned int align = TYPE_ALIGN_UNIT (type);
5533
5534       /* __sync builtins require strict data alignment.  */
5535       if (exact_log2 (align) >= index)
5536         {
5537           /* Atomic load.  */
5538           if (loaded_val == stored_val
5539               && (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
5540                   || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
5541               && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
5542               && expand_omp_atomic_load (load_bb, addr, loaded_val, index))
5543             return;
5544
5545           /* Atomic store.  */
5546           if ((GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
5547                || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
5548               && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
5549               && store_bb == single_succ (load_bb)
5550               && first_stmt (store_bb) == store
5551               && expand_omp_atomic_store (load_bb, addr, loaded_val,
5552                                           stored_val, index))
5553             return;
5554
5555           /* When possible, use specialized atomic update functions.  */
5556           if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
5557               && store_bb == single_succ (load_bb)
5558               && expand_omp_atomic_fetch_op (load_bb, addr,
5559                                              loaded_val, stored_val, index))
5560             return;
5561
5562           /* If we don't have specialized __sync builtins, try and implement
5563              as a compare and swap loop.  */
5564           if (expand_omp_atomic_pipeline (load_bb, store_bb, addr,
5565                                           loaded_val, stored_val, index))
5566             return;
5567         }
5568     }
5569
5570   /* The ultimate fallback is wrapping the operation in a mutex.  */
5571   expand_omp_atomic_mutex (load_bb, store_bb, addr, loaded_val, stored_val);
5572 }
5573
5574
5575 /* Expand the parallel region tree rooted at REGION.  Expansion
5576    proceeds in depth-first order.  Innermost regions are expanded
5577    first.  This way, parallel regions that require a new function to
5578    be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
5579    internal dependencies in their body.  */
5580
5581 static void
5582 expand_omp (struct omp_region *region)
5583 {
5584   while (region)
5585     {
5586       location_t saved_location;
5587
5588       /* First, determine whether this is a combined parallel+workshare
5589          region.  */
5590       if (region->type == GIMPLE_OMP_PARALLEL)
5591         determine_parallel_type (region);
5592
5593       if (region->inner)
5594         expand_omp (region->inner);
5595
5596       saved_location = input_location;
5597       if (gimple_has_location (last_stmt (region->entry)))
5598         input_location = gimple_location (last_stmt (region->entry));
5599
5600       switch (region->type)
5601         {
5602         case GIMPLE_OMP_PARALLEL:
5603         case GIMPLE_OMP_TASK:
5604           expand_omp_taskreg (region);
5605           break;
5606
5607         case GIMPLE_OMP_FOR:
5608           expand_omp_for (region);
5609           break;
5610
5611         case GIMPLE_OMP_SECTIONS:
5612           expand_omp_sections (region);
5613           break;
5614
5615         case GIMPLE_OMP_SECTION:
5616           /* Individual omp sections are handled together with their
5617              parent GIMPLE_OMP_SECTIONS region.  */
5618           break;
5619
5620         case GIMPLE_OMP_SINGLE:
5621           expand_omp_single (region);
5622           break;
5623
5624         case GIMPLE_OMP_MASTER:
5625         case GIMPLE_OMP_ORDERED:
5626         case GIMPLE_OMP_CRITICAL:
5627           expand_omp_synch (region);
5628           break;
5629
5630         case GIMPLE_OMP_ATOMIC_LOAD:
5631           expand_omp_atomic (region);
5632           break;
5633
5634         default:
5635           gcc_unreachable ();
5636         }
5637
5638       input_location = saved_location;
5639       region = region->next;
5640     }
5641 }
5642
5643
5644 /* Helper for build_omp_regions.  Scan the dominator tree starting at
5645    block BB.  PARENT is the region that contains BB.  If SINGLE_TREE is
5646    true, the function ends once a single tree is built (otherwise, whole
5647    forest of OMP constructs may be built).  */
5648
5649 static void
5650 build_omp_regions_1 (basic_block bb, struct omp_region *parent,
5651                      bool single_tree)
5652 {
5653   gimple_stmt_iterator gsi;
5654   gimple stmt;
5655   basic_block son;
5656
5657   gsi = gsi_last_bb (bb);
5658   if (!gsi_end_p (gsi) && is_gimple_omp (gsi_stmt (gsi)))
5659     {
5660       struct omp_region *region;
5661       enum gimple_code code;
5662
5663       stmt = gsi_stmt (gsi);
5664       code = gimple_code (stmt);
5665       if (code == GIMPLE_OMP_RETURN)
5666         {
5667           /* STMT is the return point out of region PARENT.  Mark it
5668              as the exit point and make PARENT the immediately
5669              enclosing region.  */
5670           gcc_assert (parent);
5671           region = parent;
5672           region->exit = bb;
5673           parent = parent->outer;
5674         }
5675       else if (code == GIMPLE_OMP_ATOMIC_STORE)
5676         {
5677           /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
5678              GIMPLE_OMP_RETURN, but matches with
5679              GIMPLE_OMP_ATOMIC_LOAD.  */
5680           gcc_assert (parent);
5681           gcc_assert (parent->type == GIMPLE_OMP_ATOMIC_LOAD);
5682           region = parent;
5683           region->exit = bb;
5684           parent = parent->outer;
5685         }
5686
5687       else if (code == GIMPLE_OMP_CONTINUE)
5688         {
5689           gcc_assert (parent);
5690           parent->cont = bb;
5691         }
5692       else if (code == GIMPLE_OMP_SECTIONS_SWITCH)
5693         {
5694           /* GIMPLE_OMP_SECTIONS_SWITCH is part of
5695              GIMPLE_OMP_SECTIONS, and we do nothing for it.  */
5696           ;
5697         }
5698       else
5699         {
5700           /* Otherwise, this directive becomes the parent for a new
5701              region.  */
5702           region = new_omp_region (bb, code, parent);
5703           parent = region;
5704         }
5705     }
5706
5707   if (single_tree && !parent)
5708     return;
5709
5710   for (son = first_dom_son (CDI_DOMINATORS, bb);
5711        son;
5712        son = next_dom_son (CDI_DOMINATORS, son))
5713     build_omp_regions_1 (son, parent, single_tree);
5714 }
5715
5716 /* Builds the tree of OMP regions rooted at ROOT, storing it to
5717    root_omp_region.  */
5718
5719 static void
5720 build_omp_regions_root (basic_block root)
5721 {
5722   gcc_assert (root_omp_region == NULL);
5723   build_omp_regions_1 (root, NULL, true);
5724   gcc_assert (root_omp_region != NULL);
5725 }
5726
5727 /* Expands omp construct (and its subconstructs) starting in HEAD.  */
5728
5729 void
5730 omp_expand_local (basic_block head)
5731 {
5732   build_omp_regions_root (head);
5733   if (dump_file && (dump_flags & TDF_DETAILS))
5734     {
5735       fprintf (dump_file, "\nOMP region tree\n\n");
5736       dump_omp_region (dump_file, root_omp_region, 0);
5737       fprintf (dump_file, "\n");
5738     }
5739
5740   remove_exit_barriers (root_omp_region);
5741   expand_omp (root_omp_region);
5742
5743   free_omp_regions ();
5744 }
5745
5746 /* Scan the CFG and build a tree of OMP regions.  Return the root of
5747    the OMP region tree.  */
5748
5749 static void
5750 build_omp_regions (void)
5751 {
5752   gcc_assert (root_omp_region == NULL);
5753   calculate_dominance_info (CDI_DOMINATORS);
5754   build_omp_regions_1 (ENTRY_BLOCK_PTR, NULL, false);
5755 }
5756
5757 /* Main entry point for expanding OMP-GIMPLE into runtime calls.  */
5758
5759 static unsigned int
5760 execute_expand_omp (void)
5761 {
5762   build_omp_regions ();
5763
5764   if (!root_omp_region)
5765     return 0;
5766
5767   if (dump_file)
5768     {
5769       fprintf (dump_file, "\nOMP region tree\n\n");
5770       dump_omp_region (dump_file, root_omp_region, 0);
5771       fprintf (dump_file, "\n");
5772     }
5773
5774   remove_exit_barriers (root_omp_region);
5775
5776   expand_omp (root_omp_region);
5777
5778   cleanup_tree_cfg ();
5779
5780   free_omp_regions ();
5781
5782   return 0;
5783 }
5784
5785 /* OMP expansion -- the default pass, run before creation of SSA form.  */
5786
5787 static bool
5788 gate_expand_omp (void)
5789 {
5790   return (flag_openmp != 0 && !seen_error ());
5791 }
5792
5793 struct gimple_opt_pass pass_expand_omp =
5794 {
5795  {
5796   GIMPLE_PASS,
5797   "ompexp",                             /* name */
5798   gate_expand_omp,                      /* gate */
5799   execute_expand_omp,                   /* execute */
5800   NULL,                                 /* sub */
5801   NULL,                                 /* next */
5802   0,                                    /* static_pass_number */
5803   TV_NONE,                              /* tv_id */
5804   PROP_gimple_any,                      /* properties_required */
5805   0,                                    /* properties_provided */
5806   0,                                    /* properties_destroyed */
5807   0,                                    /* todo_flags_start */
5808   0                                     /* todo_flags_finish */
5809  }
5810 };
5811 \f
5812 /* Routines to lower OpenMP directives into OMP-GIMPLE.  */
5813
5814 /* Lower the OpenMP sections directive in the current statement in GSI_P.
5815    CTX is the enclosing OMP context for the current statement.  */
5816
5817 static void
5818 lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
5819 {
5820   tree block, control;
5821   gimple_stmt_iterator tgsi;
5822   unsigned i, len;
5823   gimple stmt, new_stmt, bind, t;
5824   gimple_seq ilist, dlist, olist, new_body, body;
5825   struct gimplify_ctx gctx;
5826
5827   stmt = gsi_stmt (*gsi_p);
5828
5829   push_gimplify_context (&gctx);
5830
5831   dlist = NULL;
5832   ilist = NULL;
5833   lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
5834                            &ilist, &dlist, ctx);
5835
5836   tgsi = gsi_start (gimple_omp_body (stmt));
5837   for (len = 0; !gsi_end_p (tgsi); len++, gsi_next (&tgsi))
5838     continue;
5839
5840   tgsi = gsi_start (gimple_omp_body (stmt));
5841   body = NULL;
5842   for (i = 0; i < len; i++, gsi_next (&tgsi))
5843     {
5844       omp_context *sctx;
5845       gimple sec_start;
5846
5847       sec_start = gsi_stmt (tgsi);
5848       sctx = maybe_lookup_ctx (sec_start);
5849       gcc_assert (sctx);
5850
5851       gimple_seq_add_stmt (&body, sec_start);
5852
5853       lower_omp (gimple_omp_body (sec_start), sctx);
5854       gimple_seq_add_seq (&body, gimple_omp_body (sec_start));
5855       gimple_omp_set_body (sec_start, NULL);
5856
5857       if (i == len - 1)
5858         {
5859           gimple_seq l = NULL;
5860           lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
5861                                      &l, ctx);
5862           gimple_seq_add_seq (&body, l);
5863           gimple_omp_section_set_last (sec_start);
5864         }
5865
5866       gimple_seq_add_stmt (&body, gimple_build_omp_return (false));
5867     }
5868
5869   block = make_node (BLOCK);
5870   bind = gimple_build_bind (NULL, body, block);
5871
5872   olist = NULL;
5873   lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
5874
5875   block = make_node (BLOCK);
5876   new_stmt = gimple_build_bind (NULL, NULL, block);
5877
5878   pop_gimplify_context (new_stmt);
5879   gimple_bind_append_vars (new_stmt, ctx->block_vars);
5880   BLOCK_VARS (block) = gimple_bind_vars (bind);
5881   if (BLOCK_VARS (block))
5882     TREE_USED (block) = 1;
5883
5884   new_body = NULL;
5885   gimple_seq_add_seq (&new_body, ilist);
5886   gimple_seq_add_stmt (&new_body, stmt);
5887   gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
5888   gimple_seq_add_stmt (&new_body, bind);
5889
5890   control = create_tmp_var (unsigned_type_node, ".section");
5891   t = gimple_build_omp_continue (control, control);
5892   gimple_omp_sections_set_control (stmt, control);
5893   gimple_seq_add_stmt (&new_body, t);
5894
5895   gimple_seq_add_seq (&new_body, olist);
5896   gimple_seq_add_seq (&new_body, dlist);
5897
5898   new_body = maybe_catch_exception (new_body);
5899
5900   t = gimple_build_omp_return
5901         (!!find_omp_clause (gimple_omp_sections_clauses (stmt),
5902                             OMP_CLAUSE_NOWAIT));
5903   gimple_seq_add_stmt (&new_body, t);
5904
5905   gimple_bind_set_body (new_stmt, new_body);
5906   gimple_omp_set_body (stmt, NULL);
5907
5908   gsi_replace (gsi_p, new_stmt, true);
5909 }
5910
5911
5912 /* A subroutine of lower_omp_single.  Expand the simple form of
5913    a GIMPLE_OMP_SINGLE, without a copyprivate clause:
5914
5915         if (GOMP_single_start ())
5916           BODY;
5917         [ GOMP_barrier (); ]    -> unless 'nowait' is present.
5918
5919   FIXME.  It may be better to delay expanding the logic of this until
5920   pass_expand_omp.  The expanded logic may make the job more difficult
5921   to a synchronization analysis pass.  */
5922
5923 static void
5924 lower_omp_single_simple (gimple single_stmt, gimple_seq *pre_p)
5925 {
5926   location_t loc = gimple_location (single_stmt);
5927   tree tlabel = create_artificial_label (loc);
5928   tree flabel = create_artificial_label (loc);
5929   gimple call, cond;
5930   tree lhs, decl;
5931
5932   decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START);
5933   lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)), NULL);
5934   call = gimple_build_call (decl, 0);
5935   gimple_call_set_lhs (call, lhs);
5936   gimple_seq_add_stmt (pre_p, call);
5937
5938   cond = gimple_build_cond (EQ_EXPR, lhs,
5939                             fold_convert_loc (loc, TREE_TYPE (lhs),
5940                                               boolean_true_node),
5941                             tlabel, flabel);
5942   gimple_seq_add_stmt (pre_p, cond);
5943   gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
5944   gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
5945   gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
5946 }
5947
5948
5949 /* A subroutine of lower_omp_single.  Expand the simple form of
5950    a GIMPLE_OMP_SINGLE, with a copyprivate clause:
5951
5952         #pragma omp single copyprivate (a, b, c)
5953
5954    Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
5955
5956       {
5957         if ((copyout_p = GOMP_single_copy_start ()) == NULL)
5958           {
5959             BODY;
5960             copyout.a = a;
5961             copyout.b = b;
5962             copyout.c = c;
5963             GOMP_single_copy_end (&copyout);
5964           }
5965         else
5966           {
5967             a = copyout_p->a;
5968             b = copyout_p->b;
5969             c = copyout_p->c;
5970           }
5971         GOMP_barrier ();
5972       }
5973
5974   FIXME.  It may be better to delay expanding the logic of this until
5975   pass_expand_omp.  The expanded logic may make the job more difficult
5976   to a synchronization analysis pass.  */
5977
5978 static void
5979 lower_omp_single_copy (gimple single_stmt, gimple_seq *pre_p, omp_context *ctx)
5980 {
5981   tree ptr_type, t, l0, l1, l2, bfn_decl;
5982   gimple_seq copyin_seq;
5983   location_t loc = gimple_location (single_stmt);
5984
5985   ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
5986
5987   ptr_type = build_pointer_type (ctx->record_type);
5988   ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
5989
5990   l0 = create_artificial_label (loc);
5991   l1 = create_artificial_label (loc);
5992   l2 = create_artificial_label (loc);
5993
5994   bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START);
5995   t = build_call_expr_loc (loc, bfn_decl, 0);
5996   t = fold_convert_loc (loc, ptr_type, t);
5997   gimplify_assign (ctx->receiver_decl, t, pre_p);
5998
5999   t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
6000               build_int_cst (ptr_type, 0));
6001   t = build3 (COND_EXPR, void_type_node, t,
6002               build_and_jump (&l0), build_and_jump (&l1));
6003   gimplify_and_add (t, pre_p);
6004
6005   gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
6006
6007   gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
6008
6009   copyin_seq = NULL;
6010   lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
6011                               &copyin_seq, ctx);
6012
6013   t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
6014   bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END);
6015   t = build_call_expr_loc (loc, bfn_decl, 1, t);
6016   gimplify_and_add (t, pre_p);
6017
6018   t = build_and_jump (&l2);
6019   gimplify_and_add (t, pre_p);
6020
6021   gimple_seq_add_stmt (pre_p, gimple_build_label (l1));
6022
6023   gimple_seq_add_seq (pre_p, copyin_seq);
6024
6025   gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
6026 }
6027
6028
6029 /* Expand code for an OpenMP single directive.  */
6030
6031 static void
6032 lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6033 {
6034   tree block;
6035   gimple t, bind, single_stmt = gsi_stmt (*gsi_p);
6036   gimple_seq bind_body, dlist;
6037   struct gimplify_ctx gctx;
6038
6039   push_gimplify_context (&gctx);
6040
6041   bind_body = NULL;
6042   lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
6043                            &bind_body, &dlist, ctx);
6044   lower_omp (gimple_omp_body (single_stmt), ctx);
6045
6046   gimple_seq_add_stmt (&bind_body, single_stmt);
6047
6048   if (ctx->record_type)
6049     lower_omp_single_copy (single_stmt, &bind_body, ctx);
6050   else
6051     lower_omp_single_simple (single_stmt, &bind_body);
6052
6053   gimple_omp_set_body (single_stmt, NULL);
6054
6055   gimple_seq_add_seq (&bind_body, dlist);
6056
6057   bind_body = maybe_catch_exception (bind_body);
6058
6059   t = gimple_build_omp_return
6060         (!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
6061                             OMP_CLAUSE_NOWAIT));
6062   gimple_seq_add_stmt (&bind_body, t);
6063
6064   block = make_node (BLOCK);
6065   bind = gimple_build_bind (NULL, bind_body, block);
6066
6067   pop_gimplify_context (bind);
6068
6069   gimple_bind_append_vars (bind, ctx->block_vars);
6070   BLOCK_VARS (block) = ctx->block_vars;
6071   gsi_replace (gsi_p, bind, true);
6072   if (BLOCK_VARS (block))
6073     TREE_USED (block) = 1;
6074 }
6075
6076
6077 /* Expand code for an OpenMP master directive.  */
6078
6079 static void
6080 lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6081 {
6082   tree block, lab = NULL, x, bfn_decl;
6083   gimple stmt = gsi_stmt (*gsi_p), bind;
6084   location_t loc = gimple_location (stmt);
6085   gimple_seq tseq;
6086   struct gimplify_ctx gctx;
6087
6088   push_gimplify_context (&gctx);
6089
6090   block = make_node (BLOCK);
6091   bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
6092                                  block);
6093
6094   bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
6095   x = build_call_expr_loc (loc, bfn_decl, 0);
6096   x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
6097   x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
6098   tseq = NULL;
6099   gimplify_and_add (x, &tseq);
6100   gimple_bind_add_seq (bind, tseq);
6101
6102   lower_omp (gimple_omp_body (stmt), ctx);
6103   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6104   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6105   gimple_omp_set_body (stmt, NULL);
6106
6107   gimple_bind_add_stmt (bind, gimple_build_label (lab));
6108
6109   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6110
6111   pop_gimplify_context (bind);
6112
6113   gimple_bind_append_vars (bind, ctx->block_vars);
6114   BLOCK_VARS (block) = ctx->block_vars;
6115   gsi_replace (gsi_p, bind, true);
6116 }
6117
6118
6119 /* Expand code for an OpenMP ordered directive.  */
6120
6121 static void
6122 lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6123 {
6124   tree block;
6125   gimple stmt = gsi_stmt (*gsi_p), bind, x;
6126   struct gimplify_ctx gctx;
6127
6128   push_gimplify_context (&gctx);
6129
6130   block = make_node (BLOCK);
6131   bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
6132                                    block);
6133
6134   x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
6135                          0);
6136   gimple_bind_add_stmt (bind, x);
6137
6138   lower_omp (gimple_omp_body (stmt), ctx);
6139   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6140   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6141   gimple_omp_set_body (stmt, NULL);
6142
6143   x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END), 0);
6144   gimple_bind_add_stmt (bind, x);
6145
6146   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6147
6148   pop_gimplify_context (bind);
6149
6150   gimple_bind_append_vars (bind, ctx->block_vars);
6151   BLOCK_VARS (block) = gimple_bind_vars (bind);
6152   gsi_replace (gsi_p, bind, true);
6153 }
6154
6155
6156 /* Gimplify a GIMPLE_OMP_CRITICAL statement.  This is a relatively simple
6157    substitution of a couple of function calls.  But in the NAMED case,
6158    requires that languages coordinate a symbol name.  It is therefore
6159    best put here in common code.  */
6160
6161 static GTY((param1_is (tree), param2_is (tree)))
6162   splay_tree critical_name_mutexes;
6163
6164 static void
6165 lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6166 {
6167   tree block;
6168   tree name, lock, unlock;
6169   gimple stmt = gsi_stmt (*gsi_p), bind;
6170   location_t loc = gimple_location (stmt);
6171   gimple_seq tbody;
6172   struct gimplify_ctx gctx;
6173
6174   name = gimple_omp_critical_name (stmt);
6175   if (name)
6176     {
6177       tree decl;
6178       splay_tree_node n;
6179
6180       if (!critical_name_mutexes)
6181         critical_name_mutexes
6182           = splay_tree_new_ggc (splay_tree_compare_pointers,
6183                                 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_s,
6184                                 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_node_s);
6185
6186       n = splay_tree_lookup (critical_name_mutexes, (splay_tree_key) name);
6187       if (n == NULL)
6188         {
6189           char *new_str;
6190
6191           decl = create_tmp_var_raw (ptr_type_node, NULL);
6192
6193           new_str = ACONCAT ((".gomp_critical_user_",
6194                               IDENTIFIER_POINTER (name), NULL));
6195           DECL_NAME (decl) = get_identifier (new_str);
6196           TREE_PUBLIC (decl) = 1;
6197           TREE_STATIC (decl) = 1;
6198           DECL_COMMON (decl) = 1;
6199           DECL_ARTIFICIAL (decl) = 1;
6200           DECL_IGNORED_P (decl) = 1;
6201           varpool_finalize_decl (decl);
6202
6203           splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
6204                              (splay_tree_value) decl);
6205         }
6206       else
6207         decl = (tree) n->value;
6208
6209       lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START);
6210       lock = build_call_expr_loc (loc, lock, 1, build_fold_addr_expr_loc (loc, decl));
6211
6212       unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END);
6213       unlock = build_call_expr_loc (loc, unlock, 1,
6214                                 build_fold_addr_expr_loc (loc, decl));
6215     }
6216   else
6217     {
6218       lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START);
6219       lock = build_call_expr_loc (loc, lock, 0);
6220
6221       unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END);
6222       unlock = build_call_expr_loc (loc, unlock, 0);
6223     }
6224
6225   push_gimplify_context (&gctx);
6226
6227   block = make_node (BLOCK);
6228   bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt), block);
6229
6230   tbody = gimple_bind_body (bind);
6231   gimplify_and_add (lock, &tbody);
6232   gimple_bind_set_body (bind, tbody);
6233
6234   lower_omp (gimple_omp_body (stmt), ctx);
6235   gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6236   gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6237   gimple_omp_set_body (stmt, NULL);
6238
6239   tbody = gimple_bind_body (bind);
6240   gimplify_and_add (unlock, &tbody);
6241   gimple_bind_set_body (bind, tbody);
6242
6243   gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6244
6245   pop_gimplify_context (bind);
6246   gimple_bind_append_vars (bind, ctx->block_vars);
6247   BLOCK_VARS (block) = gimple_bind_vars (bind);
6248   gsi_replace (gsi_p, bind, true);
6249 }
6250
6251
6252 /* A subroutine of lower_omp_for.  Generate code to emit the predicate
6253    for a lastprivate clause.  Given a loop control predicate of (V
6254    cond N2), we gate the clause on (!(V cond N2)).  The lowered form
6255    is appended to *DLIST, iterator initialization is appended to
6256    *BODY_P.  */
6257
6258 static void
6259 lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
6260                            gimple_seq *dlist, struct omp_context *ctx)
6261 {
6262   tree clauses, cond, vinit;
6263   enum tree_code cond_code;
6264   gimple_seq stmts;
6265
6266   cond_code = fd->loop.cond_code;
6267   cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
6268
6269   /* When possible, use a strict equality expression.  This can let VRP
6270      type optimizations deduce the value and remove a copy.  */
6271   if (host_integerp (fd->loop.step, 0))
6272     {
6273       HOST_WIDE_INT step = TREE_INT_CST_LOW (fd->loop.step);
6274       if (step == 1 || step == -1)
6275         cond_code = EQ_EXPR;
6276     }
6277
6278   cond = build2 (cond_code, boolean_type_node, fd->loop.v, fd->loop.n2);
6279
6280   clauses = gimple_omp_for_clauses (fd->for_stmt);
6281   stmts = NULL;
6282   lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
6283   if (!gimple_seq_empty_p (stmts))
6284     {
6285       gimple_seq_add_seq (&stmts, *dlist);
6286       *dlist = stmts;
6287
6288       /* Optimize: v = 0; is usually cheaper than v = some_other_constant.  */
6289       vinit = fd->loop.n1;
6290       if (cond_code == EQ_EXPR
6291           && host_integerp (fd->loop.n2, 0)
6292           && ! integer_zerop (fd->loop.n2))
6293         vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
6294
6295       /* Initialize the iterator variable, so that threads that don't execute
6296          any iterations don't execute the lastprivate clauses by accident.  */
6297       gimplify_assign (fd->loop.v, vinit, body_p);
6298     }
6299 }
6300
6301
6302 /* Lower code for an OpenMP loop directive.  */
6303
6304 static void
6305 lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6306 {
6307   tree *rhs_p, block;
6308   struct omp_for_data fd;
6309   gimple stmt = gsi_stmt (*gsi_p), new_stmt;
6310   gimple_seq omp_for_body, body, dlist;
6311   size_t i;
6312   struct gimplify_ctx gctx;
6313
6314   push_gimplify_context (&gctx);
6315
6316   lower_omp (gimple_omp_for_pre_body (stmt), ctx);
6317   lower_omp (gimple_omp_body (stmt), ctx);
6318
6319   block = make_node (BLOCK);
6320   new_stmt = gimple_build_bind (NULL, NULL, block);
6321
6322   /* Move declaration of temporaries in the loop body before we make
6323      it go away.  */
6324   omp_for_body = gimple_omp_body (stmt);
6325   if (!gimple_seq_empty_p (omp_for_body)
6326       && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
6327     {
6328       tree vars = gimple_bind_vars (gimple_seq_first_stmt (omp_for_body));
6329       gimple_bind_append_vars (new_stmt, vars);
6330     }
6331
6332   /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR.  */
6333   dlist = NULL;
6334   body = NULL;
6335   lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx);
6336   gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
6337
6338   /* Lower the header expressions.  At this point, we can assume that
6339      the header is of the form:
6340
6341         #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
6342
6343      We just need to make sure that VAL1, VAL2 and VAL3 are lowered
6344      using the .omp_data_s mapping, if needed.  */
6345   for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
6346     {
6347       rhs_p = gimple_omp_for_initial_ptr (stmt, i);
6348       if (!is_gimple_min_invariant (*rhs_p))
6349         *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6350
6351       rhs_p = gimple_omp_for_final_ptr (stmt, i);
6352       if (!is_gimple_min_invariant (*rhs_p))
6353         *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6354
6355       rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
6356       if (!is_gimple_min_invariant (*rhs_p))
6357         *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6358     }
6359
6360   /* Once lowered, extract the bounds and clauses.  */
6361   extract_omp_for_data (stmt, &fd, NULL);
6362
6363   lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
6364
6365   gimple_seq_add_stmt (&body, stmt);
6366   gimple_seq_add_seq (&body, gimple_omp_body (stmt));
6367
6368   gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
6369                                                          fd.loop.v));
6370
6371   /* After the loop, add exit clauses.  */
6372   lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, ctx);
6373   gimple_seq_add_seq (&body, dlist);
6374
6375   body = maybe_catch_exception (body);
6376
6377   /* Region exit marker goes at the end of the loop body.  */
6378   gimple_seq_add_stmt (&body, gimple_build_omp_return (fd.have_nowait));
6379
6380   pop_gimplify_context (new_stmt);
6381
6382   gimple_bind_append_vars (new_stmt, ctx->block_vars);
6383   BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
6384   if (BLOCK_VARS (block))
6385     TREE_USED (block) = 1;
6386
6387   gimple_bind_set_body (new_stmt, body);
6388   gimple_omp_set_body (stmt, NULL);
6389   gimple_omp_for_set_pre_body (stmt, NULL);
6390   gsi_replace (gsi_p, new_stmt, true);
6391 }
6392
6393 /* Callback for walk_stmts.  Check if the current statement only contains
6394    GIMPLE_OMP_FOR or GIMPLE_OMP_PARALLEL.  */
6395
6396 static tree
6397 check_combined_parallel (gimple_stmt_iterator *gsi_p,
6398                          bool *handled_ops_p,
6399                          struct walk_stmt_info *wi)
6400 {
6401   int *info = (int *) wi->info;
6402   gimple stmt = gsi_stmt (*gsi_p);
6403
6404   *handled_ops_p = true;
6405   switch (gimple_code (stmt))
6406     {
6407     WALK_SUBSTMTS;
6408
6409     case GIMPLE_OMP_FOR:
6410     case GIMPLE_OMP_SECTIONS:
6411       *info = *info == 0 ? 1 : -1;
6412       break;
6413     default:
6414       *info = -1;
6415       break;
6416     }
6417   return NULL;
6418 }
6419
6420 struct omp_taskcopy_context
6421 {
6422   /* This field must be at the beginning, as we do "inheritance": Some
6423      callback functions for tree-inline.c (e.g., omp_copy_decl)
6424      receive a copy_body_data pointer that is up-casted to an
6425      omp_context pointer.  */
6426   copy_body_data cb;
6427   omp_context *ctx;
6428 };
6429
6430 static tree
6431 task_copyfn_copy_decl (tree var, copy_body_data *cb)
6432 {
6433   struct omp_taskcopy_context *tcctx = (struct omp_taskcopy_context *) cb;
6434
6435   if (splay_tree_lookup (tcctx->ctx->sfield_map, (splay_tree_key) var))
6436     return create_tmp_var (TREE_TYPE (var), NULL);
6437
6438   return var;
6439 }
6440
6441 static tree
6442 task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
6443 {
6444   tree name, new_fields = NULL, type, f;
6445
6446   type = lang_hooks.types.make_type (RECORD_TYPE);
6447   name = DECL_NAME (TYPE_NAME (orig_type));
6448   name = build_decl (gimple_location (tcctx->ctx->stmt),
6449                      TYPE_DECL, name, type);
6450   TYPE_NAME (type) = name;
6451
6452   for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
6453     {
6454       tree new_f = copy_node (f);
6455       DECL_CONTEXT (new_f) = type;
6456       TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
6457       TREE_CHAIN (new_f) = new_fields;
6458       walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6459       walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6460       walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
6461                  &tcctx->cb, NULL);
6462       new_fields = new_f;
6463       *pointer_map_insert (tcctx->cb.decl_map, f) = new_f;
6464     }
6465   TYPE_FIELDS (type) = nreverse (new_fields);
6466   layout_type (type);
6467   return type;
6468 }
6469
6470 /* Create task copyfn.  */
6471
6472 static void
6473 create_task_copyfn (gimple task_stmt, omp_context *ctx)
6474 {
6475   struct function *child_cfun;
6476   tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
6477   tree record_type, srecord_type, bind, list;
6478   bool record_needs_remap = false, srecord_needs_remap = false;
6479   splay_tree_node n;
6480   struct omp_taskcopy_context tcctx;
6481   struct gimplify_ctx gctx;
6482   location_t loc = gimple_location (task_stmt);
6483
6484   child_fn = gimple_omp_task_copy_fn (task_stmt);
6485   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
6486   gcc_assert (child_cfun->cfg == NULL);
6487   DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();
6488
6489   /* Reset DECL_CONTEXT on function arguments.  */
6490   for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
6491     DECL_CONTEXT (t) = child_fn;
6492
6493   /* Populate the function.  */
6494   push_gimplify_context (&gctx);
6495   current_function_decl = child_fn;
6496
6497   bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
6498   TREE_SIDE_EFFECTS (bind) = 1;
6499   list = NULL;
6500   DECL_SAVED_TREE (child_fn) = bind;
6501   DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);
6502
6503   /* Remap src and dst argument types if needed.  */
6504   record_type = ctx->record_type;
6505   srecord_type = ctx->srecord_type;
6506   for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
6507     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6508       {
6509         record_needs_remap = true;
6510         break;
6511       }
6512   for (f = TYPE_FIELDS (srecord_type); f ; f = DECL_CHAIN (f))
6513     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6514       {
6515         srecord_needs_remap = true;
6516         break;
6517       }
6518
6519   if (record_needs_remap || srecord_needs_remap)
6520     {
6521       memset (&tcctx, '\0', sizeof (tcctx));
6522       tcctx.cb.src_fn = ctx->cb.src_fn;
6523       tcctx.cb.dst_fn = child_fn;
6524       tcctx.cb.src_node = cgraph_get_node (tcctx.cb.src_fn);
6525       gcc_checking_assert (tcctx.cb.src_node);
6526       tcctx.cb.dst_node = tcctx.cb.src_node;
6527       tcctx.cb.src_cfun = ctx->cb.src_cfun;
6528       tcctx.cb.copy_decl = task_copyfn_copy_decl;
6529       tcctx.cb.eh_lp_nr = 0;
6530       tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
6531       tcctx.cb.decl_map = pointer_map_create ();
6532       tcctx.ctx = ctx;
6533
6534       if (record_needs_remap)
6535         record_type = task_copyfn_remap_type (&tcctx, record_type);
6536       if (srecord_needs_remap)
6537         srecord_type = task_copyfn_remap_type (&tcctx, srecord_type);
6538     }
6539   else
6540     tcctx.cb.decl_map = NULL;
6541
6542   push_cfun (child_cfun);
6543
6544   arg = DECL_ARGUMENTS (child_fn);
6545   TREE_TYPE (arg) = build_pointer_type (record_type);
6546   sarg = DECL_CHAIN (arg);
6547   TREE_TYPE (sarg) = build_pointer_type (srecord_type);
6548
6549   /* First pass: initialize temporaries used in record_type and srecord_type
6550      sizes and field offsets.  */
6551   if (tcctx.cb.decl_map)
6552     for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6553       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6554         {
6555           tree *p;
6556
6557           decl = OMP_CLAUSE_DECL (c);
6558           p = (tree *) pointer_map_contains (tcctx.cb.decl_map, decl);
6559           if (p == NULL)
6560             continue;
6561           n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6562           sf = (tree) n->value;
6563           sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6564           src = build_simple_mem_ref_loc (loc, sarg);
6565           src = omp_build_component_ref (src, sf);
6566           t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
6567           append_to_statement_list (t, &list);
6568         }
6569
6570   /* Second pass: copy shared var pointers and copy construct non-VLA
6571      firstprivate vars.  */
6572   for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6573     switch (OMP_CLAUSE_CODE (c))
6574       {
6575       case OMP_CLAUSE_SHARED:
6576         decl = OMP_CLAUSE_DECL (c);
6577         n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6578         if (n == NULL)
6579           break;
6580         f = (tree) n->value;
6581         if (tcctx.cb.decl_map)
6582           f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6583         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6584         sf = (tree) n->value;
6585         if (tcctx.cb.decl_map)
6586           sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6587         src = build_simple_mem_ref_loc (loc, sarg);
6588         src = omp_build_component_ref (src, sf);
6589         dst = build_simple_mem_ref_loc (loc, arg);
6590         dst = omp_build_component_ref (dst, f);
6591         t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6592         append_to_statement_list (t, &list);
6593         break;
6594       case OMP_CLAUSE_FIRSTPRIVATE:
6595         decl = OMP_CLAUSE_DECL (c);
6596         if (is_variable_sized (decl))
6597           break;
6598         n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6599         if (n == NULL)
6600           break;
6601         f = (tree) n->value;
6602         if (tcctx.cb.decl_map)
6603           f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6604         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6605         if (n != NULL)
6606           {
6607             sf = (tree) n->value;
6608             if (tcctx.cb.decl_map)
6609               sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6610             src = build_simple_mem_ref_loc (loc, sarg);
6611             src = omp_build_component_ref (src, sf);
6612             if (use_pointer_for_field (decl, NULL) || is_reference (decl))
6613               src = build_simple_mem_ref_loc (loc, src);
6614           }
6615         else
6616           src = decl;
6617         dst = build_simple_mem_ref_loc (loc, arg);
6618         dst = omp_build_component_ref (dst, f);
6619         t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6620         append_to_statement_list (t, &list);
6621         break;
6622       case OMP_CLAUSE_PRIVATE:
6623         if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c))
6624           break;
6625         decl = OMP_CLAUSE_DECL (c);
6626         n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6627         f = (tree) n->value;
6628         if (tcctx.cb.decl_map)
6629           f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6630         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6631         if (n != NULL)
6632           {
6633             sf = (tree) n->value;
6634             if (tcctx.cb.decl_map)
6635               sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6636             src = build_simple_mem_ref_loc (loc, sarg);
6637             src = omp_build_component_ref (src, sf);
6638             if (use_pointer_for_field (decl, NULL))
6639               src = build_simple_mem_ref_loc (loc, src);
6640           }
6641         else
6642           src = decl;
6643         dst = build_simple_mem_ref_loc (loc, arg);
6644         dst = omp_build_component_ref (dst, f);
6645         t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6646         append_to_statement_list (t, &list);
6647         break;
6648       default:
6649         break;
6650       }
6651
6652   /* Last pass: handle VLA firstprivates.  */
6653   if (tcctx.cb.decl_map)
6654     for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6655       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6656         {
6657           tree ind, ptr, df;
6658
6659           decl = OMP_CLAUSE_DECL (c);
6660           if (!is_variable_sized (decl))
6661             continue;
6662           n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6663           if (n == NULL)
6664             continue;
6665           f = (tree) n->value;
6666           f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6667           gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
6668           ind = DECL_VALUE_EXPR (decl);
6669           gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
6670           gcc_assert (DECL_P (TREE_OPERAND (ind, 0)));
6671           n = splay_tree_lookup (ctx->sfield_map,
6672                                  (splay_tree_key) TREE_OPERAND (ind, 0));
6673           sf = (tree) n->value;
6674           sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6675           src = build_simple_mem_ref_loc (loc, sarg);
6676           src = omp_build_component_ref (src, sf);
6677           src = build_simple_mem_ref_loc (loc, src);
6678           dst = build_simple_mem_ref_loc (loc, arg);
6679           dst = omp_build_component_ref (dst, f);
6680           t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6681           append_to_statement_list (t, &list);
6682           n = splay_tree_lookup (ctx->field_map,
6683                                  (splay_tree_key) TREE_OPERAND (ind, 0));
6684           df = (tree) n->value;
6685           df = *(tree *) pointer_map_contains (tcctx.cb.decl_map, df);
6686           ptr = build_simple_mem_ref_loc (loc, arg);
6687           ptr = omp_build_component_ref (ptr, df);
6688           t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
6689                       build_fold_addr_expr_loc (loc, dst));
6690           append_to_statement_list (t, &list);
6691         }
6692
6693   t = build1 (RETURN_EXPR, void_type_node, NULL);
6694   append_to_statement_list (t, &list);
6695
6696   if (tcctx.cb.decl_map)
6697     pointer_map_destroy (tcctx.cb.decl_map);
6698   pop_gimplify_context (NULL);
6699   BIND_EXPR_BODY (bind) = list;
6700   pop_cfun ();
6701   current_function_decl = ctx->cb.src_fn;
6702 }
6703
6704 /* Lower the OpenMP parallel or task directive in the current statement
6705    in GSI_P.  CTX holds context information for the directive.  */
6706
6707 static void
6708 lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6709 {
6710   tree clauses;
6711   tree child_fn, t;
6712   gimple stmt = gsi_stmt (*gsi_p);
6713   gimple par_bind, bind;
6714   gimple_seq par_body, olist, ilist, par_olist, par_ilist, new_body;
6715   struct gimplify_ctx gctx;
6716   location_t loc = gimple_location (stmt);
6717
6718   clauses = gimple_omp_taskreg_clauses (stmt);
6719   par_bind = gimple_seq_first_stmt (gimple_omp_body (stmt));
6720   par_body = gimple_bind_body (par_bind);
6721   child_fn = ctx->cb.dst_fn;
6722   if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
6723       && !gimple_omp_parallel_combined_p (stmt))
6724     {
6725       struct walk_stmt_info wi;
6726       int ws_num = 0;
6727
6728       memset (&wi, 0, sizeof (wi));
6729       wi.info = &ws_num;
6730       wi.val_only = true;
6731       walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
6732       if (ws_num == 1)
6733         gimple_omp_parallel_set_combined_p (stmt, true);
6734     }
6735   if (ctx->srecord_type)
6736     create_task_copyfn (stmt, ctx);
6737
6738   push_gimplify_context (&gctx);
6739
6740   par_olist = NULL;
6741   par_ilist = NULL;
6742   lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
6743   lower_omp (par_body, ctx);
6744   if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
6745     lower_reduction_clauses (clauses, &par_olist, ctx);
6746
6747   /* Declare all the variables created by mapping and the variables
6748      declared in the scope of the parallel body.  */
6749   record_vars_into (ctx->block_vars, child_fn);
6750   record_vars_into (gimple_bind_vars (par_bind), child_fn);
6751
6752   if (ctx->record_type)
6753     {
6754       ctx->sender_decl
6755         = create_tmp_var (ctx->srecord_type ? ctx->srecord_type
6756                           : ctx->record_type, ".omp_data_o");
6757       DECL_NAMELESS (ctx->sender_decl) = 1;
6758       TREE_ADDRESSABLE (ctx->sender_decl) = 1;
6759       gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
6760     }
6761
6762   olist = NULL;
6763   ilist = NULL;
6764   lower_send_clauses (clauses, &ilist, &olist, ctx);
6765   lower_send_shared_vars (&ilist, &olist, ctx);
6766
6767   /* Once all the expansions are done, sequence all the different
6768      fragments inside gimple_omp_body.  */
6769
6770   new_body = NULL;
6771
6772   if (ctx->record_type)
6773     {
6774       t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
6775       /* fixup_child_record_type might have changed receiver_decl's type.  */
6776       t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
6777       gimple_seq_add_stmt (&new_body,
6778                            gimple_build_assign (ctx->receiver_decl, t));
6779     }
6780
6781   gimple_seq_add_seq (&new_body, par_ilist);
6782   gimple_seq_add_seq (&new_body, par_body);
6783   gimple_seq_add_seq (&new_body, par_olist);
6784   new_body = maybe_catch_exception (new_body);
6785   gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
6786   gimple_omp_set_body (stmt, new_body);
6787
6788   bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
6789   gimple_bind_add_stmt (bind, stmt);
6790   if (ilist || olist)
6791     {
6792       gimple_seq_add_stmt (&ilist, bind);
6793       gimple_seq_add_seq (&ilist, olist);
6794       bind = gimple_build_bind (NULL, ilist, NULL);
6795     }
6796
6797   gsi_replace (gsi_p, bind, true);
6798
6799   pop_gimplify_context (NULL);
6800 }
6801
6802 /* Callback for lower_omp_1.  Return non-NULL if *tp needs to be
6803    regimplified.  If DATA is non-NULL, lower_omp_1 is outside
6804    of OpenMP context, but with task_shared_vars set.  */
6805
6806 static tree
6807 lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
6808                         void *data)
6809 {
6810   tree t = *tp;
6811
6812   /* Any variable with DECL_VALUE_EXPR needs to be regimplified.  */
6813   if (TREE_CODE (t) == VAR_DECL && data == NULL && DECL_HAS_VALUE_EXPR_P (t))
6814     return t;
6815
6816   if (task_shared_vars
6817       && DECL_P (t)
6818       && bitmap_bit_p (task_shared_vars, DECL_UID (t)))
6819     return t;
6820
6821   /* If a global variable has been privatized, TREE_CONSTANT on
6822      ADDR_EXPR might be wrong.  */
6823   if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
6824     recompute_tree_invariant_for_addr_expr (t);
6825
6826   *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
6827   return NULL_TREE;
6828 }
6829
6830 static void
6831 lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6832 {
6833   gimple stmt = gsi_stmt (*gsi_p);
6834   struct walk_stmt_info wi;
6835
6836   if (gimple_has_location (stmt))
6837     input_location = gimple_location (stmt);
6838
6839   if (task_shared_vars)
6840     memset (&wi, '\0', sizeof (wi));
6841
6842   /* If we have issued syntax errors, avoid doing any heavy lifting.
6843      Just replace the OpenMP directives with a NOP to avoid
6844      confusing RTL expansion.  */
6845   if (seen_error () && is_gimple_omp (stmt))
6846     {
6847       gsi_replace (gsi_p, gimple_build_nop (), true);
6848       return;
6849     }
6850
6851   switch (gimple_code (stmt))
6852     {
6853     case GIMPLE_COND:
6854       if ((ctx || task_shared_vars)
6855           && (walk_tree (gimple_cond_lhs_ptr (stmt), lower_omp_regimplify_p,
6856                          ctx ? NULL : &wi, NULL)
6857               || walk_tree (gimple_cond_rhs_ptr (stmt), lower_omp_regimplify_p,
6858                             ctx ? NULL : &wi, NULL)))
6859         gimple_regimplify_operands (stmt, gsi_p);
6860       break;
6861     case GIMPLE_CATCH:
6862       lower_omp (gimple_catch_handler (stmt), ctx);
6863       break;
6864     case GIMPLE_EH_FILTER:
6865       lower_omp (gimple_eh_filter_failure (stmt), ctx);
6866       break;
6867     case GIMPLE_TRY:
6868       lower_omp (gimple_try_eval (stmt), ctx);
6869       lower_omp (gimple_try_cleanup (stmt), ctx);
6870       break;
6871     case GIMPLE_BIND:
6872       lower_omp (gimple_bind_body (stmt), ctx);
6873       break;
6874     case GIMPLE_OMP_PARALLEL:
6875     case GIMPLE_OMP_TASK:
6876       ctx = maybe_lookup_ctx (stmt);
6877       lower_omp_taskreg (gsi_p, ctx);
6878       break;
6879     case GIMPLE_OMP_FOR:
6880       ctx = maybe_lookup_ctx (stmt);
6881       gcc_assert (ctx);
6882       lower_omp_for (gsi_p, ctx);
6883       break;
6884     case GIMPLE_OMP_SECTIONS:
6885       ctx = maybe_lookup_ctx (stmt);
6886       gcc_assert (ctx);
6887       lower_omp_sections (gsi_p, ctx);
6888       break;
6889     case GIMPLE_OMP_SINGLE:
6890       ctx = maybe_lookup_ctx (stmt);
6891       gcc_assert (ctx);
6892       lower_omp_single (gsi_p, ctx);
6893       break;
6894     case GIMPLE_OMP_MASTER:
6895       ctx = maybe_lookup_ctx (stmt);
6896       gcc_assert (ctx);
6897       lower_omp_master (gsi_p, ctx);
6898       break;
6899     case GIMPLE_OMP_ORDERED:
6900       ctx = maybe_lookup_ctx (stmt);
6901       gcc_assert (ctx);
6902       lower_omp_ordered (gsi_p, ctx);
6903       break;
6904     case GIMPLE_OMP_CRITICAL:
6905       ctx = maybe_lookup_ctx (stmt);
6906       gcc_assert (ctx);
6907       lower_omp_critical (gsi_p, ctx);
6908       break;
6909     case GIMPLE_OMP_ATOMIC_LOAD:
6910       if ((ctx || task_shared_vars)
6911           && walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt),
6912                         lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
6913         gimple_regimplify_operands (stmt, gsi_p);
6914       break;
6915     default:
6916       if ((ctx || task_shared_vars)
6917           && walk_gimple_op (stmt, lower_omp_regimplify_p,
6918                              ctx ? NULL : &wi))
6919         gimple_regimplify_operands (stmt, gsi_p);
6920       break;
6921     }
6922 }
6923
6924 static void
6925 lower_omp (gimple_seq body, omp_context *ctx)
6926 {
6927   location_t saved_location = input_location;
6928   gimple_stmt_iterator gsi = gsi_start (body);
6929   for (gsi = gsi_start (body); !gsi_end_p (gsi); gsi_next (&gsi))
6930     lower_omp_1 (&gsi, ctx);
6931   input_location = saved_location;
6932 }
6933 \f
6934 /* Main entry point.  */
6935
6936 static unsigned int
6937 execute_lower_omp (void)
6938 {
6939   gimple_seq body;
6940
6941   /* This pass always runs, to provide PROP_gimple_lomp.
6942      But there is nothing to do unless -fopenmp is given.  */
6943   if (flag_openmp == 0)
6944     return 0;
6945
6946   all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
6947                                  delete_omp_context);
6948
6949   body = gimple_body (current_function_decl);
6950   scan_omp (body, NULL);
6951   gcc_assert (taskreg_nesting_level == 0);
6952
6953   if (all_contexts->root)
6954     {
6955       struct gimplify_ctx gctx;
6956
6957       if (task_shared_vars)
6958         push_gimplify_context (&gctx);
6959       lower_omp (body, NULL);
6960       if (task_shared_vars)
6961         pop_gimplify_context (NULL);
6962     }
6963
6964   if (all_contexts)
6965     {
6966       splay_tree_delete (all_contexts);
6967       all_contexts = NULL;
6968     }
6969   BITMAP_FREE (task_shared_vars);
6970   return 0;
6971 }
6972
6973 struct gimple_opt_pass pass_lower_omp =
6974 {
6975  {
6976   GIMPLE_PASS,
6977   "omplower",                           /* name */
6978   NULL,                                 /* gate */
6979   execute_lower_omp,                    /* execute */
6980   NULL,                                 /* sub */
6981   NULL,                                 /* next */
6982   0,                                    /* static_pass_number */
6983   TV_NONE,                              /* tv_id */
6984   PROP_gimple_any,                      /* properties_required */
6985   PROP_gimple_lomp,                     /* properties_provided */
6986   0,                                    /* properties_destroyed */
6987   0,                                    /* todo_flags_start */
6988   0                                     /* todo_flags_finish */
6989  }
6990 };
6991 \f
6992 /* The following is a utility to diagnose OpenMP structured block violations.
6993    It is not part of the "omplower" pass, as that's invoked too late.  It
6994    should be invoked by the respective front ends after gimplification.  */
6995
6996 static splay_tree all_labels;
6997
6998 /* Check for mismatched contexts and generate an error if needed.  Return
6999    true if an error is detected.  */
7000
7001 static bool
7002 diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
7003                gimple branch_ctx, gimple label_ctx)
7004 {
7005   if (label_ctx == branch_ctx)
7006     return false;
7007
7008
7009   /*
7010      Previously we kept track of the label's entire context in diagnose_sb_[12]
7011      so we could traverse it and issue a correct "exit" or "enter" error
7012      message upon a structured block violation.
7013
7014      We built the context by building a list with tree_cons'ing, but there is
7015      no easy counterpart in gimple tuples.  It seems like far too much work
7016      for issuing exit/enter error messages.  If someone really misses the
7017      distinct error message... patches welcome.
7018    */
7019
7020 #if 0
7021   /* Try to avoid confusing the user by producing and error message
7022      with correct "exit" or "enter" verbiage.  We prefer "exit"
7023      unless we can show that LABEL_CTX is nested within BRANCH_CTX.  */
7024   if (branch_ctx == NULL)
7025     exit_p = false;
7026   else
7027     {
7028       while (label_ctx)
7029         {
7030           if (TREE_VALUE (label_ctx) == branch_ctx)
7031             {
7032               exit_p = false;
7033               break;
7034             }
7035           label_ctx = TREE_CHAIN (label_ctx);
7036         }
7037     }
7038
7039   if (exit_p)
7040     error ("invalid exit from OpenMP structured block");
7041   else
7042     error ("invalid entry to OpenMP structured block");
7043 #endif
7044
7045   /* If it's obvious we have an invalid entry, be specific about the error.  */
7046   if (branch_ctx == NULL)
7047     error ("invalid entry to OpenMP structured block");
7048   else
7049     /* Otherwise, be vague and lazy, but efficient.  */
7050     error ("invalid branch to/from an OpenMP structured block");
7051
7052   gsi_replace (gsi_p, gimple_build_nop (), false);
7053   return true;
7054 }
7055
7056 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
7057    where each label is found.  */
7058
7059 static tree
7060 diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
7061                struct walk_stmt_info *wi)
7062 {
7063   gimple context = (gimple) wi->info;
7064   gimple inner_context;
7065   gimple stmt = gsi_stmt (*gsi_p);
7066
7067   *handled_ops_p = true;
7068
7069  switch (gimple_code (stmt))
7070     {
7071     WALK_SUBSTMTS;
7072
7073     case GIMPLE_OMP_PARALLEL:
7074     case GIMPLE_OMP_TASK:
7075     case GIMPLE_OMP_SECTIONS:
7076     case GIMPLE_OMP_SINGLE:
7077     case GIMPLE_OMP_SECTION:
7078     case GIMPLE_OMP_MASTER:
7079     case GIMPLE_OMP_ORDERED:
7080     case GIMPLE_OMP_CRITICAL:
7081       /* The minimal context here is just the current OMP construct.  */
7082       inner_context = stmt;
7083       wi->info = inner_context;
7084       walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
7085       wi->info = context;
7086       break;
7087
7088     case GIMPLE_OMP_FOR:
7089       inner_context = stmt;
7090       wi->info = inner_context;
7091       /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7092          walk them.  */
7093       walk_gimple_seq (gimple_omp_for_pre_body (stmt),
7094                        diagnose_sb_1, NULL, wi);
7095       walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
7096       wi->info = context;
7097       break;
7098
7099     case GIMPLE_LABEL:
7100       splay_tree_insert (all_labels, (splay_tree_key) gimple_label_label (stmt),
7101                          (splay_tree_value) context);
7102       break;
7103
7104     default:
7105       break;
7106     }
7107
7108   return NULL_TREE;
7109 }
7110
7111 /* Pass 2: Check each branch and see if its context differs from that of
7112    the destination label's context.  */
7113
7114 static tree
7115 diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
7116                struct walk_stmt_info *wi)
7117 {
7118   gimple context = (gimple) wi->info;
7119   splay_tree_node n;
7120   gimple stmt = gsi_stmt (*gsi_p);
7121
7122   *handled_ops_p = true;
7123
7124   switch (gimple_code (stmt))
7125     {
7126     WALK_SUBSTMTS;
7127
7128     case GIMPLE_OMP_PARALLEL:
7129     case GIMPLE_OMP_TASK:
7130     case GIMPLE_OMP_SECTIONS:
7131     case GIMPLE_OMP_SINGLE:
7132     case GIMPLE_OMP_SECTION:
7133     case GIMPLE_OMP_MASTER:
7134     case GIMPLE_OMP_ORDERED:
7135     case GIMPLE_OMP_CRITICAL:
7136       wi->info = stmt;
7137       walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
7138       wi->info = context;
7139       break;
7140
7141     case GIMPLE_OMP_FOR:
7142       wi->info = stmt;
7143       /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7144          walk them.  */
7145       walk_gimple_seq (gimple_omp_for_pre_body (stmt),
7146                        diagnose_sb_2, NULL, wi);
7147       walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
7148       wi->info = context;
7149       break;
7150
7151     case GIMPLE_COND:
7152         {
7153           tree lab = gimple_cond_true_label (stmt);
7154           if (lab)
7155             {
7156               n = splay_tree_lookup (all_labels,
7157                                      (splay_tree_key) lab);
7158               diagnose_sb_0 (gsi_p, context,
7159                              n ? (gimple) n->value : NULL);
7160             }
7161           lab = gimple_cond_false_label (stmt);
7162           if (lab)
7163             {
7164               n = splay_tree_lookup (all_labels,
7165                                      (splay_tree_key) lab);
7166               diagnose_sb_0 (gsi_p, context,
7167                              n ? (gimple) n->value : NULL);
7168             }
7169         }
7170       break;
7171
7172     case GIMPLE_GOTO:
7173       {
7174         tree lab = gimple_goto_dest (stmt);
7175         if (TREE_CODE (lab) != LABEL_DECL)
7176           break;
7177
7178         n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
7179         diagnose_sb_0 (gsi_p, context, n ? (gimple) n->value : NULL);
7180       }
7181       break;
7182
7183     case GIMPLE_SWITCH:
7184       {
7185         unsigned int i;
7186         for (i = 0; i < gimple_switch_num_labels (stmt); ++i)
7187           {
7188             tree lab = CASE_LABEL (gimple_switch_label (stmt, i));
7189             n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
7190             if (n && diagnose_sb_0 (gsi_p, context, (gimple) n->value))
7191               break;
7192           }
7193       }
7194       break;
7195
7196     case GIMPLE_RETURN:
7197       diagnose_sb_0 (gsi_p, context, NULL);
7198       break;
7199
7200     default:
7201       break;
7202     }
7203
7204   return NULL_TREE;
7205 }
7206
7207 static unsigned int
7208 diagnose_omp_structured_block_errors (void)
7209 {
7210   struct walk_stmt_info wi;
7211   gimple_seq body = gimple_body (current_function_decl);
7212
7213   all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
7214
7215   memset (&wi, 0, sizeof (wi));
7216   walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);
7217
7218   memset (&wi, 0, sizeof (wi));
7219   wi.want_locations = true;
7220   walk_gimple_seq (body, diagnose_sb_2, NULL, &wi);
7221
7222   splay_tree_delete (all_labels);
7223   all_labels = NULL;
7224
7225   return 0;
7226 }
7227
7228 static bool
7229 gate_diagnose_omp_blocks (void)
7230 {
7231   return flag_openmp != 0;
7232 }
7233
7234 struct gimple_opt_pass pass_diagnose_omp_blocks =
7235 {
7236   {
7237     GIMPLE_PASS,
7238     "*diagnose_omp_blocks",             /* name */
7239     gate_diagnose_omp_blocks,           /* gate */
7240     diagnose_omp_structured_block_errors,       /* execute */
7241     NULL,                               /* sub */
7242     NULL,                               /* next */
7243     0,                                  /* static_pass_number */
7244     TV_NONE,                            /* tv_id */
7245     PROP_gimple_any,                    /* properties_required */
7246     0,                                  /* properties_provided */
7247     0,                                  /* properties_destroyed */
7248     0,                                  /* todo_flags_start */
7249     0,                                  /* todo_flags_finish */
7250   }
7251 };
7252
7253 #include "gt-omp-low.h"