OSDN Git Service

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