OSDN Git Service

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