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