OSDN Git Service

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