OSDN Git Service

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