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