OSDN Git Service

2007-10-19 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / omp-low.c
1 /* Lowering pass for OpenMP directives.  Converts OpenMP directives
2    into explicit calls to the runtime library (libgomp) and data
3    marshalling to implement data sharing and copying clauses.
4    Contributed by Diego Novillo <dnovillo@redhat.com>
5
6    Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
7
8 This file is part of GCC.
9
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
14
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3.  If not see
22 <http://www.gnu.org/licenses/>.  */
23
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "tree.h"
29 #include "rtl.h"
30 #include "tree-gimple.h"
31 #include "tree-inline.h"
32 #include "langhooks.h"
33 #include "diagnostic.h"
34 #include "tree-flow.h"
35 #include "timevar.h"
36 #include "flags.h"
37 #include "function.h"
38 #include "expr.h"
39 #include "toplev.h"
40 #include "tree-pass.h"
41 #include "ggc.h"
42 #include "except.h"
43 #include "splay-tree.h"
44
45
46 /* Lowering of OpenMP parallel and workshare constructs proceeds in two 
47    phases.  The first phase scans the function looking for OMP statements
48    and then for variables that must be replaced to satisfy data sharing
49    clauses.  The second phase expands code for the constructs, as well as
50    re-gimplifying things when variables have been replaced with complex
51    expressions.
52
53    Final code generation is done by pass_expand_omp.  The flowgraph is
54    scanned for parallel regions which are then moved to a new
55    function, to be invoked by the thread library.  */
56
57 /* Context structure.  Used to store information about each parallel
58    directive in the code.  */
59
60 typedef struct omp_context
61 {
62   /* This field must be at the beginning, as we do "inheritance": Some
63      callback functions for tree-inline.c (e.g., omp_copy_decl)
64      receive a copy_body_data pointer that is up-casted to an
65      omp_context pointer.  */
66   copy_body_data cb;
67
68   /* The tree of contexts corresponding to the encountered constructs.  */
69   struct omp_context *outer;
70   tree stmt;
71
72   /* Map variables to fields in a structure that allows communication 
73      between sending and receiving threads.  */
74   splay_tree field_map;
75   tree record_type;
76   tree sender_decl;
77   tree receiver_decl;
78
79   /* A chain of variables to add to the top-level block surrounding the
80      construct.  In the case of a parallel, this is in the child function.  */
81   tree block_vars;
82
83   /* What to do with variables with implicitly determined sharing
84      attributes.  */
85   enum omp_clause_default_kind default_kind;
86
87   /* Nesting depth of this context.  Used to beautify error messages re
88      invalid gotos.  The outermost ctx is depth 1, with depth 0 being
89      reserved for the main body of the function.  */
90   int depth;
91
92   /* True if this parallel directive is nested within another.  */
93   bool is_nested;
94 } omp_context;
95
96
97 /* A structure describing the main elements of a parallel loop.  */
98
99 struct omp_for_data
100 {
101   tree v, n1, n2, step, chunk_size, for_stmt;
102   enum tree_code cond_code;
103   tree pre;
104   bool have_nowait, have_ordered;
105   enum omp_clause_schedule_kind sched_kind;
106 };
107
108
109 static splay_tree all_contexts;
110 static int parallel_nesting_level;
111 struct omp_region *root_omp_region;
112
113 static void scan_omp (tree *, omp_context *);
114 static void lower_omp (tree *, omp_context *);
115 static tree lookup_decl_in_outer_ctx (tree, omp_context *);
116 static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
117
118 /* Find an OpenMP clause of type KIND within CLAUSES.  */
119
120 tree
121 find_omp_clause (tree clauses, enum tree_code kind)
122 {
123   for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
124     if (OMP_CLAUSE_CODE (clauses) == kind)
125       return clauses;
126
127   return NULL_TREE;
128 }
129
130 /* Return true if CTX is for an omp parallel.  */
131
132 static inline bool
133 is_parallel_ctx (omp_context *ctx)
134 {
135   return TREE_CODE (ctx->stmt) == OMP_PARALLEL;
136 }
137
138
139 /* Return true if REGION is a combined parallel+workshare region.  */
140
141 static inline bool
142 is_combined_parallel (struct omp_region *region)
143 {
144   return region->is_combined_parallel;
145 }
146
147
148 /* Extract the header elements of parallel loop FOR_STMT and store
149    them into *FD.  */
150
151 static void
152 extract_omp_for_data (tree for_stmt, struct omp_for_data *fd)
153 {
154   tree t, var;
155
156   fd->for_stmt = for_stmt;
157   fd->pre = NULL;
158
159   t = OMP_FOR_INIT (for_stmt);
160   gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
161   fd->v = GIMPLE_STMT_OPERAND (t, 0);
162   gcc_assert (SSA_VAR_P (fd->v));
163   gcc_assert (TREE_CODE (TREE_TYPE (fd->v)) == INTEGER_TYPE);
164   var = TREE_CODE (fd->v) == SSA_NAME ? SSA_NAME_VAR (fd->v) : fd->v;
165   fd->n1 = GIMPLE_STMT_OPERAND (t, 1);
166
167   t = OMP_FOR_COND (for_stmt);
168   fd->cond_code = TREE_CODE (t);
169   gcc_assert (TREE_OPERAND (t, 0) == var);
170   fd->n2 = TREE_OPERAND (t, 1);
171   switch (fd->cond_code)
172     {
173     case LT_EXPR:
174     case GT_EXPR:
175       break;
176     case LE_EXPR:
177       fd->n2 = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->n2), fd->n2,
178                            build_int_cst (TREE_TYPE (fd->n2), 1));
179       fd->cond_code = LT_EXPR;
180       break;
181     case GE_EXPR:
182       fd->n2 = fold_build2 (MINUS_EXPR, TREE_TYPE (fd->n2), fd->n2,
183                            build_int_cst (TREE_TYPE (fd->n2), 1));
184       fd->cond_code = GT_EXPR;
185       break;
186     default:
187       gcc_unreachable ();
188     }
189
190   t = OMP_FOR_INCR (fd->for_stmt);
191   gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
192   gcc_assert (GIMPLE_STMT_OPERAND (t, 0) == var);
193   t = GIMPLE_STMT_OPERAND (t, 1);
194   gcc_assert (TREE_OPERAND (t, 0) == var);
195   switch (TREE_CODE (t))
196     {
197     case PLUS_EXPR:
198       fd->step = TREE_OPERAND (t, 1);
199       break;
200     case MINUS_EXPR:
201       fd->step = TREE_OPERAND (t, 1);
202       fd->step = fold_build1 (NEGATE_EXPR, TREE_TYPE (fd->step), fd->step);
203       break;
204     default:
205       gcc_unreachable ();
206     }
207
208   fd->have_nowait = fd->have_ordered = false;
209   fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
210   fd->chunk_size = NULL_TREE;
211
212   for (t = OMP_FOR_CLAUSES (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
213     switch (OMP_CLAUSE_CODE (t))
214       {
215       case OMP_CLAUSE_NOWAIT:
216         fd->have_nowait = true;
217         break;
218       case OMP_CLAUSE_ORDERED:
219         fd->have_ordered = true;
220         break;
221       case OMP_CLAUSE_SCHEDULE:
222         fd->sched_kind = OMP_CLAUSE_SCHEDULE_KIND (t);
223         fd->chunk_size = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t);
224         break;
225       default:
226         break;
227       }
228
229   if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
230     gcc_assert (fd->chunk_size == NULL);
231   else if (fd->chunk_size == NULL)
232     {
233       /* We only need to compute a default chunk size for ordered
234          static loops and dynamic loops.  */
235       if (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC || fd->have_ordered)
236         fd->chunk_size = (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
237                          ? integer_zero_node : integer_one_node;
238     }
239 }
240
241
242 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
243    is the immediate dominator of PAR_ENTRY_BB, return true if there
244    are no data dependencies that would prevent expanding the parallel
245    directive at PAR_ENTRY_BB as a combined parallel+workshare region.
246
247    When expanding a combined parallel+workshare region, the call to
248    the child function may need additional arguments in the case of
249    OMP_FOR regions.  In some cases, these arguments are computed out
250    of variables passed in from the parent to the child via 'struct
251    .omp_data_s'.  For instance:
252
253         #pragma omp parallel for schedule (guided, i * 4)
254         for (j ...)
255
256    Is lowered into:
257
258         # BLOCK 2 (PAR_ENTRY_BB)
259         .omp_data_o.i = i;
260         #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
261         
262         # BLOCK 3 (WS_ENTRY_BB)
263         .omp_data_i = &.omp_data_o;
264         D.1667 = .omp_data_i->i;
265         D.1598 = D.1667 * 4;
266         #pragma omp for schedule (guided, D.1598)
267
268    When we outline the parallel region, the call to the child function
269    'bar.omp_fn.0' will need the value D.1598 in its argument list, but
270    that value is computed *after* the call site.  So, in principle we
271    cannot do the transformation.
272
273    To see whether the code in WS_ENTRY_BB blocks the combined
274    parallel+workshare call, we collect all the variables used in the
275    OMP_FOR header check whether they appear on the LHS of any
276    statement in WS_ENTRY_BB.  If so, then we cannot emit the combined
277    call.
278
279    FIXME.  If we had the SSA form built at this point, we could merely
280    hoist the code in block 3 into block 2 and be done with it.  But at
281    this point we don't have dataflow information and though we could
282    hack something up here, it is really not worth the aggravation.  */
283
284 static bool
285 workshare_safe_to_combine_p (basic_block par_entry_bb, basic_block ws_entry_bb)
286 {
287   struct omp_for_data fd;
288   tree par_stmt, ws_stmt;
289
290   par_stmt = last_stmt (par_entry_bb);
291   ws_stmt = last_stmt (ws_entry_bb);
292
293   if (TREE_CODE (ws_stmt) == OMP_SECTIONS)
294     return true;
295
296   gcc_assert (TREE_CODE (ws_stmt) == OMP_FOR);
297
298   extract_omp_for_data (ws_stmt, &fd);
299
300   /* FIXME.  We give up too easily here.  If any of these arguments
301      are not constants, they will likely involve variables that have
302      been mapped into fields of .omp_data_s for sharing with the child
303      function.  With appropriate data flow, it would be possible to
304      see through this.  */
305   if (!is_gimple_min_invariant (fd.n1)
306       || !is_gimple_min_invariant (fd.n2)
307       || !is_gimple_min_invariant (fd.step)
308       || (fd.chunk_size && !is_gimple_min_invariant (fd.chunk_size)))
309     return false;
310
311   return true;
312 }
313
314
315 /* Collect additional arguments needed to emit a combined
316    parallel+workshare call.  WS_STMT is the workshare directive being
317    expanded.  */
318
319 static tree
320 get_ws_args_for (tree ws_stmt)
321 {
322   tree t;
323
324   if (TREE_CODE (ws_stmt) == OMP_FOR)
325     {
326       struct omp_for_data fd;
327       tree ws_args;
328
329       extract_omp_for_data (ws_stmt, &fd);
330
331       ws_args = NULL_TREE;
332       if (fd.chunk_size)
333         {
334           t = fold_convert (long_integer_type_node, fd.chunk_size);
335           ws_args = tree_cons (NULL, t, ws_args);
336         }
337
338       t = fold_convert (long_integer_type_node, fd.step);
339       ws_args = tree_cons (NULL, t, ws_args);
340
341       t = fold_convert (long_integer_type_node, fd.n2);
342       ws_args = tree_cons (NULL, t, ws_args);
343
344       t = fold_convert (long_integer_type_node, fd.n1);
345       ws_args = tree_cons (NULL, t, ws_args);
346
347       return ws_args;
348     }
349   else if (TREE_CODE (ws_stmt) == OMP_SECTIONS)
350     {
351       /* Number of sections is equal to the number of edges from the
352          OMP_SECTIONS_SWITCH statement, except for the one to the exit
353          of the sections region.  */
354       basic_block bb = single_succ (bb_for_stmt (ws_stmt));
355       t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
356       t = tree_cons (NULL, t, NULL);
357       return t;
358     }
359
360   gcc_unreachable ();
361 }
362
363
364 /* Discover whether REGION is a combined parallel+workshare region.  */
365
366 static void
367 determine_parallel_type (struct omp_region *region)
368 {
369   basic_block par_entry_bb, par_exit_bb;
370   basic_block ws_entry_bb, ws_exit_bb;
371
372   if (region == NULL || region->inner == NULL
373       || region->exit == NULL || region->inner->exit == NULL
374       || region->inner->cont == NULL)
375     return;
376
377   /* We only support parallel+for and parallel+sections.  */
378   if (region->type != OMP_PARALLEL
379       || (region->inner->type != OMP_FOR
380           && region->inner->type != OMP_SECTIONS))
381     return;
382
383   /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
384      WS_EXIT_BB -> PAR_EXIT_BB.  */
385   par_entry_bb = region->entry;
386   par_exit_bb = region->exit;
387   ws_entry_bb = region->inner->entry;
388   ws_exit_bb = region->inner->exit;
389
390   if (single_succ (par_entry_bb) == ws_entry_bb
391       && single_succ (ws_exit_bb) == par_exit_bb
392       && workshare_safe_to_combine_p (par_entry_bb, ws_entry_bb)
393       && (OMP_PARALLEL_COMBINED (last_stmt (par_entry_bb))
394           || (last_and_only_stmt (ws_entry_bb)
395               && last_and_only_stmt (par_exit_bb))))
396     {
397       tree ws_stmt = last_stmt (ws_entry_bb);
398
399       if (region->inner->type == OMP_FOR)
400         {
401           /* If this is a combined parallel loop, we need to determine
402              whether or not to use the combined library calls.  There
403              are two cases where we do not apply the transformation:
404              static loops and any kind of ordered loop.  In the first
405              case, we already open code the loop so there is no need
406              to do anything else.  In the latter case, the combined
407              parallel loop call would still need extra synchronization
408              to implement ordered semantics, so there would not be any
409              gain in using the combined call.  */
410           tree clauses = OMP_FOR_CLAUSES (ws_stmt);
411           tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
412           if (c == NULL
413               || OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_STATIC
414               || find_omp_clause (clauses, OMP_CLAUSE_ORDERED))
415             {
416               region->is_combined_parallel = false;
417               region->inner->is_combined_parallel = false;
418               return;
419             }
420         }
421
422       region->is_combined_parallel = true;
423       region->inner->is_combined_parallel = true;
424       region->ws_args = get_ws_args_for (ws_stmt);
425     }
426 }
427
428
429 /* Return true if EXPR is variable sized.  */
430
431 static inline bool
432 is_variable_sized (const_tree expr)
433 {
434   return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
435 }
436
437 /* Return true if DECL is a reference type.  */
438
439 static inline bool
440 is_reference (tree decl)
441 {
442   return lang_hooks.decls.omp_privatize_by_reference (decl);
443 }
444
445 /* Lookup variables in the decl or field splay trees.  The "maybe" form
446    allows for the variable form to not have been entered, otherwise we
447    assert that the variable must have been entered.  */
448
449 static inline tree
450 lookup_decl (tree var, omp_context *ctx)
451 {
452   tree *n;
453   n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
454   return *n;
455 }
456
457 static inline tree
458 maybe_lookup_decl (tree var, omp_context *ctx)
459 {
460   tree *n;
461   n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
462   return n ? *n : NULL_TREE;
463 }
464
465 static inline tree
466 lookup_field (tree var, omp_context *ctx)
467 {
468   splay_tree_node n;
469   n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
470   return (tree) n->value;
471 }
472
473 static inline tree
474 maybe_lookup_field (tree var, omp_context *ctx)
475 {
476   splay_tree_node n;
477   n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
478   return n ? (tree) n->value : NULL_TREE;
479 }
480
481 /* Return true if DECL should be copied by pointer.  SHARED_P is true
482    if DECL is to be shared.  */
483
484 static bool
485 use_pointer_for_field (const_tree decl, bool shared_p)
486 {
487   if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
488     return true;
489
490   /* We can only use copy-in/copy-out semantics for shared variables
491      when we know the value is not accessible from an outer scope.  */
492   if (shared_p)
493     {
494       /* ??? Trivially accessible from anywhere.  But why would we even
495          be passing an address in this case?  Should we simply assert
496          this to be false, or should we have a cleanup pass that removes
497          these from the list of mappings?  */
498       if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
499         return true;
500
501       /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
502          without analyzing the expression whether or not its location
503          is accessible to anyone else.  In the case of nested parallel
504          regions it certainly may be.  */
505       if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
506         return true;
507
508       /* Do not use copy-in/copy-out for variables that have their
509          address taken.  */
510       if (TREE_ADDRESSABLE (decl))
511         return true;
512     }
513
514   return false;
515 }
516
517 /* Create a new VAR_DECL and copy information from VAR to it.  */
518
519 tree
520 copy_var_decl (tree var, tree name, tree type)
521 {
522   tree copy = build_decl (VAR_DECL, name, type);
523
524   TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
525   TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (var);
526   DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
527   DECL_NO_TBAA_P (copy) = DECL_NO_TBAA_P (var);
528   DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
529   DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
530   DECL_CONTEXT (copy) = DECL_CONTEXT (var);
531   TREE_USED (copy) = 1;
532   DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
533
534   return copy;
535 }
536
537 /* Construct a new automatic decl similar to VAR.  */
538
539 static tree
540 omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
541 {
542   tree copy = copy_var_decl (var, name, type);
543
544   DECL_CONTEXT (copy) = current_function_decl;
545   TREE_CHAIN (copy) = ctx->block_vars;
546   ctx->block_vars = copy;
547
548   return copy;
549 }
550
551 static tree
552 omp_copy_decl_1 (tree var, omp_context *ctx)
553 {
554   return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
555 }
556
557 /* Build tree nodes to access the field for VAR on the receiver side.  */
558
559 static tree
560 build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
561 {
562   tree x, field = lookup_field (var, ctx);
563
564   /* If the receiver record type was remapped in the child function,
565      remap the field into the new record type.  */
566   x = maybe_lookup_field (field, ctx);
567   if (x != NULL)
568     field = x;
569
570   x = build_fold_indirect_ref (ctx->receiver_decl);
571   x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL);
572   if (by_ref)
573     x = build_fold_indirect_ref (x);
574
575   return x;
576 }
577
578 /* Build tree nodes to access VAR in the scope outer to CTX.  In the case
579    of a parallel, this is a component reference; for workshare constructs
580    this is some variable.  */
581
582 static tree
583 build_outer_var_ref (tree var, omp_context *ctx)
584 {
585   tree x;
586
587   if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
588     x = var;
589   else if (is_variable_sized (var))
590     {
591       x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
592       x = build_outer_var_ref (x, ctx);
593       x = build_fold_indirect_ref (x);
594     }
595   else if (is_parallel_ctx (ctx))
596     {
597       bool by_ref = use_pointer_for_field (var, false);
598       x = build_receiver_ref (var, by_ref, ctx);
599     }
600   else if (ctx->outer)
601     x = lookup_decl (var, ctx->outer);
602   else if (is_reference (var))
603     /* This can happen with orphaned constructs.  If var is reference, it is
604        possible it is shared and as such valid.  */
605     x = var;
606   else
607     gcc_unreachable ();
608
609   if (is_reference (var))
610     x = build_fold_indirect_ref (x);
611
612   return x;
613 }
614
615 /* Build tree nodes to access the field for VAR on the sender side.  */
616
617 static tree
618 build_sender_ref (tree var, omp_context *ctx)
619 {
620   tree field = lookup_field (var, ctx);
621   return build3 (COMPONENT_REF, TREE_TYPE (field),
622                  ctx->sender_decl, field, NULL);
623 }
624
625 /* Add a new field for VAR inside the structure CTX->SENDER_DECL.  */
626
627 static void
628 install_var_field (tree var, bool by_ref, omp_context *ctx)
629 {
630   tree field, type;
631
632   gcc_assert (!splay_tree_lookup (ctx->field_map, (splay_tree_key) var));
633
634   type = TREE_TYPE (var);
635   if (by_ref)
636     type = build_pointer_type (type);
637
638   field = build_decl (FIELD_DECL, DECL_NAME (var), type);
639
640   /* Remember what variable this field was created for.  This does have a
641      side effect of making dwarf2out ignore this member, so for helpful
642      debugging we clear it later in delete_omp_context.  */
643   DECL_ABSTRACT_ORIGIN (field) = var;
644
645   insert_field_into_struct (ctx->record_type, field);
646
647   splay_tree_insert (ctx->field_map, (splay_tree_key) var,
648                      (splay_tree_value) field);
649 }
650
651 static tree
652 install_var_local (tree var, omp_context *ctx)
653 {
654   tree new_var = omp_copy_decl_1 (var, ctx);
655   insert_decl_map (&ctx->cb, var, new_var);
656   return new_var;
657 }
658
659 /* Adjust the replacement for DECL in CTX for the new context.  This means
660    copying the DECL_VALUE_EXPR, and fixing up the type.  */
661
662 static void
663 fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
664 {
665   tree new_decl, size;
666
667   new_decl = lookup_decl (decl, ctx);
668
669   TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
670
671   if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
672       && DECL_HAS_VALUE_EXPR_P (decl))
673     {
674       tree ve = DECL_VALUE_EXPR (decl);
675       walk_tree (&ve, copy_body_r, &ctx->cb, NULL);
676       SET_DECL_VALUE_EXPR (new_decl, ve);
677       DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
678     }
679
680   if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
681     {
682       size = remap_decl (DECL_SIZE (decl), &ctx->cb);
683       if (size == error_mark_node)
684         size = TYPE_SIZE (TREE_TYPE (new_decl));
685       DECL_SIZE (new_decl) = size;
686
687       size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
688       if (size == error_mark_node)
689         size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
690       DECL_SIZE_UNIT (new_decl) = size;
691     }
692 }
693
694 /* The callback for remap_decl.  Search all containing contexts for a
695    mapping of the variable; this avoids having to duplicate the splay
696    tree ahead of time.  We know a mapping doesn't already exist in the
697    given context.  Create new mappings to implement default semantics.  */
698
699 static tree
700 omp_copy_decl (tree var, copy_body_data *cb)
701 {
702   omp_context *ctx = (omp_context *) cb;
703   tree new_var;
704
705   if (TREE_CODE (var) == LABEL_DECL)
706     {
707       new_var = create_artificial_label ();
708       DECL_CONTEXT (new_var) = current_function_decl;
709       insert_decl_map (&ctx->cb, var, new_var);
710       return new_var;
711     }
712
713   while (!is_parallel_ctx (ctx))
714     {
715       ctx = ctx->outer;
716       if (ctx == NULL)
717         return var;
718       new_var = maybe_lookup_decl (var, ctx);
719       if (new_var)
720         return new_var;
721     }
722
723   if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
724     return var;
725
726   return error_mark_node;
727 }
728
729
730 /* Return the parallel region associated with STMT.  */
731
732 /* Debugging dumps for parallel regions.  */
733 void dump_omp_region (FILE *, struct omp_region *, int);
734 void debug_omp_region (struct omp_region *);
735 void debug_all_omp_regions (void);
736
737 /* Dump the parallel region tree rooted at REGION.  */
738
739 void
740 dump_omp_region (FILE *file, struct omp_region *region, int indent)
741 {
742   fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
743            tree_code_name[region->type]);
744
745   if (region->inner)
746     dump_omp_region (file, region->inner, indent + 4);
747
748   if (region->cont)
749     {
750       fprintf (file, "%*sbb %d: OMP_CONTINUE\n", indent, "",
751                region->cont->index);
752     }
753     
754   if (region->exit)
755     fprintf (file, "%*sbb %d: OMP_RETURN\n", indent, "",
756              region->exit->index);
757   else
758     fprintf (file, "%*s[no exit marker]\n", indent, "");
759
760   if (region->next)
761     dump_omp_region (file, region->next, indent);
762 }
763
764 void
765 debug_omp_region (struct omp_region *region)
766 {
767   dump_omp_region (stderr, region, 0);
768 }
769
770 void
771 debug_all_omp_regions (void)
772 {
773   dump_omp_region (stderr, root_omp_region, 0);
774 }
775
776
777 /* Create a new parallel region starting at STMT inside region PARENT.  */
778
779 struct omp_region *
780 new_omp_region (basic_block bb, enum tree_code type, struct omp_region *parent)
781 {
782   struct omp_region *region = xcalloc (1, sizeof (*region));
783
784   region->outer = parent;
785   region->entry = bb;
786   region->type = type;
787
788   if (parent)
789     {
790       /* This is a nested region.  Add it to the list of inner
791          regions in PARENT.  */
792       region->next = parent->inner;
793       parent->inner = region;
794     }
795   else
796     {
797       /* This is a toplevel region.  Add it to the list of toplevel
798          regions in ROOT_OMP_REGION.  */
799       region->next = root_omp_region;
800       root_omp_region = region;
801     }
802
803   return region;
804 }
805
806 /* Release the memory associated with the region tree rooted at REGION.  */
807
808 static void
809 free_omp_region_1 (struct omp_region *region)
810 {
811   struct omp_region *i, *n;
812
813   for (i = region->inner; i ; i = n)
814     {
815       n = i->next;
816       free_omp_region_1 (i);
817     }
818
819   free (region);
820 }
821
822 /* Release the memory for the entire omp region tree.  */
823
824 void
825 free_omp_regions (void)
826 {
827   struct omp_region *r, *n;
828   for (r = root_omp_region; r ; r = n)
829     {
830       n = r->next;
831       free_omp_region_1 (r);
832     }
833   root_omp_region = NULL;
834 }
835
836
837 /* Create a new context, with OUTER_CTX being the surrounding context.  */
838
839 static omp_context *
840 new_omp_context (tree stmt, omp_context *outer_ctx)
841 {
842   omp_context *ctx = XCNEW (omp_context);
843
844   splay_tree_insert (all_contexts, (splay_tree_key) stmt,
845                      (splay_tree_value) ctx);
846   ctx->stmt = stmt;
847
848   if (outer_ctx)
849     {
850       ctx->outer = outer_ctx;
851       ctx->cb = outer_ctx->cb;
852       ctx->cb.block = NULL;
853       ctx->depth = outer_ctx->depth + 1;
854     }
855   else
856     {
857       ctx->cb.src_fn = current_function_decl;
858       ctx->cb.dst_fn = current_function_decl;
859       ctx->cb.src_node = cgraph_node (current_function_decl);
860       ctx->cb.dst_node = ctx->cb.src_node;
861       ctx->cb.src_cfun = cfun;
862       ctx->cb.copy_decl = omp_copy_decl;
863       ctx->cb.eh_region = -1;
864       ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
865       ctx->depth = 1;
866     }
867
868   ctx->cb.decl_map = pointer_map_create ();
869
870   return ctx;
871 }
872
873 /* Destroy a omp_context data structures.  Called through the splay tree
874    value delete callback.  */
875
876 static void
877 delete_omp_context (splay_tree_value value)
878 {
879   omp_context *ctx = (omp_context *) value;
880
881   pointer_map_destroy (ctx->cb.decl_map);
882
883   if (ctx->field_map)
884     splay_tree_delete (ctx->field_map);
885
886   /* We hijacked DECL_ABSTRACT_ORIGIN earlier.  We need to clear it before
887      it produces corrupt debug information.  */
888   if (ctx->record_type)
889     {
890       tree t;
891       for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
892         DECL_ABSTRACT_ORIGIN (t) = NULL;
893     }
894
895   XDELETE (ctx);
896 }
897
898 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
899    context.  */
900
901 static void
902 fixup_child_record_type (omp_context *ctx)
903 {
904   tree f, type = ctx->record_type;
905
906   /* ??? It isn't sufficient to just call remap_type here, because
907      variably_modified_type_p doesn't work the way we expect for
908      record types.  Testing each field for whether it needs remapping
909      and creating a new record by hand works, however.  */
910   for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
911     if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
912       break;
913   if (f)
914     {
915       tree name, new_fields = NULL;
916
917       type = lang_hooks.types.make_type (RECORD_TYPE);
918       name = DECL_NAME (TYPE_NAME (ctx->record_type));
919       name = build_decl (TYPE_DECL, name, type);
920       TYPE_NAME (type) = name;
921
922       for (f = TYPE_FIELDS (ctx->record_type); f ; f = TREE_CHAIN (f))
923         {
924           tree new_f = copy_node (f);
925           DECL_CONTEXT (new_f) = type;
926           TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
927           TREE_CHAIN (new_f) = new_fields;
928           new_fields = new_f;
929
930           /* Arrange to be able to look up the receiver field
931              given the sender field.  */
932           splay_tree_insert (ctx->field_map, (splay_tree_key) f,
933                              (splay_tree_value) new_f);
934         }
935       TYPE_FIELDS (type) = nreverse (new_fields);
936       layout_type (type);
937     }
938
939   TREE_TYPE (ctx->receiver_decl) = build_pointer_type (type);
940 }
941
942 /* Instantiate decls as necessary in CTX to satisfy the data sharing
943    specified by CLAUSES.  */
944
945 static void
946 scan_sharing_clauses (tree clauses, omp_context *ctx)
947 {
948   tree c, decl;
949   bool scan_array_reductions = false;
950
951   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
952     {
953       bool by_ref;
954
955       switch (OMP_CLAUSE_CODE (c))
956         {
957         case OMP_CLAUSE_PRIVATE:
958           decl = OMP_CLAUSE_DECL (c);
959           if (!is_variable_sized (decl))
960             install_var_local (decl, ctx);
961           break;
962
963         case OMP_CLAUSE_SHARED:
964           gcc_assert (is_parallel_ctx (ctx));
965           decl = OMP_CLAUSE_DECL (c);
966           gcc_assert (!is_variable_sized (decl));
967           by_ref = use_pointer_for_field (decl, true);
968           /* Global variables don't need to be copied,
969              the receiver side will use them directly.  */
970           if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
971             break;
972           if (! TREE_READONLY (decl)
973               || TREE_ADDRESSABLE (decl)
974               || by_ref
975               || is_reference (decl))
976             {
977               install_var_field (decl, by_ref, ctx);
978               install_var_local (decl, ctx);
979               break;
980             }
981           /* We don't need to copy const scalar vars back.  */
982           OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
983           goto do_private;
984
985         case OMP_CLAUSE_LASTPRIVATE:
986           /* Let the corresponding firstprivate clause create
987              the variable.  */
988           if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
989             break;
990           /* FALLTHRU */
991
992         case OMP_CLAUSE_FIRSTPRIVATE:
993         case OMP_CLAUSE_REDUCTION:
994           decl = OMP_CLAUSE_DECL (c);
995         do_private:
996           if (is_variable_sized (decl))
997             break;
998           else if (is_parallel_ctx (ctx)
999                    && ! is_global_var (maybe_lookup_decl_in_outer_ctx (decl,
1000                                                                        ctx)))
1001             {
1002               by_ref = use_pointer_for_field (decl, false);
1003               install_var_field (decl, by_ref, ctx);
1004             }
1005           install_var_local (decl, ctx);
1006           break;
1007
1008         case OMP_CLAUSE_COPYPRIVATE:
1009           if (ctx->outer)
1010             scan_omp (&OMP_CLAUSE_DECL (c), ctx->outer);
1011           /* FALLTHRU */
1012
1013         case OMP_CLAUSE_COPYIN:
1014           decl = OMP_CLAUSE_DECL (c);
1015           by_ref = use_pointer_for_field (decl, false);
1016           install_var_field (decl, by_ref, ctx);
1017           break;
1018
1019         case OMP_CLAUSE_DEFAULT:
1020           ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
1021           break;
1022
1023         case OMP_CLAUSE_IF:
1024         case OMP_CLAUSE_NUM_THREADS:
1025         case OMP_CLAUSE_SCHEDULE:
1026           if (ctx->outer)
1027             scan_omp (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
1028           break;
1029
1030         case OMP_CLAUSE_NOWAIT:
1031         case OMP_CLAUSE_ORDERED:
1032           break;
1033
1034         default:
1035           gcc_unreachable ();
1036         }
1037     }
1038
1039   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1040     {
1041       switch (OMP_CLAUSE_CODE (c))
1042         {
1043         case OMP_CLAUSE_LASTPRIVATE:
1044           /* Let the corresponding firstprivate clause create
1045              the variable.  */
1046           if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1047             break;
1048           /* FALLTHRU */
1049
1050         case OMP_CLAUSE_PRIVATE:
1051         case OMP_CLAUSE_FIRSTPRIVATE:
1052         case OMP_CLAUSE_REDUCTION:
1053           decl = OMP_CLAUSE_DECL (c);
1054           if (is_variable_sized (decl))
1055             install_var_local (decl, ctx);
1056           fixup_remapped_decl (decl, ctx,
1057                                OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
1058                                && OMP_CLAUSE_PRIVATE_DEBUG (c));
1059           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1060               && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1061             scan_array_reductions = true;
1062           break;
1063
1064         case OMP_CLAUSE_SHARED:
1065           decl = OMP_CLAUSE_DECL (c);
1066           if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1067             fixup_remapped_decl (decl, ctx, false);
1068           break;
1069
1070         case OMP_CLAUSE_COPYPRIVATE:
1071         case OMP_CLAUSE_COPYIN:
1072         case OMP_CLAUSE_DEFAULT:
1073         case OMP_CLAUSE_IF:
1074         case OMP_CLAUSE_NUM_THREADS:
1075         case OMP_CLAUSE_SCHEDULE:
1076         case OMP_CLAUSE_NOWAIT:
1077         case OMP_CLAUSE_ORDERED:
1078           break;
1079
1080         default:
1081           gcc_unreachable ();
1082         }
1083     }
1084
1085   if (scan_array_reductions)
1086     for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1087       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1088           && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1089         {
1090           scan_omp (&OMP_CLAUSE_REDUCTION_INIT (c), ctx);
1091           scan_omp (&OMP_CLAUSE_REDUCTION_MERGE (c), ctx);
1092         }
1093 }
1094
1095 /* Create a new name for omp child function.  Returns an identifier.  */
1096
1097 static GTY(()) unsigned int tmp_ompfn_id_num;
1098
1099 static tree
1100 create_omp_child_function_name (void)
1101 {
1102   tree name = DECL_ASSEMBLER_NAME (current_function_decl);
1103   size_t len = IDENTIFIER_LENGTH (name);
1104   char *tmp_name, *prefix;
1105
1106   prefix = alloca (len + sizeof ("_omp_fn"));
1107   memcpy (prefix, IDENTIFIER_POINTER (name), len);
1108   strcpy (prefix + len, "_omp_fn");
1109 #ifndef NO_DOT_IN_LABEL
1110   prefix[len] = '.';
1111 #elif !defined NO_DOLLAR_IN_LABEL
1112   prefix[len] = '$';
1113 #endif
1114   ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, tmp_ompfn_id_num++);
1115   return get_identifier (tmp_name);
1116 }
1117
1118 /* Build a decl for the omp child function.  It'll not contain a body
1119    yet, just the bare decl.  */
1120
1121 static void
1122 create_omp_child_function (omp_context *ctx)
1123 {
1124   tree decl, type, name, t;
1125
1126   name = create_omp_child_function_name ();
1127   type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
1128
1129   decl = build_decl (FUNCTION_DECL, name, type);
1130   decl = lang_hooks.decls.pushdecl (decl);
1131
1132   ctx->cb.dst_fn = decl;
1133
1134   TREE_STATIC (decl) = 1;
1135   TREE_USED (decl) = 1;
1136   DECL_ARTIFICIAL (decl) = 1;
1137   DECL_IGNORED_P (decl) = 0;
1138   TREE_PUBLIC (decl) = 0;
1139   DECL_UNINLINABLE (decl) = 1;
1140   DECL_EXTERNAL (decl) = 0;
1141   DECL_CONTEXT (decl) = NULL_TREE;
1142   DECL_INITIAL (decl) = make_node (BLOCK);
1143
1144   t = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1145   DECL_ARTIFICIAL (t) = 1;
1146   DECL_IGNORED_P (t) = 1;
1147   DECL_RESULT (decl) = t;
1148
1149   t = build_decl (PARM_DECL, get_identifier (".omp_data_i"), ptr_type_node);
1150   DECL_ARTIFICIAL (t) = 1;
1151   DECL_ARG_TYPE (t) = ptr_type_node;
1152   DECL_CONTEXT (t) = current_function_decl;
1153   TREE_USED (t) = 1;
1154   DECL_ARGUMENTS (decl) = t;
1155   ctx->receiver_decl = t;
1156
1157   /* Allocate memory for the function structure.  The call to 
1158      allocate_struct_function clobbers CFUN, so we need to restore
1159      it afterward.  */
1160   push_struct_function (decl);
1161   DECL_SOURCE_LOCATION (decl) = EXPR_LOCATION (ctx->stmt);
1162   cfun->function_end_locus = EXPR_LOCATION (ctx->stmt);
1163   pop_cfun ();
1164 }
1165
1166
1167 /* Scan an OpenMP parallel directive.  */
1168
1169 static void
1170 scan_omp_parallel (tree *stmt_p, omp_context *outer_ctx)
1171 {
1172   omp_context *ctx;
1173   tree name;
1174
1175   /* Ignore parallel directives with empty bodies, unless there
1176      are copyin clauses.  */
1177   if (optimize > 0
1178       && empty_body_p (OMP_PARALLEL_BODY (*stmt_p))
1179       && find_omp_clause (OMP_CLAUSES (*stmt_p), OMP_CLAUSE_COPYIN) == NULL)
1180     {
1181       *stmt_p = build_empty_stmt ();
1182       return;
1183     }
1184
1185   ctx = new_omp_context (*stmt_p, outer_ctx);
1186   if (parallel_nesting_level > 1)
1187     ctx->is_nested = true;
1188   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1189   ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
1190   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1191   name = create_tmp_var_name (".omp_data_s");
1192   name = build_decl (TYPE_DECL, name, ctx->record_type);
1193   TYPE_NAME (ctx->record_type) = name;
1194   create_omp_child_function (ctx);
1195   OMP_PARALLEL_FN (*stmt_p) = ctx->cb.dst_fn;
1196
1197   scan_sharing_clauses (OMP_PARALLEL_CLAUSES (*stmt_p), ctx);
1198   scan_omp (&OMP_PARALLEL_BODY (*stmt_p), ctx);
1199
1200   if (TYPE_FIELDS (ctx->record_type) == NULL)
1201     ctx->record_type = ctx->receiver_decl = NULL;
1202   else
1203     {
1204       layout_type (ctx->record_type);
1205       fixup_child_record_type (ctx);
1206     }
1207 }
1208
1209
1210 /* Scan an OpenMP loop directive.  */
1211
1212 static void
1213 scan_omp_for (tree *stmt_p, omp_context *outer_ctx)
1214 {
1215   omp_context *ctx;
1216   tree stmt;
1217
1218   stmt = *stmt_p;
1219   ctx = new_omp_context (stmt, outer_ctx);
1220
1221   scan_sharing_clauses (OMP_FOR_CLAUSES (stmt), ctx);
1222
1223   scan_omp (&OMP_FOR_PRE_BODY (stmt), ctx);
1224   scan_omp (&OMP_FOR_INIT (stmt), ctx);
1225   scan_omp (&OMP_FOR_COND (stmt), ctx);
1226   scan_omp (&OMP_FOR_INCR (stmt), ctx);
1227   scan_omp (&OMP_FOR_BODY (stmt), ctx);
1228 }
1229
1230 /* Scan an OpenMP sections directive.  */
1231
1232 static void
1233 scan_omp_sections (tree *stmt_p, omp_context *outer_ctx)
1234 {
1235   tree stmt;
1236   omp_context *ctx;
1237
1238   stmt = *stmt_p;
1239   ctx = new_omp_context (stmt, outer_ctx);
1240   scan_sharing_clauses (OMP_SECTIONS_CLAUSES (stmt), ctx);
1241   scan_omp (&OMP_SECTIONS_BODY (stmt), ctx);
1242 }
1243
1244 /* Scan an OpenMP single directive.  */
1245
1246 static void
1247 scan_omp_single (tree *stmt_p, omp_context *outer_ctx)
1248 {
1249   tree stmt = *stmt_p;
1250   omp_context *ctx;
1251   tree name;
1252
1253   ctx = new_omp_context (stmt, outer_ctx);
1254   ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1255   ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1256   name = create_tmp_var_name (".omp_copy_s");
1257   name = build_decl (TYPE_DECL, name, ctx->record_type);
1258   TYPE_NAME (ctx->record_type) = name;
1259
1260   scan_sharing_clauses (OMP_SINGLE_CLAUSES (stmt), ctx);
1261   scan_omp (&OMP_SINGLE_BODY (stmt), ctx);
1262
1263   if (TYPE_FIELDS (ctx->record_type) == NULL)
1264     ctx->record_type = NULL;
1265   else
1266     layout_type (ctx->record_type);
1267 }
1268
1269
1270 /* Check OpenMP nesting restrictions.  */
1271 static void
1272 check_omp_nesting_restrictions (tree t, omp_context *ctx)
1273 {
1274   switch (TREE_CODE (t))
1275     {
1276     case OMP_FOR:
1277     case OMP_SECTIONS:
1278     case OMP_SINGLE:
1279       for (; ctx != NULL; ctx = ctx->outer)
1280         switch (TREE_CODE (ctx->stmt))
1281           {
1282           case OMP_FOR:
1283           case OMP_SECTIONS:
1284           case OMP_SINGLE:
1285           case OMP_ORDERED:
1286           case OMP_MASTER:
1287             warning (0, "work-sharing region may not be closely nested inside "
1288                         "of work-sharing, critical, ordered or master region");
1289             return;
1290           case OMP_PARALLEL:
1291             return;
1292           default:
1293             break;
1294           }
1295       break;
1296     case OMP_MASTER:
1297       for (; ctx != NULL; ctx = ctx->outer)
1298         switch (TREE_CODE (ctx->stmt))
1299           {
1300           case OMP_FOR:
1301           case OMP_SECTIONS:
1302           case OMP_SINGLE:
1303             warning (0, "master region may not be closely nested inside "
1304                         "of work-sharing region");
1305             return;
1306           case OMP_PARALLEL:
1307             return;
1308           default:
1309             break;
1310           }
1311       break;
1312     case OMP_ORDERED:
1313       for (; ctx != NULL; ctx = ctx->outer)
1314         switch (TREE_CODE (ctx->stmt))
1315           {
1316           case OMP_CRITICAL:
1317             warning (0, "ordered region may not be closely nested inside "
1318                         "of critical region");
1319             return;
1320           case OMP_FOR:
1321             if (find_omp_clause (OMP_CLAUSES (ctx->stmt),
1322                                  OMP_CLAUSE_ORDERED) == NULL)
1323               warning (0, "ordered region must be closely nested inside "
1324                           "a loop region with an ordered clause");
1325             return;
1326           case OMP_PARALLEL:
1327             return;
1328           default:
1329             break;
1330           }
1331       break;
1332     case OMP_CRITICAL:
1333       for (; ctx != NULL; ctx = ctx->outer)
1334         if (TREE_CODE (ctx->stmt) == OMP_CRITICAL
1335             && OMP_CRITICAL_NAME (t) == OMP_CRITICAL_NAME (ctx->stmt))
1336           {
1337             warning (0, "critical region may not be nested inside a critical "
1338                         "region with the same name");
1339             return;
1340           }
1341       break;
1342     default:
1343       break;
1344     }
1345 }
1346
1347
1348 /* Callback for walk_stmts used to scan for OpenMP directives at TP.  */
1349
1350 static tree
1351 scan_omp_1 (tree *tp, int *walk_subtrees, void *data)
1352 {
1353   struct walk_stmt_info *wi = data;
1354   omp_context *ctx = wi->info;
1355   tree t = *tp;
1356
1357   if (EXPR_HAS_LOCATION (t))
1358     input_location = EXPR_LOCATION (t);
1359
1360   /* Check the OpenMP nesting restrictions.  */
1361   if (OMP_DIRECTIVE_P (t) && ctx != NULL)
1362     check_omp_nesting_restrictions (t, ctx);
1363
1364   *walk_subtrees = 0;
1365   switch (TREE_CODE (t))
1366     {
1367     case OMP_PARALLEL:
1368       parallel_nesting_level++;
1369       scan_omp_parallel (tp, ctx);
1370       parallel_nesting_level--;
1371       break;
1372
1373     case OMP_FOR:
1374       scan_omp_for (tp, ctx);
1375       break;
1376
1377     case OMP_SECTIONS:
1378       scan_omp_sections (tp, ctx);
1379       break;
1380
1381     case OMP_SINGLE:
1382       scan_omp_single (tp, ctx);
1383       break;
1384
1385     case OMP_SECTION:
1386     case OMP_MASTER:
1387     case OMP_ORDERED:
1388     case OMP_CRITICAL:
1389       ctx = new_omp_context (*tp, ctx);
1390       scan_omp (&OMP_BODY (*tp), ctx);
1391       break;
1392
1393     case BIND_EXPR:
1394       {
1395         tree var;
1396         *walk_subtrees = 1;
1397
1398         for (var = BIND_EXPR_VARS (t); var ; var = TREE_CHAIN (var))
1399           insert_decl_map (&ctx->cb, var, var);
1400       }
1401       break;
1402
1403     case VAR_DECL:
1404     case PARM_DECL:
1405     case LABEL_DECL:
1406     case RESULT_DECL:
1407       if (ctx)
1408         *tp = remap_decl (t, &ctx->cb);
1409       break;
1410
1411     default:
1412       if (ctx && TYPE_P (t))
1413         *tp = remap_type (t, &ctx->cb);
1414       else if (!DECL_P (t))
1415         *walk_subtrees = 1;
1416       break;
1417     }
1418
1419   return NULL_TREE;
1420 }
1421
1422
1423 /* Scan all the statements starting at STMT_P.  CTX contains context
1424    information about the OpenMP directives and clauses found during
1425    the scan.  */
1426
1427 static void
1428 scan_omp (tree *stmt_p, omp_context *ctx)
1429 {
1430   location_t saved_location;
1431   struct walk_stmt_info wi;
1432
1433   memset (&wi, 0, sizeof (wi));
1434   wi.callback = scan_omp_1;
1435   wi.info = ctx;
1436   wi.want_bind_expr = (ctx != NULL);
1437   wi.want_locations = true;
1438
1439   saved_location = input_location;
1440   walk_stmts (&wi, stmt_p);
1441   input_location = saved_location;
1442 }
1443 \f
1444 /* Re-gimplification and code generation routines.  */
1445
1446 /* Build a call to GOMP_barrier.  */
1447
1448 static tree
1449 build_omp_barrier (void)
1450 {
1451   return build_call_expr (built_in_decls[BUILT_IN_GOMP_BARRIER], 0);
1452 }
1453
1454 /* If a context was created for STMT when it was scanned, return it.  */
1455
1456 static omp_context *
1457 maybe_lookup_ctx (tree stmt)
1458 {
1459   splay_tree_node n;
1460   n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
1461   return n ? (omp_context *) n->value : NULL;
1462 }
1463
1464
1465 /* Find the mapping for DECL in CTX or the immediately enclosing
1466    context that has a mapping for DECL.
1467
1468    If CTX is a nested parallel directive, we may have to use the decl
1469    mappings created in CTX's parent context.  Suppose that we have the
1470    following parallel nesting (variable UIDs showed for clarity):
1471
1472         iD.1562 = 0;
1473         #omp parallel shared(iD.1562)           -> outer parallel
1474           iD.1562 = iD.1562 + 1;
1475
1476           #omp parallel shared (iD.1562)        -> inner parallel
1477              iD.1562 = iD.1562 - 1;
1478
1479    Each parallel structure will create a distinct .omp_data_s structure
1480    for copying iD.1562 in/out of the directive:
1481
1482         outer parallel          .omp_data_s.1.i -> iD.1562
1483         inner parallel          .omp_data_s.2.i -> iD.1562
1484
1485    A shared variable mapping will produce a copy-out operation before
1486    the parallel directive and a copy-in operation after it.  So, in
1487    this case we would have:
1488
1489         iD.1562 = 0;
1490         .omp_data_o.1.i = iD.1562;
1491         #omp parallel shared(iD.1562)           -> outer parallel
1492           .omp_data_i.1 = &.omp_data_o.1
1493           .omp_data_i.1->i = .omp_data_i.1->i + 1;
1494
1495           .omp_data_o.2.i = iD.1562;            -> **
1496           #omp parallel shared(iD.1562)         -> inner parallel
1497             .omp_data_i.2 = &.omp_data_o.2
1498             .omp_data_i.2->i = .omp_data_i.2->i - 1;
1499
1500
1501     ** This is a problem.  The symbol iD.1562 cannot be referenced
1502        inside the body of the outer parallel region.  But since we are
1503        emitting this copy operation while expanding the inner parallel
1504        directive, we need to access the CTX structure of the outer
1505        parallel directive to get the correct mapping:
1506
1507           .omp_data_o.2.i = .omp_data_i.1->i
1508
1509     Since there may be other workshare or parallel directives enclosing
1510     the parallel directive, it may be necessary to walk up the context
1511     parent chain.  This is not a problem in general because nested
1512     parallelism happens only rarely.  */
1513
1514 static tree
1515 lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
1516 {
1517   tree t;
1518   omp_context *up;
1519
1520   gcc_assert (ctx->is_nested);
1521
1522   for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
1523     t = maybe_lookup_decl (decl, up);
1524
1525   gcc_assert (t || is_global_var (decl));
1526
1527   return t ? t : decl;
1528 }
1529
1530
1531 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
1532    in outer contexts.  */
1533
1534 static tree
1535 maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
1536 {
1537   tree t = NULL;
1538   omp_context *up;
1539
1540   if (ctx->is_nested)
1541     for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
1542       t = maybe_lookup_decl (decl, up);
1543
1544   return t ? t : decl;
1545 }
1546
1547
1548 /* Construct the initialization value for reduction CLAUSE.  */
1549
1550 tree
1551 omp_reduction_init (tree clause, tree type)
1552 {
1553   switch (OMP_CLAUSE_REDUCTION_CODE (clause))
1554     {
1555     case PLUS_EXPR:
1556     case MINUS_EXPR:
1557     case BIT_IOR_EXPR:
1558     case BIT_XOR_EXPR:
1559     case TRUTH_OR_EXPR:
1560     case TRUTH_ORIF_EXPR:
1561     case TRUTH_XOR_EXPR:
1562     case NE_EXPR:
1563       return fold_convert (type, integer_zero_node);
1564
1565     case MULT_EXPR:
1566     case TRUTH_AND_EXPR:
1567     case TRUTH_ANDIF_EXPR:
1568     case EQ_EXPR:
1569       return fold_convert (type, integer_one_node);
1570
1571     case BIT_AND_EXPR:
1572       return fold_convert (type, integer_minus_one_node);
1573
1574     case MAX_EXPR:
1575       if (SCALAR_FLOAT_TYPE_P (type))
1576         {
1577           REAL_VALUE_TYPE max, min;
1578           if (HONOR_INFINITIES (TYPE_MODE (type)))
1579             {
1580               real_inf (&max);
1581               real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
1582             }
1583           else
1584             real_maxval (&min, 1, TYPE_MODE (type));
1585           return build_real (type, min);
1586         }
1587       else
1588         {
1589           gcc_assert (INTEGRAL_TYPE_P (type));
1590           return TYPE_MIN_VALUE (type);
1591         }
1592
1593     case MIN_EXPR:
1594       if (SCALAR_FLOAT_TYPE_P (type))
1595         {
1596           REAL_VALUE_TYPE max;
1597           if (HONOR_INFINITIES (TYPE_MODE (type)))
1598             real_inf (&max);
1599           else
1600             real_maxval (&max, 0, TYPE_MODE (type));
1601           return build_real (type, max);
1602         }
1603       else
1604         {
1605           gcc_assert (INTEGRAL_TYPE_P (type));
1606           return TYPE_MAX_VALUE (type);
1607         }
1608
1609     default:
1610       gcc_unreachable ();
1611     }
1612 }
1613
1614 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
1615    from the receiver (aka child) side and initializers for REFERENCE_TYPE
1616    private variables.  Initialization statements go in ILIST, while calls
1617    to destructors go in DLIST.  */
1618
1619 static void
1620 lower_rec_input_clauses (tree clauses, tree *ilist, tree *dlist,
1621                          omp_context *ctx)
1622 {
1623   tree_stmt_iterator diter;
1624   tree c, dtor, copyin_seq, x, ptr;
1625   bool copyin_by_ref = false;
1626   bool lastprivate_firstprivate = false;
1627   int pass;
1628
1629   *dlist = alloc_stmt_list ();
1630   diter = tsi_start (*dlist);
1631   copyin_seq = NULL;
1632
1633   /* Do all the fixed sized types in the first pass, and the variable sized
1634      types in the second pass.  This makes sure that the scalar arguments to
1635      the variable sized types are processed before we use them in the 
1636      variable sized operations.  */
1637   for (pass = 0; pass < 2; ++pass)
1638     {
1639       for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1640         {
1641           enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
1642           tree var, new_var;
1643           bool by_ref;
1644
1645           switch (c_kind)
1646             {
1647             case OMP_CLAUSE_PRIVATE:
1648               if (OMP_CLAUSE_PRIVATE_DEBUG (c))
1649                 continue;
1650               break;
1651             case OMP_CLAUSE_SHARED:
1652               if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
1653                 {
1654                   gcc_assert (is_global_var (OMP_CLAUSE_DECL (c)));
1655                   continue;
1656                 }
1657             case OMP_CLAUSE_FIRSTPRIVATE:
1658             case OMP_CLAUSE_COPYIN:
1659             case OMP_CLAUSE_REDUCTION:
1660               break;
1661             case OMP_CLAUSE_LASTPRIVATE:
1662               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1663                 {
1664                   lastprivate_firstprivate = true;
1665                   if (pass != 0)
1666                     continue;
1667                 }
1668               break;
1669             default:
1670               continue;
1671             }
1672
1673           new_var = var = OMP_CLAUSE_DECL (c);
1674           if (c_kind != OMP_CLAUSE_COPYIN)
1675             new_var = lookup_decl (var, ctx);
1676
1677           if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
1678             {
1679               if (pass != 0)
1680                 continue;
1681             }
1682           else if (is_variable_sized (var))
1683             {
1684               /* For variable sized types, we need to allocate the
1685                  actual storage here.  Call alloca and store the
1686                  result in the pointer decl that we created elsewhere.  */
1687               if (pass == 0)
1688                 continue;
1689
1690               ptr = DECL_VALUE_EXPR (new_var);
1691               gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
1692               ptr = TREE_OPERAND (ptr, 0);
1693               gcc_assert (DECL_P (ptr));
1694
1695               x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
1696               x = build_call_expr (built_in_decls[BUILT_IN_ALLOCA], 1, x);
1697               x = fold_convert (TREE_TYPE (ptr), x);
1698               x = build_gimple_modify_stmt (ptr, x);
1699               gimplify_and_add (x, ilist);
1700             }
1701           else if (is_reference (var))
1702             {
1703               /* For references that are being privatized for Fortran,
1704                  allocate new backing storage for the new pointer
1705                  variable.  This allows us to avoid changing all the
1706                  code that expects a pointer to something that expects
1707                  a direct variable.  Note that this doesn't apply to
1708                  C++, since reference types are disallowed in data
1709                  sharing clauses there, except for NRV optimized
1710                  return values.  */
1711               if (pass == 0)
1712                 continue;
1713
1714               x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
1715               if (TREE_CONSTANT (x))
1716                 {
1717                   const char *name = NULL;
1718                   if (DECL_NAME (var))
1719                     name = IDENTIFIER_POINTER (DECL_NAME (new_var));
1720
1721                   x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
1722                                           name);
1723                   gimple_add_tmp_var (x);
1724                   x = build_fold_addr_expr_with_type (x, TREE_TYPE (new_var));
1725                 }
1726               else
1727                 {
1728                   x = build_call_expr (built_in_decls[BUILT_IN_ALLOCA], 1, x);
1729                   x = fold_convert (TREE_TYPE (new_var), x);
1730                 }
1731
1732               x = build_gimple_modify_stmt (new_var, x);
1733               gimplify_and_add (x, ilist);
1734
1735               new_var = build_fold_indirect_ref (new_var);
1736             }
1737           else if (c_kind == OMP_CLAUSE_REDUCTION
1738                    && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1739             {
1740               if (pass == 0)
1741                 continue;
1742             }
1743           else if (pass != 0)
1744             continue;
1745
1746           switch (OMP_CLAUSE_CODE (c))
1747             {
1748             case OMP_CLAUSE_SHARED:
1749               /* Shared global vars are just accessed directly.  */
1750               if (is_global_var (new_var))
1751                 break;
1752               /* Set up the DECL_VALUE_EXPR for shared variables now.  This
1753                  needs to be delayed until after fixup_child_record_type so
1754                  that we get the correct type during the dereference.  */
1755               by_ref = use_pointer_for_field (var, true);
1756               x = build_receiver_ref (var, by_ref, ctx);
1757               SET_DECL_VALUE_EXPR (new_var, x);
1758               DECL_HAS_VALUE_EXPR_P (new_var) = 1;
1759
1760               /* ??? If VAR is not passed by reference, and the variable
1761                  hasn't been initialized yet, then we'll get a warning for
1762                  the store into the omp_data_s structure.  Ideally, we'd be
1763                  able to notice this and not store anything at all, but 
1764                  we're generating code too early.  Suppress the warning.  */
1765               if (!by_ref)
1766                 TREE_NO_WARNING (var) = 1;
1767               break;
1768
1769             case OMP_CLAUSE_LASTPRIVATE:
1770               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1771                 break;
1772               /* FALLTHRU */
1773
1774             case OMP_CLAUSE_PRIVATE:
1775               x = lang_hooks.decls.omp_clause_default_ctor (c, new_var);
1776               if (x)
1777                 gimplify_and_add (x, ilist);
1778               /* FALLTHRU */
1779
1780             do_dtor:
1781               x = lang_hooks.decls.omp_clause_dtor (c, new_var);
1782               if (x)
1783                 {
1784                   dtor = x;
1785                   gimplify_stmt (&dtor);
1786                   tsi_link_before (&diter, dtor, TSI_SAME_STMT);
1787                 }
1788               break;
1789
1790             case OMP_CLAUSE_FIRSTPRIVATE:
1791               x = build_outer_var_ref (var, ctx);
1792               x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
1793               gimplify_and_add (x, ilist);
1794               goto do_dtor;
1795               break;
1796
1797             case OMP_CLAUSE_COPYIN:
1798               by_ref = use_pointer_for_field (var, false);
1799               x = build_receiver_ref (var, by_ref, ctx);
1800               x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
1801               append_to_statement_list (x, &copyin_seq);
1802               copyin_by_ref |= by_ref;
1803               break;
1804
1805             case OMP_CLAUSE_REDUCTION:
1806               if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1807                 {
1808                   gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c), ilist);
1809                   OMP_CLAUSE_REDUCTION_INIT (c) = NULL;
1810                 }
1811               else
1812                 {
1813                   x = omp_reduction_init (c, TREE_TYPE (new_var));
1814                   gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
1815                   x = build_gimple_modify_stmt (new_var, x);
1816                   gimplify_and_add (x, ilist);
1817                 }
1818               break;
1819
1820             default:
1821               gcc_unreachable ();
1822             }
1823         }
1824     }
1825
1826   /* The copyin sequence is not to be executed by the main thread, since
1827      that would result in self-copies.  Perhaps not visible to scalars,
1828      but it certainly is to C++ operator=.  */
1829   if (copyin_seq)
1830     {
1831       x = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
1832       x = build2 (NE_EXPR, boolean_type_node, x,
1833                   build_int_cst (TREE_TYPE (x), 0));
1834       x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
1835       gimplify_and_add (x, ilist);
1836     }
1837
1838   /* If any copyin variable is passed by reference, we must ensure the
1839      master thread doesn't modify it before it is copied over in all
1840      threads.  Similarly for variables in both firstprivate and
1841      lastprivate clauses we need to ensure the lastprivate copying
1842      happens after firstprivate copying in all threads.  */
1843   if (copyin_by_ref || lastprivate_firstprivate)
1844     gimplify_and_add (build_omp_barrier (), ilist);
1845 }
1846
1847
1848 /* Generate code to implement the LASTPRIVATE clauses.  This is used for
1849    both parallel and workshare constructs.  PREDICATE may be NULL if it's
1850    always true.   */
1851
1852 static void
1853 lower_lastprivate_clauses (tree clauses, tree predicate, tree *stmt_list,
1854                             omp_context *ctx)
1855 {
1856   tree sub_list, x, c;
1857
1858   /* Early exit if there are no lastprivate clauses.  */
1859   clauses = find_omp_clause (clauses, OMP_CLAUSE_LASTPRIVATE);
1860   if (clauses == NULL)
1861     {
1862       /* If this was a workshare clause, see if it had been combined
1863          with its parallel.  In that case, look for the clauses on the
1864          parallel statement itself.  */
1865       if (is_parallel_ctx (ctx))
1866         return;
1867
1868       ctx = ctx->outer;
1869       if (ctx == NULL || !is_parallel_ctx (ctx))
1870         return;
1871
1872       clauses = find_omp_clause (OMP_PARALLEL_CLAUSES (ctx->stmt),
1873                                  OMP_CLAUSE_LASTPRIVATE);
1874       if (clauses == NULL)
1875         return;
1876     }
1877
1878   sub_list = alloc_stmt_list ();
1879
1880   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1881     {
1882       tree var, new_var;
1883
1884       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LASTPRIVATE)
1885         continue;
1886
1887       var = OMP_CLAUSE_DECL (c);
1888       new_var = lookup_decl (var, ctx);
1889
1890       x = build_outer_var_ref (var, ctx);
1891       if (is_reference (var))
1892         new_var = build_fold_indirect_ref (new_var);
1893       x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
1894       append_to_statement_list (x, &sub_list);
1895     }
1896
1897   if (predicate)
1898     x = build3 (COND_EXPR, void_type_node, predicate, sub_list, NULL);
1899   else
1900     x = sub_list;
1901
1902   gimplify_and_add (x, stmt_list);
1903 }
1904
1905
1906 /* Generate code to implement the REDUCTION clauses.  */
1907
1908 static void
1909 lower_reduction_clauses (tree clauses, tree *stmt_list, omp_context *ctx)
1910 {
1911   tree sub_list = NULL, x, c;
1912   int count = 0;
1913
1914   /* First see if there is exactly one reduction clause.  Use OMP_ATOMIC
1915      update in that case, otherwise use a lock.  */
1916   for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
1917     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
1918       {
1919         if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1920           {
1921             /* Never use OMP_ATOMIC for array reductions.  */
1922             count = -1;
1923             break;
1924           }
1925         count++;
1926       }
1927
1928   if (count == 0)
1929     return;
1930
1931   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1932     {
1933       tree var, ref, new_var;
1934       enum tree_code code;
1935
1936       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
1937         continue;
1938
1939       var = OMP_CLAUSE_DECL (c);
1940       new_var = lookup_decl (var, ctx);
1941       if (is_reference (var))
1942         new_var = build_fold_indirect_ref (new_var);
1943       ref = build_outer_var_ref (var, ctx);
1944       code = OMP_CLAUSE_REDUCTION_CODE (c);
1945
1946       /* reduction(-:var) sums up the partial results, so it acts
1947          identically to reduction(+:var).  */
1948       if (code == MINUS_EXPR)
1949         code = PLUS_EXPR;
1950
1951       if (count == 1)
1952         {
1953           tree addr = build_fold_addr_expr (ref);
1954
1955           addr = save_expr (addr);
1956           ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
1957           x = fold_build2 (code, TREE_TYPE (ref), ref, new_var);
1958           x = build2 (OMP_ATOMIC, void_type_node, addr, x);
1959           gimplify_and_add (x, stmt_list);
1960           return;
1961         }
1962
1963       if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1964         {
1965           tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
1966
1967           if (is_reference (var))
1968             ref = build_fold_addr_expr (ref);
1969           SET_DECL_VALUE_EXPR (placeholder, ref);
1970           DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
1971           gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c), &sub_list);
1972           OMP_CLAUSE_REDUCTION_MERGE (c) = NULL;
1973           OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
1974         }
1975       else
1976         {
1977           x = build2 (code, TREE_TYPE (ref), ref, new_var);
1978           ref = build_outer_var_ref (var, ctx);
1979           x = build_gimple_modify_stmt (ref, x);
1980           append_to_statement_list (x, &sub_list);
1981         }
1982     }
1983
1984   x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ATOMIC_START], 0);
1985   gimplify_and_add (x, stmt_list);
1986
1987   gimplify_and_add (sub_list, stmt_list);
1988
1989   x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ATOMIC_END], 0);
1990   gimplify_and_add (x, stmt_list);
1991 }
1992
1993
1994 /* Generate code to implement the COPYPRIVATE clauses.  */
1995
1996 static void
1997 lower_copyprivate_clauses (tree clauses, tree *slist, tree *rlist,
1998                             omp_context *ctx)
1999 {
2000   tree c;
2001
2002   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2003     {
2004       tree var, ref, x;
2005       bool by_ref;
2006
2007       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
2008         continue;
2009
2010       var = OMP_CLAUSE_DECL (c);
2011       by_ref = use_pointer_for_field (var, false);
2012
2013       ref = build_sender_ref (var, ctx);
2014       x = (ctx->is_nested) ? lookup_decl_in_outer_ctx (var, ctx) : var;
2015       x = by_ref ? build_fold_addr_expr (x) : x;
2016       x = build_gimple_modify_stmt (ref, x);
2017       gimplify_and_add (x, slist);
2018
2019       ref = build_receiver_ref (var, by_ref, ctx);
2020       if (is_reference (var))
2021         {
2022           ref = build_fold_indirect_ref (ref);
2023           var = build_fold_indirect_ref (var);
2024         }
2025       x = lang_hooks.decls.omp_clause_assign_op (c, var, ref);
2026       gimplify_and_add (x, rlist);
2027     }
2028 }
2029
2030
2031 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
2032    and REDUCTION from the sender (aka parent) side.  */
2033
2034 static void
2035 lower_send_clauses (tree clauses, tree *ilist, tree *olist, omp_context *ctx)
2036 {
2037   tree c;
2038
2039   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2040     {
2041       tree val, ref, x, var;
2042       bool by_ref, do_in = false, do_out = false;
2043
2044       switch (OMP_CLAUSE_CODE (c))
2045         {
2046         case OMP_CLAUSE_FIRSTPRIVATE:
2047         case OMP_CLAUSE_COPYIN:
2048         case OMP_CLAUSE_LASTPRIVATE:
2049         case OMP_CLAUSE_REDUCTION:
2050           break;
2051         default:
2052           continue;
2053         }
2054
2055       var = val = OMP_CLAUSE_DECL (c);
2056       if (ctx->is_nested)
2057         var = lookup_decl_in_outer_ctx (val, ctx);
2058
2059       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
2060           && is_global_var (var))
2061         continue;
2062       if (is_variable_sized (val))
2063         continue;
2064       by_ref = use_pointer_for_field (val, false);
2065
2066       switch (OMP_CLAUSE_CODE (c))
2067         {
2068         case OMP_CLAUSE_FIRSTPRIVATE:
2069         case OMP_CLAUSE_COPYIN:
2070           do_in = true;
2071           break;
2072
2073         case OMP_CLAUSE_LASTPRIVATE:
2074           if (by_ref || is_reference (val))
2075             {
2076               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2077                 continue;
2078               do_in = true;
2079             }
2080           else
2081             do_out = true;
2082           break;
2083
2084         case OMP_CLAUSE_REDUCTION:
2085           do_in = true;
2086           do_out = !(by_ref || is_reference (val));
2087           break;
2088
2089         default:
2090           gcc_unreachable ();
2091         }
2092
2093       if (do_in)
2094         {
2095           ref = build_sender_ref (val, ctx);
2096           x = by_ref ? build_fold_addr_expr (var) : var;
2097           x = build_gimple_modify_stmt (ref, x);
2098           gimplify_and_add (x, ilist);
2099         }
2100
2101       if (do_out)
2102         {
2103           ref = build_sender_ref (val, ctx);
2104           x = build_gimple_modify_stmt (var, ref);
2105           gimplify_and_add (x, olist);
2106         }
2107     }
2108 }
2109
2110 /* Generate code to implement SHARED from the sender (aka parent) side.
2111    This is trickier, since OMP_PARALLEL_CLAUSES doesn't list things that
2112    got automatically shared.  */
2113
2114 static void
2115 lower_send_shared_vars (tree *ilist, tree *olist, omp_context *ctx)
2116 {
2117   tree var, ovar, nvar, f, x;
2118
2119   if (ctx->record_type == NULL)
2120     return;
2121
2122   for (f = TYPE_FIELDS (ctx->record_type); f ; f = TREE_CHAIN (f))
2123     {
2124       ovar = DECL_ABSTRACT_ORIGIN (f);
2125       nvar = maybe_lookup_decl (ovar, ctx);
2126       if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
2127         continue;
2128
2129       var = ovar;
2130
2131       /* If CTX is a nested parallel directive.  Find the immediately
2132          enclosing parallel or workshare construct that contains a
2133          mapping for OVAR.  */
2134       if (ctx->is_nested)
2135         var = lookup_decl_in_outer_ctx (ovar, ctx);
2136
2137       if (use_pointer_for_field (ovar, true))
2138         {
2139           x = build_sender_ref (ovar, ctx);
2140           var = build_fold_addr_expr (var);
2141           x = build_gimple_modify_stmt (x, var);
2142           gimplify_and_add (x, ilist);
2143         }
2144       else
2145         {
2146           x = build_sender_ref (ovar, ctx);
2147           x = build_gimple_modify_stmt (x, var);
2148           gimplify_and_add (x, ilist);
2149
2150           x = build_sender_ref (ovar, ctx);
2151           x = build_gimple_modify_stmt (var, x);
2152           gimplify_and_add (x, olist);
2153         }
2154     }
2155 }
2156
2157 /* Build the function calls to GOMP_parallel_start etc to actually 
2158    generate the parallel operation.  REGION is the parallel region
2159    being expanded.  BB is the block where to insert the code.  WS_ARGS
2160    will be set if this is a call to a combined parallel+workshare
2161    construct, it contains the list of additional arguments needed by
2162    the workshare construct.  */
2163
2164 static void
2165 expand_parallel_call (struct omp_region *region, basic_block bb,
2166                       tree entry_stmt, tree ws_args)
2167 {
2168   tree t, t1, t2, val, cond, c, clauses;
2169   block_stmt_iterator si;
2170   int start_ix;
2171
2172   clauses = OMP_PARALLEL_CLAUSES (entry_stmt);
2173
2174   /* Determine what flavor of GOMP_parallel_start we will be
2175      emitting.  */
2176   start_ix = BUILT_IN_GOMP_PARALLEL_START;
2177   if (is_combined_parallel (region))
2178     {
2179       switch (region->inner->type)
2180         {
2181         case OMP_FOR:
2182           start_ix = BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
2183                      + region->inner->sched_kind;
2184           break;
2185         case OMP_SECTIONS:
2186           start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS_START;
2187           break;
2188         default:
2189           gcc_unreachable ();
2190         }
2191     }
2192
2193   /* By default, the value of NUM_THREADS is zero (selected at run time)
2194      and there is no conditional.  */
2195   cond = NULL_TREE;
2196   val = build_int_cst (unsigned_type_node, 0);
2197
2198   c = find_omp_clause (clauses, OMP_CLAUSE_IF);
2199   if (c)
2200     cond = OMP_CLAUSE_IF_EXPR (c);
2201
2202   c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
2203   if (c)
2204     val = OMP_CLAUSE_NUM_THREADS_EXPR (c);
2205
2206   /* Ensure 'val' is of the correct type.  */
2207   val = fold_convert (unsigned_type_node, val);
2208
2209   /* If we found the clause 'if (cond)', build either
2210      (cond != 0) or (cond ? val : 1u).  */
2211   if (cond)
2212     {
2213       block_stmt_iterator si;
2214
2215       cond = gimple_boolify (cond);
2216
2217       if (integer_zerop (val))
2218         val = fold_build2 (EQ_EXPR, unsigned_type_node, cond,
2219                            build_int_cst (TREE_TYPE (cond), 0));
2220       else
2221         {
2222           basic_block cond_bb, then_bb, else_bb;
2223           edge e, e_then, e_else;
2224           tree t, tmp_then, tmp_else, tmp_join, tmp_var;
2225
2226           tmp_var = create_tmp_var (TREE_TYPE (val), NULL);
2227           if (gimple_in_ssa_p (cfun))
2228             {
2229               tmp_then = make_ssa_name (tmp_var, NULL_TREE);
2230               tmp_else = make_ssa_name (tmp_var, NULL_TREE);
2231               tmp_join = make_ssa_name (tmp_var, NULL_TREE);
2232             }
2233           else
2234             {
2235               tmp_then = tmp_var;
2236               tmp_else = tmp_var;
2237               tmp_join = tmp_var;
2238             }
2239
2240           e = split_block (bb, NULL);
2241           cond_bb = e->src;
2242           bb = e->dest;
2243           remove_edge (e);
2244
2245           then_bb = create_empty_bb (cond_bb);
2246           else_bb = create_empty_bb (then_bb);
2247           set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
2248           set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
2249
2250           t = build3 (COND_EXPR, void_type_node,
2251                       cond, NULL_TREE, NULL_TREE);
2252
2253           si = bsi_start (cond_bb);
2254           bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2255
2256           si = bsi_start (then_bb);
2257           t = build_gimple_modify_stmt (tmp_then, val);
2258           if (gimple_in_ssa_p (cfun))
2259             SSA_NAME_DEF_STMT (tmp_then) = t;
2260           bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2261
2262           si = bsi_start (else_bb);
2263           t = build_gimple_modify_stmt (tmp_else, 
2264                                         build_int_cst (unsigned_type_node, 1));
2265           if (gimple_in_ssa_p (cfun))
2266             SSA_NAME_DEF_STMT (tmp_else) = t;
2267           bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2268
2269           make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
2270           make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
2271           e_then = make_edge (then_bb, bb, EDGE_FALLTHRU);
2272           e_else = make_edge (else_bb, bb, EDGE_FALLTHRU);
2273
2274           if (gimple_in_ssa_p (cfun))
2275             {
2276               tree phi = create_phi_node (tmp_join, bb);
2277               SSA_NAME_DEF_STMT (tmp_join) = phi;
2278               add_phi_arg (phi, tmp_then, e_then);
2279               add_phi_arg (phi, tmp_else, e_else);
2280             }
2281
2282           val = tmp_join;
2283         }
2284
2285       si = bsi_start (bb);
2286       val = force_gimple_operand_bsi (&si, val, true, NULL_TREE,
2287                                       false, BSI_CONTINUE_LINKING);
2288     }
2289
2290   si = bsi_last (bb);
2291   t = OMP_PARALLEL_DATA_ARG (entry_stmt);
2292   if (t == NULL)
2293     t1 = null_pointer_node;
2294   else
2295     t1 = build_fold_addr_expr (t);
2296   t2 = build_fold_addr_expr (OMP_PARALLEL_FN (entry_stmt));
2297
2298   if (ws_args)
2299     {
2300       tree args = tree_cons (NULL, t2,
2301                              tree_cons (NULL, t1,
2302                                         tree_cons (NULL, val, ws_args)));
2303       t = build_function_call_expr (built_in_decls[start_ix], args);
2304     }
2305   else
2306     t = build_call_expr (built_in_decls[start_ix], 3, t2, t1, val);
2307
2308   force_gimple_operand_bsi (&si, t, true, NULL_TREE,
2309                             false, BSI_CONTINUE_LINKING);
2310
2311   t = OMP_PARALLEL_DATA_ARG (entry_stmt);
2312   if (t == NULL)
2313     t = null_pointer_node;
2314   else
2315     t = build_fold_addr_expr (t);
2316   t = build_call_expr (OMP_PARALLEL_FN (entry_stmt), 1, t);
2317   force_gimple_operand_bsi (&si, t, true, NULL_TREE,
2318                             false, BSI_CONTINUE_LINKING);
2319
2320   t = build_call_expr (built_in_decls[BUILT_IN_GOMP_PARALLEL_END], 0);
2321   force_gimple_operand_bsi (&si, t, true, NULL_TREE,
2322                             false, BSI_CONTINUE_LINKING);
2323 }
2324
2325
2326 /* If exceptions are enabled, wrap *STMT_P in a MUST_NOT_THROW catch
2327    handler.  This prevents programs from violating the structured
2328    block semantics with throws.  */
2329
2330 static void
2331 maybe_catch_exception (tree *stmt_p)
2332 {
2333   tree f, t;
2334
2335   if (!flag_exceptions)
2336     return;
2337
2338   if (lang_protect_cleanup_actions)
2339     t = lang_protect_cleanup_actions ();
2340   else
2341     t = build_call_expr (built_in_decls[BUILT_IN_TRAP], 0);
2342   f = build2 (EH_FILTER_EXPR, void_type_node, NULL, NULL);
2343   EH_FILTER_MUST_NOT_THROW (f) = 1;
2344   gimplify_and_add (t, &EH_FILTER_FAILURE (f));
2345   
2346   t = build2 (TRY_CATCH_EXPR, void_type_node, *stmt_p, NULL);
2347   append_to_statement_list (f, &TREE_OPERAND (t, 1));
2348
2349   *stmt_p = NULL;
2350   append_to_statement_list (t, stmt_p);
2351 }
2352
2353 /* Chain all the DECLs in LIST by their TREE_CHAIN fields.  */
2354
2355 static tree
2356 list2chain (tree list)
2357 {
2358   tree t;
2359
2360   for (t = list; t; t = TREE_CHAIN (t))
2361     {
2362       tree var = TREE_VALUE (t);
2363       if (TREE_CHAIN (t))
2364         TREE_CHAIN (var) = TREE_VALUE (TREE_CHAIN (t));
2365       else
2366         TREE_CHAIN (var) = NULL_TREE;
2367     }
2368
2369   return list ? TREE_VALUE (list) : NULL_TREE;
2370 }
2371
2372
2373 /* Remove barriers in REGION->EXIT's block.  Note that this is only
2374    valid for OMP_PARALLEL regions.  Since the end of a parallel region
2375    is an implicit barrier, any workshare inside the OMP_PARALLEL that
2376    left a barrier at the end of the OMP_PARALLEL region can now be
2377    removed.  */
2378
2379 static void
2380 remove_exit_barrier (struct omp_region *region)
2381 {
2382   block_stmt_iterator si;
2383   basic_block exit_bb;
2384   edge_iterator ei;
2385   edge e;
2386   tree t;
2387
2388   exit_bb = region->exit;
2389
2390   /* If the parallel region doesn't return, we don't have REGION->EXIT
2391      block at all.  */
2392   if (! exit_bb)
2393     return;
2394
2395   /* The last insn in the block will be the parallel's OMP_RETURN.  The
2396      workshare's OMP_RETURN will be in a preceding block.  The kinds of
2397      statements that can appear in between are extremely limited -- no
2398      memory operations at all.  Here, we allow nothing at all, so the
2399      only thing we allow to precede this OMP_RETURN is a label.  */
2400   si = bsi_last (exit_bb);
2401   gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
2402   bsi_prev (&si);
2403   if (!bsi_end_p (si) && TREE_CODE (bsi_stmt (si)) != LABEL_EXPR)
2404     return;
2405
2406   FOR_EACH_EDGE (e, ei, exit_bb->preds)
2407     {
2408       si = bsi_last (e->src);
2409       if (bsi_end_p (si))
2410         continue;
2411       t = bsi_stmt (si);
2412       if (TREE_CODE (t) == OMP_RETURN)
2413         OMP_RETURN_NOWAIT (t) = 1;
2414     }
2415 }
2416
2417 static void
2418 remove_exit_barriers (struct omp_region *region)
2419 {
2420   if (region->type == OMP_PARALLEL)
2421     remove_exit_barrier (region);
2422
2423   if (region->inner)
2424     {
2425       region = region->inner;
2426       remove_exit_barriers (region);
2427       while (region->next)
2428         {
2429           region = region->next;
2430           remove_exit_barriers (region);
2431         }
2432     }
2433 }
2434
2435 /* Expand the OpenMP parallel directive starting at REGION.  */
2436
2437 static void
2438 expand_omp_parallel (struct omp_region *region)
2439 {
2440   basic_block entry_bb, exit_bb, new_bb;
2441   struct function *child_cfun;
2442   tree child_fn, block, t, ws_args;
2443   block_stmt_iterator si;
2444   tree entry_stmt;
2445   edge e;
2446
2447   entry_stmt = last_stmt (region->entry);
2448   child_fn = OMP_PARALLEL_FN (entry_stmt);
2449   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
2450
2451   entry_bb = region->entry;
2452   exit_bb = region->exit;
2453
2454   if (is_combined_parallel (region))
2455     ws_args = region->ws_args;
2456   else
2457     ws_args = NULL_TREE;
2458
2459   if (child_cfun->cfg)
2460     {
2461       /* Due to inlining, it may happen that we have already outlined
2462          the region, in which case all we need to do is make the
2463          sub-graph unreachable and emit the parallel call.  */
2464       edge entry_succ_e, exit_succ_e;
2465       block_stmt_iterator si;
2466
2467       entry_succ_e = single_succ_edge (entry_bb);
2468
2469       si = bsi_last (entry_bb);
2470       gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_PARALLEL);
2471       bsi_remove (&si, true);
2472
2473       new_bb = entry_bb;
2474       if (exit_bb)
2475         {
2476           exit_succ_e = single_succ_edge (exit_bb);
2477           make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
2478         }
2479       remove_edge_and_dominated_blocks (entry_succ_e);
2480     }
2481   else
2482     {
2483       /* If the parallel region needs data sent from the parent
2484          function, then the very first statement (except possible
2485          tree profile counter updates) of the parallel body
2486          is a copy assignment .OMP_DATA_I = &.OMP_DATA_O.  Since
2487          &.OMP_DATA_O is passed as an argument to the child function,
2488          we need to replace it with the argument as seen by the child
2489          function.
2490
2491          In most cases, this will end up being the identity assignment
2492          .OMP_DATA_I = .OMP_DATA_I.  However, if the parallel body had
2493          a function call that has been inlined, the original PARM_DECL
2494          .OMP_DATA_I may have been converted into a different local
2495          variable.  In which case, we need to keep the assignment.  */
2496       if (OMP_PARALLEL_DATA_ARG (entry_stmt))
2497         {
2498           basic_block entry_succ_bb = single_succ (entry_bb);
2499           block_stmt_iterator si;
2500           tree parcopy_stmt = NULL_TREE, arg, narg;
2501
2502           for (si = bsi_start (entry_succ_bb); ; bsi_next (&si))
2503             {
2504               tree stmt, arg;
2505
2506               gcc_assert (!bsi_end_p (si));
2507               stmt = bsi_stmt (si);
2508               if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
2509                 continue;
2510
2511               arg = GIMPLE_STMT_OPERAND (stmt, 1);
2512               STRIP_NOPS (arg);
2513               if (TREE_CODE (arg) == ADDR_EXPR
2514                   && TREE_OPERAND (arg, 0)
2515                      == OMP_PARALLEL_DATA_ARG (entry_stmt))
2516                 {
2517                   parcopy_stmt = stmt;
2518                   break;
2519                 }
2520             }
2521
2522           gcc_assert (parcopy_stmt != NULL_TREE);
2523           arg = DECL_ARGUMENTS (child_fn);
2524
2525           if (!gimple_in_ssa_p (cfun))
2526             {
2527               if (GIMPLE_STMT_OPERAND (parcopy_stmt, 0) == arg)
2528                 bsi_remove (&si, true);
2529               else
2530                 GIMPLE_STMT_OPERAND (parcopy_stmt, 1) = arg;
2531             }
2532           else
2533             {
2534               /* If we are in ssa form, we must load the value from the default
2535                  definition of the argument.  That should not be defined now,
2536                  since the argument is not used uninitialized.  */
2537               gcc_assert (gimple_default_def (cfun, arg) == NULL);
2538               narg = make_ssa_name (arg, build_empty_stmt ());
2539               set_default_def (arg, narg);
2540               GIMPLE_STMT_OPERAND (parcopy_stmt, 1) = narg;
2541               update_stmt (parcopy_stmt);
2542             }
2543         }
2544
2545       /* Declare local variables needed in CHILD_CFUN.  */
2546       block = DECL_INITIAL (child_fn);
2547       BLOCK_VARS (block) = list2chain (child_cfun->unexpanded_var_list);
2548       DECL_SAVED_TREE (child_fn) = bb_stmt_list (single_succ (entry_bb));
2549
2550       /* Reset DECL_CONTEXT on function arguments.  */
2551       for (t = DECL_ARGUMENTS (child_fn); t; t = TREE_CHAIN (t))
2552         DECL_CONTEXT (t) = child_fn;
2553
2554       /* Split ENTRY_BB at OMP_PARALLEL so that it can be moved to the
2555          child function.  */
2556       si = bsi_last (entry_bb);
2557       t = bsi_stmt (si);
2558       gcc_assert (t && TREE_CODE (t) == OMP_PARALLEL);
2559       bsi_remove (&si, true);
2560       e = split_block (entry_bb, t);
2561       entry_bb = e->dest;
2562       single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
2563
2564       /* Convert OMP_RETURN into a RETURN_EXPR.  */
2565       if (exit_bb)
2566         {
2567           si = bsi_last (exit_bb);
2568           gcc_assert (!bsi_end_p (si)
2569                       && TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
2570           t = build1 (RETURN_EXPR, void_type_node, NULL);
2571           bsi_insert_after (&si, t, BSI_SAME_STMT);
2572           bsi_remove (&si, true);
2573         }
2574
2575       /* Move the parallel region into CHILD_CFUN.  */
2576  
2577       if (gimple_in_ssa_p (cfun))
2578         {
2579           push_cfun (child_cfun);
2580           init_tree_ssa ();
2581           init_ssa_operands ();
2582           cfun->gimple_df->in_ssa_p = true;
2583           pop_cfun ();
2584         }
2585       new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb);
2586       if (exit_bb)
2587         single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
2588
2589       /* Inform the callgraph about the new function.  */
2590       DECL_STRUCT_FUNCTION (child_fn)->curr_properties
2591         = cfun->curr_properties;
2592       cgraph_add_new_function (child_fn, true);
2593
2594       /* Fix the callgraph edges for child_cfun.  Those for cfun will be
2595          fixed in a following pass.  */
2596       push_cfun (child_cfun);
2597       rebuild_cgraph_edges ();
2598       pop_cfun ();
2599     }
2600
2601   /* Emit a library call to launch the children threads.  */
2602   expand_parallel_call (region, new_bb, entry_stmt, ws_args);
2603   update_ssa (TODO_update_ssa_only_virtuals);
2604 }
2605
2606
2607 /* A subroutine of expand_omp_for.  Generate code for a parallel
2608    loop with any schedule.  Given parameters:
2609
2610         for (V = N1; V cond N2; V += STEP) BODY;
2611
2612    where COND is "<" or ">", we generate pseudocode
2613
2614         more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
2615         if (more) goto L0; else goto L3;
2616     L0:
2617         V = istart0;
2618         iend = iend0;
2619     L1:
2620         BODY;
2621         V += STEP;
2622         if (V cond iend) goto L1; else goto L2;
2623     L2:
2624         if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
2625     L3:
2626
2627     If this is a combined omp parallel loop, instead of the call to
2628     GOMP_loop_foo_start, we call GOMP_loop_foo_next.  */
2629
2630 static void
2631 expand_omp_for_generic (struct omp_region *region,
2632                         struct omp_for_data *fd,
2633                         enum built_in_function start_fn,
2634                         enum built_in_function next_fn)
2635 {
2636   tree type, istart0, iend0, iend, phi;
2637   tree t, vmain, vback;
2638   basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb;
2639   basic_block l2_bb = NULL, l3_bb = NULL;
2640   block_stmt_iterator si;
2641   bool in_combined_parallel = is_combined_parallel (region);
2642   bool broken_loop = region->cont == NULL;
2643   edge e, ne;
2644
2645   gcc_assert (!broken_loop || !in_combined_parallel);
2646
2647   type = TREE_TYPE (fd->v);
2648
2649   istart0 = create_tmp_var (long_integer_type_node, ".istart0");
2650   iend0 = create_tmp_var (long_integer_type_node, ".iend0");
2651   TREE_ADDRESSABLE (istart0) = 1;
2652   TREE_ADDRESSABLE (iend0) = 1;
2653   if (gimple_in_ssa_p (cfun))
2654     {
2655       add_referenced_var (istart0);
2656       add_referenced_var (iend0);
2657     }
2658
2659   entry_bb = region->entry;
2660   cont_bb = region->cont;
2661   gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
2662   gcc_assert (broken_loop
2663               || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
2664   l0_bb = split_edge (FALLTHRU_EDGE (entry_bb));
2665   l1_bb = single_succ (l0_bb);
2666   if (!broken_loop)
2667     {
2668       l2_bb = create_empty_bb (cont_bb);
2669       gcc_assert (BRANCH_EDGE (cont_bb)->dest == l1_bb);
2670       gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
2671     }
2672   else
2673     l2_bb = NULL;
2674   l3_bb = BRANCH_EDGE (entry_bb)->dest;
2675   exit_bb = region->exit;
2676
2677   si = bsi_last (entry_bb);
2678   gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
2679   if (in_combined_parallel)
2680     {
2681       /* In a combined parallel loop, emit a call to
2682          GOMP_loop_foo_next.  */
2683       t = build_call_expr (built_in_decls[next_fn], 2,
2684                            build_fold_addr_expr (istart0),
2685                            build_fold_addr_expr (iend0));
2686     }
2687   else
2688     {
2689       tree t0, t1, t2, t3, t4;
2690       /* If this is not a combined parallel loop, emit a call to
2691          GOMP_loop_foo_start in ENTRY_BB.  */
2692       t4 = build_fold_addr_expr (iend0);
2693       t3 = build_fold_addr_expr (istart0);
2694       t2 = fold_convert (long_integer_type_node, fd->step);
2695       t1 = fold_convert (long_integer_type_node, fd->n2);
2696       t0 = fold_convert (long_integer_type_node, fd->n1);
2697       if (fd->chunk_size)
2698         {
2699           t = fold_convert (long_integer_type_node, fd->chunk_size);
2700           t = build_call_expr (built_in_decls[start_fn], 6,
2701                                t0, t1, t2, t, t3, t4);
2702         }
2703       else
2704         t = build_call_expr (built_in_decls[start_fn], 5,
2705                              t0, t1, t2, t3, t4);
2706     }
2707   t = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
2708                                 true, BSI_SAME_STMT);
2709   t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2710   bsi_insert_after (&si, t, BSI_SAME_STMT);
2711
2712   /* V may be used outside of the loop (e.g., to handle lastprivate clause).
2713      If this is the case, its value is undefined if the loop is not entered
2714      at all.  To handle this case, set its initial value to N1.  */
2715   if (gimple_in_ssa_p (cfun))
2716     {
2717       e = find_edge (entry_bb, l3_bb);
2718       for (phi = phi_nodes (l3_bb); phi; phi = PHI_CHAIN (phi))
2719         if (PHI_ARG_DEF_FROM_EDGE (phi, e) == fd->v)
2720           SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), fd->n1);
2721     }
2722   else
2723     {
2724       t = build_gimple_modify_stmt (fd->v, fd->n1);
2725       bsi_insert_before (&si, t, BSI_SAME_STMT);
2726     }
2727
2728   /* Remove the OMP_FOR statement.  */
2729   bsi_remove (&si, true);
2730
2731   /* Iteration setup for sequential loop goes in L0_BB.  */
2732   si = bsi_start (l0_bb);
2733   t = fold_convert (type, istart0);
2734   t = force_gimple_operand_bsi (&si, t, false, NULL_TREE,
2735                                 false, BSI_CONTINUE_LINKING);
2736   t = build_gimple_modify_stmt (fd->v, t);
2737   bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2738   if (gimple_in_ssa_p (cfun))
2739     SSA_NAME_DEF_STMT (fd->v) = t;
2740
2741   t = fold_convert (type, iend0);
2742   iend = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
2743                                    false, BSI_CONTINUE_LINKING);
2744
2745   if (!broken_loop)
2746     {
2747       /* Code to control the increment and predicate for the sequential
2748          loop goes in the CONT_BB.  */
2749       si = bsi_last (cont_bb);
2750       t = bsi_stmt (si);
2751       gcc_assert (TREE_CODE (t) == OMP_CONTINUE);
2752       vmain = TREE_OPERAND (t, 1);
2753       vback = TREE_OPERAND (t, 0);
2754
2755       t = fold_build2 (PLUS_EXPR, type, vmain, fd->step);
2756       t = force_gimple_operand_bsi (&si, t, false, NULL_TREE,
2757                                     true, BSI_SAME_STMT);
2758       t = build_gimple_modify_stmt (vback, t);
2759       bsi_insert_before (&si, t, BSI_SAME_STMT);
2760       if (gimple_in_ssa_p (cfun))
2761         SSA_NAME_DEF_STMT (vback) = t;
2762   
2763       t = build2 (fd->cond_code, boolean_type_node, vback, iend);
2764       t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2765       bsi_insert_before (&si, t, BSI_SAME_STMT);
2766
2767       /* Remove OMP_CONTINUE.  */
2768       bsi_remove (&si, true);
2769
2770       /* Emit code to get the next parallel iteration in L2_BB.  */
2771       si = bsi_start (l2_bb);
2772
2773       t = build_call_expr (built_in_decls[next_fn], 2,
2774                            build_fold_addr_expr (istart0),
2775                            build_fold_addr_expr (iend0));
2776       t = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
2777                                     false, BSI_CONTINUE_LINKING);
2778       t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2779       bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2780     }
2781
2782   /* Add the loop cleanup function.  */
2783   si = bsi_last (exit_bb);
2784   if (OMP_RETURN_NOWAIT (bsi_stmt (si)))
2785     t = built_in_decls[BUILT_IN_GOMP_LOOP_END_NOWAIT];
2786   else
2787     t = built_in_decls[BUILT_IN_GOMP_LOOP_END];
2788   t = build_call_expr (t, 0);
2789   bsi_insert_after (&si, t, BSI_SAME_STMT);
2790   bsi_remove (&si, true);
2791
2792   /* Connect the new blocks.  */
2793   find_edge (entry_bb, l0_bb)->flags = EDGE_TRUE_VALUE;
2794   find_edge (entry_bb, l3_bb)->flags = EDGE_FALSE_VALUE;
2795
2796   if (!broken_loop)
2797     {
2798       e = find_edge (cont_bb, l3_bb);
2799       ne = make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
2800
2801       for (phi = phi_nodes (l3_bb); phi; phi = PHI_CHAIN (phi))
2802         SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, ne),
2803                  PHI_ARG_DEF_FROM_EDGE (phi, e));
2804       remove_edge (e);
2805
2806       find_edge (cont_bb, l1_bb)->flags = EDGE_TRUE_VALUE;
2807       make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
2808       make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
2809
2810       set_immediate_dominator (CDI_DOMINATORS, l2_bb,
2811                                recompute_dominator (CDI_DOMINATORS, l2_bb));
2812       set_immediate_dominator (CDI_DOMINATORS, l3_bb,
2813                                recompute_dominator (CDI_DOMINATORS, l3_bb));
2814       set_immediate_dominator (CDI_DOMINATORS, l0_bb,
2815                                recompute_dominator (CDI_DOMINATORS, l0_bb));
2816       set_immediate_dominator (CDI_DOMINATORS, l1_bb,
2817                                recompute_dominator (CDI_DOMINATORS, l1_bb));
2818     }
2819 }
2820
2821
2822 /* A subroutine of expand_omp_for.  Generate code for a parallel
2823    loop with static schedule and no specified chunk size.  Given
2824    parameters:
2825
2826         for (V = N1; V cond N2; V += STEP) BODY;
2827
2828    where COND is "<" or ">", we generate pseudocode
2829
2830         if (cond is <)
2831           adj = STEP - 1;
2832         else
2833           adj = STEP + 1;
2834         n = (adj + N2 - N1) / STEP;
2835         q = n / nthreads;
2836         q += (q * nthreads != n);
2837         s0 = q * threadid;
2838         e0 = min(s0 + q, n);
2839         V = s0 * STEP + N1;
2840         if (s0 >= e0) goto L2; else goto L0;
2841     L0:
2842         e = e0 * STEP + N1;
2843     L1:
2844         BODY;
2845         V += STEP;
2846         if (V cond e) goto L1;
2847     L2:
2848 */
2849
2850 static void
2851 expand_omp_for_static_nochunk (struct omp_region *region,
2852                                struct omp_for_data *fd)
2853 {
2854   tree n, q, s0, e0, e, t, nthreads, threadid;
2855   tree type, vmain, vback;
2856   basic_block entry_bb, exit_bb, seq_start_bb, body_bb, cont_bb;
2857   basic_block fin_bb;
2858   block_stmt_iterator si;
2859
2860   type = TREE_TYPE (fd->v);
2861
2862   entry_bb = region->entry;
2863   cont_bb = region->cont;
2864   gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
2865   gcc_assert (BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
2866   seq_start_bb = split_edge (FALLTHRU_EDGE (entry_bb));
2867   body_bb = single_succ (seq_start_bb);
2868   gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
2869   gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
2870   fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
2871   exit_bb = region->exit;
2872
2873   /* Iteration space partitioning goes in ENTRY_BB.  */
2874   si = bsi_last (entry_bb);
2875   gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
2876
2877   t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
2878   t = fold_convert (type, t);
2879   nthreads = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
2880                                        true, BSI_SAME_STMT);
2881   
2882   t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
2883   t = fold_convert (type, t);
2884   threadid = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
2885                                        true, BSI_SAME_STMT);
2886
2887   fd->n1 = force_gimple_operand_bsi (&si,
2888                                      fold_convert (type, fd->n1),
2889                                      true, NULL_TREE,
2890                                      true, BSI_SAME_STMT);
2891
2892   fd->n2 = force_gimple_operand_bsi (&si,
2893                                     fold_convert (type, fd->n2),
2894                                     true, NULL_TREE,
2895                                     true, BSI_SAME_STMT);
2896
2897   fd->step = force_gimple_operand_bsi (&si,
2898                                        fold_convert (type, fd->step),
2899                                        true, NULL_TREE,
2900                                        true, BSI_SAME_STMT);
2901
2902   t = build_int_cst (type, (fd->cond_code == LT_EXPR ? -1 : 1));
2903   t = fold_build2 (PLUS_EXPR, type, fd->step, t);
2904   t = fold_build2 (PLUS_EXPR, type, t, fd->n2);
2905   t = fold_build2 (MINUS_EXPR, type, t, fd->n1);
2906   t = fold_build2 (TRUNC_DIV_EXPR, type, t, fd->step);
2907   t = fold_convert (type, t);
2908   n = force_gimple_operand_bsi (&si, t, true, NULL_TREE, true, BSI_SAME_STMT);
2909
2910   t = fold_build2 (TRUNC_DIV_EXPR, type, n, nthreads);
2911   q = force_gimple_operand_bsi (&si, t, true, NULL_TREE, true, BSI_SAME_STMT);
2912
2913   t = fold_build2 (MULT_EXPR, type, q, nthreads);
2914   t = fold_build2 (NE_EXPR, type, t, n);
2915   t = fold_build2 (PLUS_EXPR, type, q, t);
2916   q = force_gimple_operand_bsi (&si, t, true, NULL_TREE, true, BSI_SAME_STMT);
2917
2918   t = build2 (MULT_EXPR, type, q, threadid);
2919   s0 = force_gimple_operand_bsi (&si, t, true, NULL_TREE, true, BSI_SAME_STMT);
2920
2921   t = fold_build2 (PLUS_EXPR, type, s0, q);
2922   t = fold_build2 (MIN_EXPR, type, t, n);
2923   e0 = force_gimple_operand_bsi (&si, t, true, NULL_TREE, true, BSI_SAME_STMT);
2924
2925   t = fold_convert (type, s0);
2926   t = fold_build2 (MULT_EXPR, type, t, fd->step);
2927   t = fold_build2 (PLUS_EXPR, type, t, fd->n1);
2928   t = force_gimple_operand_bsi (&si, t, false, NULL_TREE,
2929                                 true, BSI_SAME_STMT);
2930   t = build_gimple_modify_stmt (fd->v, t);
2931   bsi_insert_before (&si, t, BSI_SAME_STMT);
2932   if (gimple_in_ssa_p (cfun))
2933     SSA_NAME_DEF_STMT (fd->v) = t;
2934
2935   t = build2 (GE_EXPR, boolean_type_node, s0, e0);
2936   t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2937   bsi_insert_before (&si, t, BSI_SAME_STMT);
2938
2939   /* Remove the OMP_FOR statement.  */
2940   bsi_remove (&si, true);
2941
2942   /* Setup code for sequential iteration goes in SEQ_START_BB.  */
2943   si = bsi_start (seq_start_bb);
2944
2945   t = fold_convert (type, e0);
2946   t = fold_build2 (MULT_EXPR, type, t, fd->step);
2947   t = fold_build2 (PLUS_EXPR, type, t, fd->n1);
2948   e = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
2949                                 false, BSI_CONTINUE_LINKING);
2950
2951   /* The code controlling the sequential loop replaces the OMP_CONTINUE.  */
2952   si = bsi_last (cont_bb);
2953   t = bsi_stmt (si);
2954   gcc_assert (TREE_CODE (t) == OMP_CONTINUE);
2955   vmain = TREE_OPERAND (t, 1);
2956   vback = TREE_OPERAND (t, 0);
2957
2958   t = fold_build2 (PLUS_EXPR, type, vmain, fd->step);
2959   t = force_gimple_operand_bsi (&si, t, false, NULL_TREE,
2960                                 true, BSI_SAME_STMT);
2961   t = build_gimple_modify_stmt (vback, t);
2962   bsi_insert_before (&si, t, BSI_SAME_STMT);
2963   if (gimple_in_ssa_p (cfun))
2964     SSA_NAME_DEF_STMT (vback) = t;
2965
2966   t = build2 (fd->cond_code, boolean_type_node, vback, e);
2967   t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2968   bsi_insert_before (&si, t, BSI_SAME_STMT);
2969
2970   /* Remove the OMP_CONTINUE statement.  */
2971   bsi_remove (&si, true);
2972
2973   /* Replace the OMP_RETURN with a barrier, or nothing.  */
2974   si = bsi_last (exit_bb);
2975   if (!OMP_RETURN_NOWAIT (bsi_stmt (si)))
2976     force_gimple_operand_bsi (&si, build_omp_barrier (), false, NULL_TREE,
2977                               false, BSI_SAME_STMT);
2978   bsi_remove (&si, true);
2979
2980   /* Connect all the blocks.  */
2981   find_edge (entry_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
2982   find_edge (entry_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
2983
2984   find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
2985   find_edge (cont_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
2986  
2987   set_immediate_dominator (CDI_DOMINATORS, seq_start_bb, entry_bb);
2988   set_immediate_dominator (CDI_DOMINATORS, body_bb,
2989                            recompute_dominator (CDI_DOMINATORS, body_bb));
2990   set_immediate_dominator (CDI_DOMINATORS, fin_bb,
2991                            recompute_dominator (CDI_DOMINATORS, fin_bb));
2992 }
2993
2994
2995 /* A subroutine of expand_omp_for.  Generate code for a parallel
2996    loop with static schedule and a specified chunk size.  Given
2997    parameters:
2998
2999         for (V = N1; V cond N2; V += STEP) BODY;
3000
3001    where COND is "<" or ">", we generate pseudocode
3002
3003         if (cond is <)
3004           adj = STEP - 1;
3005         else
3006           adj = STEP + 1;
3007         n = (adj + N2 - N1) / STEP;
3008         trip = 0;
3009         V = threadid * CHUNK * STEP + N1;  -- this extra definition of V is
3010                                               here so that V is defined
3011                                               if the loop is not entered
3012     L0:
3013         s0 = (trip * nthreads + threadid) * CHUNK;
3014         e0 = min(s0 + CHUNK, n);
3015         if (s0 < n) goto L1; else goto L4;
3016     L1:
3017         V = s0 * STEP + N1;
3018         e = e0 * STEP + N1;
3019     L2:
3020         BODY;
3021         V += STEP;
3022         if (V cond e) goto L2; else goto L3;
3023     L3:
3024         trip += 1;
3025         goto L0;
3026     L4:
3027 */
3028
3029 static void
3030 expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
3031 {
3032   tree n, s0, e0, e, t, phi, nphi, args;
3033   tree trip_var, trip_init, trip_main, trip_back, nthreads, threadid;
3034   tree type, cont, v_main, v_back, v_extra;
3035   basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
3036   basic_block trip_update_bb, cont_bb, fin_bb;
3037   block_stmt_iterator si;
3038   edge se, re, ene;
3039
3040   type = TREE_TYPE (fd->v);
3041
3042   entry_bb = region->entry;
3043   se = split_block (entry_bb, last_stmt (entry_bb));
3044   entry_bb = se->src;
3045   iter_part_bb = se->dest;
3046   cont_bb = region->cont;
3047   gcc_assert (EDGE_COUNT (iter_part_bb->succs) == 2);
3048   gcc_assert (BRANCH_EDGE (iter_part_bb)->dest
3049               == FALLTHRU_EDGE (cont_bb)->dest);
3050   seq_start_bb = split_edge (FALLTHRU_EDGE (iter_part_bb));
3051   body_bb = single_succ (seq_start_bb);
3052   gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
3053   gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
3054   fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
3055   trip_update_bb = split_edge (FALLTHRU_EDGE (cont_bb));
3056   exit_bb = region->exit;
3057
3058   /* Trip and adjustment setup goes in ENTRY_BB.  */
3059   si = bsi_last (entry_bb);
3060   gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
3061
3062   t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
3063   t = fold_convert (type, t);
3064   nthreads = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
3065                                        true, BSI_SAME_STMT);
3066   
3067   t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
3068   t = fold_convert (type, t);
3069   threadid = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
3070                                        true, BSI_SAME_STMT);
3071
3072   fd->n1 = force_gimple_operand_bsi (&si, fold_convert (type, fd->n1),
3073                                      true, NULL_TREE,
3074                                      true, BSI_SAME_STMT);
3075   fd->n2 = force_gimple_operand_bsi (&si, fold_convert (type, fd->n2),
3076                                      true, NULL_TREE,
3077                                      true, BSI_SAME_STMT);
3078   fd->step = force_gimple_operand_bsi (&si, fold_convert (type, fd->step),
3079                                        true, NULL_TREE,
3080                                        true, BSI_SAME_STMT);
3081   fd->chunk_size
3082           = force_gimple_operand_bsi (&si, fold_convert (type,
3083                                                          fd->chunk_size),
3084                                       true, NULL_TREE,
3085                                       true, BSI_SAME_STMT);
3086
3087   t = build_int_cst (type, (fd->cond_code == LT_EXPR ? -1 : 1));
3088   t = fold_build2 (PLUS_EXPR, type, fd->step, t);
3089   t = fold_build2 (PLUS_EXPR, type, t, fd->n2);
3090   t = fold_build2 (MINUS_EXPR, type, t, fd->n1);
3091   t = fold_build2 (TRUNC_DIV_EXPR, type, t, fd->step);
3092   t = fold_convert (type, t);
3093   n = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
3094                                 true, BSI_SAME_STMT);
3095
3096   trip_var = create_tmp_var (type, ".trip");
3097   if (gimple_in_ssa_p (cfun))
3098     {
3099       add_referenced_var (trip_var);
3100       trip_init = make_ssa_name (trip_var, NULL_TREE);
3101       trip_main = make_ssa_name (trip_var, NULL_TREE);
3102       trip_back = make_ssa_name (trip_var, NULL_TREE);
3103     }
3104   else
3105     {
3106       trip_init = trip_var;
3107       trip_main = trip_var;
3108       trip_back = trip_var;
3109     }
3110
3111   t = build_gimple_modify_stmt (trip_init, build_int_cst (type, 0));
3112   bsi_insert_before (&si, t, BSI_SAME_STMT);
3113   if (gimple_in_ssa_p (cfun))
3114     SSA_NAME_DEF_STMT (trip_init) = t;
3115
3116   t = fold_build2 (MULT_EXPR, type, threadid, fd->chunk_size);
3117   t = fold_build2 (MULT_EXPR, type, t, fd->step);
3118   t = fold_build2 (PLUS_EXPR, type, t, fd->n1);
3119   v_extra = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
3120                                       true, BSI_SAME_STMT);
3121
3122   /* Remove the OMP_FOR.  */
3123   bsi_remove (&si, true);
3124
3125   /* Iteration space partitioning goes in ITER_PART_BB.  */
3126   si = bsi_last (iter_part_bb);
3127
3128   t = fold_build2 (MULT_EXPR, type, trip_main, nthreads);
3129   t = fold_build2 (PLUS_EXPR, type, t, threadid);
3130   t = fold_build2 (MULT_EXPR, type, t, fd->chunk_size);
3131   s0 = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
3132                                  false, BSI_CONTINUE_LINKING);
3133
3134   t = fold_build2 (PLUS_EXPR, type, s0, fd->chunk_size);
3135   t = fold_build2 (MIN_EXPR, type, t, n);
3136   e0 = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
3137                                  false, BSI_CONTINUE_LINKING);
3138
3139   t = build2 (LT_EXPR, boolean_type_node, s0, n);
3140   t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
3141   bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
3142
3143   /* Setup code for sequential iteration goes in SEQ_START_BB.  */
3144   si = bsi_start (seq_start_bb);
3145
3146   t = fold_convert (type, s0);
3147   t = fold_build2 (MULT_EXPR, type, t, fd->step);
3148   t = fold_build2 (PLUS_EXPR, type, t, fd->n1);
3149   t = force_gimple_operand_bsi (&si, t, false, NULL_TREE,
3150                                 false, BSI_CONTINUE_LINKING);
3151   t = build_gimple_modify_stmt (fd->v, t);
3152   bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
3153   if (gimple_in_ssa_p (cfun))
3154     SSA_NAME_DEF_STMT (fd->v) = t;
3155
3156   t = fold_convert (type, e0);
3157   t = fold_build2 (MULT_EXPR, type, t, fd->step);
3158   t = fold_build2 (PLUS_EXPR, type, t, fd->n1);
3159   e = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
3160                                 false, BSI_CONTINUE_LINKING);
3161
3162   /* The code controlling the sequential loop goes in CONT_BB,
3163      replacing the OMP_CONTINUE.  */
3164   si = bsi_last (cont_bb);
3165   cont = bsi_stmt (si);
3166   gcc_assert (TREE_CODE (cont) == OMP_CONTINUE);
3167   v_main = TREE_OPERAND (cont, 1);
3168   v_back = TREE_OPERAND (cont, 0);
3169
3170   t = build2 (PLUS_EXPR, type, v_main, fd->step);
3171   t = build_gimple_modify_stmt (v_back, t);
3172   bsi_insert_before (&si, t, BSI_SAME_STMT);
3173   if (gimple_in_ssa_p (cfun))
3174     SSA_NAME_DEF_STMT (v_back) = t;
3175
3176   t = build2 (fd->cond_code, boolean_type_node, v_back, e);
3177   t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
3178   bsi_insert_before (&si, t, BSI_SAME_STMT);
3179   
3180   /* Remove OMP_CONTINUE.  */
3181   bsi_remove (&si, true);
3182
3183   /* Trip update code goes into TRIP_UPDATE_BB.  */
3184   si = bsi_start (trip_update_bb);
3185
3186   t = build_int_cst (type, 1);
3187   t = build2 (PLUS_EXPR, type, trip_main, t);
3188   t = build_gimple_modify_stmt (trip_back, t);
3189   bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
3190   if (gimple_in_ssa_p (cfun))
3191     SSA_NAME_DEF_STMT (trip_back) = t;
3192
3193   /* Replace the OMP_RETURN with a barrier, or nothing.  */
3194   si = bsi_last (exit_bb);
3195   if (!OMP_RETURN_NOWAIT (bsi_stmt (si)))
3196     force_gimple_operand_bsi (&si, build_omp_barrier (), false, NULL_TREE,
3197                               false, BSI_SAME_STMT);
3198   bsi_remove (&si, true);
3199
3200   /* Connect the new blocks.  */
3201   find_edge (iter_part_bb, seq_start_bb)->flags = EDGE_TRUE_VALUE;
3202   find_edge (iter_part_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
3203
3204   find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
3205   find_edge (cont_bb, trip_update_bb)->flags = EDGE_FALSE_VALUE;
3206
3207   redirect_edge_and_branch (single_succ_edge (trip_update_bb), iter_part_bb);
3208
3209   if (gimple_in_ssa_p (cfun))
3210     {
3211       /* When we redirect the edge from trip_update_bb to iter_part_bb, we
3212          remove arguments of the phi nodes in fin_bb.  We need to create
3213          appropriate phi nodes in iter_part_bb instead.  */
3214       se = single_pred_edge (fin_bb);
3215       re = single_succ_edge (trip_update_bb);
3216       ene = single_succ_edge (entry_bb);
3217
3218       args = PENDING_STMT (re);
3219       PENDING_STMT (re) = NULL_TREE;
3220       for (phi = phi_nodes (fin_bb);
3221            phi && args;
3222            phi = PHI_CHAIN (phi), args = TREE_CHAIN (args))
3223         {
3224           t = PHI_RESULT (phi);
3225           gcc_assert (t == TREE_PURPOSE (args));
3226           nphi = create_phi_node (t, iter_part_bb);
3227           SSA_NAME_DEF_STMT (t) = nphi;
3228
3229           t = PHI_ARG_DEF_FROM_EDGE (phi, se);
3230           /* A special case -- fd->v is not yet computed in iter_part_bb, we
3231              need to use v_extra instead.  */
3232           if (t == fd->v)
3233             t = v_extra;
3234           add_phi_arg (nphi, t, ene);
3235           add_phi_arg (nphi, TREE_VALUE (args), re);
3236         }
3237       gcc_assert (!phi && !args);
3238       while ((phi = phi_nodes (fin_bb)) != NULL_TREE)
3239         remove_phi_node (phi, NULL_TREE, false);
3240
3241       /* Make phi node for trip.  */
3242       phi = create_phi_node (trip_main, iter_part_bb);
3243       SSA_NAME_DEF_STMT (trip_main) = phi;
3244       add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb));
3245       add_phi_arg (phi, trip_init, single_succ_edge (entry_bb));
3246     }
3247
3248   set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
3249   set_immediate_dominator (CDI_DOMINATORS, iter_part_bb,
3250                            recompute_dominator (CDI_DOMINATORS, iter_part_bb));
3251   set_immediate_dominator (CDI_DOMINATORS, fin_bb,
3252                            recompute_dominator (CDI_DOMINATORS, fin_bb));
3253   set_immediate_dominator (CDI_DOMINATORS, seq_start_bb,
3254                            recompute_dominator (CDI_DOMINATORS, seq_start_bb));
3255   set_immediate_dominator (CDI_DOMINATORS, body_bb,
3256                            recompute_dominator (CDI_DOMINATORS, body_bb));
3257 }
3258
3259
3260 /* Expand the OpenMP loop defined by REGION.  */
3261
3262 static void
3263 expand_omp_for (struct omp_region *region)
3264 {
3265   struct omp_for_data fd;
3266
3267   extract_omp_for_data (last_stmt (region->entry), &fd);
3268   region->sched_kind = fd.sched_kind;
3269
3270   if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
3271       && !fd.have_ordered
3272       && region->cont != NULL)
3273     {
3274       if (fd.chunk_size == NULL)
3275         expand_omp_for_static_nochunk (region, &fd);
3276       else
3277         expand_omp_for_static_chunk (region, &fd);
3278     }
3279   else
3280     {
3281       int fn_index = fd.sched_kind + fd.have_ordered * 4;
3282       int start_ix = BUILT_IN_GOMP_LOOP_STATIC_START + fn_index;
3283       int next_ix = BUILT_IN_GOMP_LOOP_STATIC_NEXT + fn_index;
3284       expand_omp_for_generic (region, &fd, start_ix, next_ix);
3285     }
3286
3287   update_ssa (TODO_update_ssa_only_virtuals);
3288 }
3289
3290
3291 /* Expand code for an OpenMP sections directive.  In pseudo code, we generate
3292
3293         v = GOMP_sections_start (n);
3294     L0:
3295         switch (v)
3296           {
3297           case 0:
3298             goto L2;
3299           case 1:
3300             section 1;
3301             goto L1;
3302           case 2:
3303             ...
3304           case n:
3305             ...
3306           default:
3307             abort ();
3308           }
3309     L1:
3310         v = GOMP_sections_next ();
3311         goto L0;
3312     L2:
3313         reduction;
3314
3315     If this is a combined parallel sections, replace the call to
3316     GOMP_sections_start with call to GOMP_sections_next.  */
3317
3318 static void
3319 expand_omp_sections (struct omp_region *region)
3320 {
3321   tree label_vec, l1, l2, t, u, sections_stmt, vin, vmain, vnext, cont;
3322   unsigned i, casei, len;
3323   basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
3324   block_stmt_iterator si;
3325   struct omp_region *inner;
3326   bool exit_reachable = region->cont != NULL;
3327
3328   gcc_assert (exit_reachable == (region->exit != NULL));
3329   entry_bb = region->entry;
3330   l0_bb = single_succ (entry_bb);
3331   l1_bb = region->cont;
3332   l2_bb = region->exit;
3333   if (exit_reachable)
3334     {
3335       gcc_assert (single_pred (l2_bb) == l0_bb);
3336       default_bb = create_empty_bb (l1_bb->prev_bb);
3337       l1 = tree_block_label (l1_bb);
3338       l2 = tree_block_label (l2_bb);
3339     }
3340   else
3341     {
3342       default_bb = create_empty_bb (l0_bb);
3343       l1 = NULL_TREE;
3344       l2 = tree_block_label (default_bb);
3345     }
3346
3347   /* We will build a switch() with enough cases for all the
3348      OMP_SECTION regions, a '0' case to handle the end of more work
3349      and a default case to abort if something goes wrong.  */
3350   len = EDGE_COUNT (l0_bb->succs);
3351   label_vec = make_tree_vec (len + 1);
3352
3353   /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
3354      OMP_SECTIONS statement.  */
3355   si = bsi_last (entry_bb);
3356   sections_stmt = bsi_stmt (si);
3357   gcc_assert (TREE_CODE (sections_stmt) == OMP_SECTIONS);
3358   vin = OMP_SECTIONS_CONTROL (sections_stmt);
3359   if (!is_combined_parallel (region))
3360     {
3361       /* If we are not inside a combined parallel+sections region,
3362          call GOMP_sections_start.  */
3363       t = build_int_cst (unsigned_type_node,
3364                          exit_reachable ? len - 1 : len);
3365       u = built_in_decls[BUILT_IN_GOMP_SECTIONS_START];
3366       t = build_call_expr (u, 1, t);
3367     }
3368   else
3369     {
3370       /* Otherwise, call GOMP_sections_next.  */
3371       u = built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT];
3372       t = build_call_expr (u, 0);
3373     }
3374   t = build_gimple_modify_stmt (vin, t);
3375   bsi_insert_after (&si, t, BSI_SAME_STMT);
3376   if (gimple_in_ssa_p (cfun))
3377     SSA_NAME_DEF_STMT (vin) = t;
3378   bsi_remove (&si, true);
3379
3380   /* The switch() statement replacing OMP_SECTIONS_SWITCH goes in L0_BB.  */
3381   si = bsi_last (l0_bb);
3382   gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SECTIONS_SWITCH);
3383   if (exit_reachable)
3384     {
3385       cont = last_stmt (l1_bb);
3386       gcc_assert (TREE_CODE (cont) == OMP_CONTINUE);
3387       vmain = TREE_OPERAND (cont, 1);
3388       vnext = TREE_OPERAND (cont, 0);
3389     }
3390   else
3391     {
3392       vmain = vin;
3393       vnext = NULL_TREE;
3394     }
3395
3396   t = build3 (SWITCH_EXPR, void_type_node, vmain, NULL, label_vec);
3397   bsi_insert_after (&si, t, BSI_SAME_STMT);
3398   bsi_remove (&si, true);
3399
3400   i = 0;
3401   if (exit_reachable)
3402     {
3403       t = build3 (CASE_LABEL_EXPR, void_type_node,
3404                   build_int_cst (unsigned_type_node, 0), NULL, l2);
3405       TREE_VEC_ELT (label_vec, 0) = t;
3406       i++;
3407     }
3408
3409   /* Convert each OMP_SECTION into a CASE_LABEL_EXPR.  */
3410   for (inner = region->inner, casei = 1;
3411        inner;
3412        inner = inner->next, i++, casei++)
3413     {
3414       basic_block s_entry_bb, s_exit_bb;
3415
3416       s_entry_bb = inner->entry;
3417       s_exit_bb = inner->exit;
3418
3419       t = tree_block_label (s_entry_bb);
3420       u = build_int_cst (unsigned_type_node, casei);
3421       u = build3 (CASE_LABEL_EXPR, void_type_node, u, NULL, t);
3422       TREE_VEC_ELT (label_vec, i) = u;
3423
3424       si = bsi_last (s_entry_bb);
3425       gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SECTION);
3426       gcc_assert (i < len || OMP_SECTION_LAST (bsi_stmt (si)));
3427       bsi_remove (&si, true);
3428       single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
3429
3430       if (s_exit_bb == NULL)
3431         continue;
3432
3433       si = bsi_last (s_exit_bb);
3434       gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
3435       bsi_remove (&si, true);
3436
3437       single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
3438     }
3439
3440   /* Error handling code goes in DEFAULT_BB.  */
3441   t = tree_block_label (default_bb);
3442   u = build3 (CASE_LABEL_EXPR, void_type_node, NULL, NULL, t);
3443   TREE_VEC_ELT (label_vec, len) = u;
3444   make_edge (l0_bb, default_bb, 0);
3445
3446   si = bsi_start (default_bb);
3447   t = build_call_expr (built_in_decls[BUILT_IN_TRAP], 0);
3448   bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
3449
3450   if (exit_reachable)
3451     {
3452       /* Code to get the next section goes in L1_BB.  */
3453       si = bsi_last (l1_bb);
3454       gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
3455
3456       t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT], 0);
3457       t = build_gimple_modify_stmt (vnext, t);
3458       bsi_insert_after (&si, t, BSI_SAME_STMT);
3459       if (gimple_in_ssa_p (cfun))
3460         SSA_NAME_DEF_STMT (vnext) = t;
3461       bsi_remove (&si, true);
3462
3463       single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
3464
3465       /* Cleanup function replaces OMP_RETURN in EXIT_BB.  */
3466       si = bsi_last (l2_bb);
3467       if (OMP_RETURN_NOWAIT (bsi_stmt (si)))
3468         t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END_NOWAIT];
3469       else
3470         t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END];
3471       t = build_call_expr (t, 0);
3472       bsi_insert_after (&si, t, BSI_SAME_STMT);
3473       bsi_remove (&si, true);
3474     }
3475
3476   set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb);
3477 }
3478
3479
3480 /* Expand code for an OpenMP single directive.  We've already expanded
3481    much of the code, here we simply place the GOMP_barrier call.  */
3482
3483 static void
3484 expand_omp_single (struct omp_region *region)
3485 {
3486   basic_block entry_bb, exit_bb;
3487   block_stmt_iterator si;
3488   bool need_barrier = false;
3489
3490   entry_bb = region->entry;
3491   exit_bb = region->exit;
3492
3493   si = bsi_last (entry_bb);
3494   /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
3495      be removed.  We need to ensure that the thread that entered the single
3496      does not exit before the data is copied out by the other threads.  */
3497   if (find_omp_clause (OMP_SINGLE_CLAUSES (bsi_stmt (si)),
3498                        OMP_CLAUSE_COPYPRIVATE))
3499     need_barrier = true;
3500   gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SINGLE);
3501   bsi_remove (&si, true);
3502   single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3503
3504   si = bsi_last (exit_bb);
3505   if (!OMP_RETURN_NOWAIT (bsi_stmt (si)) || need_barrier)
3506     force_gimple_operand_bsi (&si, build_omp_barrier (), false, NULL_TREE,
3507                               false, BSI_SAME_STMT);
3508   bsi_remove (&si, true);
3509   single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
3510 }
3511
3512
3513 /* Generic expansion for OpenMP synchronization directives: master,
3514    ordered and critical.  All we need to do here is remove the entry
3515    and exit markers for REGION.  */
3516
3517 static void
3518 expand_omp_synch (struct omp_region *region)
3519 {
3520   basic_block entry_bb, exit_bb;
3521   block_stmt_iterator si;
3522
3523   entry_bb = region->entry;
3524   exit_bb = region->exit;
3525
3526   si = bsi_last (entry_bb);
3527   gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SINGLE
3528               || TREE_CODE (bsi_stmt (si)) == OMP_MASTER
3529               || TREE_CODE (bsi_stmt (si)) == OMP_ORDERED
3530               || TREE_CODE (bsi_stmt (si)) == OMP_CRITICAL);
3531   bsi_remove (&si, true);
3532   single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3533
3534   if (exit_bb)
3535     {
3536       si = bsi_last (exit_bb);
3537       gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
3538       bsi_remove (&si, true);
3539       single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
3540     }
3541 }
3542
3543
3544 /* Expand the parallel region tree rooted at REGION.  Expansion
3545    proceeds in depth-first order.  Innermost regions are expanded
3546    first.  This way, parallel regions that require a new function to
3547    be created (e.g., OMP_PARALLEL) can be expanded without having any
3548    internal dependencies in their body.  */
3549
3550 static void
3551 expand_omp (struct omp_region *region)
3552 {
3553   while (region)
3554     {
3555       if (region->inner)
3556         expand_omp (region->inner);
3557
3558       switch (region->type)
3559         {
3560         case OMP_PARALLEL:
3561           expand_omp_parallel (region);
3562           break;
3563
3564         case OMP_FOR:
3565           expand_omp_for (region);
3566           break;
3567
3568         case OMP_SECTIONS:
3569           expand_omp_sections (region);
3570           break;
3571
3572         case OMP_SECTION:
3573           /* Individual omp sections are handled together with their
3574              parent OMP_SECTIONS region.  */
3575           break;
3576
3577         case OMP_SINGLE:
3578           expand_omp_single (region);
3579           break;
3580
3581         case OMP_MASTER:
3582         case OMP_ORDERED:
3583         case OMP_CRITICAL:
3584           expand_omp_synch (region);
3585           break;
3586
3587         default:
3588           gcc_unreachable ();
3589         }
3590
3591       region = region->next;
3592     }
3593 }
3594
3595
3596 /* Helper for build_omp_regions.  Scan the dominator tree starting at
3597    block BB.  PARENT is the region that contains BB.  If SINGLE_TREE is
3598    true, the function ends once a single tree is built (otherwise, whole
3599    forest of OMP constructs may be built).  */
3600
3601 static void
3602 build_omp_regions_1 (basic_block bb, struct omp_region *parent,
3603                      bool single_tree)
3604 {
3605   block_stmt_iterator si;
3606   tree stmt;
3607   basic_block son;
3608
3609   si = bsi_last (bb);
3610   if (!bsi_end_p (si) && OMP_DIRECTIVE_P (bsi_stmt (si)))
3611     {
3612       struct omp_region *region;
3613       enum tree_code code;
3614
3615       stmt = bsi_stmt (si);
3616       code = TREE_CODE (stmt);
3617
3618       if (code == OMP_RETURN)
3619         {
3620           /* STMT is the return point out of region PARENT.  Mark it
3621              as the exit point and make PARENT the immediately
3622              enclosing region.  */
3623           gcc_assert (parent);
3624           region = parent;
3625           region->exit = bb;
3626           parent = parent->outer;
3627
3628           /* If REGION is a parallel region, determine whether it is
3629              a combined parallel+workshare region.  */
3630           if (region->type == OMP_PARALLEL)
3631             determine_parallel_type (region);
3632         }
3633       else if (code == OMP_CONTINUE)
3634         {
3635           gcc_assert (parent);
3636           parent->cont = bb;
3637         }
3638       else if (code == OMP_SECTIONS_SWITCH)
3639         {
3640           /* OMP_SECTIONS_SWITCH is part of OMP_SECTIONS, and we do nothing for
3641              it.  */
3642         }
3643       else
3644         {
3645           /* Otherwise, this directive becomes the parent for a new
3646              region.  */
3647           region = new_omp_region (bb, code, parent);
3648           parent = region;
3649         }
3650     }
3651
3652   if (single_tree && !parent)
3653     return;
3654
3655   for (son = first_dom_son (CDI_DOMINATORS, bb);
3656        son;
3657        son = next_dom_son (CDI_DOMINATORS, son))
3658     build_omp_regions_1 (son, parent, single_tree);
3659 }
3660
3661 /* Builds the tree of OMP regions rooted at ROOT, storing it to
3662    root_omp_region.  */
3663
3664 static void
3665 build_omp_regions_root (basic_block root)
3666 {
3667   gcc_assert (root_omp_region == NULL);
3668   build_omp_regions_1 (root, NULL, true);
3669   gcc_assert (root_omp_region != NULL);
3670 }
3671
3672 /* Expands omp construct (and its subconstructs) starting in HEAD.  */
3673
3674 void
3675 omp_expand_local (basic_block head)
3676 {
3677   build_omp_regions_root (head);
3678   if (dump_file && (dump_flags & TDF_DETAILS))
3679     {
3680       fprintf (dump_file, "\nOMP region tree\n\n");
3681       dump_omp_region (dump_file, root_omp_region, 0);
3682       fprintf (dump_file, "\n");
3683     }
3684
3685   remove_exit_barriers (root_omp_region);
3686   expand_omp (root_omp_region);
3687
3688   free_omp_regions ();
3689 }
3690
3691 /* Scan the CFG and build a tree of OMP regions.  Return the root of
3692    the OMP region tree.  */
3693
3694 static void
3695 build_omp_regions (void)
3696 {
3697   gcc_assert (root_omp_region == NULL);
3698   calculate_dominance_info (CDI_DOMINATORS);
3699   build_omp_regions_1 (ENTRY_BLOCK_PTR, NULL, false);
3700 }
3701
3702
3703 /* Main entry point for expanding OMP-GIMPLE into runtime calls.  */
3704
3705 static unsigned int
3706 execute_expand_omp (void)
3707 {
3708   build_omp_regions ();
3709
3710   if (!root_omp_region)
3711     return 0;
3712
3713   if (dump_file)
3714     {
3715       fprintf (dump_file, "\nOMP region tree\n\n");
3716       dump_omp_region (dump_file, root_omp_region, 0);
3717       fprintf (dump_file, "\n");
3718     }
3719
3720   remove_exit_barriers (root_omp_region);
3721
3722   expand_omp (root_omp_region);
3723
3724   cleanup_tree_cfg ();
3725
3726   free_omp_regions ();
3727
3728   return 0;
3729 }
3730
3731 /* OMP expansion in SSA form.  For testing purposes only.  */
3732
3733 static bool
3734 gate_expand_omp_ssa (void)
3735 {
3736   return flag_openmp_ssa && flag_openmp != 0 && errorcount == 0;
3737 }
3738
3739 struct tree_opt_pass pass_expand_omp_ssa = 
3740 {
3741   "ompexpssa",                          /* name */
3742   gate_expand_omp_ssa,                  /* gate */
3743   execute_expand_omp,                   /* execute */
3744   NULL,                                 /* sub */
3745   NULL,                                 /* next */
3746   0,                                    /* static_pass_number */
3747   0,                                    /* tv_id */
3748   PROP_gimple_any,                      /* properties_required */
3749   PROP_gimple_lomp,                     /* properties_provided */
3750   0,                                    /* properties_destroyed */
3751   0,                                    /* todo_flags_start */
3752   TODO_dump_func,                       /* todo_flags_finish */
3753   0                                     /* letter */
3754 };
3755
3756 /* OMP expansion -- the default pass, run before creation of SSA form.  */
3757
3758 static bool
3759 gate_expand_omp (void)
3760 {
3761   return ((!flag_openmp_ssa || !optimize)
3762           && flag_openmp != 0 && errorcount == 0);
3763 }
3764
3765 struct tree_opt_pass pass_expand_omp = 
3766 {
3767   "ompexp",                             /* name */
3768   gate_expand_omp,                      /* gate */
3769   execute_expand_omp,                   /* execute */
3770   NULL,                                 /* sub */
3771   NULL,                                 /* next */
3772   0,                                    /* static_pass_number */
3773   0,                                    /* tv_id */
3774   PROP_gimple_any,                      /* properties_required */
3775   PROP_gimple_lomp,                     /* properties_provided */
3776   0,                                    /* properties_destroyed */
3777   0,                                    /* todo_flags_start */
3778   TODO_dump_func,                       /* todo_flags_finish */
3779   0                                     /* letter */
3780 };
3781 \f
3782 /* Routines to lower OpenMP directives into OMP-GIMPLE.  */
3783
3784 /* Lower the OpenMP sections directive in *STMT_P.  */
3785
3786 static void
3787 lower_omp_sections (tree *stmt_p, omp_context *ctx)
3788 {
3789   tree new_stmt, stmt, body, bind, block, ilist, olist, new_body, control;
3790   tree t, dlist;
3791   tree_stmt_iterator tsi;
3792   unsigned i, len;
3793
3794   stmt = *stmt_p;
3795
3796   push_gimplify_context ();
3797
3798   dlist = NULL;
3799   ilist = NULL;
3800   lower_rec_input_clauses (OMP_SECTIONS_CLAUSES (stmt), &ilist, &dlist, ctx);
3801
3802   tsi = tsi_start (OMP_SECTIONS_BODY (stmt));
3803   for (len = 0; !tsi_end_p (tsi); len++, tsi_next (&tsi))
3804     continue;
3805
3806   tsi = tsi_start (OMP_SECTIONS_BODY (stmt));
3807   body = alloc_stmt_list ();
3808   for (i = 0; i < len; i++, tsi_next (&tsi))
3809     {
3810       omp_context *sctx;
3811       tree sec_start, sec_end;
3812
3813       sec_start = tsi_stmt (tsi);
3814       sctx = maybe_lookup_ctx (sec_start);
3815       gcc_assert (sctx);
3816
3817       append_to_statement_list (sec_start, &body);
3818
3819       lower_omp (&OMP_SECTION_BODY (sec_start), sctx);
3820       append_to_statement_list (OMP_SECTION_BODY (sec_start), &body);
3821       OMP_SECTION_BODY (sec_start) = NULL;
3822
3823       if (i == len - 1)
3824         {
3825           tree l = alloc_stmt_list ();
3826           lower_lastprivate_clauses (OMP_SECTIONS_CLAUSES (stmt), NULL,
3827                                      &l, ctx);
3828           append_to_statement_list (l, &body);
3829           OMP_SECTION_LAST (sec_start) = 1;
3830         }
3831       
3832       sec_end = make_node (OMP_RETURN);
3833       append_to_statement_list (sec_end, &body);
3834     }
3835
3836   block = make_node (BLOCK);
3837   bind = build3 (BIND_EXPR, void_type_node, NULL, body, block);
3838
3839   olist = NULL_TREE;
3840   lower_reduction_clauses (OMP_SECTIONS_CLAUSES (stmt), &olist, ctx);
3841
3842   pop_gimplify_context (NULL_TREE);
3843   record_vars_into (ctx->block_vars, ctx->cb.dst_fn);
3844
3845   new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
3846   TREE_SIDE_EFFECTS (new_stmt) = 1;
3847
3848   new_body = alloc_stmt_list ();
3849   append_to_statement_list (ilist, &new_body);
3850   append_to_statement_list (stmt, &new_body);
3851   append_to_statement_list (make_node (OMP_SECTIONS_SWITCH), &new_body);
3852   append_to_statement_list (bind, &new_body);
3853
3854   control = create_tmp_var (unsigned_type_node, ".section");
3855   t = build2 (OMP_CONTINUE, void_type_node, control, control);
3856   OMP_SECTIONS_CONTROL (stmt) = control;
3857   append_to_statement_list (t, &new_body);
3858
3859   append_to_statement_list (olist, &new_body);
3860   append_to_statement_list (dlist, &new_body);
3861
3862   maybe_catch_exception (&new_body);
3863
3864   t = make_node (OMP_RETURN);
3865   OMP_RETURN_NOWAIT (t) = !!find_omp_clause (OMP_SECTIONS_CLAUSES (stmt),
3866                                              OMP_CLAUSE_NOWAIT);
3867   append_to_statement_list (t, &new_body);
3868
3869   BIND_EXPR_BODY (new_stmt) = new_body;
3870   OMP_SECTIONS_BODY (stmt) = NULL;
3871
3872   *stmt_p = new_stmt;
3873 }
3874
3875
3876 /* A subroutine of lower_omp_single.  Expand the simple form of
3877    an OMP_SINGLE, without a copyprivate clause:
3878
3879         if (GOMP_single_start ())
3880           BODY;
3881         [ GOMP_barrier (); ]    -> unless 'nowait' is present.
3882
3883   FIXME.  It may be better to delay expanding the logic of this until
3884   pass_expand_omp.  The expanded logic may make the job more difficult
3885   to a synchronization analysis pass.  */
3886
3887 static void
3888 lower_omp_single_simple (tree single_stmt, tree *pre_p)
3889 {
3890   tree t;
3891
3892   t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_START], 0);
3893   t = build3 (COND_EXPR, void_type_node, t,
3894               OMP_SINGLE_BODY (single_stmt), NULL);
3895   gimplify_and_add (t, pre_p);
3896 }
3897
3898
3899 /* A subroutine of lower_omp_single.  Expand the simple form of
3900    an OMP_SINGLE, with a copyprivate clause:
3901
3902         #pragma omp single copyprivate (a, b, c)
3903
3904    Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
3905
3906       {
3907         if ((copyout_p = GOMP_single_copy_start ()) == NULL)
3908           {
3909             BODY;
3910             copyout.a = a;
3911             copyout.b = b;
3912             copyout.c = c;
3913             GOMP_single_copy_end (&copyout);
3914           }
3915         else
3916           {
3917             a = copyout_p->a;
3918             b = copyout_p->b;
3919             c = copyout_p->c;
3920           }
3921         GOMP_barrier ();
3922       }
3923
3924   FIXME.  It may be better to delay expanding the logic of this until
3925   pass_expand_omp.  The expanded logic may make the job more difficult
3926   to a synchronization analysis pass.  */
3927
3928 static void
3929 lower_omp_single_copy (tree single_stmt, tree *pre_p, omp_context *ctx)
3930 {
3931   tree ptr_type, t, l0, l1, l2, copyin_seq;
3932
3933   ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
3934
3935   ptr_type = build_pointer_type (ctx->record_type);
3936   ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
3937
3938   l0 = create_artificial_label ();
3939   l1 = create_artificial_label ();
3940   l2 = create_artificial_label ();
3941
3942   t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_START], 0);
3943   t = fold_convert (ptr_type, t);
3944   t = build_gimple_modify_stmt (ctx->receiver_decl, t);
3945   gimplify_and_add (t, pre_p);
3946
3947   t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
3948               build_int_cst (ptr_type, 0));
3949   t = build3 (COND_EXPR, void_type_node, t,
3950               build_and_jump (&l0), build_and_jump (&l1));
3951   gimplify_and_add (t, pre_p);
3952
3953   t = build1 (LABEL_EXPR, void_type_node, l0);
3954   gimplify_and_add (t, pre_p);
3955
3956   append_to_statement_list (OMP_SINGLE_BODY (single_stmt), pre_p);
3957
3958   copyin_seq = NULL;
3959   lower_copyprivate_clauses (OMP_SINGLE_CLAUSES (single_stmt), pre_p,
3960                               &copyin_seq, ctx);
3961
3962   t = build_fold_addr_expr (ctx->sender_decl);
3963   t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_END], 1, t);
3964   gimplify_and_add (t, pre_p);
3965
3966   t = build_and_jump (&l2);
3967   gimplify_and_add (t, pre_p);
3968
3969   t = build1 (LABEL_EXPR, void_type_node, l1);
3970   gimplify_and_add (t, pre_p);
3971
3972   append_to_statement_list (copyin_seq, pre_p);
3973
3974   t = build1 (LABEL_EXPR, void_type_node, l2);
3975   gimplify_and_add (t, pre_p);
3976 }
3977
3978
3979 /* Expand code for an OpenMP single directive.  */
3980
3981 static void
3982 lower_omp_single (tree *stmt_p, omp_context *ctx)
3983 {
3984   tree t, bind, block, single_stmt = *stmt_p, dlist;
3985
3986   push_gimplify_context ();
3987
3988   block = make_node (BLOCK);
3989   *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3990   TREE_SIDE_EFFECTS (bind) = 1;
3991
3992   lower_rec_input_clauses (OMP_SINGLE_CLAUSES (single_stmt),
3993                            &BIND_EXPR_BODY (bind), &dlist, ctx);
3994   lower_omp (&OMP_SINGLE_BODY (single_stmt), ctx);
3995
3996   append_to_statement_list (single_stmt, &BIND_EXPR_BODY (bind));
3997
3998   if (ctx->record_type)
3999     lower_omp_single_copy (single_stmt, &BIND_EXPR_BODY (bind), ctx);
4000   else
4001     lower_omp_single_simple (single_stmt, &BIND_EXPR_BODY (bind));
4002
4003   OMP_SINGLE_BODY (single_stmt) = NULL;
4004
4005   append_to_statement_list (dlist, &BIND_EXPR_BODY (bind));
4006
4007   maybe_catch_exception (&BIND_EXPR_BODY (bind));
4008
4009   t = make_node (OMP_RETURN);
4010   OMP_RETURN_NOWAIT (t) = !!find_omp_clause (OMP_SINGLE_CLAUSES (single_stmt),
4011                                              OMP_CLAUSE_NOWAIT);
4012   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
4013
4014   pop_gimplify_context (bind);
4015
4016   BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
4017   BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
4018 }
4019
4020
4021 /* Expand code for an OpenMP master directive.  */
4022
4023 static void
4024 lower_omp_master (tree *stmt_p, omp_context *ctx)
4025 {
4026   tree bind, block, stmt = *stmt_p, lab = NULL, x;
4027
4028   push_gimplify_context ();
4029
4030   block = make_node (BLOCK);
4031   *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
4032   TREE_SIDE_EFFECTS (bind) = 1;
4033
4034   append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
4035
4036   x = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
4037   x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
4038   x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
4039   gimplify_and_add (x, &BIND_EXPR_BODY (bind));
4040
4041   lower_omp (&OMP_MASTER_BODY (stmt), ctx);
4042   maybe_catch_exception (&OMP_MASTER_BODY (stmt));
4043   append_to_statement_list (OMP_MASTER_BODY (stmt), &BIND_EXPR_BODY (bind));
4044   OMP_MASTER_BODY (stmt) = NULL;
4045
4046   x = build1 (LABEL_EXPR, void_type_node, lab);
4047   gimplify_and_add (x, &BIND_EXPR_BODY (bind));
4048
4049   x = make_node (OMP_RETURN);
4050   OMP_RETURN_NOWAIT (x) = 1;
4051   append_to_statement_list (x, &BIND_EXPR_BODY (bind));
4052
4053   pop_gimplify_context (bind);
4054
4055   BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
4056   BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
4057 }
4058
4059
4060 /* Expand code for an OpenMP ordered directive.  */
4061
4062 static void
4063 lower_omp_ordered (tree *stmt_p, omp_context *ctx)
4064 {
4065   tree bind, block, stmt = *stmt_p, x;
4066
4067   push_gimplify_context ();
4068
4069   block = make_node (BLOCK);
4070   *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
4071   TREE_SIDE_EFFECTS (bind) = 1;
4072
4073   append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
4074
4075   x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ORDERED_START], 0);
4076   gimplify_and_add (x, &BIND_EXPR_BODY (bind));
4077
4078   lower_omp (&OMP_ORDERED_BODY (stmt), ctx);
4079   maybe_catch_exception (&OMP_ORDERED_BODY (stmt));
4080   append_to_statement_list (OMP_ORDERED_BODY (stmt), &BIND_EXPR_BODY (bind));
4081   OMP_ORDERED_BODY (stmt) = NULL;
4082
4083   x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ORDERED_END], 0);
4084   gimplify_and_add (x, &BIND_EXPR_BODY (bind));
4085
4086   x = make_node (OMP_RETURN);
4087   OMP_RETURN_NOWAIT (x) = 1;
4088   append_to_statement_list (x, &BIND_EXPR_BODY (bind));
4089
4090   pop_gimplify_context (bind);
4091
4092   BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
4093   BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
4094 }
4095
4096
4097 /* Gimplify an OMP_CRITICAL statement.  This is a relatively simple
4098    substitution of a couple of function calls.  But in the NAMED case,
4099    requires that languages coordinate a symbol name.  It is therefore
4100    best put here in common code.  */
4101
4102 static GTY((param1_is (tree), param2_is (tree)))
4103   splay_tree critical_name_mutexes;
4104
4105 static void
4106 lower_omp_critical (tree *stmt_p, omp_context *ctx)
4107 {
4108   tree bind, block, stmt = *stmt_p;
4109   tree t, lock, unlock, name;
4110
4111   name = OMP_CRITICAL_NAME (stmt);
4112   if (name)
4113     {
4114       tree decl;
4115       splay_tree_node n;
4116
4117       if (!critical_name_mutexes)
4118         critical_name_mutexes
4119           = splay_tree_new_ggc (splay_tree_compare_pointers);
4120
4121       n = splay_tree_lookup (critical_name_mutexes, (splay_tree_key) name);
4122       if (n == NULL)
4123         {
4124           char *new_str;
4125
4126           decl = create_tmp_var_raw (ptr_type_node, NULL);
4127
4128           new_str = ACONCAT ((".gomp_critical_user_",
4129                               IDENTIFIER_POINTER (name), NULL));
4130           DECL_NAME (decl) = get_identifier (new_str);
4131           TREE_PUBLIC (decl) = 1;
4132           TREE_STATIC (decl) = 1;
4133           DECL_COMMON (decl) = 1;
4134           DECL_ARTIFICIAL (decl) = 1;
4135           DECL_IGNORED_P (decl) = 1;
4136           varpool_finalize_decl (decl);
4137
4138           splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
4139                              (splay_tree_value) decl);
4140         }
4141       else
4142         decl = (tree) n->value;
4143
4144       lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_START];
4145       lock = build_call_expr (lock, 1, build_fold_addr_expr (decl));
4146
4147       unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_END];
4148       unlock = build_call_expr (unlock, 1, build_fold_addr_expr (decl));
4149     }
4150   else
4151     {
4152       lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_START];
4153       lock = build_call_expr (lock, 0);
4154
4155       unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_END];
4156       unlock = build_call_expr (unlock, 0);
4157     }
4158
4159   push_gimplify_context ();
4160
4161   block = make_node (BLOCK);
4162   *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
4163   TREE_SIDE_EFFECTS (bind) = 1;
4164
4165   append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
4166
4167   gimplify_and_add (lock, &BIND_EXPR_BODY (bind));
4168
4169   lower_omp (&OMP_CRITICAL_BODY (stmt), ctx);
4170   maybe_catch_exception (&OMP_CRITICAL_BODY (stmt));
4171   append_to_statement_list (OMP_CRITICAL_BODY (stmt), &BIND_EXPR_BODY (bind));
4172   OMP_CRITICAL_BODY (stmt) = NULL;
4173
4174   gimplify_and_add (unlock, &BIND_EXPR_BODY (bind));
4175
4176   t = make_node (OMP_RETURN);
4177   OMP_RETURN_NOWAIT (t) = 1;
4178   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
4179
4180   pop_gimplify_context (bind);
4181   BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
4182   BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
4183 }
4184
4185
4186 /* A subroutine of lower_omp_for.  Generate code to emit the predicate
4187    for a lastprivate clause.  Given a loop control predicate of (V
4188    cond N2), we gate the clause on (!(V cond N2)).  The lowered form
4189    is appended to *DLIST, iterator initialization is appended to
4190    *BODY_P.  */
4191
4192 static void
4193 lower_omp_for_lastprivate (struct omp_for_data *fd, tree *body_p,
4194                            tree *dlist, struct omp_context *ctx)
4195 {
4196   tree clauses, cond, stmts, vinit, t;
4197   enum tree_code cond_code;
4198   
4199   cond_code = fd->cond_code;
4200   cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
4201
4202   /* When possible, use a strict equality expression.  This can let VRP
4203      type optimizations deduce the value and remove a copy.  */
4204   if (host_integerp (fd->step, 0))
4205     {
4206       HOST_WIDE_INT step = TREE_INT_CST_LOW (fd->step);
4207       if (step == 1 || step == -1)
4208         cond_code = EQ_EXPR;
4209     }
4210
4211   cond = build2 (cond_code, boolean_type_node, fd->v, fd->n2);
4212
4213   clauses = OMP_FOR_CLAUSES (fd->for_stmt);
4214   stmts = NULL;
4215   lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
4216   if (stmts != NULL)
4217     {
4218       append_to_statement_list (stmts, dlist);
4219
4220       /* Optimize: v = 0; is usually cheaper than v = some_other_constant.  */
4221       vinit = fd->n1;
4222       if (cond_code == EQ_EXPR
4223           && host_integerp (fd->n2, 0)
4224           && ! integer_zerop (fd->n2))
4225         vinit = build_int_cst (TREE_TYPE (fd->v), 0);
4226
4227       /* Initialize the iterator variable, so that threads that don't execute
4228          any iterations don't execute the lastprivate clauses by accident.  */
4229       t = build_gimple_modify_stmt (fd->v, vinit);
4230       gimplify_and_add (t, body_p);
4231     }
4232 }
4233
4234
4235 /* Lower code for an OpenMP loop directive.  */
4236
4237 static void
4238 lower_omp_for (tree *stmt_p, omp_context *ctx)
4239 {
4240   tree t, stmt, ilist, dlist, new_stmt, *body_p, *rhs_p;
4241   struct omp_for_data fd;
4242
4243   stmt = *stmt_p;
4244
4245   push_gimplify_context ();
4246
4247   lower_omp (&OMP_FOR_PRE_BODY (stmt), ctx);
4248   lower_omp (&OMP_FOR_BODY (stmt), ctx);
4249
4250   /* Move declaration of temporaries in the loop body before we make
4251      it go away.  */
4252   if (TREE_CODE (OMP_FOR_BODY (stmt)) == BIND_EXPR)
4253     record_vars_into (BIND_EXPR_VARS (OMP_FOR_BODY (stmt)), ctx->cb.dst_fn);
4254
4255   new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
4256   TREE_SIDE_EFFECTS (new_stmt) = 1;
4257   body_p = &BIND_EXPR_BODY (new_stmt);
4258
4259   /* The pre-body and input clauses go before the lowered OMP_FOR.  */
4260   ilist = NULL;
4261   dlist = NULL;
4262   append_to_statement_list (OMP_FOR_PRE_BODY (stmt), body_p);
4263   lower_rec_input_clauses (OMP_FOR_CLAUSES (stmt), body_p, &dlist, ctx);
4264
4265   /* Lower the header expressions.  At this point, we can assume that
4266      the header is of the form:
4267
4268         #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
4269
4270      We just need to make sure that VAL1, VAL2 and VAL3 are lowered
4271      using the .omp_data_s mapping, if needed.  */
4272   rhs_p = &GIMPLE_STMT_OPERAND (OMP_FOR_INIT (stmt), 1);
4273   if (!is_gimple_min_invariant (*rhs_p))
4274     *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
4275
4276   rhs_p = &TREE_OPERAND (OMP_FOR_COND (stmt), 1);
4277   if (!is_gimple_min_invariant (*rhs_p))
4278     *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
4279
4280   rhs_p = &TREE_OPERAND (GIMPLE_STMT_OPERAND (OMP_FOR_INCR (stmt), 1), 1);
4281   if (!is_gimple_min_invariant (*rhs_p))
4282     *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
4283
4284   /* Once lowered, extract the bounds and clauses.  */
4285   extract_omp_for_data (stmt, &fd);
4286
4287   lower_omp_for_lastprivate (&fd, body_p, &dlist, ctx);
4288
4289   append_to_statement_list (stmt, body_p);
4290
4291   append_to_statement_list (OMP_FOR_BODY (stmt), body_p);
4292
4293   t = build2 (OMP_CONTINUE, void_type_node, fd.v, fd.v);
4294   append_to_statement_list (t, body_p);
4295
4296   /* After the loop, add exit clauses.  */
4297   lower_reduction_clauses (OMP_FOR_CLAUSES (stmt), body_p, ctx);
4298   append_to_statement_list (dlist, body_p);
4299
4300   maybe_catch_exception (body_p);
4301
4302   /* Region exit marker goes at the end of the loop body.  */
4303   t = make_node (OMP_RETURN);
4304   OMP_RETURN_NOWAIT (t) = fd.have_nowait;
4305   append_to_statement_list (t, body_p);
4306
4307   pop_gimplify_context (NULL_TREE);
4308   record_vars_into (ctx->block_vars, ctx->cb.dst_fn);
4309
4310   OMP_FOR_BODY (stmt) = NULL_TREE;
4311   OMP_FOR_PRE_BODY (stmt) = NULL_TREE;
4312   *stmt_p = new_stmt;
4313 }
4314
4315 /* Callback for walk_stmts.  Check if *TP only contains OMP_FOR
4316    or OMP_PARALLEL.  */
4317
4318 static tree
4319 check_combined_parallel (tree *tp, int *walk_subtrees, void *data)
4320 {
4321   struct walk_stmt_info *wi = data;
4322   int *info = wi->info;
4323
4324   *walk_subtrees = 0;
4325   switch (TREE_CODE (*tp))
4326     {
4327     case OMP_FOR:
4328     case OMP_SECTIONS:
4329       *info = *info == 0 ? 1 : -1;
4330       break;
4331     default:
4332       *info = -1;
4333       break;
4334     }
4335   return NULL;
4336 }
4337
4338 /* Lower the OpenMP parallel directive in *STMT_P.  CTX holds context
4339    information for the directive.  */
4340
4341 static void
4342 lower_omp_parallel (tree *stmt_p, omp_context *ctx)
4343 {
4344   tree clauses, par_bind, par_body, new_body, bind;
4345   tree olist, ilist, par_olist, par_ilist;
4346   tree stmt, child_fn, t;
4347
4348   stmt = *stmt_p;
4349
4350   clauses = OMP_PARALLEL_CLAUSES (stmt);
4351   par_bind = OMP_PARALLEL_BODY (stmt);
4352   par_body = BIND_EXPR_BODY (par_bind);
4353   child_fn = ctx->cb.dst_fn;
4354   if (!OMP_PARALLEL_COMBINED (stmt))
4355     {
4356       struct walk_stmt_info wi;
4357       int ws_num = 0;
4358
4359       memset (&wi, 0, sizeof (wi));
4360       wi.callback = check_combined_parallel;
4361       wi.info = &ws_num;
4362       wi.val_only = true;
4363       walk_stmts (&wi, &par_bind);
4364       if (ws_num == 1)
4365         OMP_PARALLEL_COMBINED (stmt) = 1;
4366     }
4367
4368   push_gimplify_context ();
4369
4370   par_olist = NULL_TREE;
4371   par_ilist = NULL_TREE;
4372   lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
4373   lower_omp (&par_body, ctx);
4374   lower_reduction_clauses (clauses, &par_olist, ctx);
4375
4376   /* Declare all the variables created by mapping and the variables
4377      declared in the scope of the parallel body.  */
4378   record_vars_into (ctx->block_vars, child_fn);
4379   record_vars_into (BIND_EXPR_VARS (par_bind), child_fn);
4380
4381   if (ctx->record_type)
4382     {
4383       ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_data_o");
4384       OMP_PARALLEL_DATA_ARG (stmt) = ctx->sender_decl;
4385     }
4386
4387   olist = NULL_TREE;
4388   ilist = NULL_TREE;
4389   lower_send_clauses (clauses, &ilist, &olist, ctx);
4390   lower_send_shared_vars (&ilist, &olist, ctx);
4391
4392   /* Once all the expansions are done, sequence all the different
4393      fragments inside OMP_PARALLEL_BODY.  */
4394   bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
4395   append_to_statement_list (ilist, &BIND_EXPR_BODY (bind));
4396
4397   new_body = alloc_stmt_list ();
4398
4399   if (ctx->record_type)
4400     {
4401       t = build_fold_addr_expr (ctx->sender_decl);
4402       /* fixup_child_record_type might have changed receiver_decl's type.  */
4403       t = fold_convert (TREE_TYPE (ctx->receiver_decl), t);
4404       t = build_gimple_modify_stmt (ctx->receiver_decl, t);
4405       append_to_statement_list (t, &new_body);
4406     }
4407
4408   append_to_statement_list (par_ilist, &new_body);
4409   append_to_statement_list (par_body, &new_body);
4410   append_to_statement_list (par_olist, &new_body);
4411   maybe_catch_exception (&new_body);
4412   t = make_node (OMP_RETURN);
4413   append_to_statement_list (t, &new_body);
4414   OMP_PARALLEL_BODY (stmt) = new_body;
4415
4416   append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
4417   append_to_statement_list (olist, &BIND_EXPR_BODY (bind));
4418
4419   *stmt_p = bind;
4420
4421   pop_gimplify_context (NULL_TREE);
4422 }
4423
4424
4425 /* Pass *TP back through the gimplifier within the context determined by WI.
4426    This handles replacement of DECL_VALUE_EXPR, as well as adjusting the 
4427    flags on ADDR_EXPR.  */
4428
4429 static void
4430 lower_regimplify (tree *tp, struct walk_stmt_info *wi)
4431 {
4432   enum gimplify_status gs;
4433   tree pre = NULL;
4434
4435   if (wi->is_lhs)
4436     gs = gimplify_expr (tp, &pre, NULL, is_gimple_lvalue, fb_lvalue);
4437   else if (wi->val_only)
4438     gs = gimplify_expr (tp, &pre, NULL, is_gimple_val, fb_rvalue);
4439   else
4440     gs = gimplify_expr (tp, &pre, NULL, is_gimple_formal_tmp_var, fb_rvalue);
4441   gcc_assert (gs == GS_ALL_DONE);
4442
4443   if (pre)
4444     tsi_link_before (&wi->tsi, pre, TSI_SAME_STMT);
4445 }
4446
4447 /* Copy EXP into a temporary.  Insert the initialization statement before TSI.  */
4448
4449 static tree
4450 init_tmp_var (tree exp, tree_stmt_iterator *tsi)
4451 {
4452   tree t, stmt;
4453
4454   t = create_tmp_var (TREE_TYPE (exp), NULL);
4455   DECL_GIMPLE_REG_P (t) = 1;
4456   stmt = build_gimple_modify_stmt (t, exp);
4457   SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
4458   tsi_link_before (tsi, stmt, TSI_SAME_STMT);
4459
4460   return t;
4461 }
4462
4463 /* Similarly, but copy from the temporary and insert the statement
4464    after the iterator.  */
4465
4466 static tree
4467 save_tmp_var (tree exp, tree_stmt_iterator *tsi)
4468 {
4469   tree t, stmt;
4470
4471   t = create_tmp_var (TREE_TYPE (exp), NULL);
4472   DECL_GIMPLE_REG_P (t) = 1;
4473   stmt = build_gimple_modify_stmt (exp, t);
4474   SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
4475   tsi_link_after (tsi, stmt, TSI_SAME_STMT);
4476
4477   return t;
4478 }
4479
4480 /* Callback for walk_stmts.  Lower the OpenMP directive pointed by TP.  */
4481
4482 static tree
4483 lower_omp_1 (tree *tp, int *walk_subtrees, void *data)
4484 {
4485   struct walk_stmt_info *wi = data;
4486   omp_context *ctx = wi->info;
4487   tree t = *tp;
4488
4489   /* If we have issued syntax errors, avoid doing any heavy lifting.
4490      Just replace the OpenMP directives with a NOP to avoid
4491      confusing RTL expansion.  */
4492   if (errorcount && OMP_DIRECTIVE_P (*tp))
4493     {
4494       *tp = build_empty_stmt ();
4495       return NULL_TREE;
4496     }
4497
4498   *walk_subtrees = 0;
4499   switch (TREE_CODE (*tp))
4500     {
4501     case OMP_PARALLEL:
4502       ctx = maybe_lookup_ctx (t);
4503       lower_omp_parallel (tp, ctx);
4504       break;
4505
4506     case OMP_FOR:
4507       ctx = maybe_lookup_ctx (t);
4508       gcc_assert (ctx);
4509       lower_omp_for (tp, ctx);
4510       break;
4511
4512     case OMP_SECTIONS:
4513       ctx = maybe_lookup_ctx (t);
4514       gcc_assert (ctx);
4515       lower_omp_sections (tp, ctx);
4516       break;
4517
4518     case OMP_SINGLE:
4519       ctx = maybe_lookup_ctx (t);
4520       gcc_assert (ctx);
4521       lower_omp_single (tp, ctx);
4522       break;
4523
4524     case OMP_MASTER:
4525       ctx = maybe_lookup_ctx (t);
4526       gcc_assert (ctx);
4527       lower_omp_master (tp, ctx);
4528       break;
4529
4530     case OMP_ORDERED:
4531       ctx = maybe_lookup_ctx (t);
4532       gcc_assert (ctx);
4533       lower_omp_ordered (tp, ctx);
4534       break;
4535
4536     case OMP_CRITICAL:
4537       ctx = maybe_lookup_ctx (t);
4538       gcc_assert (ctx);
4539       lower_omp_critical (tp, ctx);
4540       break;
4541
4542     case VAR_DECL:
4543       if (ctx && DECL_HAS_VALUE_EXPR_P (t))
4544         {
4545           lower_regimplify (&t, wi);
4546           if (wi->val_only)
4547             {
4548               if (wi->is_lhs)
4549                 t = save_tmp_var (t, &wi->tsi);
4550               else
4551                 t = init_tmp_var (t, &wi->tsi);
4552             }
4553           *tp = t;
4554         }
4555       break;
4556
4557     case ADDR_EXPR:
4558       if (ctx)
4559         lower_regimplify (tp, wi);
4560       break;
4561
4562     case ARRAY_REF:
4563     case ARRAY_RANGE_REF:
4564     case REALPART_EXPR:
4565     case IMAGPART_EXPR:
4566     case COMPONENT_REF:
4567     case VIEW_CONVERT_EXPR:
4568       if (ctx)
4569         lower_regimplify (tp, wi);
4570       break;
4571
4572     case INDIRECT_REF:
4573       if (ctx)
4574         {
4575           wi->is_lhs = false;
4576           wi->val_only = true;
4577           lower_regimplify (&TREE_OPERAND (t, 0), wi);
4578         }
4579       break;
4580
4581     default:
4582       if (!TYPE_P (t) && !DECL_P (t))
4583         *walk_subtrees = 1;
4584       break;
4585     }
4586
4587   return NULL_TREE;
4588 }
4589
4590 static void
4591 lower_omp (tree *stmt_p, omp_context *ctx)
4592 {
4593   struct walk_stmt_info wi;
4594
4595   memset (&wi, 0, sizeof (wi));
4596   wi.callback = lower_omp_1;
4597   wi.info = ctx;
4598   wi.val_only = true;
4599   wi.want_locations = true;
4600
4601   walk_stmts (&wi, stmt_p);
4602 }
4603 \f
4604 /* Main entry point.  */
4605
4606 static unsigned int
4607 execute_lower_omp (void)
4608 {
4609   all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
4610                                  delete_omp_context);
4611
4612   scan_omp (&DECL_SAVED_TREE (current_function_decl), NULL);
4613   gcc_assert (parallel_nesting_level == 0);
4614
4615   if (all_contexts->root)
4616     lower_omp (&DECL_SAVED_TREE (current_function_decl), NULL);
4617
4618   if (all_contexts)
4619     {
4620       splay_tree_delete (all_contexts);
4621       all_contexts = NULL;
4622     }
4623   return 0;
4624 }
4625
4626 static bool
4627 gate_lower_omp (void)
4628 {
4629   return flag_openmp != 0;
4630 }
4631
4632 struct tree_opt_pass pass_lower_omp = 
4633 {
4634   "omplower",                           /* name */
4635   gate_lower_omp,                       /* gate */
4636   execute_lower_omp,                    /* execute */
4637   NULL,                                 /* sub */
4638   NULL,                                 /* next */
4639   0,                                    /* static_pass_number */
4640   0,                                    /* tv_id */
4641   PROP_gimple_any,                      /* properties_required */
4642   PROP_gimple_lomp,                     /* properties_provided */
4643   0,                                    /* properties_destroyed */
4644   0,                                    /* todo_flags_start */
4645   TODO_dump_func,                       /* todo_flags_finish */
4646   0                                     /* letter */
4647 };
4648 \f
4649 /* The following is a utility to diagnose OpenMP structured block violations.
4650    It is not part of the "omplower" pass, as that's invoked too late.  It
4651    should be invoked by the respective front ends after gimplification.  */
4652
4653 static splay_tree all_labels;
4654
4655 /* Check for mismatched contexts and generate an error if needed.  Return
4656    true if an error is detected.  */
4657
4658 static bool
4659 diagnose_sb_0 (tree *stmt_p, tree branch_ctx, tree label_ctx)
4660 {
4661   bool exit_p = true;
4662
4663   if ((label_ctx ? TREE_VALUE (label_ctx) : NULL) == branch_ctx)
4664     return false;
4665
4666   /* Try to avoid confusing the user by producing and error message
4667      with correct "exit" or "enter" verbage.  We prefer "exit"
4668      unless we can show that LABEL_CTX is nested within BRANCH_CTX.  */
4669   if (branch_ctx == NULL)
4670     exit_p = false;
4671   else
4672     {
4673       while (label_ctx)
4674         {
4675           if (TREE_VALUE (label_ctx) == branch_ctx)
4676             {
4677               exit_p = false;
4678               break;
4679             }
4680           label_ctx = TREE_CHAIN (label_ctx);
4681         }
4682     }
4683
4684   if (exit_p)
4685     error ("invalid exit from OpenMP structured block");
4686   else
4687     error ("invalid entry to OpenMP structured block");
4688
4689   *stmt_p = build_empty_stmt ();
4690   return true;
4691 }
4692
4693 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
4694    where in the tree each label is found.  */
4695
4696 static tree
4697 diagnose_sb_1 (tree *tp, int *walk_subtrees, void *data)
4698 {
4699   struct walk_stmt_info *wi = data;
4700   tree context = (tree) wi->info;
4701   tree inner_context;
4702   tree t = *tp;
4703
4704   *walk_subtrees = 0;
4705   switch (TREE_CODE (t))
4706     {
4707     case OMP_PARALLEL:
4708     case OMP_SECTIONS:
4709     case OMP_SINGLE:
4710       walk_tree (&OMP_CLAUSES (t), diagnose_sb_1, wi, NULL);
4711       /* FALLTHRU */
4712     case OMP_SECTION:
4713     case OMP_MASTER:
4714     case OMP_ORDERED:
4715     case OMP_CRITICAL:
4716       /* The minimal context here is just a tree of statements.  */
4717       inner_context = tree_cons (NULL, t, context);
4718       wi->info = inner_context;
4719       walk_stmts (wi, &OMP_BODY (t));
4720       wi->info = context;
4721       break;
4722
4723     case OMP_FOR:
4724       walk_tree (&OMP_FOR_CLAUSES (t), diagnose_sb_1, wi, NULL);
4725       inner_context = tree_cons (NULL, t, context);
4726       wi->info = inner_context;
4727       walk_tree (&OMP_FOR_INIT (t), diagnose_sb_1, wi, NULL);
4728       walk_tree (&OMP_FOR_COND (t), diagnose_sb_1, wi, NULL);
4729       walk_tree (&OMP_FOR_INCR (t), diagnose_sb_1, wi, NULL);
4730       walk_stmts (wi, &OMP_FOR_PRE_BODY (t));
4731       walk_stmts (wi, &OMP_FOR_BODY (t));
4732       wi->info = context;
4733       break;
4734
4735     case LABEL_EXPR:
4736       splay_tree_insert (all_labels, (splay_tree_key) LABEL_EXPR_LABEL (t),
4737                          (splay_tree_value) context);
4738       break;
4739
4740     default:
4741       break;
4742     }
4743
4744   return NULL_TREE;
4745 }
4746
4747 /* Pass 2: Check each branch and see if its context differs from that of
4748    the destination label's context.  */
4749
4750 static tree
4751 diagnose_sb_2 (tree *tp, int *walk_subtrees, void *data)
4752 {
4753   struct walk_stmt_info *wi = data;
4754   tree context = (tree) wi->info;
4755   splay_tree_node n;
4756   tree t = *tp;
4757
4758   *walk_subtrees = 0;
4759   switch (TREE_CODE (t))
4760     {
4761     case OMP_PARALLEL:
4762     case OMP_SECTIONS:
4763     case OMP_SINGLE:
4764       walk_tree (&OMP_CLAUSES (t), diagnose_sb_2, wi, NULL);
4765       /* FALLTHRU */
4766     case OMP_SECTION:
4767     case OMP_MASTER:
4768     case OMP_ORDERED:
4769     case OMP_CRITICAL:
4770       wi->info = t;
4771       walk_stmts (wi, &OMP_BODY (t));
4772       wi->info = context;
4773       break;
4774
4775     case OMP_FOR:
4776       walk_tree (&OMP_FOR_CLAUSES (t), diagnose_sb_2, wi, NULL);
4777       wi->info = t;
4778       walk_tree (&OMP_FOR_INIT (t), diagnose_sb_2, wi, NULL);
4779       walk_tree (&OMP_FOR_COND (t), diagnose_sb_2, wi, NULL);
4780       walk_tree (&OMP_FOR_INCR (t), diagnose_sb_2, wi, NULL);
4781       walk_stmts (wi, &OMP_FOR_PRE_BODY (t));
4782       walk_stmts (wi, &OMP_FOR_BODY (t));
4783       wi->info = context;
4784       break;
4785
4786     case GOTO_EXPR:
4787       {
4788         tree lab = GOTO_DESTINATION (t);
4789         if (TREE_CODE (lab) != LABEL_DECL)
4790           break;
4791
4792         n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
4793         diagnose_sb_0 (tp, context, n ? (tree) n->value : NULL_TREE);
4794       }
4795       break;
4796
4797     case SWITCH_EXPR:
4798       {
4799         tree vec = SWITCH_LABELS (t);
4800         int i, len = TREE_VEC_LENGTH (vec);
4801         for (i = 0; i < len; ++i)
4802           {
4803             tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
4804             n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
4805             if (diagnose_sb_0 (tp, context, (tree) n->value))
4806               break;
4807           }
4808       }
4809       break;
4810
4811     case RETURN_EXPR:
4812       diagnose_sb_0 (tp, context, NULL_TREE);
4813       break;
4814
4815     default:
4816       break;
4817     }
4818
4819   return NULL_TREE;
4820 }
4821
4822 void
4823 diagnose_omp_structured_block_errors (tree fndecl)
4824 {
4825   tree save_current = current_function_decl;
4826   struct walk_stmt_info wi;
4827
4828   current_function_decl = fndecl;
4829
4830   all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
4831
4832   memset (&wi, 0, sizeof (wi));
4833   wi.callback = diagnose_sb_1;
4834   walk_stmts (&wi, &DECL_SAVED_TREE (fndecl));
4835
4836   memset (&wi, 0, sizeof (wi));
4837   wi.callback = diagnose_sb_2;
4838   wi.want_locations = true;
4839   wi.want_return_expr = true;
4840   walk_stmts (&wi, &DECL_SAVED_TREE (fndecl));
4841
4842   splay_tree_delete (all_labels);
4843   all_labels = NULL;
4844
4845   current_function_decl = save_current;
4846 }
4847
4848 #include "gt-omp-low.h"