OSDN Git Service

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