OSDN Git Service

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