OSDN Git Service

gcc/ada/
[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 }
2604
2605
2606 /* A subroutine of expand_omp_for.  Generate code for a parallel
2607    loop with any schedule.  Given parameters:
2608
2609         for (V = N1; V cond N2; V += STEP) BODY;
2610
2611    where COND is "<" or ">", we generate pseudocode
2612
2613         more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
2614         if (more) goto L0; else goto L3;
2615     L0:
2616         V = istart0;
2617         iend = iend0;
2618     L1:
2619         BODY;
2620         V += STEP;
2621         if (V cond iend) goto L1; else goto L2;
2622     L2:
2623         if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
2624     L3:
2625
2626     If this is a combined omp parallel loop, instead of the call to
2627     GOMP_loop_foo_start, we call GOMP_loop_foo_next.  */
2628
2629 static void
2630 expand_omp_for_generic (struct omp_region *region,
2631                         struct omp_for_data *fd,
2632                         enum built_in_function start_fn,
2633                         enum built_in_function next_fn)
2634 {
2635   tree type, istart0, iend0, iend, phi;
2636   tree t, vmain, vback;
2637   basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb;
2638   basic_block l2_bb = NULL, l3_bb = NULL;
2639   block_stmt_iterator si;
2640   bool in_combined_parallel = is_combined_parallel (region);
2641   bool broken_loop = region->cont == NULL;
2642   edge e, ne;
2643
2644   gcc_assert (!broken_loop || !in_combined_parallel);
2645
2646   type = TREE_TYPE (fd->v);
2647
2648   istart0 = create_tmp_var (long_integer_type_node, ".istart0");
2649   iend0 = create_tmp_var (long_integer_type_node, ".iend0");
2650   TREE_ADDRESSABLE (istart0) = 1;
2651   TREE_ADDRESSABLE (iend0) = 1;
2652   if (gimple_in_ssa_p (cfun))
2653     {
2654       add_referenced_var (istart0);
2655       add_referenced_var (iend0);
2656     }
2657
2658   entry_bb = region->entry;
2659   cont_bb = region->cont;
2660   gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
2661   gcc_assert (broken_loop
2662               || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
2663   l0_bb = split_edge (FALLTHRU_EDGE (entry_bb));
2664   l1_bb = single_succ (l0_bb);
2665   if (!broken_loop)
2666     {
2667       l2_bb = create_empty_bb (cont_bb);
2668       gcc_assert (BRANCH_EDGE (cont_bb)->dest == l1_bb);
2669       gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
2670     }
2671   else
2672     l2_bb = NULL;
2673   l3_bb = BRANCH_EDGE (entry_bb)->dest;
2674   exit_bb = region->exit;
2675
2676   si = bsi_last (entry_bb);
2677   gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
2678   if (in_combined_parallel)
2679     {
2680       /* In a combined parallel loop, emit a call to
2681          GOMP_loop_foo_next.  */
2682       t = build_call_expr (built_in_decls[next_fn], 2,
2683                            build_fold_addr_expr (istart0),
2684                            build_fold_addr_expr (iend0));
2685     }
2686   else
2687     {
2688       tree t0, t1, t2, t3, t4;
2689       /* If this is not a combined parallel loop, emit a call to
2690          GOMP_loop_foo_start in ENTRY_BB.  */
2691       t4 = build_fold_addr_expr (iend0);
2692       t3 = build_fold_addr_expr (istart0);
2693       t2 = fold_convert (long_integer_type_node, fd->step);
2694       t1 = fold_convert (long_integer_type_node, fd->n2);
2695       t0 = fold_convert (long_integer_type_node, fd->n1);
2696       if (fd->chunk_size)
2697         {
2698           t = fold_convert (long_integer_type_node, fd->chunk_size);
2699           t = build_call_expr (built_in_decls[start_fn], 6,
2700                                t0, t1, t2, t, t3, t4);
2701         }
2702       else
2703         t = build_call_expr (built_in_decls[start_fn], 5,
2704                              t0, t1, t2, t3, t4);
2705     }
2706   t = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
2707                                 true, BSI_SAME_STMT);
2708   t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2709   bsi_insert_after (&si, t, BSI_SAME_STMT);
2710
2711   /* V may be used outside of the loop (e.g., to handle lastprivate clause).
2712      If this is the case, its value is undefined if the loop is not entered
2713      at all.  To handle this case, set its initial value to N1.  */
2714   if (gimple_in_ssa_p (cfun))
2715     {
2716       e = find_edge (entry_bb, l3_bb);
2717       for (phi = phi_nodes (l3_bb); phi; phi = PHI_CHAIN (phi))
2718         if (PHI_ARG_DEF_FROM_EDGE (phi, e) == fd->v)
2719           SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), fd->n1);
2720     }
2721   else
2722     {
2723       t = build_gimple_modify_stmt (fd->v, fd->n1);
2724       bsi_insert_before (&si, t, BSI_SAME_STMT);
2725     }
2726
2727   /* Remove the OMP_FOR statement.  */
2728   bsi_remove (&si, true);
2729
2730   /* Iteration setup for sequential loop goes in L0_BB.  */
2731   si = bsi_start (l0_bb);
2732   t = fold_convert (type, istart0);
2733   t = force_gimple_operand_bsi (&si, t, false, NULL_TREE,
2734                                 false, BSI_CONTINUE_LINKING);
2735   t = build_gimple_modify_stmt (fd->v, t);
2736   bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2737   if (gimple_in_ssa_p (cfun))
2738     SSA_NAME_DEF_STMT (fd->v) = t;
2739
2740   t = fold_convert (type, iend0);
2741   iend = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
2742                                    false, BSI_CONTINUE_LINKING);
2743
2744   if (!broken_loop)
2745     {
2746       /* Code to control the increment and predicate for the sequential
2747          loop goes in the CONT_BB.  */
2748       si = bsi_last (cont_bb);
2749       t = bsi_stmt (si);
2750       gcc_assert (TREE_CODE (t) == OMP_CONTINUE);
2751       vmain = TREE_OPERAND (t, 1);
2752       vback = TREE_OPERAND (t, 0);
2753
2754       t = fold_build2 (PLUS_EXPR, type, vmain, fd->step);
2755       t = force_gimple_operand_bsi (&si, t, false, NULL_TREE,
2756                                     true, BSI_SAME_STMT);
2757       t = build_gimple_modify_stmt (vback, t);
2758       bsi_insert_before (&si, t, BSI_SAME_STMT);
2759       if (gimple_in_ssa_p (cfun))
2760         SSA_NAME_DEF_STMT (vback) = t;
2761   
2762       t = build2 (fd->cond_code, boolean_type_node, vback, iend);
2763       t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2764       bsi_insert_before (&si, t, BSI_SAME_STMT);
2765
2766       /* Remove OMP_CONTINUE.  */
2767       bsi_remove (&si, true);
2768
2769       /* Emit code to get the next parallel iteration in L2_BB.  */
2770       si = bsi_start (l2_bb);
2771
2772       t = build_call_expr (built_in_decls[next_fn], 2,
2773                            build_fold_addr_expr (istart0),
2774                            build_fold_addr_expr (iend0));
2775       t = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
2776                                     false, BSI_CONTINUE_LINKING);
2777       t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2778       bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2779     }
2780
2781   /* Add the loop cleanup function.  */
2782   si = bsi_last (exit_bb);
2783   if (OMP_RETURN_NOWAIT (bsi_stmt (si)))
2784     t = built_in_decls[BUILT_IN_GOMP_LOOP_END_NOWAIT];
2785   else
2786     t = built_in_decls[BUILT_IN_GOMP_LOOP_END];
2787   t = build_call_expr (t, 0);
2788   bsi_insert_after (&si, t, BSI_SAME_STMT);
2789   bsi_remove (&si, true);
2790
2791   /* Connect the new blocks.  */
2792   find_edge (entry_bb, l0_bb)->flags = EDGE_TRUE_VALUE;
2793   find_edge (entry_bb, l3_bb)->flags = EDGE_FALSE_VALUE;
2794
2795   if (!broken_loop)
2796     {
2797       e = find_edge (cont_bb, l3_bb);
2798       ne = make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
2799
2800       for (phi = phi_nodes (l3_bb); phi; phi = PHI_CHAIN (phi))
2801         SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, ne),
2802                  PHI_ARG_DEF_FROM_EDGE (phi, e));
2803       remove_edge (e);
2804
2805       find_edge (cont_bb, l1_bb)->flags = EDGE_TRUE_VALUE;
2806       make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
2807       make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
2808
2809       set_immediate_dominator (CDI_DOMINATORS, l2_bb,
2810                                recompute_dominator (CDI_DOMINATORS, l2_bb));
2811       set_immediate_dominator (CDI_DOMINATORS, l3_bb,
2812                                recompute_dominator (CDI_DOMINATORS, l3_bb));
2813       set_immediate_dominator (CDI_DOMINATORS, l0_bb,
2814                                recompute_dominator (CDI_DOMINATORS, l0_bb));
2815       set_immediate_dominator (CDI_DOMINATORS, l1_bb,
2816                                recompute_dominator (CDI_DOMINATORS, l1_bb));
2817     }
2818 }
2819
2820
2821 /* A subroutine of expand_omp_for.  Generate code for a parallel
2822    loop with static schedule and no specified chunk size.  Given
2823    parameters:
2824
2825         for (V = N1; V cond N2; V += STEP) BODY;
2826
2827    where COND is "<" or ">", we generate pseudocode
2828
2829         if (cond is <)
2830           adj = STEP - 1;
2831         else
2832           adj = STEP + 1;
2833         n = (adj + N2 - N1) / STEP;
2834         q = n / nthreads;
2835         q += (q * nthreads != n);
2836         s0 = q * threadid;
2837         e0 = min(s0 + q, n);
2838         V = s0 * STEP + N1;
2839         if (s0 >= e0) goto L2; else goto L0;
2840     L0:
2841         e = e0 * STEP + N1;
2842     L1:
2843         BODY;
2844         V += STEP;
2845         if (V cond e) goto L1;
2846     L2:
2847 */
2848
2849 static void
2850 expand_omp_for_static_nochunk (struct omp_region *region,
2851                                struct omp_for_data *fd)
2852 {
2853   tree n, q, s0, e0, e, t, nthreads, threadid;
2854   tree type, vmain, vback;
2855   basic_block entry_bb, exit_bb, seq_start_bb, body_bb, cont_bb;
2856   basic_block fin_bb;
2857   block_stmt_iterator si;
2858
2859   type = TREE_TYPE (fd->v);
2860
2861   entry_bb = region->entry;
2862   cont_bb = region->cont;
2863   gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
2864   gcc_assert (BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
2865   seq_start_bb = split_edge (FALLTHRU_EDGE (entry_bb));
2866   body_bb = single_succ (seq_start_bb);
2867   gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
2868   gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
2869   fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
2870   exit_bb = region->exit;
2871
2872   /* Iteration space partitioning goes in ENTRY_BB.  */
2873   si = bsi_last (entry_bb);
2874   gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
2875
2876   t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
2877   t = fold_convert (type, t);
2878   nthreads = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
2879                                        true, BSI_SAME_STMT);
2880   
2881   t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
2882   t = fold_convert (type, t);
2883   threadid = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
2884                                        true, BSI_SAME_STMT);
2885
2886   fd->n1 = force_gimple_operand_bsi (&si,
2887                                      fold_convert (type, fd->n1),
2888                                      true, NULL_TREE,
2889                                      true, BSI_SAME_STMT);
2890
2891   fd->n2 = force_gimple_operand_bsi (&si,
2892                                     fold_convert (type, fd->n2),
2893                                     true, NULL_TREE,
2894                                     true, BSI_SAME_STMT);
2895
2896   fd->step = force_gimple_operand_bsi (&si,
2897                                        fold_convert (type, fd->step),
2898                                        true, NULL_TREE,
2899                                        true, BSI_SAME_STMT);
2900
2901   t = build_int_cst (type, (fd->cond_code == LT_EXPR ? -1 : 1));
2902   t = fold_build2 (PLUS_EXPR, type, fd->step, t);
2903   t = fold_build2 (PLUS_EXPR, type, t, fd->n2);
2904   t = fold_build2 (MINUS_EXPR, type, t, fd->n1);
2905   t = fold_build2 (TRUNC_DIV_EXPR, type, t, fd->step);
2906   t = fold_convert (type, t);
2907   n = force_gimple_operand_bsi (&si, t, true, NULL_TREE, true, BSI_SAME_STMT);
2908
2909   t = fold_build2 (TRUNC_DIV_EXPR, type, n, nthreads);
2910   q = force_gimple_operand_bsi (&si, t, true, NULL_TREE, true, BSI_SAME_STMT);
2911
2912   t = fold_build2 (MULT_EXPR, type, q, nthreads);
2913   t = fold_build2 (NE_EXPR, type, t, n);
2914   t = fold_build2 (PLUS_EXPR, type, q, t);
2915   q = force_gimple_operand_bsi (&si, t, true, NULL_TREE, true, BSI_SAME_STMT);
2916
2917   t = build2 (MULT_EXPR, type, q, threadid);
2918   s0 = force_gimple_operand_bsi (&si, t, true, NULL_TREE, true, BSI_SAME_STMT);
2919
2920   t = fold_build2 (PLUS_EXPR, type, s0, q);
2921   t = fold_build2 (MIN_EXPR, type, t, n);
2922   e0 = force_gimple_operand_bsi (&si, t, true, NULL_TREE, true, BSI_SAME_STMT);
2923
2924   t = fold_convert (type, s0);
2925   t = fold_build2 (MULT_EXPR, type, t, fd->step);
2926   t = fold_build2 (PLUS_EXPR, type, t, fd->n1);
2927   t = force_gimple_operand_bsi (&si, t, false, NULL_TREE,
2928                                 true, BSI_SAME_STMT);
2929   t = build_gimple_modify_stmt (fd->v, t);
2930   bsi_insert_before (&si, t, BSI_SAME_STMT);
2931   if (gimple_in_ssa_p (cfun))
2932     SSA_NAME_DEF_STMT (fd->v) = t;
2933
2934   t = build2 (GE_EXPR, boolean_type_node, s0, e0);
2935   t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2936   bsi_insert_before (&si, t, BSI_SAME_STMT);
2937
2938   /* Remove the OMP_FOR statement.  */
2939   bsi_remove (&si, true);
2940
2941   /* Setup code for sequential iteration goes in SEQ_START_BB.  */
2942   si = bsi_start (seq_start_bb);
2943
2944   t = fold_convert (type, e0);
2945   t = fold_build2 (MULT_EXPR, type, t, fd->step);
2946   t = fold_build2 (PLUS_EXPR, type, t, fd->n1);
2947   e = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
2948                                 false, BSI_CONTINUE_LINKING);
2949
2950   /* The code controlling the sequential loop replaces the OMP_CONTINUE.  */
2951   si = bsi_last (cont_bb);
2952   t = bsi_stmt (si);
2953   gcc_assert (TREE_CODE (t) == OMP_CONTINUE);
2954   vmain = TREE_OPERAND (t, 1);
2955   vback = TREE_OPERAND (t, 0);
2956
2957   t = fold_build2 (PLUS_EXPR, type, vmain, fd->step);
2958   t = force_gimple_operand_bsi (&si, t, false, NULL_TREE,
2959                                 true, BSI_SAME_STMT);
2960   t = build_gimple_modify_stmt (vback, t);
2961   bsi_insert_before (&si, t, BSI_SAME_STMT);
2962   if (gimple_in_ssa_p (cfun))
2963     SSA_NAME_DEF_STMT (vback) = t;
2964
2965   t = build2 (fd->cond_code, boolean_type_node, vback, e);
2966   t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2967   bsi_insert_before (&si, t, BSI_SAME_STMT);
2968
2969   /* Remove the OMP_CONTINUE statement.  */
2970   bsi_remove (&si, true);
2971
2972   /* Replace the OMP_RETURN with a barrier, or nothing.  */
2973   si = bsi_last (exit_bb);
2974   if (!OMP_RETURN_NOWAIT (bsi_stmt (si)))
2975     force_gimple_operand_bsi (&si, build_omp_barrier (), false, NULL_TREE,
2976                               false, BSI_SAME_STMT);
2977   bsi_remove (&si, true);
2978
2979   /* Connect all the blocks.  */
2980   find_edge (entry_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
2981   find_edge (entry_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
2982
2983   find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
2984   find_edge (cont_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
2985  
2986   set_immediate_dominator (CDI_DOMINATORS, seq_start_bb, entry_bb);
2987   set_immediate_dominator (CDI_DOMINATORS, body_bb,
2988                            recompute_dominator (CDI_DOMINATORS, body_bb));
2989   set_immediate_dominator (CDI_DOMINATORS, fin_bb,
2990                            recompute_dominator (CDI_DOMINATORS, fin_bb));
2991 }
2992
2993
2994 /* A subroutine of expand_omp_for.  Generate code for a parallel
2995    loop with static schedule and a specified chunk size.  Given
2996    parameters:
2997
2998         for (V = N1; V cond N2; V += STEP) BODY;
2999
3000    where COND is "<" or ">", we generate pseudocode
3001
3002         if (cond is <)
3003           adj = STEP - 1;
3004         else
3005           adj = STEP + 1;
3006         n = (adj + N2 - N1) / STEP;
3007         trip = 0;
3008         V = threadid * CHUNK * STEP + N1;  -- this extra definition of V is
3009                                               here so that V is defined
3010                                               if the loop is not entered
3011     L0:
3012         s0 = (trip * nthreads + threadid) * CHUNK;
3013         e0 = min(s0 + CHUNK, n);
3014         if (s0 < n) goto L1; else goto L4;
3015     L1:
3016         V = s0 * STEP + N1;
3017         e = e0 * STEP + N1;
3018     L2:
3019         BODY;
3020         V += STEP;
3021         if (V cond e) goto L2; else goto L3;
3022     L3:
3023         trip += 1;
3024         goto L0;
3025     L4:
3026 */
3027
3028 static void
3029 expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
3030 {
3031   tree n, s0, e0, e, t, phi, nphi, args;
3032   tree trip_var, trip_init, trip_main, trip_back, nthreads, threadid;
3033   tree type, cont, v_main, v_back, v_extra;
3034   basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
3035   basic_block trip_update_bb, cont_bb, fin_bb;
3036   block_stmt_iterator si;
3037   edge se, re, ene;
3038
3039   type = TREE_TYPE (fd->v);
3040
3041   entry_bb = region->entry;
3042   se = split_block (entry_bb, last_stmt (entry_bb));
3043   entry_bb = se->src;
3044   iter_part_bb = se->dest;
3045   cont_bb = region->cont;
3046   gcc_assert (EDGE_COUNT (iter_part_bb->succs) == 2);
3047   gcc_assert (BRANCH_EDGE (iter_part_bb)->dest
3048               == FALLTHRU_EDGE (cont_bb)->dest);
3049   seq_start_bb = split_edge (FALLTHRU_EDGE (iter_part_bb));
3050   body_bb = single_succ (seq_start_bb);
3051   gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
3052   gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
3053   fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
3054   trip_update_bb = split_edge (FALLTHRU_EDGE (cont_bb));
3055   exit_bb = region->exit;
3056
3057   /* Trip and adjustment setup goes in ENTRY_BB.  */
3058   si = bsi_last (entry_bb);
3059   gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
3060
3061   t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
3062   t = fold_convert (type, t);
3063   nthreads = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
3064                                        true, BSI_SAME_STMT);
3065   
3066   t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
3067   t = fold_convert (type, t);
3068   threadid = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
3069                                        true, BSI_SAME_STMT);
3070
3071   fd->n1 = force_gimple_operand_bsi (&si, fold_convert (type, fd->n1),
3072                                      true, NULL_TREE,
3073                                      true, BSI_SAME_STMT);
3074   fd->n2 = force_gimple_operand_bsi (&si, fold_convert (type, fd->n2),
3075                                      true, NULL_TREE,
3076                                      true, BSI_SAME_STMT);
3077   fd->step = force_gimple_operand_bsi (&si, fold_convert (type, fd->step),
3078                                        true, NULL_TREE,
3079                                        true, BSI_SAME_STMT);
3080   fd->chunk_size
3081           = force_gimple_operand_bsi (&si, fold_convert (type,
3082                                                          fd->chunk_size),
3083                                       true, NULL_TREE,
3084                                       true, BSI_SAME_STMT);
3085
3086   t = build_int_cst (type, (fd->cond_code == LT_EXPR ? -1 : 1));
3087   t = fold_build2 (PLUS_EXPR, type, fd->step, t);
3088   t = fold_build2 (PLUS_EXPR, type, t, fd->n2);
3089   t = fold_build2 (MINUS_EXPR, type, t, fd->n1);
3090   t = fold_build2 (TRUNC_DIV_EXPR, type, t, fd->step);
3091   t = fold_convert (type, t);
3092   n = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
3093                                 true, BSI_SAME_STMT);
3094
3095   trip_var = create_tmp_var (type, ".trip");
3096   if (gimple_in_ssa_p (cfun))
3097     {
3098       add_referenced_var (trip_var);
3099       trip_init = make_ssa_name (trip_var, NULL_TREE);
3100       trip_main = make_ssa_name (trip_var, NULL_TREE);
3101       trip_back = make_ssa_name (trip_var, NULL_TREE);
3102     }
3103   else
3104     {
3105       trip_init = trip_var;
3106       trip_main = trip_var;
3107       trip_back = trip_var;
3108     }
3109
3110   t = build_gimple_modify_stmt (trip_init, build_int_cst (type, 0));
3111   bsi_insert_before (&si, t, BSI_SAME_STMT);
3112   if (gimple_in_ssa_p (cfun))
3113     SSA_NAME_DEF_STMT (trip_init) = t;
3114
3115   t = fold_build2 (MULT_EXPR, type, threadid, fd->chunk_size);
3116   t = fold_build2 (MULT_EXPR, type, t, fd->step);
3117   t = fold_build2 (PLUS_EXPR, type, t, fd->n1);
3118   v_extra = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
3119                                       true, BSI_SAME_STMT);
3120
3121   /* Remove the OMP_FOR.  */
3122   bsi_remove (&si, true);
3123
3124   /* Iteration space partitioning goes in ITER_PART_BB.  */
3125   si = bsi_last (iter_part_bb);
3126
3127   t = fold_build2 (MULT_EXPR, type, trip_main, nthreads);
3128   t = fold_build2 (PLUS_EXPR, type, t, threadid);
3129   t = fold_build2 (MULT_EXPR, type, t, fd->chunk_size);
3130   s0 = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
3131                                  false, BSI_CONTINUE_LINKING);
3132
3133   t = fold_build2 (PLUS_EXPR, type, s0, fd->chunk_size);
3134   t = fold_build2 (MIN_EXPR, type, t, n);
3135   e0 = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
3136                                  false, BSI_CONTINUE_LINKING);
3137
3138   t = build2 (LT_EXPR, boolean_type_node, s0, n);
3139   t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
3140   bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
3141
3142   /* Setup code for sequential iteration goes in SEQ_START_BB.  */
3143   si = bsi_start (seq_start_bb);
3144
3145   t = fold_convert (type, s0);
3146   t = fold_build2 (MULT_EXPR, type, t, fd->step);
3147   t = fold_build2 (PLUS_EXPR, type, t, fd->n1);
3148   t = force_gimple_operand_bsi (&si, t, false, NULL_TREE,
3149                                 false, BSI_CONTINUE_LINKING);
3150   t = build_gimple_modify_stmt (fd->v, t);
3151   bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
3152   if (gimple_in_ssa_p (cfun))
3153     SSA_NAME_DEF_STMT (fd->v) = t;
3154
3155   t = fold_convert (type, e0);
3156   t = fold_build2 (MULT_EXPR, type, t, fd->step);
3157   t = fold_build2 (PLUS_EXPR, type, t, fd->n1);
3158   e = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
3159                                 false, BSI_CONTINUE_LINKING);
3160
3161   /* The code controlling the sequential loop goes in CONT_BB,
3162      replacing the OMP_CONTINUE.  */
3163   si = bsi_last (cont_bb);
3164   cont = bsi_stmt (si);
3165   gcc_assert (TREE_CODE (cont) == OMP_CONTINUE);
3166   v_main = TREE_OPERAND (cont, 1);
3167   v_back = TREE_OPERAND (cont, 0);
3168
3169   t = build2 (PLUS_EXPR, type, v_main, fd->step);
3170   t = build_gimple_modify_stmt (v_back, t);
3171   bsi_insert_before (&si, t, BSI_SAME_STMT);
3172   if (gimple_in_ssa_p (cfun))
3173     SSA_NAME_DEF_STMT (v_back) = t;
3174
3175   t = build2 (fd->cond_code, boolean_type_node, v_back, e);
3176   t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
3177   bsi_insert_before (&si, t, BSI_SAME_STMT);
3178   
3179   /* Remove OMP_CONTINUE.  */
3180   bsi_remove (&si, true);
3181
3182   /* Trip update code goes into TRIP_UPDATE_BB.  */
3183   si = bsi_start (trip_update_bb);
3184
3185   t = build_int_cst (type, 1);
3186   t = build2 (PLUS_EXPR, type, trip_main, t);
3187   t = build_gimple_modify_stmt (trip_back, t);
3188   bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
3189   if (gimple_in_ssa_p (cfun))
3190     SSA_NAME_DEF_STMT (trip_back) = t;
3191
3192   /* Replace the OMP_RETURN with a barrier, or nothing.  */
3193   si = bsi_last (exit_bb);
3194   if (!OMP_RETURN_NOWAIT (bsi_stmt (si)))
3195     force_gimple_operand_bsi (&si, build_omp_barrier (), false, NULL_TREE,
3196                               false, BSI_SAME_STMT);
3197   bsi_remove (&si, true);
3198
3199   /* Connect the new blocks.  */
3200   find_edge (iter_part_bb, seq_start_bb)->flags = EDGE_TRUE_VALUE;
3201   find_edge (iter_part_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
3202
3203   find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
3204   find_edge (cont_bb, trip_update_bb)->flags = EDGE_FALSE_VALUE;
3205
3206   redirect_edge_and_branch (single_succ_edge (trip_update_bb), iter_part_bb);
3207
3208   if (gimple_in_ssa_p (cfun))
3209     {
3210       /* When we redirect the edge from trip_update_bb to iter_part_bb, we
3211          remove arguments of the phi nodes in fin_bb.  We need to create
3212          appropriate phi nodes in iter_part_bb instead.  */
3213       se = single_pred_edge (fin_bb);
3214       re = single_succ_edge (trip_update_bb);
3215       ene = single_succ_edge (entry_bb);
3216
3217       args = PENDING_STMT (re);
3218       PENDING_STMT (re) = NULL_TREE;
3219       for (phi = phi_nodes (fin_bb);
3220            phi && args;
3221            phi = PHI_CHAIN (phi), args = TREE_CHAIN (args))
3222         {
3223           t = PHI_RESULT (phi);
3224           gcc_assert (t == TREE_PURPOSE (args));
3225           nphi = create_phi_node (t, iter_part_bb);
3226           SSA_NAME_DEF_STMT (t) = nphi;
3227
3228           t = PHI_ARG_DEF_FROM_EDGE (phi, se);
3229           /* A special case -- fd->v is not yet computed in iter_part_bb, we
3230              need to use v_extra instead.  */
3231           if (t == fd->v)
3232             t = v_extra;
3233           add_phi_arg (nphi, t, ene);
3234           add_phi_arg (nphi, TREE_VALUE (args), re);
3235         }
3236       gcc_assert (!phi && !args);
3237       while ((phi = phi_nodes (fin_bb)) != NULL_TREE)
3238         remove_phi_node (phi, NULL_TREE, false);
3239
3240       /* Make phi node for trip.  */
3241       phi = create_phi_node (trip_main, iter_part_bb);
3242       SSA_NAME_DEF_STMT (trip_main) = phi;
3243       add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb));
3244       add_phi_arg (phi, trip_init, single_succ_edge (entry_bb));
3245     }
3246
3247   set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
3248   set_immediate_dominator (CDI_DOMINATORS, iter_part_bb,
3249                            recompute_dominator (CDI_DOMINATORS, iter_part_bb));
3250   set_immediate_dominator (CDI_DOMINATORS, fin_bb,
3251                            recompute_dominator (CDI_DOMINATORS, fin_bb));
3252   set_immediate_dominator (CDI_DOMINATORS, seq_start_bb,
3253                            recompute_dominator (CDI_DOMINATORS, seq_start_bb));
3254   set_immediate_dominator (CDI_DOMINATORS, body_bb,
3255                            recompute_dominator (CDI_DOMINATORS, body_bb));
3256 }
3257
3258
3259 /* Expand the OpenMP loop defined by REGION.  */
3260
3261 static void
3262 expand_omp_for (struct omp_region *region)
3263 {
3264   struct omp_for_data fd;
3265
3266   extract_omp_for_data (last_stmt (region->entry), &fd);
3267   region->sched_kind = fd.sched_kind;
3268
3269   if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
3270       && !fd.have_ordered
3271       && region->cont != NULL)
3272     {
3273       if (fd.chunk_size == NULL)
3274         expand_omp_for_static_nochunk (region, &fd);
3275       else
3276         expand_omp_for_static_chunk (region, &fd);
3277     }
3278   else
3279     {
3280       int fn_index = fd.sched_kind + fd.have_ordered * 4;
3281       int start_ix = BUILT_IN_GOMP_LOOP_STATIC_START + fn_index;
3282       int next_ix = BUILT_IN_GOMP_LOOP_STATIC_NEXT + fn_index;
3283       expand_omp_for_generic (region, &fd, start_ix, next_ix);
3284     }
3285 }
3286
3287
3288 /* Expand code for an OpenMP sections directive.  In pseudo code, we generate
3289
3290         v = GOMP_sections_start (n);
3291     L0:
3292         switch (v)
3293           {
3294           case 0:
3295             goto L2;
3296           case 1:
3297             section 1;
3298             goto L1;
3299           case 2:
3300             ...
3301           case n:
3302             ...
3303           default:
3304             abort ();
3305           }
3306     L1:
3307         v = GOMP_sections_next ();
3308         goto L0;
3309     L2:
3310         reduction;
3311
3312     If this is a combined parallel sections, replace the call to
3313     GOMP_sections_start with call to GOMP_sections_next.  */
3314
3315 static void
3316 expand_omp_sections (struct omp_region *region)
3317 {
3318   tree label_vec, l1, l2, t, u, sections_stmt, vin, vmain, vnext, cont;
3319   unsigned i, casei, len;
3320   basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
3321   block_stmt_iterator si;
3322   struct omp_region *inner;
3323   bool exit_reachable = region->cont != NULL;
3324
3325   gcc_assert (exit_reachable == (region->exit != NULL));
3326   entry_bb = region->entry;
3327   l0_bb = single_succ (entry_bb);
3328   l1_bb = region->cont;
3329   l2_bb = region->exit;
3330   if (exit_reachable)
3331     {
3332       gcc_assert (single_pred (l2_bb) == l0_bb);
3333       default_bb = create_empty_bb (l1_bb->prev_bb);
3334       l1 = tree_block_label (l1_bb);
3335       l2 = tree_block_label (l2_bb);
3336     }
3337   else
3338     {
3339       default_bb = create_empty_bb (l0_bb);
3340       l1 = NULL_TREE;
3341       l2 = tree_block_label (default_bb);
3342     }
3343
3344   /* We will build a switch() with enough cases for all the
3345      OMP_SECTION regions, a '0' case to handle the end of more work
3346      and a default case to abort if something goes wrong.  */
3347   len = EDGE_COUNT (l0_bb->succs);
3348   label_vec = make_tree_vec (len + 1);
3349
3350   /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
3351      OMP_SECTIONS statement.  */
3352   si = bsi_last (entry_bb);
3353   sections_stmt = bsi_stmt (si);
3354   gcc_assert (TREE_CODE (sections_stmt) == OMP_SECTIONS);
3355   vin = OMP_SECTIONS_CONTROL (sections_stmt);
3356   if (!is_combined_parallel (region))
3357     {
3358       /* If we are not inside a combined parallel+sections region,
3359          call GOMP_sections_start.  */
3360       t = build_int_cst (unsigned_type_node,
3361                          exit_reachable ? len - 1 : len);
3362       u = built_in_decls[BUILT_IN_GOMP_SECTIONS_START];
3363       t = build_call_expr (u, 1, t);
3364     }
3365   else
3366     {
3367       /* Otherwise, call GOMP_sections_next.  */
3368       u = built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT];
3369       t = build_call_expr (u, 0);
3370     }
3371   t = build_gimple_modify_stmt (vin, t);
3372   bsi_insert_after (&si, t, BSI_SAME_STMT);
3373   if (gimple_in_ssa_p (cfun))
3374     SSA_NAME_DEF_STMT (vin) = t;
3375   bsi_remove (&si, true);
3376
3377   /* The switch() statement replacing OMP_SECTIONS_SWITCH goes in L0_BB.  */
3378   si = bsi_last (l0_bb);
3379   gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SECTIONS_SWITCH);
3380   if (exit_reachable)
3381     {
3382       cont = last_stmt (l1_bb);
3383       gcc_assert (TREE_CODE (cont) == OMP_CONTINUE);
3384       vmain = TREE_OPERAND (cont, 1);
3385       vnext = TREE_OPERAND (cont, 0);
3386     }
3387   else
3388     {
3389       vmain = vin;
3390       vnext = NULL_TREE;
3391     }
3392
3393   t = build3 (SWITCH_EXPR, void_type_node, vmain, NULL, label_vec);
3394   bsi_insert_after (&si, t, BSI_SAME_STMT);
3395   bsi_remove (&si, true);
3396
3397   i = 0;
3398   if (exit_reachable)
3399     {
3400       t = build3 (CASE_LABEL_EXPR, void_type_node,
3401                   build_int_cst (unsigned_type_node, 0), NULL, l2);
3402       TREE_VEC_ELT (label_vec, 0) = t;
3403       i++;
3404     }
3405
3406   /* Convert each OMP_SECTION into a CASE_LABEL_EXPR.  */
3407   for (inner = region->inner, casei = 1;
3408        inner;
3409        inner = inner->next, i++, casei++)
3410     {
3411       basic_block s_entry_bb, s_exit_bb;
3412
3413       s_entry_bb = inner->entry;
3414       s_exit_bb = inner->exit;
3415
3416       t = tree_block_label (s_entry_bb);
3417       u = build_int_cst (unsigned_type_node, casei);
3418       u = build3 (CASE_LABEL_EXPR, void_type_node, u, NULL, t);
3419       TREE_VEC_ELT (label_vec, i) = u;
3420
3421       si = bsi_last (s_entry_bb);
3422       gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SECTION);
3423       gcc_assert (i < len || OMP_SECTION_LAST (bsi_stmt (si)));
3424       bsi_remove (&si, true);
3425       single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
3426
3427       if (s_exit_bb == NULL)
3428         continue;
3429
3430       si = bsi_last (s_exit_bb);
3431       gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
3432       bsi_remove (&si, true);
3433
3434       single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
3435     }
3436
3437   /* Error handling code goes in DEFAULT_BB.  */
3438   t = tree_block_label (default_bb);
3439   u = build3 (CASE_LABEL_EXPR, void_type_node, NULL, NULL, t);
3440   TREE_VEC_ELT (label_vec, len) = u;
3441   make_edge (l0_bb, default_bb, 0);
3442
3443   si = bsi_start (default_bb);
3444   t = build_call_expr (built_in_decls[BUILT_IN_TRAP], 0);
3445   bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
3446
3447   if (exit_reachable)
3448     {
3449       /* Code to get the next section goes in L1_BB.  */
3450       si = bsi_last (l1_bb);
3451       gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
3452
3453       t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT], 0);
3454       t = build_gimple_modify_stmt (vnext, t);
3455       bsi_insert_after (&si, t, BSI_SAME_STMT);
3456       if (gimple_in_ssa_p (cfun))
3457         SSA_NAME_DEF_STMT (vnext) = t;
3458       bsi_remove (&si, true);
3459
3460       single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
3461
3462       /* Cleanup function replaces OMP_RETURN in EXIT_BB.  */
3463       si = bsi_last (l2_bb);
3464       if (OMP_RETURN_NOWAIT (bsi_stmt (si)))
3465         t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END_NOWAIT];
3466       else
3467         t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END];
3468       t = build_call_expr (t, 0);
3469       bsi_insert_after (&si, t, BSI_SAME_STMT);
3470       bsi_remove (&si, true);
3471     }
3472
3473   set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb);
3474 }
3475
3476
3477 /* Expand code for an OpenMP single directive.  We've already expanded
3478    much of the code, here we simply place the GOMP_barrier call.  */
3479
3480 static void
3481 expand_omp_single (struct omp_region *region)
3482 {
3483   basic_block entry_bb, exit_bb;
3484   block_stmt_iterator si;
3485   bool need_barrier = false;
3486
3487   entry_bb = region->entry;
3488   exit_bb = region->exit;
3489
3490   si = bsi_last (entry_bb);
3491   /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
3492      be removed.  We need to ensure that the thread that entered the single
3493      does not exit before the data is copied out by the other threads.  */
3494   if (find_omp_clause (OMP_SINGLE_CLAUSES (bsi_stmt (si)),
3495                        OMP_CLAUSE_COPYPRIVATE))
3496     need_barrier = true;
3497   gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SINGLE);
3498   bsi_remove (&si, true);
3499   single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3500
3501   si = bsi_last (exit_bb);
3502   if (!OMP_RETURN_NOWAIT (bsi_stmt (si)) || need_barrier)
3503     force_gimple_operand_bsi (&si, build_omp_barrier (), false, NULL_TREE,
3504                               false, BSI_SAME_STMT);
3505   bsi_remove (&si, true);
3506   single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
3507 }
3508
3509
3510 /* Generic expansion for OpenMP synchronization directives: master,
3511    ordered and critical.  All we need to do here is remove the entry
3512    and exit markers for REGION.  */
3513
3514 static void
3515 expand_omp_synch (struct omp_region *region)
3516 {
3517   basic_block entry_bb, exit_bb;
3518   block_stmt_iterator si;
3519
3520   entry_bb = region->entry;
3521   exit_bb = region->exit;
3522
3523   si = bsi_last (entry_bb);
3524   gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SINGLE
3525               || TREE_CODE (bsi_stmt (si)) == OMP_MASTER
3526               || TREE_CODE (bsi_stmt (si)) == OMP_ORDERED
3527               || TREE_CODE (bsi_stmt (si)) == OMP_CRITICAL);
3528   bsi_remove (&si, true);
3529   single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3530
3531   if (exit_bb)
3532     {
3533       si = bsi_last (exit_bb);
3534       gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
3535       bsi_remove (&si, true);
3536       single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
3537     }
3538 }
3539
3540
3541 /* Expand the parallel region tree rooted at REGION.  Expansion
3542    proceeds in depth-first order.  Innermost regions are expanded
3543    first.  This way, parallel regions that require a new function to
3544    be created (e.g., OMP_PARALLEL) can be expanded without having any
3545    internal dependencies in their body.  */
3546
3547 static void
3548 expand_omp (struct omp_region *region)
3549 {
3550   while (region)
3551     {
3552       if (region->inner)
3553         expand_omp (region->inner);
3554
3555       switch (region->type)
3556         {
3557         case OMP_PARALLEL:
3558           expand_omp_parallel (region);
3559           break;
3560
3561         case OMP_FOR:
3562           expand_omp_for (region);
3563           break;
3564
3565         case OMP_SECTIONS:
3566           expand_omp_sections (region);
3567           break;
3568
3569         case OMP_SECTION:
3570           /* Individual omp sections are handled together with their
3571              parent OMP_SECTIONS region.  */
3572           break;
3573
3574         case OMP_SINGLE:
3575           expand_omp_single (region);
3576           break;
3577
3578         case OMP_MASTER:
3579         case OMP_ORDERED:
3580         case OMP_CRITICAL:
3581           expand_omp_synch (region);
3582           break;
3583
3584         default:
3585           gcc_unreachable ();
3586         }
3587
3588       region = region->next;
3589     }
3590 }
3591
3592
3593 /* Helper for build_omp_regions.  Scan the dominator tree starting at
3594    block BB.  PARENT is the region that contains BB.  */
3595
3596 static void
3597 build_omp_regions_1 (basic_block bb, struct omp_region *parent)
3598 {
3599   block_stmt_iterator si;
3600   tree stmt;
3601   basic_block son;
3602
3603   si = bsi_last (bb);
3604   if (!bsi_end_p (si) && OMP_DIRECTIVE_P (bsi_stmt (si)))
3605     {
3606       struct omp_region *region;
3607       enum tree_code code;
3608
3609       stmt = bsi_stmt (si);
3610       code = TREE_CODE (stmt);
3611
3612       if (code == OMP_RETURN)
3613         {
3614           /* STMT is the return point out of region PARENT.  Mark it
3615              as the exit point and make PARENT the immediately
3616              enclosing region.  */
3617           gcc_assert (parent);
3618           region = parent;
3619           region->exit = bb;
3620           parent = parent->outer;
3621
3622           /* If REGION is a parallel region, determine whether it is
3623              a combined parallel+workshare region.  */
3624           if (region->type == OMP_PARALLEL)
3625             determine_parallel_type (region);
3626         }
3627       else if (code == OMP_CONTINUE)
3628         {
3629           gcc_assert (parent);
3630           parent->cont = bb;
3631         }
3632       else if (code == OMP_SECTIONS_SWITCH)
3633         {
3634           /* OMP_SECTIONS_SWITCH is part of OMP_SECTIONS, and we do nothing for
3635              it.  */
3636         }
3637       else
3638         {
3639           /* Otherwise, this directive becomes the parent for a new
3640              region.  */
3641           region = new_omp_region (bb, code, parent);
3642           parent = region;
3643         }
3644     }
3645
3646   for (son = first_dom_son (CDI_DOMINATORS, bb);
3647        son;
3648        son = next_dom_son (CDI_DOMINATORS, son))
3649     build_omp_regions_1 (son, parent);
3650 }
3651
3652
3653 /* Scan the CFG and build a tree of OMP regions.  Return the root of
3654    the OMP region tree.  */
3655
3656 static void
3657 build_omp_regions (void)
3658 {
3659   gcc_assert (root_omp_region == NULL);
3660   calculate_dominance_info (CDI_DOMINATORS);
3661   build_omp_regions_1 (ENTRY_BLOCK_PTR, NULL);
3662 }
3663
3664
3665 /* Main entry point for expanding OMP-GIMPLE into runtime calls.  */
3666
3667 static unsigned int
3668 execute_expand_omp (void)
3669 {
3670   build_omp_regions ();
3671
3672   if (!root_omp_region)
3673     return 0;
3674
3675   if (dump_file)
3676     {
3677       fprintf (dump_file, "\nOMP region tree\n\n");
3678       dump_omp_region (dump_file, root_omp_region, 0);
3679       fprintf (dump_file, "\n");
3680     }
3681
3682   remove_exit_barriers (root_omp_region);
3683
3684   expand_omp (root_omp_region);
3685
3686   cleanup_tree_cfg ();
3687
3688   free_omp_regions ();
3689
3690   return 0;
3691 }
3692
3693 /* OMP expansion in SSA form.  For testing purposes only.  */
3694
3695 static bool
3696 gate_expand_omp_ssa (void)
3697 {
3698   return flag_openmp_ssa && flag_openmp != 0 && errorcount == 0;
3699 }
3700
3701 struct tree_opt_pass pass_expand_omp_ssa = 
3702 {
3703   "ompexpssa",                          /* name */
3704   gate_expand_omp_ssa,                  /* gate */
3705   execute_expand_omp,                   /* execute */
3706   NULL,                                 /* sub */
3707   NULL,                                 /* next */
3708   0,                                    /* static_pass_number */
3709   0,                                    /* tv_id */
3710   PROP_gimple_any,                      /* properties_required */
3711   PROP_gimple_lomp,                     /* properties_provided */
3712   0,                                    /* properties_destroyed */
3713   0,                                    /* todo_flags_start */
3714   TODO_dump_func,                       /* todo_flags_finish */
3715   0                                     /* letter */
3716 };
3717
3718 /* OMP expansion -- the default pass, run before creation of SSA form.  */
3719
3720 static bool
3721 gate_expand_omp (void)
3722 {
3723   return ((!flag_openmp_ssa || !optimize)
3724           && flag_openmp != 0 && errorcount == 0);
3725 }
3726
3727 struct tree_opt_pass pass_expand_omp = 
3728 {
3729   "ompexp",                             /* name */
3730   gate_expand_omp,                      /* gate */
3731   execute_expand_omp,                   /* execute */
3732   NULL,                                 /* sub */
3733   NULL,                                 /* next */
3734   0,                                    /* static_pass_number */
3735   0,                                    /* tv_id */
3736   PROP_gimple_any,                      /* properties_required */
3737   PROP_gimple_lomp,                     /* properties_provided */
3738   0,                                    /* properties_destroyed */
3739   0,                                    /* todo_flags_start */
3740   TODO_dump_func,                       /* todo_flags_finish */
3741   0                                     /* letter */
3742 };
3743 \f
3744 /* Routines to lower OpenMP directives into OMP-GIMPLE.  */
3745
3746 /* Lower the OpenMP sections directive in *STMT_P.  */
3747
3748 static void
3749 lower_omp_sections (tree *stmt_p, omp_context *ctx)
3750 {
3751   tree new_stmt, stmt, body, bind, block, ilist, olist, new_body, control;
3752   tree t, dlist;
3753   tree_stmt_iterator tsi;
3754   unsigned i, len;
3755
3756   stmt = *stmt_p;
3757
3758   push_gimplify_context ();
3759
3760   dlist = NULL;
3761   ilist = NULL;
3762   lower_rec_input_clauses (OMP_SECTIONS_CLAUSES (stmt), &ilist, &dlist, ctx);
3763
3764   tsi = tsi_start (OMP_SECTIONS_BODY (stmt));
3765   for (len = 0; !tsi_end_p (tsi); len++, tsi_next (&tsi))
3766     continue;
3767
3768   tsi = tsi_start (OMP_SECTIONS_BODY (stmt));
3769   body = alloc_stmt_list ();
3770   for (i = 0; i < len; i++, tsi_next (&tsi))
3771     {
3772       omp_context *sctx;
3773       tree sec_start, sec_end;
3774
3775       sec_start = tsi_stmt (tsi);
3776       sctx = maybe_lookup_ctx (sec_start);
3777       gcc_assert (sctx);
3778
3779       append_to_statement_list (sec_start, &body);
3780
3781       lower_omp (&OMP_SECTION_BODY (sec_start), sctx);
3782       append_to_statement_list (OMP_SECTION_BODY (sec_start), &body);
3783       OMP_SECTION_BODY (sec_start) = NULL;
3784
3785       if (i == len - 1)
3786         {
3787           tree l = alloc_stmt_list ();
3788           lower_lastprivate_clauses (OMP_SECTIONS_CLAUSES (stmt), NULL,
3789                                      &l, ctx);
3790           append_to_statement_list (l, &body);
3791           OMP_SECTION_LAST (sec_start) = 1;
3792         }
3793       
3794       sec_end = make_node (OMP_RETURN);
3795       append_to_statement_list (sec_end, &body);
3796     }
3797
3798   block = make_node (BLOCK);
3799   bind = build3 (BIND_EXPR, void_type_node, NULL, body, block);
3800
3801   olist = NULL_TREE;
3802   lower_reduction_clauses (OMP_SECTIONS_CLAUSES (stmt), &olist, ctx);
3803
3804   pop_gimplify_context (NULL_TREE);
3805   record_vars_into (ctx->block_vars, ctx->cb.dst_fn);
3806
3807   new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
3808   TREE_SIDE_EFFECTS (new_stmt) = 1;
3809
3810   new_body = alloc_stmt_list ();
3811   append_to_statement_list (ilist, &new_body);
3812   append_to_statement_list (stmt, &new_body);
3813   append_to_statement_list (make_node (OMP_SECTIONS_SWITCH), &new_body);
3814   append_to_statement_list (bind, &new_body);
3815
3816   control = create_tmp_var (unsigned_type_node, ".section");
3817   t = build2 (OMP_CONTINUE, void_type_node, control, control);
3818   OMP_SECTIONS_CONTROL (stmt) = control;
3819   append_to_statement_list (t, &new_body);
3820
3821   append_to_statement_list (olist, &new_body);
3822   append_to_statement_list (dlist, &new_body);
3823
3824   maybe_catch_exception (&new_body);
3825
3826   t = make_node (OMP_RETURN);
3827   OMP_RETURN_NOWAIT (t) = !!find_omp_clause (OMP_SECTIONS_CLAUSES (stmt),
3828                                              OMP_CLAUSE_NOWAIT);
3829   append_to_statement_list (t, &new_body);
3830
3831   BIND_EXPR_BODY (new_stmt) = new_body;
3832   OMP_SECTIONS_BODY (stmt) = NULL;
3833
3834   *stmt_p = new_stmt;
3835 }
3836
3837
3838 /* A subroutine of lower_omp_single.  Expand the simple form of
3839    an OMP_SINGLE, without a copyprivate clause:
3840
3841         if (GOMP_single_start ())
3842           BODY;
3843         [ GOMP_barrier (); ]    -> unless 'nowait' is present.
3844
3845   FIXME.  It may be better to delay expanding the logic of this until
3846   pass_expand_omp.  The expanded logic may make the job more difficult
3847   to a synchronization analysis pass.  */
3848
3849 static void
3850 lower_omp_single_simple (tree single_stmt, tree *pre_p)
3851 {
3852   tree t;
3853
3854   t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_START], 0);
3855   t = build3 (COND_EXPR, void_type_node, t,
3856               OMP_SINGLE_BODY (single_stmt), NULL);
3857   gimplify_and_add (t, pre_p);
3858 }
3859
3860
3861 /* A subroutine of lower_omp_single.  Expand the simple form of
3862    an OMP_SINGLE, with a copyprivate clause:
3863
3864         #pragma omp single copyprivate (a, b, c)
3865
3866    Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
3867
3868       {
3869         if ((copyout_p = GOMP_single_copy_start ()) == NULL)
3870           {
3871             BODY;
3872             copyout.a = a;
3873             copyout.b = b;
3874             copyout.c = c;
3875             GOMP_single_copy_end (&copyout);
3876           }
3877         else
3878           {
3879             a = copyout_p->a;
3880             b = copyout_p->b;
3881             c = copyout_p->c;
3882           }
3883         GOMP_barrier ();
3884       }
3885
3886   FIXME.  It may be better to delay expanding the logic of this until
3887   pass_expand_omp.  The expanded logic may make the job more difficult
3888   to a synchronization analysis pass.  */
3889
3890 static void
3891 lower_omp_single_copy (tree single_stmt, tree *pre_p, omp_context *ctx)
3892 {
3893   tree ptr_type, t, l0, l1, l2, copyin_seq;
3894
3895   ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
3896
3897   ptr_type = build_pointer_type (ctx->record_type);
3898   ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
3899
3900   l0 = create_artificial_label ();
3901   l1 = create_artificial_label ();
3902   l2 = create_artificial_label ();
3903
3904   t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_START], 0);
3905   t = fold_convert (ptr_type, t);
3906   t = build_gimple_modify_stmt (ctx->receiver_decl, t);
3907   gimplify_and_add (t, pre_p);
3908
3909   t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
3910               build_int_cst (ptr_type, 0));
3911   t = build3 (COND_EXPR, void_type_node, t,
3912               build_and_jump (&l0), build_and_jump (&l1));
3913   gimplify_and_add (t, pre_p);
3914
3915   t = build1 (LABEL_EXPR, void_type_node, l0);
3916   gimplify_and_add (t, pre_p);
3917
3918   append_to_statement_list (OMP_SINGLE_BODY (single_stmt), pre_p);
3919
3920   copyin_seq = NULL;
3921   lower_copyprivate_clauses (OMP_SINGLE_CLAUSES (single_stmt), pre_p,
3922                               &copyin_seq, ctx);
3923
3924   t = build_fold_addr_expr (ctx->sender_decl);
3925   t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_END], 1, t);
3926   gimplify_and_add (t, pre_p);
3927
3928   t = build_and_jump (&l2);
3929   gimplify_and_add (t, pre_p);
3930
3931   t = build1 (LABEL_EXPR, void_type_node, l1);
3932   gimplify_and_add (t, pre_p);
3933
3934   append_to_statement_list (copyin_seq, pre_p);
3935
3936   t = build1 (LABEL_EXPR, void_type_node, l2);
3937   gimplify_and_add (t, pre_p);
3938 }
3939
3940
3941 /* Expand code for an OpenMP single directive.  */
3942
3943 static void
3944 lower_omp_single (tree *stmt_p, omp_context *ctx)
3945 {
3946   tree t, bind, block, single_stmt = *stmt_p, dlist;
3947
3948   push_gimplify_context ();
3949
3950   block = make_node (BLOCK);
3951   *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3952   TREE_SIDE_EFFECTS (bind) = 1;
3953
3954   lower_rec_input_clauses (OMP_SINGLE_CLAUSES (single_stmt),
3955                            &BIND_EXPR_BODY (bind), &dlist, ctx);
3956   lower_omp (&OMP_SINGLE_BODY (single_stmt), ctx);
3957
3958   append_to_statement_list (single_stmt, &BIND_EXPR_BODY (bind));
3959
3960   if (ctx->record_type)
3961     lower_omp_single_copy (single_stmt, &BIND_EXPR_BODY (bind), ctx);
3962   else
3963     lower_omp_single_simple (single_stmt, &BIND_EXPR_BODY (bind));
3964
3965   OMP_SINGLE_BODY (single_stmt) = NULL;
3966
3967   append_to_statement_list (dlist, &BIND_EXPR_BODY (bind));
3968
3969   maybe_catch_exception (&BIND_EXPR_BODY (bind));
3970
3971   t = make_node (OMP_RETURN);
3972   OMP_RETURN_NOWAIT (t) = !!find_omp_clause (OMP_SINGLE_CLAUSES (single_stmt),
3973                                              OMP_CLAUSE_NOWAIT);
3974   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3975
3976   pop_gimplify_context (bind);
3977
3978   BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
3979   BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
3980 }
3981
3982
3983 /* Expand code for an OpenMP master directive.  */
3984
3985 static void
3986 lower_omp_master (tree *stmt_p, omp_context *ctx)
3987 {
3988   tree bind, block, stmt = *stmt_p, lab = NULL, x;
3989
3990   push_gimplify_context ();
3991
3992   block = make_node (BLOCK);
3993   *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3994   TREE_SIDE_EFFECTS (bind) = 1;
3995
3996   append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
3997
3998   x = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
3999   x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
4000   x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
4001   gimplify_and_add (x, &BIND_EXPR_BODY (bind));
4002
4003   lower_omp (&OMP_MASTER_BODY (stmt), ctx);
4004   maybe_catch_exception (&OMP_MASTER_BODY (stmt));
4005   append_to_statement_list (OMP_MASTER_BODY (stmt), &BIND_EXPR_BODY (bind));
4006   OMP_MASTER_BODY (stmt) = NULL;
4007
4008   x = build1 (LABEL_EXPR, void_type_node, lab);
4009   gimplify_and_add (x, &BIND_EXPR_BODY (bind));
4010
4011   x = make_node (OMP_RETURN);
4012   OMP_RETURN_NOWAIT (x) = 1;
4013   append_to_statement_list (x, &BIND_EXPR_BODY (bind));
4014
4015   pop_gimplify_context (bind);
4016
4017   BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
4018   BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
4019 }
4020
4021
4022 /* Expand code for an OpenMP ordered directive.  */
4023
4024 static void
4025 lower_omp_ordered (tree *stmt_p, omp_context *ctx)
4026 {
4027   tree bind, block, stmt = *stmt_p, x;
4028
4029   push_gimplify_context ();
4030
4031   block = make_node (BLOCK);
4032   *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
4033   TREE_SIDE_EFFECTS (bind) = 1;
4034
4035   append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
4036
4037   x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ORDERED_START], 0);
4038   gimplify_and_add (x, &BIND_EXPR_BODY (bind));
4039
4040   lower_omp (&OMP_ORDERED_BODY (stmt), ctx);
4041   maybe_catch_exception (&OMP_ORDERED_BODY (stmt));
4042   append_to_statement_list (OMP_ORDERED_BODY (stmt), &BIND_EXPR_BODY (bind));
4043   OMP_ORDERED_BODY (stmt) = NULL;
4044
4045   x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ORDERED_END], 0);
4046   gimplify_and_add (x, &BIND_EXPR_BODY (bind));
4047
4048   x = make_node (OMP_RETURN);
4049   OMP_RETURN_NOWAIT (x) = 1;
4050   append_to_statement_list (x, &BIND_EXPR_BODY (bind));
4051
4052   pop_gimplify_context (bind);
4053
4054   BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
4055   BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
4056 }
4057
4058
4059 /* Gimplify an OMP_CRITICAL statement.  This is a relatively simple
4060    substitution of a couple of function calls.  But in the NAMED case,
4061    requires that languages coordinate a symbol name.  It is therefore
4062    best put here in common code.  */
4063
4064 static GTY((param1_is (tree), param2_is (tree)))
4065   splay_tree critical_name_mutexes;
4066
4067 static void
4068 lower_omp_critical (tree *stmt_p, omp_context *ctx)
4069 {
4070   tree bind, block, stmt = *stmt_p;
4071   tree t, lock, unlock, name;
4072
4073   name = OMP_CRITICAL_NAME (stmt);
4074   if (name)
4075     {
4076       tree decl;
4077       splay_tree_node n;
4078
4079       if (!critical_name_mutexes)
4080         critical_name_mutexes
4081           = splay_tree_new_ggc (splay_tree_compare_pointers);
4082
4083       n = splay_tree_lookup (critical_name_mutexes, (splay_tree_key) name);
4084       if (n == NULL)
4085         {
4086           char *new_str;
4087
4088           decl = create_tmp_var_raw (ptr_type_node, NULL);
4089
4090           new_str = ACONCAT ((".gomp_critical_user_",
4091                               IDENTIFIER_POINTER (name), NULL));
4092           DECL_NAME (decl) = get_identifier (new_str);
4093           TREE_PUBLIC (decl) = 1;
4094           TREE_STATIC (decl) = 1;
4095           DECL_COMMON (decl) = 1;
4096           DECL_ARTIFICIAL (decl) = 1;
4097           DECL_IGNORED_P (decl) = 1;
4098           varpool_finalize_decl (decl);
4099
4100           splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
4101                              (splay_tree_value) decl);
4102         }
4103       else
4104         decl = (tree) n->value;
4105
4106       lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_START];
4107       lock = build_call_expr (lock, 1, build_fold_addr_expr (decl));
4108
4109       unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_END];
4110       unlock = build_call_expr (unlock, 1, build_fold_addr_expr (decl));
4111     }
4112   else
4113     {
4114       lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_START];
4115       lock = build_call_expr (lock, 0);
4116
4117       unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_END];
4118       unlock = build_call_expr (unlock, 0);
4119     }
4120
4121   push_gimplify_context ();
4122
4123   block = make_node (BLOCK);
4124   *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
4125   TREE_SIDE_EFFECTS (bind) = 1;
4126
4127   append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
4128
4129   gimplify_and_add (lock, &BIND_EXPR_BODY (bind));
4130
4131   lower_omp (&OMP_CRITICAL_BODY (stmt), ctx);
4132   maybe_catch_exception (&OMP_CRITICAL_BODY (stmt));
4133   append_to_statement_list (OMP_CRITICAL_BODY (stmt), &BIND_EXPR_BODY (bind));
4134   OMP_CRITICAL_BODY (stmt) = NULL;
4135
4136   gimplify_and_add (unlock, &BIND_EXPR_BODY (bind));
4137
4138   t = make_node (OMP_RETURN);
4139   OMP_RETURN_NOWAIT (t) = 1;
4140   append_to_statement_list (t, &BIND_EXPR_BODY (bind));
4141
4142   pop_gimplify_context (bind);
4143   BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
4144   BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
4145 }
4146
4147
4148 /* A subroutine of lower_omp_for.  Generate code to emit the predicate
4149    for a lastprivate clause.  Given a loop control predicate of (V
4150    cond N2), we gate the clause on (!(V cond N2)).  The lowered form
4151    is appended to *DLIST, iterator initialization is appended to
4152    *BODY_P.  */
4153
4154 static void
4155 lower_omp_for_lastprivate (struct omp_for_data *fd, tree *body_p,
4156                            tree *dlist, struct omp_context *ctx)
4157 {
4158   tree clauses, cond, stmts, vinit, t;
4159   enum tree_code cond_code;
4160   
4161   cond_code = fd->cond_code;
4162   cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
4163
4164   /* When possible, use a strict equality expression.  This can let VRP
4165      type optimizations deduce the value and remove a copy.  */
4166   if (host_integerp (fd->step, 0))
4167     {
4168       HOST_WIDE_INT step = TREE_INT_CST_LOW (fd->step);
4169       if (step == 1 || step == -1)
4170         cond_code = EQ_EXPR;
4171     }
4172
4173   cond = build2 (cond_code, boolean_type_node, fd->v, fd->n2);
4174
4175   clauses = OMP_FOR_CLAUSES (fd->for_stmt);
4176   stmts = NULL;
4177   lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
4178   if (stmts != NULL)
4179     {
4180       append_to_statement_list (stmts, dlist);
4181
4182       /* Optimize: v = 0; is usually cheaper than v = some_other_constant.  */
4183       vinit = fd->n1;
4184       if (cond_code == EQ_EXPR
4185           && host_integerp (fd->n2, 0)
4186           && ! integer_zerop (fd->n2))
4187         vinit = build_int_cst (TREE_TYPE (fd->v), 0);
4188
4189       /* Initialize the iterator variable, so that threads that don't execute
4190          any iterations don't execute the lastprivate clauses by accident.  */
4191       t = build_gimple_modify_stmt (fd->v, vinit);
4192       gimplify_and_add (t, body_p);
4193     }
4194 }
4195
4196
4197 /* Lower code for an OpenMP loop directive.  */
4198
4199 static void
4200 lower_omp_for (tree *stmt_p, omp_context *ctx)
4201 {
4202   tree t, stmt, ilist, dlist, new_stmt, *body_p, *rhs_p;
4203   struct omp_for_data fd;
4204
4205   stmt = *stmt_p;
4206
4207   push_gimplify_context ();
4208
4209   lower_omp (&OMP_FOR_PRE_BODY (stmt), ctx);
4210   lower_omp (&OMP_FOR_BODY (stmt), ctx);
4211
4212   /* Move declaration of temporaries in the loop body before we make
4213      it go away.  */
4214   if (TREE_CODE (OMP_FOR_BODY (stmt)) == BIND_EXPR)
4215     record_vars_into (BIND_EXPR_VARS (OMP_FOR_BODY (stmt)), ctx->cb.dst_fn);
4216
4217   new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
4218   TREE_SIDE_EFFECTS (new_stmt) = 1;
4219   body_p = &BIND_EXPR_BODY (new_stmt);
4220
4221   /* The pre-body and input clauses go before the lowered OMP_FOR.  */
4222   ilist = NULL;
4223   dlist = NULL;
4224   append_to_statement_list (OMP_FOR_PRE_BODY (stmt), body_p);
4225   lower_rec_input_clauses (OMP_FOR_CLAUSES (stmt), body_p, &dlist, ctx);
4226
4227   /* Lower the header expressions.  At this point, we can assume that
4228      the header is of the form:
4229
4230         #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
4231
4232      We just need to make sure that VAL1, VAL2 and VAL3 are lowered
4233      using the .omp_data_s mapping, if needed.  */
4234   rhs_p = &GIMPLE_STMT_OPERAND (OMP_FOR_INIT (stmt), 1);
4235   if (!is_gimple_min_invariant (*rhs_p))
4236     *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
4237
4238   rhs_p = &TREE_OPERAND (OMP_FOR_COND (stmt), 1);
4239   if (!is_gimple_min_invariant (*rhs_p))
4240     *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
4241
4242   rhs_p = &TREE_OPERAND (GIMPLE_STMT_OPERAND (OMP_FOR_INCR (stmt), 1), 1);
4243   if (!is_gimple_min_invariant (*rhs_p))
4244     *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
4245
4246   /* Once lowered, extract the bounds and clauses.  */
4247   extract_omp_for_data (stmt, &fd);
4248
4249   lower_omp_for_lastprivate (&fd, body_p, &dlist, ctx);
4250
4251   append_to_statement_list (stmt, body_p);
4252
4253   append_to_statement_list (OMP_FOR_BODY (stmt), body_p);
4254
4255   t = build2 (OMP_CONTINUE, void_type_node, fd.v, fd.v);
4256   append_to_statement_list (t, body_p);
4257
4258   /* After the loop, add exit clauses.  */
4259   lower_reduction_clauses (OMP_FOR_CLAUSES (stmt), body_p, ctx);
4260   append_to_statement_list (dlist, body_p);
4261
4262   maybe_catch_exception (body_p);
4263
4264   /* Region exit marker goes at the end of the loop body.  */
4265   t = make_node (OMP_RETURN);
4266   OMP_RETURN_NOWAIT (t) = fd.have_nowait;
4267   append_to_statement_list (t, body_p);
4268
4269   pop_gimplify_context (NULL_TREE);
4270   record_vars_into (ctx->block_vars, ctx->cb.dst_fn);
4271
4272   OMP_FOR_BODY (stmt) = NULL_TREE;
4273   OMP_FOR_PRE_BODY (stmt) = NULL_TREE;
4274   *stmt_p = new_stmt;
4275 }
4276
4277 /* Callback for walk_stmts.  Check if *TP only contains OMP_FOR
4278    or OMP_PARALLEL.  */
4279
4280 static tree
4281 check_combined_parallel (tree *tp, int *walk_subtrees, void *data)
4282 {
4283   struct walk_stmt_info *wi = data;
4284   int *info = wi->info;
4285
4286   *walk_subtrees = 0;
4287   switch (TREE_CODE (*tp))
4288     {
4289     case OMP_FOR:
4290     case OMP_SECTIONS:
4291       *info = *info == 0 ? 1 : -1;
4292       break;
4293     default:
4294       *info = -1;
4295       break;
4296     }
4297   return NULL;
4298 }
4299
4300 /* Lower the OpenMP parallel directive in *STMT_P.  CTX holds context
4301    information for the directive.  */
4302
4303 static void
4304 lower_omp_parallel (tree *stmt_p, omp_context *ctx)
4305 {
4306   tree clauses, par_bind, par_body, new_body, bind;
4307   tree olist, ilist, par_olist, par_ilist;
4308   tree stmt, child_fn, t;
4309
4310   stmt = *stmt_p;
4311
4312   clauses = OMP_PARALLEL_CLAUSES (stmt);
4313   par_bind = OMP_PARALLEL_BODY (stmt);
4314   par_body = BIND_EXPR_BODY (par_bind);
4315   child_fn = ctx->cb.dst_fn;
4316   if (!OMP_PARALLEL_COMBINED (stmt))
4317     {
4318       struct walk_stmt_info wi;
4319       int ws_num = 0;
4320
4321       memset (&wi, 0, sizeof (wi));
4322       wi.callback = check_combined_parallel;
4323       wi.info = &ws_num;
4324       wi.val_only = true;
4325       walk_stmts (&wi, &par_bind);
4326       if (ws_num == 1)
4327         OMP_PARALLEL_COMBINED (stmt) = 1;
4328     }
4329
4330   push_gimplify_context ();
4331
4332   par_olist = NULL_TREE;
4333   par_ilist = NULL_TREE;
4334   lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
4335   lower_omp (&par_body, ctx);
4336   lower_reduction_clauses (clauses, &par_olist, ctx);
4337
4338   /* Declare all the variables created by mapping and the variables
4339      declared in the scope of the parallel body.  */
4340   record_vars_into (ctx->block_vars, child_fn);
4341   record_vars_into (BIND_EXPR_VARS (par_bind), child_fn);
4342
4343   if (ctx->record_type)
4344     {
4345       ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_data_o");
4346       OMP_PARALLEL_DATA_ARG (stmt) = ctx->sender_decl;
4347     }
4348
4349   olist = NULL_TREE;
4350   ilist = NULL_TREE;
4351   lower_send_clauses (clauses, &ilist, &olist, ctx);
4352   lower_send_shared_vars (&ilist, &olist, ctx);
4353
4354   /* Once all the expansions are done, sequence all the different
4355      fragments inside OMP_PARALLEL_BODY.  */
4356   bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
4357   append_to_statement_list (ilist, &BIND_EXPR_BODY (bind));
4358
4359   new_body = alloc_stmt_list ();
4360
4361   if (ctx->record_type)
4362     {
4363       t = build_fold_addr_expr (ctx->sender_decl);
4364       /* fixup_child_record_type might have changed receiver_decl's type.  */
4365       t = fold_convert (TREE_TYPE (ctx->receiver_decl), t);
4366       t = build_gimple_modify_stmt (ctx->receiver_decl, t);
4367       append_to_statement_list (t, &new_body);
4368     }
4369
4370   append_to_statement_list (par_ilist, &new_body);
4371   append_to_statement_list (par_body, &new_body);
4372   append_to_statement_list (par_olist, &new_body);
4373   maybe_catch_exception (&new_body);
4374   t = make_node (OMP_RETURN);
4375   append_to_statement_list (t, &new_body);
4376   OMP_PARALLEL_BODY (stmt) = new_body;
4377
4378   append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
4379   append_to_statement_list (olist, &BIND_EXPR_BODY (bind));
4380
4381   *stmt_p = bind;
4382
4383   pop_gimplify_context (NULL_TREE);
4384 }
4385
4386
4387 /* Pass *TP back through the gimplifier within the context determined by WI.
4388    This handles replacement of DECL_VALUE_EXPR, as well as adjusting the 
4389    flags on ADDR_EXPR.  */
4390
4391 static void
4392 lower_regimplify (tree *tp, struct walk_stmt_info *wi)
4393 {
4394   enum gimplify_status gs;
4395   tree pre = NULL;
4396
4397   if (wi->is_lhs)
4398     gs = gimplify_expr (tp, &pre, NULL, is_gimple_lvalue, fb_lvalue);
4399   else if (wi->val_only)
4400     gs = gimplify_expr (tp, &pre, NULL, is_gimple_val, fb_rvalue);
4401   else
4402     gs = gimplify_expr (tp, &pre, NULL, is_gimple_formal_tmp_var, fb_rvalue);
4403   gcc_assert (gs == GS_ALL_DONE);
4404
4405   if (pre)
4406     tsi_link_before (&wi->tsi, pre, TSI_SAME_STMT);
4407 }
4408
4409 /* Copy EXP into a temporary.  Insert the initialization statement before TSI.  */
4410
4411 static tree
4412 init_tmp_var (tree exp, tree_stmt_iterator *tsi)
4413 {
4414   tree t, stmt;
4415
4416   t = create_tmp_var (TREE_TYPE (exp), NULL);
4417   DECL_GIMPLE_REG_P (t) = 1;
4418   stmt = build_gimple_modify_stmt (t, exp);
4419   SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
4420   tsi_link_before (tsi, stmt, TSI_SAME_STMT);
4421
4422   return t;
4423 }
4424
4425 /* Similarly, but copy from the temporary and insert the statement
4426    after the iterator.  */
4427
4428 static tree
4429 save_tmp_var (tree exp, tree_stmt_iterator *tsi)
4430 {
4431   tree t, stmt;
4432
4433   t = create_tmp_var (TREE_TYPE (exp), NULL);
4434   DECL_GIMPLE_REG_P (t) = 1;
4435   stmt = build_gimple_modify_stmt (exp, t);
4436   SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
4437   tsi_link_after (tsi, stmt, TSI_SAME_STMT);
4438
4439   return t;
4440 }
4441
4442 /* Callback for walk_stmts.  Lower the OpenMP directive pointed by TP.  */
4443
4444 static tree
4445 lower_omp_1 (tree *tp, int *walk_subtrees, void *data)
4446 {
4447   struct walk_stmt_info *wi = data;
4448   omp_context *ctx = wi->info;
4449   tree t = *tp;
4450
4451   /* If we have issued syntax errors, avoid doing any heavy lifting.
4452      Just replace the OpenMP directives with a NOP to avoid
4453      confusing RTL expansion.  */
4454   if (errorcount && OMP_DIRECTIVE_P (*tp))
4455     {
4456       *tp = build_empty_stmt ();
4457       return NULL_TREE;
4458     }
4459
4460   *walk_subtrees = 0;
4461   switch (TREE_CODE (*tp))
4462     {
4463     case OMP_PARALLEL:
4464       ctx = maybe_lookup_ctx (t);
4465       lower_omp_parallel (tp, ctx);
4466       break;
4467
4468     case OMP_FOR:
4469       ctx = maybe_lookup_ctx (t);
4470       gcc_assert (ctx);
4471       lower_omp_for (tp, ctx);
4472       break;
4473
4474     case OMP_SECTIONS:
4475       ctx = maybe_lookup_ctx (t);
4476       gcc_assert (ctx);
4477       lower_omp_sections (tp, ctx);
4478       break;
4479
4480     case OMP_SINGLE:
4481       ctx = maybe_lookup_ctx (t);
4482       gcc_assert (ctx);
4483       lower_omp_single (tp, ctx);
4484       break;
4485
4486     case OMP_MASTER:
4487       ctx = maybe_lookup_ctx (t);
4488       gcc_assert (ctx);
4489       lower_omp_master (tp, ctx);
4490       break;
4491
4492     case OMP_ORDERED:
4493       ctx = maybe_lookup_ctx (t);
4494       gcc_assert (ctx);
4495       lower_omp_ordered (tp, ctx);
4496       break;
4497
4498     case OMP_CRITICAL:
4499       ctx = maybe_lookup_ctx (t);
4500       gcc_assert (ctx);
4501       lower_omp_critical (tp, ctx);
4502       break;
4503
4504     case VAR_DECL:
4505       if (ctx && DECL_HAS_VALUE_EXPR_P (t))
4506         {
4507           lower_regimplify (&t, wi);
4508           if (wi->val_only)
4509             {
4510               if (wi->is_lhs)
4511                 t = save_tmp_var (t, &wi->tsi);
4512               else
4513                 t = init_tmp_var (t, &wi->tsi);
4514             }
4515           *tp = t;
4516         }
4517       break;
4518
4519     case ADDR_EXPR:
4520       if (ctx)
4521         lower_regimplify (tp, wi);
4522       break;
4523
4524     case ARRAY_REF:
4525     case ARRAY_RANGE_REF:
4526     case REALPART_EXPR:
4527     case IMAGPART_EXPR:
4528     case COMPONENT_REF:
4529     case VIEW_CONVERT_EXPR:
4530       if (ctx)
4531         lower_regimplify (tp, wi);
4532       break;
4533
4534     case INDIRECT_REF:
4535       if (ctx)
4536         {
4537           wi->is_lhs = false;
4538           wi->val_only = true;
4539           lower_regimplify (&TREE_OPERAND (t, 0), wi);
4540         }
4541       break;
4542
4543     default:
4544       if (!TYPE_P (t) && !DECL_P (t))
4545         *walk_subtrees = 1;
4546       break;
4547     }
4548
4549   return NULL_TREE;
4550 }
4551
4552 static void
4553 lower_omp (tree *stmt_p, omp_context *ctx)
4554 {
4555   struct walk_stmt_info wi;
4556
4557   memset (&wi, 0, sizeof (wi));
4558   wi.callback = lower_omp_1;
4559   wi.info = ctx;
4560   wi.val_only = true;
4561   wi.want_locations = true;
4562
4563   walk_stmts (&wi, stmt_p);
4564 }
4565 \f
4566 /* Main entry point.  */
4567
4568 static unsigned int
4569 execute_lower_omp (void)
4570 {
4571   all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
4572                                  delete_omp_context);
4573
4574   scan_omp (&DECL_SAVED_TREE (current_function_decl), NULL);
4575   gcc_assert (parallel_nesting_level == 0);
4576
4577   if (all_contexts->root)
4578     lower_omp (&DECL_SAVED_TREE (current_function_decl), NULL);
4579
4580   if (all_contexts)
4581     {
4582       splay_tree_delete (all_contexts);
4583       all_contexts = NULL;
4584     }
4585   return 0;
4586 }
4587
4588 static bool
4589 gate_lower_omp (void)
4590 {
4591   return flag_openmp != 0;
4592 }
4593
4594 struct tree_opt_pass pass_lower_omp = 
4595 {
4596   "omplower",                           /* name */
4597   gate_lower_omp,                       /* gate */
4598   execute_lower_omp,                    /* execute */
4599   NULL,                                 /* sub */
4600   NULL,                                 /* next */
4601   0,                                    /* static_pass_number */
4602   0,                                    /* tv_id */
4603   PROP_gimple_any,                      /* properties_required */
4604   PROP_gimple_lomp,                     /* properties_provided */
4605   0,                                    /* properties_destroyed */
4606   0,                                    /* todo_flags_start */
4607   TODO_dump_func,                       /* todo_flags_finish */
4608   0                                     /* letter */
4609 };
4610 \f
4611 /* The following is a utility to diagnose OpenMP structured block violations.
4612    It is not part of the "omplower" pass, as that's invoked too late.  It
4613    should be invoked by the respective front ends after gimplification.  */
4614
4615 static splay_tree all_labels;
4616
4617 /* Check for mismatched contexts and generate an error if needed.  Return
4618    true if an error is detected.  */
4619
4620 static bool
4621 diagnose_sb_0 (tree *stmt_p, tree branch_ctx, tree label_ctx)
4622 {
4623   bool exit_p = true;
4624
4625   if ((label_ctx ? TREE_VALUE (label_ctx) : NULL) == branch_ctx)
4626     return false;
4627
4628   /* Try to avoid confusing the user by producing and error message
4629      with correct "exit" or "enter" verbage.  We prefer "exit"
4630      unless we can show that LABEL_CTX is nested within BRANCH_CTX.  */
4631   if (branch_ctx == NULL)
4632     exit_p = false;
4633   else
4634     {
4635       while (label_ctx)
4636         {
4637           if (TREE_VALUE (label_ctx) == branch_ctx)
4638             {
4639               exit_p = false;
4640               break;
4641             }
4642           label_ctx = TREE_CHAIN (label_ctx);
4643         }
4644     }
4645
4646   if (exit_p)
4647     error ("invalid exit from OpenMP structured block");
4648   else
4649     error ("invalid entry to OpenMP structured block");
4650
4651   *stmt_p = build_empty_stmt ();
4652   return true;
4653 }
4654
4655 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
4656    where in the tree each label is found.  */
4657
4658 static tree
4659 diagnose_sb_1 (tree *tp, int *walk_subtrees, void *data)
4660 {
4661   struct walk_stmt_info *wi = data;
4662   tree context = (tree) wi->info;
4663   tree inner_context;
4664   tree t = *tp;
4665
4666   *walk_subtrees = 0;
4667   switch (TREE_CODE (t))
4668     {
4669     case OMP_PARALLEL:
4670     case OMP_SECTIONS:
4671     case OMP_SINGLE:
4672       walk_tree (&OMP_CLAUSES (t), diagnose_sb_1, wi, NULL);
4673       /* FALLTHRU */
4674     case OMP_SECTION:
4675     case OMP_MASTER:
4676     case OMP_ORDERED:
4677     case OMP_CRITICAL:
4678       /* The minimal context here is just a tree of statements.  */
4679       inner_context = tree_cons (NULL, t, context);
4680       wi->info = inner_context;
4681       walk_stmts (wi, &OMP_BODY (t));
4682       wi->info = context;
4683       break;
4684
4685     case OMP_FOR:
4686       walk_tree (&OMP_FOR_CLAUSES (t), diagnose_sb_1, wi, NULL);
4687       inner_context = tree_cons (NULL, t, context);
4688       wi->info = inner_context;
4689       walk_tree (&OMP_FOR_INIT (t), diagnose_sb_1, wi, NULL);
4690       walk_tree (&OMP_FOR_COND (t), diagnose_sb_1, wi, NULL);
4691       walk_tree (&OMP_FOR_INCR (t), diagnose_sb_1, wi, NULL);
4692       walk_stmts (wi, &OMP_FOR_PRE_BODY (t));
4693       walk_stmts (wi, &OMP_FOR_BODY (t));
4694       wi->info = context;
4695       break;
4696
4697     case LABEL_EXPR:
4698       splay_tree_insert (all_labels, (splay_tree_key) LABEL_EXPR_LABEL (t),
4699                          (splay_tree_value) context);
4700       break;
4701
4702     default:
4703       break;
4704     }
4705
4706   return NULL_TREE;
4707 }
4708
4709 /* Pass 2: Check each branch and see if its context differs from that of
4710    the destination label's context.  */
4711
4712 static tree
4713 diagnose_sb_2 (tree *tp, int *walk_subtrees, void *data)
4714 {
4715   struct walk_stmt_info *wi = data;
4716   tree context = (tree) wi->info;
4717   splay_tree_node n;
4718   tree t = *tp;
4719
4720   *walk_subtrees = 0;
4721   switch (TREE_CODE (t))
4722     {
4723     case OMP_PARALLEL:
4724     case OMP_SECTIONS:
4725     case OMP_SINGLE:
4726       walk_tree (&OMP_CLAUSES (t), diagnose_sb_2, wi, NULL);
4727       /* FALLTHRU */
4728     case OMP_SECTION:
4729     case OMP_MASTER:
4730     case OMP_ORDERED:
4731     case OMP_CRITICAL:
4732       wi->info = t;
4733       walk_stmts (wi, &OMP_BODY (t));
4734       wi->info = context;
4735       break;
4736
4737     case OMP_FOR:
4738       walk_tree (&OMP_FOR_CLAUSES (t), diagnose_sb_2, wi, NULL);
4739       wi->info = t;
4740       walk_tree (&OMP_FOR_INIT (t), diagnose_sb_2, wi, NULL);
4741       walk_tree (&OMP_FOR_COND (t), diagnose_sb_2, wi, NULL);
4742       walk_tree (&OMP_FOR_INCR (t), diagnose_sb_2, wi, NULL);
4743       walk_stmts (wi, &OMP_FOR_PRE_BODY (t));
4744       walk_stmts (wi, &OMP_FOR_BODY (t));
4745       wi->info = context;
4746       break;
4747
4748     case GOTO_EXPR:
4749       {
4750         tree lab = GOTO_DESTINATION (t);
4751         if (TREE_CODE (lab) != LABEL_DECL)
4752           break;
4753
4754         n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
4755         diagnose_sb_0 (tp, context, n ? (tree) n->value : NULL_TREE);
4756       }
4757       break;
4758
4759     case SWITCH_EXPR:
4760       {
4761         tree vec = SWITCH_LABELS (t);
4762         int i, len = TREE_VEC_LENGTH (vec);
4763         for (i = 0; i < len; ++i)
4764           {
4765             tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
4766             n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
4767             if (diagnose_sb_0 (tp, context, (tree) n->value))
4768               break;
4769           }
4770       }
4771       break;
4772
4773     case RETURN_EXPR:
4774       diagnose_sb_0 (tp, context, NULL_TREE);
4775       break;
4776
4777     default:
4778       break;
4779     }
4780
4781   return NULL_TREE;
4782 }
4783
4784 void
4785 diagnose_omp_structured_block_errors (tree fndecl)
4786 {
4787   tree save_current = current_function_decl;
4788   struct walk_stmt_info wi;
4789
4790   current_function_decl = fndecl;
4791
4792   all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
4793
4794   memset (&wi, 0, sizeof (wi));
4795   wi.callback = diagnose_sb_1;
4796   walk_stmts (&wi, &DECL_SAVED_TREE (fndecl));
4797
4798   memset (&wi, 0, sizeof (wi));
4799   wi.callback = diagnose_sb_2;
4800   wi.want_locations = true;
4801   wi.want_return_expr = true;
4802   walk_stmts (&wi, &DECL_SAVED_TREE (fndecl));
4803
4804   splay_tree_delete (all_labels);
4805   all_labels = NULL;
4806
4807   current_function_decl = save_current;
4808 }
4809
4810 #include "gt-omp-low.h"