OSDN Git Service

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