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