OSDN Git Service

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