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