OSDN Git Service

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