OSDN Git Service

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