tree-vectorizer.c (vectorize_loops): Do not call mark_virtual_operands_for_renaming.
[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, 2009, 2010, 2011, 2012
7 Free Software Foundation, Inc.
8
9 This file is part of GCC.
10
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 3, or (at your option) any later
14 version.
15
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING3. If not see
23 <http://www.gnu.org/licenses/>. */
24
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tm.h"
29 #include "tree.h"
30 #include "rtl.h"
31 #include "gimple.h"
32 #include "tree-iterator.h"
33 #include "tree-inline.h"
34 #include "langhooks.h"
35 #include "diagnostic-core.h"
36 #include "tree-flow.h"
37 #include "flags.h"
38 #include "function.h"
39 #include "expr.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
48 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
49 phases. The first phase scans the function looking for OMP statements
50 and then for variables that must be replaced to satisfy data sharing
51 clauses. The second phase expands code for the constructs, as well as
52 re-gimplifying things when variables have been replaced with complex
53 expressions.
54
55 Final code generation is done by pass_expand_omp. The flowgraph is
56 scanned for parallel regions which are then moved to a new
57 function, to be invoked by the thread library. */
58
59 /* Context structure. Used to store information about each parallel
60 directive in the code. */
61
62 typedef struct omp_context
63 {
64 /* This field must be at the beginning, as we do "inheritance": Some
65 callback functions for tree-inline.c (e.g., omp_copy_decl)
66 receive a copy_body_data pointer that is up-casted to an
67 omp_context pointer. */
68 copy_body_data cb;
69
70 /* The tree of contexts corresponding to the encountered constructs. */
71 struct omp_context *outer;
72 gimple stmt;
73
74 /* Map variables to fields in a structure that allows communication
75 between sending and receiving threads. */
76 splay_tree field_map;
77 tree record_type;
78 tree sender_decl;
79 tree receiver_decl;
80
81 /* These are used just by task contexts, if task firstprivate fn is
82 needed. srecord_type is used to communicate from the thread
83 that encountered the task construct to task firstprivate fn,
84 record_type is allocated by GOMP_task, initialized by task firstprivate
85 fn and passed to the task body fn. */
86 splay_tree sfield_map;
87 tree srecord_type;
88
89 /* A chain of variables to add to the top-level block surrounding the
90 construct. In the case of a parallel, this is in the child function. */
91 tree block_vars;
92
93 /* What to do with variables with implicitly determined sharing
94 attributes. */
95 enum omp_clause_default_kind default_kind;
96
97 /* Nesting depth of this context. Used to beautify error messages re
98 invalid gotos. The outermost ctx is depth 1, with depth 0 being
99 reserved for the main body of the function. */
100 int depth;
101
102 /* True if this parallel directive is nested within another. */
103 bool is_nested;
104 } omp_context;
105
106
107 struct omp_for_data_loop
108 {
109 tree v, n1, n2, step;
110 enum tree_code cond_code;
111 };
112
113 /* A structure describing the main elements of a parallel loop. */
114
115 struct omp_for_data
116 {
117 struct omp_for_data_loop loop;
118 tree chunk_size;
119 gimple for_stmt;
120 tree pre, iter_type;
121 int collapse;
122 bool have_nowait, have_ordered;
123 enum omp_clause_schedule_kind sched_kind;
124 struct omp_for_data_loop *loops;
125 };
126
127
128 static splay_tree all_contexts;
129 static int taskreg_nesting_level;
130 struct omp_region *root_omp_region;
131 static bitmap task_shared_vars;
132
133 static void scan_omp (gimple_seq *, omp_context *);
134 static tree scan_omp_1_op (tree *, int *, void *);
135
136 #define WALK_SUBSTMTS \
137 case GIMPLE_BIND: \
138 case GIMPLE_TRY: \
139 case GIMPLE_CATCH: \
140 case GIMPLE_EH_FILTER: \
141 case GIMPLE_TRANSACTION: \
142 /* The sub-statements for these should be walked. */ \
143 *handled_ops_p = false; \
144 break;
145
146 /* Convenience function for calling scan_omp_1_op on tree operands. */
147
148 static inline tree
149 scan_omp_op (tree *tp, omp_context *ctx)
150 {
151 struct walk_stmt_info wi;
152
153 memset (&wi, 0, sizeof (wi));
154 wi.info = ctx;
155 wi.want_locations = true;
156
157 return walk_tree (tp, scan_omp_1_op, &wi, NULL);
158 }
159
160 static void lower_omp (gimple_seq *, omp_context *);
161 static tree lookup_decl_in_outer_ctx (tree, omp_context *);
162 static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
163
164 /* Find an OpenMP clause of type KIND within CLAUSES. */
165
166 tree
167 find_omp_clause (tree clauses, enum omp_clause_code kind)
168 {
169 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
170 if (OMP_CLAUSE_CODE (clauses) == kind)
171 return clauses;
172
173 return NULL_TREE;
174 }
175
176 /* Return true if CTX is for an omp parallel. */
177
178 static inline bool
179 is_parallel_ctx (omp_context *ctx)
180 {
181 return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL;
182 }
183
184
185 /* Return true if CTX is for an omp task. */
186
187 static inline bool
188 is_task_ctx (omp_context *ctx)
189 {
190 return gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
191 }
192
193
194 /* Return true if CTX is for an omp parallel or omp task. */
195
196 static inline bool
197 is_taskreg_ctx (omp_context *ctx)
198 {
199 return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL
200 || gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
201 }
202
203
204 /* Return true if REGION is a combined parallel+workshare region. */
205
206 static inline bool
207 is_combined_parallel (struct omp_region *region)
208 {
209 return region->is_combined_parallel;
210 }
211
212
213 /* Extract the header elements of parallel loop FOR_STMT and store
214 them into *FD. */
215
216 static void
217 extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
218 struct omp_for_data_loop *loops)
219 {
220 tree t, var, *collapse_iter, *collapse_count;
221 tree count = NULL_TREE, iter_type = long_integer_type_node;
222 struct omp_for_data_loop *loop;
223 int i;
224 struct omp_for_data_loop dummy_loop;
225 location_t loc = gimple_location (for_stmt);
226
227 fd->for_stmt = for_stmt;
228 fd->pre = NULL;
229 fd->collapse = gimple_omp_for_collapse (for_stmt);
230 if (fd->collapse > 1)
231 fd->loops = loops;
232 else
233 fd->loops = &fd->loop;
234
235 fd->have_nowait = fd->have_ordered = false;
236 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
237 fd->chunk_size = NULL_TREE;
238 collapse_iter = NULL;
239 collapse_count = NULL;
240
241 for (t = gimple_omp_for_clauses (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
242 switch (OMP_CLAUSE_CODE (t))
243 {
244 case OMP_CLAUSE_NOWAIT:
245 fd->have_nowait = true;
246 break;
247 case OMP_CLAUSE_ORDERED:
248 fd->have_ordered = true;
249 break;
250 case OMP_CLAUSE_SCHEDULE:
251 fd->sched_kind = OMP_CLAUSE_SCHEDULE_KIND (t);
252 fd->chunk_size = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t);
253 break;
254 case OMP_CLAUSE_COLLAPSE:
255 if (fd->collapse > 1)
256 {
257 collapse_iter = &OMP_CLAUSE_COLLAPSE_ITERVAR (t);
258 collapse_count = &OMP_CLAUSE_COLLAPSE_COUNT (t);
259 }
260 default:
261 break;
262 }
263
264 /* FIXME: for now map schedule(auto) to schedule(static).
265 There should be analysis to determine whether all iterations
266 are approximately the same amount of work (then schedule(static)
267 is best) or if it varies (then schedule(dynamic,N) is better). */
268 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_AUTO)
269 {
270 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
271 gcc_assert (fd->chunk_size == NULL);
272 }
273 gcc_assert (fd->collapse == 1 || collapse_iter != NULL);
274 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
275 gcc_assert (fd->chunk_size == NULL);
276 else if (fd->chunk_size == NULL)
277 {
278 /* We only need to compute a default chunk size for ordered
279 static loops and dynamic loops. */
280 if (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
281 || fd->have_ordered
282 || fd->collapse > 1)
283 fd->chunk_size = (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
284 ? integer_zero_node : integer_one_node;
285 }
286
287 for (i = 0; i < fd->collapse; i++)
288 {
289 if (fd->collapse == 1)
290 loop = &fd->loop;
291 else if (loops != NULL)
292 loop = loops + i;
293 else
294 loop = &dummy_loop;
295
296
297 loop->v = gimple_omp_for_index (for_stmt, i);
298 gcc_assert (SSA_VAR_P (loop->v));
299 gcc_assert (TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
300 || TREE_CODE (TREE_TYPE (loop->v)) == POINTER_TYPE);
301 var = TREE_CODE (loop->v) == SSA_NAME ? SSA_NAME_VAR (loop->v) : loop->v;
302 loop->n1 = gimple_omp_for_initial (for_stmt, i);
303
304 loop->cond_code = gimple_omp_for_cond (for_stmt, i);
305 loop->n2 = gimple_omp_for_final (for_stmt, i);
306 switch (loop->cond_code)
307 {
308 case LT_EXPR:
309 case GT_EXPR:
310 break;
311 case LE_EXPR:
312 if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
313 loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, 1);
314 else
315 loop->n2 = fold_build2_loc (loc,
316 PLUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
317 build_int_cst (TREE_TYPE (loop->n2), 1));
318 loop->cond_code = LT_EXPR;
319 break;
320 case GE_EXPR:
321 if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
322 loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, -1);
323 else
324 loop->n2 = fold_build2_loc (loc,
325 MINUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
326 build_int_cst (TREE_TYPE (loop->n2), 1));
327 loop->cond_code = GT_EXPR;
328 break;
329 default:
330 gcc_unreachable ();
331 }
332
333 t = gimple_omp_for_incr (for_stmt, i);
334 gcc_assert (TREE_OPERAND (t, 0) == var);
335 switch (TREE_CODE (t))
336 {
337 case PLUS_EXPR:
338 loop->step = TREE_OPERAND (t, 1);
339 break;
340 case POINTER_PLUS_EXPR:
341 loop->step = fold_convert (ssizetype, TREE_OPERAND (t, 1));
342 break;
343 case MINUS_EXPR:
344 loop->step = TREE_OPERAND (t, 1);
345 loop->step = fold_build1_loc (loc,
346 NEGATE_EXPR, TREE_TYPE (loop->step),
347 loop->step);
348 break;
349 default:
350 gcc_unreachable ();
351 }
352
353 if (iter_type != long_long_unsigned_type_node)
354 {
355 if (POINTER_TYPE_P (TREE_TYPE (loop->v)))
356 iter_type = long_long_unsigned_type_node;
357 else if (TYPE_UNSIGNED (TREE_TYPE (loop->v))
358 && TYPE_PRECISION (TREE_TYPE (loop->v))
359 >= TYPE_PRECISION (iter_type))
360 {
361 tree n;
362
363 if (loop->cond_code == LT_EXPR)
364 n = fold_build2_loc (loc,
365 PLUS_EXPR, TREE_TYPE (loop->v),
366 loop->n2, loop->step);
367 else
368 n = loop->n1;
369 if (TREE_CODE (n) != INTEGER_CST
370 || tree_int_cst_lt (TYPE_MAX_VALUE (iter_type), n))
371 iter_type = long_long_unsigned_type_node;
372 }
373 else if (TYPE_PRECISION (TREE_TYPE (loop->v))
374 > TYPE_PRECISION (iter_type))
375 {
376 tree n1, n2;
377
378 if (loop->cond_code == LT_EXPR)
379 {
380 n1 = loop->n1;
381 n2 = fold_build2_loc (loc,
382 PLUS_EXPR, TREE_TYPE (loop->v),
383 loop->n2, loop->step);
384 }
385 else
386 {
387 n1 = fold_build2_loc (loc,
388 MINUS_EXPR, TREE_TYPE (loop->v),
389 loop->n2, loop->step);
390 n2 = loop->n1;
391 }
392 if (TREE_CODE (n1) != INTEGER_CST
393 || TREE_CODE (n2) != INTEGER_CST
394 || !tree_int_cst_lt (TYPE_MIN_VALUE (iter_type), n1)
395 || !tree_int_cst_lt (n2, TYPE_MAX_VALUE (iter_type)))
396 iter_type = long_long_unsigned_type_node;
397 }
398 }
399
400 if (collapse_count && *collapse_count == NULL)
401 {
402 if ((i == 0 || count != NULL_TREE)
403 && TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
404 && TREE_CONSTANT (loop->n1)
405 && TREE_CONSTANT (loop->n2)
406 && TREE_CODE (loop->step) == INTEGER_CST)
407 {
408 tree itype = TREE_TYPE (loop->v);
409
410 if (POINTER_TYPE_P (itype))
411 itype = signed_type_for (itype);
412 t = build_int_cst (itype, (loop->cond_code == LT_EXPR ? -1 : 1));
413 t = fold_build2_loc (loc,
414 PLUS_EXPR, itype,
415 fold_convert_loc (loc, itype, loop->step), t);
416 t = fold_build2_loc (loc, PLUS_EXPR, itype, t,
417 fold_convert_loc (loc, itype, loop->n2));
418 t = fold_build2_loc (loc, MINUS_EXPR, itype, t,
419 fold_convert_loc (loc, itype, loop->n1));
420 if (TYPE_UNSIGNED (itype) && loop->cond_code == GT_EXPR)
421 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
422 fold_build1_loc (loc, NEGATE_EXPR, itype, t),
423 fold_build1_loc (loc, NEGATE_EXPR, itype,
424 fold_convert_loc (loc, itype,
425 loop->step)));
426 else
427 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
428 fold_convert_loc (loc, itype, loop->step));
429 t = fold_convert_loc (loc, long_long_unsigned_type_node, t);
430 if (count != NULL_TREE)
431 count = fold_build2_loc (loc,
432 MULT_EXPR, long_long_unsigned_type_node,
433 count, t);
434 else
435 count = t;
436 if (TREE_CODE (count) != INTEGER_CST)
437 count = NULL_TREE;
438 }
439 else
440 count = NULL_TREE;
441 }
442 }
443
444 if (count)
445 {
446 if (!tree_int_cst_lt (count, TYPE_MAX_VALUE (long_integer_type_node)))
447 iter_type = long_long_unsigned_type_node;
448 else
449 iter_type = long_integer_type_node;
450 }
451 else if (collapse_iter && *collapse_iter != NULL)
452 iter_type = TREE_TYPE (*collapse_iter);
453 fd->iter_type = iter_type;
454 if (collapse_iter && *collapse_iter == NULL)
455 *collapse_iter = create_tmp_var (iter_type, ".iter");
456 if (collapse_count && *collapse_count == NULL)
457 {
458 if (count)
459 *collapse_count = fold_convert_loc (loc, iter_type, count);
460 else
461 *collapse_count = create_tmp_var (iter_type, ".count");
462 }
463
464 if (fd->collapse > 1)
465 {
466 fd->loop.v = *collapse_iter;
467 fd->loop.n1 = build_int_cst (TREE_TYPE (fd->loop.v), 0);
468 fd->loop.n2 = *collapse_count;
469 fd->loop.step = build_int_cst (TREE_TYPE (fd->loop.v), 1);
470 fd->loop.cond_code = LT_EXPR;
471 }
472 }
473
474
475 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
476 is the immediate dominator of PAR_ENTRY_BB, return true if there
477 are no data dependencies that would prevent expanding the parallel
478 directive at PAR_ENTRY_BB as a combined parallel+workshare region.
479
480 When expanding a combined parallel+workshare region, the call to
481 the child function may need additional arguments in the case of
482 GIMPLE_OMP_FOR regions. In some cases, these arguments are
483 computed out of variables passed in from the parent to the child
484 via 'struct .omp_data_s'. For instance:
485
486 #pragma omp parallel for schedule (guided, i * 4)
487 for (j ...)
488
489 Is lowered into:
490
491 # BLOCK 2 (PAR_ENTRY_BB)
492 .omp_data_o.i = i;
493 #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
494
495 # BLOCK 3 (WS_ENTRY_BB)
496 .omp_data_i = &.omp_data_o;
497 D.1667 = .omp_data_i->i;
498 D.1598 = D.1667 * 4;
499 #pragma omp for schedule (guided, D.1598)
500
501 When we outline the parallel region, the call to the child function
502 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
503 that value is computed *after* the call site. So, in principle we
504 cannot do the transformation.
505
506 To see whether the code in WS_ENTRY_BB blocks the combined
507 parallel+workshare call, we collect all the variables used in the
508 GIMPLE_OMP_FOR header check whether they appear on the LHS of any
509 statement in WS_ENTRY_BB. If so, then we cannot emit the combined
510 call.
511
512 FIXME. If we had the SSA form built at this point, we could merely
513 hoist the code in block 3 into block 2 and be done with it. But at
514 this point we don't have dataflow information and though we could
515 hack something up here, it is really not worth the aggravation. */
516
517 static bool
518 workshare_safe_to_combine_p (basic_block ws_entry_bb)
519 {
520 struct omp_for_data fd;
521 gimple ws_stmt = last_stmt (ws_entry_bb);
522
523 if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
524 return true;
525
526 gcc_assert (gimple_code (ws_stmt) == GIMPLE_OMP_FOR);
527
528 extract_omp_for_data (ws_stmt, &fd, NULL);
529
530 if (fd.collapse > 1 && TREE_CODE (fd.loop.n2) != INTEGER_CST)
531 return false;
532 if (fd.iter_type != long_integer_type_node)
533 return false;
534
535 /* FIXME. We give up too easily here. If any of these arguments
536 are not constants, they will likely involve variables that have
537 been mapped into fields of .omp_data_s for sharing with the child
538 function. With appropriate data flow, it would be possible to
539 see through this. */
540 if (!is_gimple_min_invariant (fd.loop.n1)
541 || !is_gimple_min_invariant (fd.loop.n2)
542 || !is_gimple_min_invariant (fd.loop.step)
543 || (fd.chunk_size && !is_gimple_min_invariant (fd.chunk_size)))
544 return false;
545
546 return true;
547 }
548
549
550 /* Collect additional arguments needed to emit a combined
551 parallel+workshare call. WS_STMT is the workshare directive being
552 expanded. */
553
554 static VEC(tree,gc) *
555 get_ws_args_for (gimple ws_stmt)
556 {
557 tree t;
558 location_t loc = gimple_location (ws_stmt);
559 VEC(tree,gc) *ws_args;
560
561 if (gimple_code (ws_stmt) == GIMPLE_OMP_FOR)
562 {
563 struct omp_for_data fd;
564
565 extract_omp_for_data (ws_stmt, &fd, NULL);
566
567 ws_args = VEC_alloc (tree, gc, 3 + (fd.chunk_size != 0));
568
569 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n1);
570 VEC_quick_push (tree, ws_args, t);
571
572 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n2);
573 VEC_quick_push (tree, ws_args, t);
574
575 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.step);
576 VEC_quick_push (tree, ws_args, t);
577
578 if (fd.chunk_size)
579 {
580 t = fold_convert_loc (loc, long_integer_type_node, fd.chunk_size);
581 VEC_quick_push (tree, ws_args, t);
582 }
583
584 return ws_args;
585 }
586 else if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
587 {
588 /* Number of sections is equal to the number of edges from the
589 GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
590 the exit of the sections region. */
591 basic_block bb = single_succ (gimple_bb (ws_stmt));
592 t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
593 ws_args = VEC_alloc (tree, gc, 1);
594 VEC_quick_push (tree, ws_args, t);
595 return ws_args;
596 }
597
598 gcc_unreachable ();
599 }
600
601
602 /* Discover whether REGION is a combined parallel+workshare region. */
603
604 static void
605 determine_parallel_type (struct omp_region *region)
606 {
607 basic_block par_entry_bb, par_exit_bb;
608 basic_block ws_entry_bb, ws_exit_bb;
609
610 if (region == NULL || region->inner == NULL
611 || region->exit == NULL || region->inner->exit == NULL
612 || region->inner->cont == NULL)
613 return;
614
615 /* We only support parallel+for and parallel+sections. */
616 if (region->type != GIMPLE_OMP_PARALLEL
617 || (region->inner->type != GIMPLE_OMP_FOR
618 && region->inner->type != GIMPLE_OMP_SECTIONS))
619 return;
620
621 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
622 WS_EXIT_BB -> PAR_EXIT_BB. */
623 par_entry_bb = region->entry;
624 par_exit_bb = region->exit;
625 ws_entry_bb = region->inner->entry;
626 ws_exit_bb = region->inner->exit;
627
628 if (single_succ (par_entry_bb) == ws_entry_bb
629 && single_succ (ws_exit_bb) == par_exit_bb
630 && workshare_safe_to_combine_p (ws_entry_bb)
631 && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb))
632 || (last_and_only_stmt (ws_entry_bb)
633 && last_and_only_stmt (par_exit_bb))))
634 {
635 gimple ws_stmt = last_stmt (ws_entry_bb);
636
637 if (region->inner->type == GIMPLE_OMP_FOR)
638 {
639 /* If this is a combined parallel loop, we need to determine
640 whether or not to use the combined library calls. There
641 are two cases where we do not apply the transformation:
642 static loops and any kind of ordered loop. In the first
643 case, we already open code the loop so there is no need
644 to do anything else. In the latter case, the combined
645 parallel loop call would still need extra synchronization
646 to implement ordered semantics, so there would not be any
647 gain in using the combined call. */
648 tree clauses = gimple_omp_for_clauses (ws_stmt);
649 tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
650 if (c == NULL
651 || OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_STATIC
652 || find_omp_clause (clauses, OMP_CLAUSE_ORDERED))
653 {
654 region->is_combined_parallel = false;
655 region->inner->is_combined_parallel = false;
656 return;
657 }
658 }
659
660 region->is_combined_parallel = true;
661 region->inner->is_combined_parallel = true;
662 region->ws_args = get_ws_args_for (ws_stmt);
663 }
664 }
665
666
667 /* Return true if EXPR is variable sized. */
668
669 static inline bool
670 is_variable_sized (const_tree expr)
671 {
672 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
673 }
674
675 /* Return true if DECL is a reference type. */
676
677 static inline bool
678 is_reference (tree decl)
679 {
680 return lang_hooks.decls.omp_privatize_by_reference (decl);
681 }
682
683 /* Lookup variables in the decl or field splay trees. The "maybe" form
684 allows for the variable form to not have been entered, otherwise we
685 assert that the variable must have been entered. */
686
687 static inline tree
688 lookup_decl (tree var, omp_context *ctx)
689 {
690 tree *n;
691 n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
692 return *n;
693 }
694
695 static inline tree
696 maybe_lookup_decl (const_tree var, omp_context *ctx)
697 {
698 tree *n;
699 n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
700 return n ? *n : NULL_TREE;
701 }
702
703 static inline tree
704 lookup_field (tree var, omp_context *ctx)
705 {
706 splay_tree_node n;
707 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
708 return (tree) n->value;
709 }
710
711 static inline tree
712 lookup_sfield (tree var, omp_context *ctx)
713 {
714 splay_tree_node n;
715 n = splay_tree_lookup (ctx->sfield_map
716 ? ctx->sfield_map : ctx->field_map,
717 (splay_tree_key) var);
718 return (tree) n->value;
719 }
720
721 static inline tree
722 maybe_lookup_field (tree var, omp_context *ctx)
723 {
724 splay_tree_node n;
725 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
726 return n ? (tree) n->value : NULL_TREE;
727 }
728
729 /* Return true if DECL should be copied by pointer. SHARED_CTX is
730 the parallel context if DECL is to be shared. */
731
732 static bool
733 use_pointer_for_field (tree decl, omp_context *shared_ctx)
734 {
735 if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
736 return true;
737
738 /* We can only use copy-in/copy-out semantics for shared variables
739 when we know the value is not accessible from an outer scope. */
740 if (shared_ctx)
741 {
742 /* ??? Trivially accessible from anywhere. But why would we even
743 be passing an address in this case? Should we simply assert
744 this to be false, or should we have a cleanup pass that removes
745 these from the list of mappings? */
746 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
747 return true;
748
749 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
750 without analyzing the expression whether or not its location
751 is accessible to anyone else. In the case of nested parallel
752 regions it certainly may be. */
753 if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
754 return true;
755
756 /* Do not use copy-in/copy-out for variables that have their
757 address taken. */
758 if (TREE_ADDRESSABLE (decl))
759 return true;
760
761 /* Disallow copy-in/out in nested parallel if
762 decl is shared in outer parallel, otherwise
763 each thread could store the shared variable
764 in its own copy-in location, making the
765 variable no longer really shared. */
766 if (!TREE_READONLY (decl) && shared_ctx->is_nested)
767 {
768 omp_context *up;
769
770 for (up = shared_ctx->outer; up; up = up->outer)
771 if (is_taskreg_ctx (up) && maybe_lookup_decl (decl, up))
772 break;
773
774 if (up)
775 {
776 tree c;
777
778 for (c = gimple_omp_taskreg_clauses (up->stmt);
779 c; c = OMP_CLAUSE_CHAIN (c))
780 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
781 && OMP_CLAUSE_DECL (c) == decl)
782 break;
783
784 if (c)
785 goto maybe_mark_addressable_and_ret;
786 }
787 }
788
789 /* For tasks avoid using copy-in/out, unless they are readonly
790 (in which case just copy-in is used). As tasks can be
791 deferred or executed in different thread, when GOMP_task
792 returns, the task hasn't necessarily terminated. */
793 if (!TREE_READONLY (decl) && is_task_ctx (shared_ctx))
794 {
795 tree outer;
796 maybe_mark_addressable_and_ret:
797 outer = maybe_lookup_decl_in_outer_ctx (decl, shared_ctx);
798 if (is_gimple_reg (outer))
799 {
800 /* Taking address of OUTER in lower_send_shared_vars
801 might need regimplification of everything that uses the
802 variable. */
803 if (!task_shared_vars)
804 task_shared_vars = BITMAP_ALLOC (NULL);
805 bitmap_set_bit (task_shared_vars, DECL_UID (outer));
806 TREE_ADDRESSABLE (outer) = 1;
807 }
808 return true;
809 }
810 }
811
812 return false;
813 }
814
815 /* Create a new VAR_DECL and copy information from VAR to it. */
816
817 tree
818 copy_var_decl (tree var, tree name, tree type)
819 {
820 tree copy = build_decl (DECL_SOURCE_LOCATION (var), VAR_DECL, name, type);
821
822 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
823 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (var);
824 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
825 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
826 DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
827 DECL_CONTEXT (copy) = DECL_CONTEXT (var);
828 TREE_USED (copy) = 1;
829 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
830
831 return copy;
832 }
833
834 /* Construct a new automatic decl similar to VAR. */
835
836 static tree
837 omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
838 {
839 tree copy = copy_var_decl (var, name, type);
840
841 DECL_CONTEXT (copy) = current_function_decl;
842 DECL_CHAIN (copy) = ctx->block_vars;
843 ctx->block_vars = copy;
844
845 return copy;
846 }
847
848 static tree
849 omp_copy_decl_1 (tree var, omp_context *ctx)
850 {
851 return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
852 }
853
854 /* Build COMPONENT_REF and set TREE_THIS_VOLATILE and TREE_READONLY on it
855 as appropriate. */
856 static tree
857 omp_build_component_ref (tree obj, tree field)
858 {
859 tree ret = build3 (COMPONENT_REF, TREE_TYPE (field), obj, field, NULL);
860 if (TREE_THIS_VOLATILE (field))
861 TREE_THIS_VOLATILE (ret) |= 1;
862 if (TREE_READONLY (field))
863 TREE_READONLY (ret) |= 1;
864 return ret;
865 }
866
867 /* Build tree nodes to access the field for VAR on the receiver side. */
868
869 static tree
870 build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
871 {
872 tree x, field = lookup_field (var, ctx);
873
874 /* If the receiver record type was remapped in the child function,
875 remap the field into the new record type. */
876 x = maybe_lookup_field (field, ctx);
877 if (x != NULL)
878 field = x;
879
880 x = build_simple_mem_ref (ctx->receiver_decl);
881 x = omp_build_component_ref (x, field);
882 if (by_ref)
883 x = build_simple_mem_ref (x);
884
885 return x;
886 }
887
888 /* Build tree nodes to access VAR in the scope outer to CTX. In the case
889 of a parallel, this is a component reference; for workshare constructs
890 this is some variable. */
891
892 static tree
893 build_outer_var_ref (tree var, omp_context *ctx)
894 {
895 tree x;
896
897 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
898 x = var;
899 else if (is_variable_sized (var))
900 {
901 x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
902 x = build_outer_var_ref (x, ctx);
903 x = build_simple_mem_ref (x);
904 }
905 else if (is_taskreg_ctx (ctx))
906 {
907 bool by_ref = use_pointer_for_field (var, NULL);
908 x = build_receiver_ref (var, by_ref, ctx);
909 }
910 else if (ctx->outer)
911 x = lookup_decl (var, ctx->outer);
912 else if (is_reference (var))
913 /* This can happen with orphaned constructs. If var is reference, it is
914 possible it is shared and as such valid. */
915 x = var;
916 else
917 gcc_unreachable ();
918
919 if (is_reference (var))
920 x = build_simple_mem_ref (x);
921
922 return x;
923 }
924
925 /* Build tree nodes to access the field for VAR on the sender side. */
926
927 static tree
928 build_sender_ref (tree var, omp_context *ctx)
929 {
930 tree field = lookup_sfield (var, ctx);
931 return omp_build_component_ref (ctx->sender_decl, field);
932 }
933
934 /* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
935
936 static void
937 install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
938 {
939 tree field, type, sfield = NULL_TREE;
940
941 gcc_assert ((mask & 1) == 0
942 || !splay_tree_lookup (ctx->field_map, (splay_tree_key) var));
943 gcc_assert ((mask & 2) == 0 || !ctx->sfield_map
944 || !splay_tree_lookup (ctx->sfield_map, (splay_tree_key) var));
945
946 type = TREE_TYPE (var);
947 if (by_ref)
948 type = build_pointer_type (type);
949 else if ((mask & 3) == 1 && is_reference (var))
950 type = TREE_TYPE (type);
951
952 field = build_decl (DECL_SOURCE_LOCATION (var),
953 FIELD_DECL, DECL_NAME (var), type);
954
955 /* Remember what variable this field was created for. This does have a
956 side effect of making dwarf2out ignore this member, so for helpful
957 debugging we clear it later in delete_omp_context. */
958 DECL_ABSTRACT_ORIGIN (field) = var;
959 if (type == TREE_TYPE (var))
960 {
961 DECL_ALIGN (field) = DECL_ALIGN (var);
962 DECL_USER_ALIGN (field) = DECL_USER_ALIGN (var);
963 TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (var);
964 }
965 else
966 DECL_ALIGN (field) = TYPE_ALIGN (type);
967
968 if ((mask & 3) == 3)
969 {
970 insert_field_into_struct (ctx->record_type, field);
971 if (ctx->srecord_type)
972 {
973 sfield = build_decl (DECL_SOURCE_LOCATION (var),
974 FIELD_DECL, DECL_NAME (var), type);
975 DECL_ABSTRACT_ORIGIN (sfield) = var;
976 DECL_ALIGN (sfield) = DECL_ALIGN (field);
977 DECL_USER_ALIGN (sfield) = DECL_USER_ALIGN (field);
978 TREE_THIS_VOLATILE (sfield) = TREE_THIS_VOLATILE (field);
979 insert_field_into_struct (ctx->srecord_type, sfield);
980 }
981 }
982 else
983 {
984 if (ctx->srecord_type == NULL_TREE)
985 {
986 tree t;
987
988 ctx->srecord_type = lang_hooks.types.make_type (RECORD_TYPE);
989 ctx->sfield_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
990 for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
991 {
992 sfield = build_decl (DECL_SOURCE_LOCATION (var),
993 FIELD_DECL, DECL_NAME (t), TREE_TYPE (t));
994 DECL_ABSTRACT_ORIGIN (sfield) = DECL_ABSTRACT_ORIGIN (t);
995 insert_field_into_struct (ctx->srecord_type, sfield);
996 splay_tree_insert (ctx->sfield_map,
997 (splay_tree_key) DECL_ABSTRACT_ORIGIN (t),
998 (splay_tree_value) sfield);
999 }
1000 }
1001 sfield = field;
1002 insert_field_into_struct ((mask & 1) ? ctx->record_type
1003 : ctx->srecord_type, field);
1004 }
1005
1006 if (mask & 1)
1007 splay_tree_insert (ctx->field_map, (splay_tree_key) var,
1008 (splay_tree_value) field);
1009 if ((mask & 2) && ctx->sfield_map)
1010 splay_tree_insert (ctx->sfield_map, (splay_tree_key) var,
1011 (splay_tree_value) sfield);
1012 }
1013
1014 static tree
1015 install_var_local (tree var, omp_context *ctx)
1016 {
1017 tree new_var = omp_copy_decl_1 (var, ctx);
1018 insert_decl_map (&ctx->cb, var, new_var);
1019 return new_var;
1020 }
1021
1022 /* Adjust the replacement for DECL in CTX for the new context. This means
1023 copying the DECL_VALUE_EXPR, and fixing up the type. */
1024
1025 static void
1026 fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
1027 {
1028 tree new_decl, size;
1029
1030 new_decl = lookup_decl (decl, ctx);
1031
1032 TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
1033
1034 if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
1035 && DECL_HAS_VALUE_EXPR_P (decl))
1036 {
1037 tree ve = DECL_VALUE_EXPR (decl);
1038 walk_tree (&ve, copy_tree_body_r, &ctx->cb, NULL);
1039 SET_DECL_VALUE_EXPR (new_decl, ve);
1040 DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
1041 }
1042
1043 if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
1044 {
1045 size = remap_decl (DECL_SIZE (decl), &ctx->cb);
1046 if (size == error_mark_node)
1047 size = TYPE_SIZE (TREE_TYPE (new_decl));
1048 DECL_SIZE (new_decl) = size;
1049
1050 size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
1051 if (size == error_mark_node)
1052 size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
1053 DECL_SIZE_UNIT (new_decl) = size;
1054 }
1055 }
1056
1057 /* The callback for remap_decl. Search all containing contexts for a
1058 mapping of the variable; this avoids having to duplicate the splay
1059 tree ahead of time. We know a mapping doesn't already exist in the
1060 given context. Create new mappings to implement default semantics. */
1061
1062 static tree
1063 omp_copy_decl (tree var, copy_body_data *cb)
1064 {
1065 omp_context *ctx = (omp_context *) cb;
1066 tree new_var;
1067
1068 if (TREE_CODE (var) == LABEL_DECL)
1069 {
1070 new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
1071 DECL_CONTEXT (new_var) = current_function_decl;
1072 insert_decl_map (&ctx->cb, var, new_var);
1073 return new_var;
1074 }
1075
1076 while (!is_taskreg_ctx (ctx))
1077 {
1078 ctx = ctx->outer;
1079 if (ctx == NULL)
1080 return var;
1081 new_var = maybe_lookup_decl (var, ctx);
1082 if (new_var)
1083 return new_var;
1084 }
1085
1086 if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
1087 return var;
1088
1089 return error_mark_node;
1090 }
1091
1092
1093 /* Return the parallel region associated with STMT. */
1094
1095 /* Debugging dumps for parallel regions. */
1096 void dump_omp_region (FILE *, struct omp_region *, int);
1097 void debug_omp_region (struct omp_region *);
1098 void debug_all_omp_regions (void);
1099
1100 /* Dump the parallel region tree rooted at REGION. */
1101
1102 void
1103 dump_omp_region (FILE *file, struct omp_region *region, int indent)
1104 {
1105 fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
1106 gimple_code_name[region->type]);
1107
1108 if (region->inner)
1109 dump_omp_region (file, region->inner, indent + 4);
1110
1111 if (region->cont)
1112 {
1113 fprintf (file, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent, "",
1114 region->cont->index);
1115 }
1116
1117 if (region->exit)
1118 fprintf (file, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent, "",
1119 region->exit->index);
1120 else
1121 fprintf (file, "%*s[no exit marker]\n", indent, "");
1122
1123 if (region->next)
1124 dump_omp_region (file, region->next, indent);
1125 }
1126
1127 DEBUG_FUNCTION void
1128 debug_omp_region (struct omp_region *region)
1129 {
1130 dump_omp_region (stderr, region, 0);
1131 }
1132
1133 DEBUG_FUNCTION void
1134 debug_all_omp_regions (void)
1135 {
1136 dump_omp_region (stderr, root_omp_region, 0);
1137 }
1138
1139
1140 /* Create a new parallel region starting at STMT inside region PARENT. */
1141
1142 struct omp_region *
1143 new_omp_region (basic_block bb, enum gimple_code type,
1144 struct omp_region *parent)
1145 {
1146 struct omp_region *region = XCNEW (struct omp_region);
1147
1148 region->outer = parent;
1149 region->entry = bb;
1150 region->type = type;
1151
1152 if (parent)
1153 {
1154 /* This is a nested region. Add it to the list of inner
1155 regions in PARENT. */
1156 region->next = parent->inner;
1157 parent->inner = region;
1158 }
1159 else
1160 {
1161 /* This is a toplevel region. Add it to the list of toplevel
1162 regions in ROOT_OMP_REGION. */
1163 region->next = root_omp_region;
1164 root_omp_region = region;
1165 }
1166
1167 return region;
1168 }
1169
1170 /* Release the memory associated with the region tree rooted at REGION. */
1171
1172 static void
1173 free_omp_region_1 (struct omp_region *region)
1174 {
1175 struct omp_region *i, *n;
1176
1177 for (i = region->inner; i ; i = n)
1178 {
1179 n = i->next;
1180 free_omp_region_1 (i);
1181 }
1182
1183 free (region);
1184 }
1185
1186 /* Release the memory for the entire omp region tree. */
1187
1188 void
1189 free_omp_regions (void)
1190 {
1191 struct omp_region *r, *n;
1192 for (r = root_omp_region; r ; r = n)
1193 {
1194 n = r->next;
1195 free_omp_region_1 (r);
1196 }
1197 root_omp_region = NULL;
1198 }
1199
1200
1201 /* Create a new context, with OUTER_CTX being the surrounding context. */
1202
1203 static omp_context *
1204 new_omp_context (gimple stmt, omp_context *outer_ctx)
1205 {
1206 omp_context *ctx = XCNEW (omp_context);
1207
1208 splay_tree_insert (all_contexts, (splay_tree_key) stmt,
1209 (splay_tree_value) ctx);
1210 ctx->stmt = stmt;
1211
1212 if (outer_ctx)
1213 {
1214 ctx->outer = outer_ctx;
1215 ctx->cb = outer_ctx->cb;
1216 ctx->cb.block = NULL;
1217 ctx->depth = outer_ctx->depth + 1;
1218 }
1219 else
1220 {
1221 ctx->cb.src_fn = current_function_decl;
1222 ctx->cb.dst_fn = current_function_decl;
1223 ctx->cb.src_node = cgraph_get_node (current_function_decl);
1224 gcc_checking_assert (ctx->cb.src_node);
1225 ctx->cb.dst_node = ctx->cb.src_node;
1226 ctx->cb.src_cfun = cfun;
1227 ctx->cb.copy_decl = omp_copy_decl;
1228 ctx->cb.eh_lp_nr = 0;
1229 ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
1230 ctx->depth = 1;
1231 }
1232
1233 ctx->cb.decl_map = pointer_map_create ();
1234
1235 return ctx;
1236 }
1237
1238 static gimple_seq maybe_catch_exception (gimple_seq);
1239
1240 /* Finalize task copyfn. */
1241
1242 static void
1243 finalize_task_copyfn (gimple task_stmt)
1244 {
1245 struct function *child_cfun;
1246 tree child_fn, old_fn;
1247 gimple_seq seq = NULL, new_seq;
1248 gimple bind;
1249
1250 child_fn = gimple_omp_task_copy_fn (task_stmt);
1251 if (child_fn == NULL_TREE)
1252 return;
1253
1254 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
1255
1256 /* Inform the callgraph about the new function. */
1257 DECL_STRUCT_FUNCTION (child_fn)->curr_properties
1258 = cfun->curr_properties & ~PROP_loops;
1259
1260 old_fn = current_function_decl;
1261 push_cfun (child_cfun);
1262 current_function_decl = child_fn;
1263 bind = gimplify_body (child_fn, false);
1264 gimple_seq_add_stmt (&seq, bind);
1265 new_seq = maybe_catch_exception (seq);
1266 if (new_seq != seq)
1267 {
1268 bind = gimple_build_bind (NULL, new_seq, NULL);
1269 seq = NULL;
1270 gimple_seq_add_stmt (&seq, bind);
1271 }
1272 gimple_set_body (child_fn, seq);
1273 pop_cfun ();
1274 current_function_decl = old_fn;
1275
1276 cgraph_add_new_function (child_fn, false);
1277 }
1278
1279 /* Destroy a omp_context data structures. Called through the splay tree
1280 value delete callback. */
1281
1282 static void
1283 delete_omp_context (splay_tree_value value)
1284 {
1285 omp_context *ctx = (omp_context *) value;
1286
1287 pointer_map_destroy (ctx->cb.decl_map);
1288
1289 if (ctx->field_map)
1290 splay_tree_delete (ctx->field_map);
1291 if (ctx->sfield_map)
1292 splay_tree_delete (ctx->sfield_map);
1293
1294 /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
1295 it produces corrupt debug information. */
1296 if (ctx->record_type)
1297 {
1298 tree t;
1299 for (t = TYPE_FIELDS (ctx->record_type); t ; t = DECL_CHAIN (t))
1300 DECL_ABSTRACT_ORIGIN (t) = NULL;
1301 }
1302 if (ctx->srecord_type)
1303 {
1304 tree t;
1305 for (t = TYPE_FIELDS (ctx->srecord_type); t ; t = DECL_CHAIN (t))
1306 DECL_ABSTRACT_ORIGIN (t) = NULL;
1307 }
1308
1309 if (is_task_ctx (ctx))
1310 finalize_task_copyfn (ctx->stmt);
1311
1312 XDELETE (ctx);
1313 }
1314
1315 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
1316 context. */
1317
1318 static void
1319 fixup_child_record_type (omp_context *ctx)
1320 {
1321 tree f, type = ctx->record_type;
1322
1323 /* ??? It isn't sufficient to just call remap_type here, because
1324 variably_modified_type_p doesn't work the way we expect for
1325 record types. Testing each field for whether it needs remapping
1326 and creating a new record by hand works, however. */
1327 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
1328 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
1329 break;
1330 if (f)
1331 {
1332 tree name, new_fields = NULL;
1333
1334 type = lang_hooks.types.make_type (RECORD_TYPE);
1335 name = DECL_NAME (TYPE_NAME (ctx->record_type));
1336 name = build_decl (DECL_SOURCE_LOCATION (ctx->receiver_decl),
1337 TYPE_DECL, name, type);
1338 TYPE_NAME (type) = name;
1339
1340 for (f = TYPE_FIELDS (ctx->record_type); f ; f = DECL_CHAIN (f))
1341 {
1342 tree new_f = copy_node (f);
1343 DECL_CONTEXT (new_f) = type;
1344 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
1345 DECL_CHAIN (new_f) = new_fields;
1346 walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &ctx->cb, NULL);
1347 walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r,
1348 &ctx->cb, NULL);
1349 walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
1350 &ctx->cb, NULL);
1351 new_fields = new_f;
1352
1353 /* Arrange to be able to look up the receiver field
1354 given the sender field. */
1355 splay_tree_insert (ctx->field_map, (splay_tree_key) f,
1356 (splay_tree_value) new_f);
1357 }
1358 TYPE_FIELDS (type) = nreverse (new_fields);
1359 layout_type (type);
1360 }
1361
1362 TREE_TYPE (ctx->receiver_decl) = build_pointer_type (type);
1363 }
1364
1365 /* Instantiate decls as necessary in CTX to satisfy the data sharing
1366 specified by CLAUSES. */
1367
1368 static void
1369 scan_sharing_clauses (tree clauses, omp_context *ctx)
1370 {
1371 tree c, decl;
1372 bool scan_array_reductions = false;
1373
1374 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1375 {
1376 bool by_ref;
1377
1378 switch (OMP_CLAUSE_CODE (c))
1379 {
1380 case OMP_CLAUSE_PRIVATE:
1381 decl = OMP_CLAUSE_DECL (c);
1382 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
1383 goto do_private;
1384 else if (!is_variable_sized (decl))
1385 install_var_local (decl, ctx);
1386 break;
1387
1388 case OMP_CLAUSE_SHARED:
1389 gcc_assert (is_taskreg_ctx (ctx));
1390 decl = OMP_CLAUSE_DECL (c);
1391 gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl))
1392 || !is_variable_sized (decl));
1393 /* Global variables don't need to be copied,
1394 the receiver side will use them directly. */
1395 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1396 break;
1397 by_ref = use_pointer_for_field (decl, ctx);
1398 if (! TREE_READONLY (decl)
1399 || TREE_ADDRESSABLE (decl)
1400 || by_ref
1401 || is_reference (decl))
1402 {
1403 install_var_field (decl, by_ref, 3, ctx);
1404 install_var_local (decl, ctx);
1405 break;
1406 }
1407 /* We don't need to copy const scalar vars back. */
1408 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
1409 goto do_private;
1410
1411 case OMP_CLAUSE_LASTPRIVATE:
1412 /* Let the corresponding firstprivate clause create
1413 the variable. */
1414 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1415 break;
1416 /* FALLTHRU */
1417
1418 case OMP_CLAUSE_FIRSTPRIVATE:
1419 case OMP_CLAUSE_REDUCTION:
1420 decl = OMP_CLAUSE_DECL (c);
1421 do_private:
1422 if (is_variable_sized (decl))
1423 {
1424 if (is_task_ctx (ctx))
1425 install_var_field (decl, false, 1, ctx);
1426 break;
1427 }
1428 else if (is_taskreg_ctx (ctx))
1429 {
1430 bool global
1431 = is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx));
1432 by_ref = use_pointer_for_field (decl, NULL);
1433
1434 if (is_task_ctx (ctx)
1435 && (global || by_ref || is_reference (decl)))
1436 {
1437 install_var_field (decl, false, 1, ctx);
1438 if (!global)
1439 install_var_field (decl, by_ref, 2, ctx);
1440 }
1441 else if (!global)
1442 install_var_field (decl, by_ref, 3, ctx);
1443 }
1444 install_var_local (decl, ctx);
1445 break;
1446
1447 case OMP_CLAUSE_COPYPRIVATE:
1448 case OMP_CLAUSE_COPYIN:
1449 decl = OMP_CLAUSE_DECL (c);
1450 by_ref = use_pointer_for_field (decl, NULL);
1451 install_var_field (decl, by_ref, 3, ctx);
1452 break;
1453
1454 case OMP_CLAUSE_DEFAULT:
1455 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
1456 break;
1457
1458 case OMP_CLAUSE_FINAL:
1459 case OMP_CLAUSE_IF:
1460 case OMP_CLAUSE_NUM_THREADS:
1461 case OMP_CLAUSE_SCHEDULE:
1462 if (ctx->outer)
1463 scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
1464 break;
1465
1466 case OMP_CLAUSE_NOWAIT:
1467 case OMP_CLAUSE_ORDERED:
1468 case OMP_CLAUSE_COLLAPSE:
1469 case OMP_CLAUSE_UNTIED:
1470 case OMP_CLAUSE_MERGEABLE:
1471 break;
1472
1473 default:
1474 gcc_unreachable ();
1475 }
1476 }
1477
1478 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1479 {
1480 switch (OMP_CLAUSE_CODE (c))
1481 {
1482 case OMP_CLAUSE_LASTPRIVATE:
1483 /* Let the corresponding firstprivate clause create
1484 the variable. */
1485 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
1486 scan_array_reductions = true;
1487 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1488 break;
1489 /* FALLTHRU */
1490
1491 case OMP_CLAUSE_PRIVATE:
1492 case OMP_CLAUSE_FIRSTPRIVATE:
1493 case OMP_CLAUSE_REDUCTION:
1494 decl = OMP_CLAUSE_DECL (c);
1495 if (is_variable_sized (decl))
1496 install_var_local (decl, ctx);
1497 fixup_remapped_decl (decl, ctx,
1498 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
1499 && OMP_CLAUSE_PRIVATE_DEBUG (c));
1500 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1501 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1502 scan_array_reductions = true;
1503 break;
1504
1505 case OMP_CLAUSE_SHARED:
1506 decl = OMP_CLAUSE_DECL (c);
1507 if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1508 fixup_remapped_decl (decl, ctx, false);
1509 break;
1510
1511 case OMP_CLAUSE_COPYPRIVATE:
1512 case OMP_CLAUSE_COPYIN:
1513 case OMP_CLAUSE_DEFAULT:
1514 case OMP_CLAUSE_IF:
1515 case OMP_CLAUSE_NUM_THREADS:
1516 case OMP_CLAUSE_SCHEDULE:
1517 case OMP_CLAUSE_NOWAIT:
1518 case OMP_CLAUSE_ORDERED:
1519 case OMP_CLAUSE_COLLAPSE:
1520 case OMP_CLAUSE_UNTIED:
1521 case OMP_CLAUSE_FINAL:
1522 case OMP_CLAUSE_MERGEABLE:
1523 break;
1524
1525 default:
1526 gcc_unreachable ();
1527 }
1528 }
1529
1530 if (scan_array_reductions)
1531 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1532 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1533 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1534 {
1535 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
1536 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
1537 }
1538 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
1539 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
1540 scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
1541 }
1542
1543 /* Create a new name for omp child function. Returns an identifier. */
1544
1545 static GTY(()) unsigned int tmp_ompfn_id_num;
1546
1547 static tree
1548 create_omp_child_function_name (bool task_copy)
1549 {
1550 return (clone_function_name (current_function_decl,
1551 task_copy ? "_omp_cpyfn" : "_omp_fn"));
1552 }
1553
1554 /* Build a decl for the omp child function. It'll not contain a body
1555 yet, just the bare decl. */
1556
1557 static void
1558 create_omp_child_function (omp_context *ctx, bool task_copy)
1559 {
1560 tree decl, type, name, t;
1561
1562 name = create_omp_child_function_name (task_copy);
1563 if (task_copy)
1564 type = build_function_type_list (void_type_node, ptr_type_node,
1565 ptr_type_node, NULL_TREE);
1566 else
1567 type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
1568
1569 decl = build_decl (gimple_location (ctx->stmt),
1570 FUNCTION_DECL, name, type);
1571
1572 if (!task_copy)
1573 ctx->cb.dst_fn = decl;
1574 else
1575 gimple_omp_task_set_copy_fn (ctx->stmt, decl);
1576
1577 TREE_STATIC (decl) = 1;
1578 TREE_USED (decl) = 1;
1579 DECL_ARTIFICIAL (decl) = 1;
1580 DECL_NAMELESS (decl) = 1;
1581 DECL_IGNORED_P (decl) = 0;
1582 TREE_PUBLIC (decl) = 0;
1583 DECL_UNINLINABLE (decl) = 1;
1584 DECL_EXTERNAL (decl) = 0;
1585 DECL_CONTEXT (decl) = NULL_TREE;
1586 DECL_INITIAL (decl) = make_node (BLOCK);
1587
1588 t = build_decl (DECL_SOURCE_LOCATION (decl),
1589 RESULT_DECL, NULL_TREE, void_type_node);
1590 DECL_ARTIFICIAL (t) = 1;
1591 DECL_IGNORED_P (t) = 1;
1592 DECL_CONTEXT (t) = decl;
1593 DECL_RESULT (decl) = t;
1594
1595 t = build_decl (DECL_SOURCE_LOCATION (decl),
1596 PARM_DECL, get_identifier (".omp_data_i"), ptr_type_node);
1597 DECL_ARTIFICIAL (t) = 1;
1598 DECL_NAMELESS (t) = 1;
1599 DECL_ARG_TYPE (t) = ptr_type_node;
1600 DECL_CONTEXT (t) = current_function_decl;
1601 TREE_USED (t) = 1;
1602 DECL_ARGUMENTS (decl) = t;
1603 if (!task_copy)
1604 ctx->receiver_decl = t;
1605 else
1606 {
1607 t = build_decl (DECL_SOURCE_LOCATION (decl),
1608 PARM_DECL, get_identifier (".omp_data_o"),
1609 ptr_type_node);
1610 DECL_ARTIFICIAL (t) = 1;
1611 DECL_NAMELESS (t) = 1;
1612 DECL_ARG_TYPE (t) = ptr_type_node;
1613 DECL_CONTEXT (t) = current_function_decl;
1614 TREE_USED (t) = 1;
1615 TREE_ADDRESSABLE (t) = 1;
1616 DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
1617 DECL_ARGUMENTS (decl) = t;
1618 }
1619
1620 /* Allocate memory for the function structure. The call to
1621 allocate_struct_function clobbers CFUN, so we need to restore
1622 it afterward. */
1623 push_struct_function (decl);
1624 cfun->function_end_locus = gimple_location (ctx->stmt);
1625 pop_cfun ();
1626 }
1627
1628
1629 /* Scan an OpenMP parallel directive. */
1630
1631 static void
1632 scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
1633 {
1634 omp_context *ctx;
1635 tree name;
1636 gimple stmt = gsi_stmt (*gsi);
1637
1638 /* Ignore parallel directives with empty bodies, unless there
1639 are copyin clauses. */
1640 if (optimize > 0
1641 && empty_body_p (gimple_omp_body (stmt))
1642 && find_omp_clause (gimple_omp_parallel_clauses (stmt),
1643 OMP_CLAUSE_COPYIN) == NULL)
1644 {
1645 gsi_replace (gsi, gimple_build_nop (), false);
1646 return;
1647 }
1648
1649 ctx = new_omp_context (stmt, outer_ctx);
1650 if (taskreg_nesting_level > 1)
1651 ctx->is_nested = true;
1652 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1653 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
1654 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1655 name = create_tmp_var_name (".omp_data_s");
1656 name = build_decl (gimple_location (stmt),
1657 TYPE_DECL, name, ctx->record_type);
1658 DECL_ARTIFICIAL (name) = 1;
1659 DECL_NAMELESS (name) = 1;
1660 TYPE_NAME (ctx->record_type) = name;
1661 create_omp_child_function (ctx, false);
1662 gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
1663
1664 scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
1665 scan_omp (gimple_omp_body_ptr (stmt), ctx);
1666
1667 if (TYPE_FIELDS (ctx->record_type) == NULL)
1668 ctx->record_type = ctx->receiver_decl = NULL;
1669 else
1670 {
1671 layout_type (ctx->record_type);
1672 fixup_child_record_type (ctx);
1673 }
1674 }
1675
1676 /* Scan an OpenMP task directive. */
1677
1678 static void
1679 scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
1680 {
1681 omp_context *ctx;
1682 tree name, t;
1683 gimple stmt = gsi_stmt (*gsi);
1684 location_t loc = gimple_location (stmt);
1685
1686 /* Ignore task directives with empty bodies. */
1687 if (optimize > 0
1688 && empty_body_p (gimple_omp_body (stmt)))
1689 {
1690 gsi_replace (gsi, gimple_build_nop (), false);
1691 return;
1692 }
1693
1694 ctx = new_omp_context (stmt, outer_ctx);
1695 if (taskreg_nesting_level > 1)
1696 ctx->is_nested = true;
1697 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1698 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
1699 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1700 name = create_tmp_var_name (".omp_data_s");
1701 name = build_decl (gimple_location (stmt),
1702 TYPE_DECL, name, ctx->record_type);
1703 DECL_ARTIFICIAL (name) = 1;
1704 DECL_NAMELESS (name) = 1;
1705 TYPE_NAME (ctx->record_type) = name;
1706 create_omp_child_function (ctx, false);
1707 gimple_omp_task_set_child_fn (stmt, ctx->cb.dst_fn);
1708
1709 scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);
1710
1711 if (ctx->srecord_type)
1712 {
1713 name = create_tmp_var_name (".omp_data_a");
1714 name = build_decl (gimple_location (stmt),
1715 TYPE_DECL, name, ctx->srecord_type);
1716 DECL_ARTIFICIAL (name) = 1;
1717 DECL_NAMELESS (name) = 1;
1718 TYPE_NAME (ctx->srecord_type) = name;
1719 create_omp_child_function (ctx, true);
1720 }
1721
1722 scan_omp (gimple_omp_body_ptr (stmt), ctx);
1723
1724 if (TYPE_FIELDS (ctx->record_type) == NULL)
1725 {
1726 ctx->record_type = ctx->receiver_decl = NULL;
1727 t = build_int_cst (long_integer_type_node, 0);
1728 gimple_omp_task_set_arg_size (stmt, t);
1729 t = build_int_cst (long_integer_type_node, 1);
1730 gimple_omp_task_set_arg_align (stmt, t);
1731 }
1732 else
1733 {
1734 tree *p, vla_fields = NULL_TREE, *q = &vla_fields;
1735 /* Move VLA fields to the end. */
1736 p = &TYPE_FIELDS (ctx->record_type);
1737 while (*p)
1738 if (!TYPE_SIZE_UNIT (TREE_TYPE (*p))
1739 || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p))))
1740 {
1741 *q = *p;
1742 *p = TREE_CHAIN (*p);
1743 TREE_CHAIN (*q) = NULL_TREE;
1744 q = &TREE_CHAIN (*q);
1745 }
1746 else
1747 p = &DECL_CHAIN (*p);
1748 *p = vla_fields;
1749 layout_type (ctx->record_type);
1750 fixup_child_record_type (ctx);
1751 if (ctx->srecord_type)
1752 layout_type (ctx->srecord_type);
1753 t = fold_convert_loc (loc, long_integer_type_node,
1754 TYPE_SIZE_UNIT (ctx->record_type));
1755 gimple_omp_task_set_arg_size (stmt, t);
1756 t = build_int_cst (long_integer_type_node,
1757 TYPE_ALIGN_UNIT (ctx->record_type));
1758 gimple_omp_task_set_arg_align (stmt, t);
1759 }
1760 }
1761
1762
1763 /* Scan an OpenMP loop directive. */
1764
1765 static void
1766 scan_omp_for (gimple stmt, omp_context *outer_ctx)
1767 {
1768 omp_context *ctx;
1769 size_t i;
1770
1771 ctx = new_omp_context (stmt, outer_ctx);
1772
1773 scan_sharing_clauses (gimple_omp_for_clauses (stmt), ctx);
1774
1775 scan_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
1776 for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
1777 {
1778 scan_omp_op (gimple_omp_for_index_ptr (stmt, i), ctx);
1779 scan_omp_op (gimple_omp_for_initial_ptr (stmt, i), ctx);
1780 scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
1781 scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
1782 }
1783 scan_omp (gimple_omp_body_ptr (stmt), ctx);
1784 }
1785
1786 /* Scan an OpenMP sections directive. */
1787
1788 static void
1789 scan_omp_sections (gimple stmt, omp_context *outer_ctx)
1790 {
1791 omp_context *ctx;
1792
1793 ctx = new_omp_context (stmt, outer_ctx);
1794 scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
1795 scan_omp (gimple_omp_body_ptr (stmt), ctx);
1796 }
1797
1798 /* Scan an OpenMP single directive. */
1799
1800 static void
1801 scan_omp_single (gimple stmt, omp_context *outer_ctx)
1802 {
1803 omp_context *ctx;
1804 tree name;
1805
1806 ctx = new_omp_context (stmt, outer_ctx);
1807 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1808 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1809 name = create_tmp_var_name (".omp_copy_s");
1810 name = build_decl (gimple_location (stmt),
1811 TYPE_DECL, name, ctx->record_type);
1812 TYPE_NAME (ctx->record_type) = name;
1813
1814 scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
1815 scan_omp (gimple_omp_body_ptr (stmt), ctx);
1816
1817 if (TYPE_FIELDS (ctx->record_type) == NULL)
1818 ctx->record_type = NULL;
1819 else
1820 layout_type (ctx->record_type);
1821 }
1822
1823
1824 /* Check OpenMP nesting restrictions. */
1825 static bool
1826 check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
1827 {
1828 switch (gimple_code (stmt))
1829 {
1830 case GIMPLE_OMP_FOR:
1831 case GIMPLE_OMP_SECTIONS:
1832 case GIMPLE_OMP_SINGLE:
1833 case GIMPLE_CALL:
1834 for (; ctx != NULL; ctx = ctx->outer)
1835 switch (gimple_code (ctx->stmt))
1836 {
1837 case GIMPLE_OMP_FOR:
1838 case GIMPLE_OMP_SECTIONS:
1839 case GIMPLE_OMP_SINGLE:
1840 case GIMPLE_OMP_ORDERED:
1841 case GIMPLE_OMP_MASTER:
1842 case GIMPLE_OMP_TASK:
1843 if (is_gimple_call (stmt))
1844 {
1845 error_at (gimple_location (stmt),
1846 "barrier region may not be closely nested inside "
1847 "of work-sharing, critical, ordered, master or "
1848 "explicit task region");
1849 return false;
1850 }
1851 error_at (gimple_location (stmt),
1852 "work-sharing region may not be closely nested inside "
1853 "of work-sharing, critical, ordered, master or explicit "
1854 "task region");
1855 return false;
1856 case GIMPLE_OMP_PARALLEL:
1857 return true;
1858 default:
1859 break;
1860 }
1861 break;
1862 case GIMPLE_OMP_MASTER:
1863 for (; ctx != NULL; ctx = ctx->outer)
1864 switch (gimple_code (ctx->stmt))
1865 {
1866 case GIMPLE_OMP_FOR:
1867 case GIMPLE_OMP_SECTIONS:
1868 case GIMPLE_OMP_SINGLE:
1869 case GIMPLE_OMP_TASK:
1870 error_at (gimple_location (stmt),
1871 "master region may not be closely nested inside "
1872 "of work-sharing or explicit task region");
1873 return false;
1874 case GIMPLE_OMP_PARALLEL:
1875 return true;
1876 default:
1877 break;
1878 }
1879 break;
1880 case GIMPLE_OMP_ORDERED:
1881 for (; ctx != NULL; ctx = ctx->outer)
1882 switch (gimple_code (ctx->stmt))
1883 {
1884 case GIMPLE_OMP_CRITICAL:
1885 case GIMPLE_OMP_TASK:
1886 error_at (gimple_location (stmt),
1887 "ordered region may not be closely nested inside "
1888 "of critical or explicit task region");
1889 return false;
1890 case GIMPLE_OMP_FOR:
1891 if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
1892 OMP_CLAUSE_ORDERED) == NULL)
1893 {
1894 error_at (gimple_location (stmt),
1895 "ordered region must be closely nested inside "
1896 "a loop region with an ordered clause");
1897 return false;
1898 }
1899 return true;
1900 case GIMPLE_OMP_PARALLEL:
1901 return true;
1902 default:
1903 break;
1904 }
1905 break;
1906 case GIMPLE_OMP_CRITICAL:
1907 for (; ctx != NULL; ctx = ctx->outer)
1908 if (gimple_code (ctx->stmt) == GIMPLE_OMP_CRITICAL
1909 && (gimple_omp_critical_name (stmt)
1910 == gimple_omp_critical_name (ctx->stmt)))
1911 {
1912 error_at (gimple_location (stmt),
1913 "critical region may not be nested inside a critical "
1914 "region with the same name");
1915 return false;
1916 }
1917 break;
1918 default:
1919 break;
1920 }
1921 return true;
1922 }
1923
1924
1925 /* Helper function scan_omp.
1926
1927 Callback for walk_tree or operators in walk_gimple_stmt used to
1928 scan for OpenMP directives in TP. */
1929
1930 static tree
1931 scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
1932 {
1933 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
1934 omp_context *ctx = (omp_context *) wi->info;
1935 tree t = *tp;
1936
1937 switch (TREE_CODE (t))
1938 {
1939 case VAR_DECL:
1940 case PARM_DECL:
1941 case LABEL_DECL:
1942 case RESULT_DECL:
1943 if (ctx)
1944 *tp = remap_decl (t, &ctx->cb);
1945 break;
1946
1947 default:
1948 if (ctx && TYPE_P (t))
1949 *tp = remap_type (t, &ctx->cb);
1950 else if (!DECL_P (t))
1951 {
1952 *walk_subtrees = 1;
1953 if (ctx)
1954 {
1955 tree tem = remap_type (TREE_TYPE (t), &ctx->cb);
1956 if (tem != TREE_TYPE (t))
1957 {
1958 if (TREE_CODE (t) == INTEGER_CST)
1959 *tp = build_int_cst_wide (tem,
1960 TREE_INT_CST_LOW (t),
1961 TREE_INT_CST_HIGH (t));
1962 else
1963 TREE_TYPE (t) = tem;
1964 }
1965 }
1966 }
1967 break;
1968 }
1969
1970 return NULL_TREE;
1971 }
1972
1973
1974 /* Helper function for scan_omp.
1975
1976 Callback for walk_gimple_stmt used to scan for OpenMP directives in
1977 the current statement in GSI. */
1978
1979 static tree
1980 scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
1981 struct walk_stmt_info *wi)
1982 {
1983 gimple stmt = gsi_stmt (*gsi);
1984 omp_context *ctx = (omp_context *) wi->info;
1985
1986 if (gimple_has_location (stmt))
1987 input_location = gimple_location (stmt);
1988
1989 /* Check the OpenMP nesting restrictions. */
1990 if (ctx != NULL)
1991 {
1992 bool remove = false;
1993 if (is_gimple_omp (stmt))
1994 remove = !check_omp_nesting_restrictions (stmt, ctx);
1995 else if (is_gimple_call (stmt))
1996 {
1997 tree fndecl = gimple_call_fndecl (stmt);
1998 if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
1999 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER)
2000 remove = !check_omp_nesting_restrictions (stmt, ctx);
2001 }
2002 if (remove)
2003 {
2004 stmt = gimple_build_nop ();
2005 gsi_replace (gsi, stmt, false);
2006 }
2007 }
2008
2009 *handled_ops_p = true;
2010
2011 switch (gimple_code (stmt))
2012 {
2013 case GIMPLE_OMP_PARALLEL:
2014 taskreg_nesting_level++;
2015 scan_omp_parallel (gsi, ctx);
2016 taskreg_nesting_level--;
2017 break;
2018
2019 case GIMPLE_OMP_TASK:
2020 taskreg_nesting_level++;
2021 scan_omp_task (gsi, ctx);
2022 taskreg_nesting_level--;
2023 break;
2024
2025 case GIMPLE_OMP_FOR:
2026 scan_omp_for (stmt, ctx);
2027 break;
2028
2029 case GIMPLE_OMP_SECTIONS:
2030 scan_omp_sections (stmt, ctx);
2031 break;
2032
2033 case GIMPLE_OMP_SINGLE:
2034 scan_omp_single (stmt, ctx);
2035 break;
2036
2037 case GIMPLE_OMP_SECTION:
2038 case GIMPLE_OMP_MASTER:
2039 case GIMPLE_OMP_ORDERED:
2040 case GIMPLE_OMP_CRITICAL:
2041 ctx = new_omp_context (stmt, ctx);
2042 scan_omp (gimple_omp_body_ptr (stmt), ctx);
2043 break;
2044
2045 case GIMPLE_BIND:
2046 {
2047 tree var;
2048
2049 *handled_ops_p = false;
2050 if (ctx)
2051 for (var = gimple_bind_vars (stmt); var ; var = DECL_CHAIN (var))
2052 insert_decl_map (&ctx->cb, var, var);
2053 }
2054 break;
2055 default:
2056 *handled_ops_p = false;
2057 break;
2058 }
2059
2060 return NULL_TREE;
2061 }
2062
2063
2064 /* Scan all the statements starting at the current statement. CTX
2065 contains context information about the OpenMP directives and
2066 clauses found during the scan. */
2067
2068 static void
2069 scan_omp (gimple_seq *body_p, omp_context *ctx)
2070 {
2071 location_t saved_location;
2072 struct walk_stmt_info wi;
2073
2074 memset (&wi, 0, sizeof (wi));
2075 wi.info = ctx;
2076 wi.want_locations = true;
2077
2078 saved_location = input_location;
2079 walk_gimple_seq_mod (body_p, scan_omp_1_stmt, scan_omp_1_op, &wi);
2080 input_location = saved_location;
2081 }
2082 \f
2083 /* Re-gimplification and code generation routines. */
2084
2085 /* Build a call to GOMP_barrier. */
2086
2087 static tree
2088 build_omp_barrier (void)
2089 {
2090 return build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_BARRIER), 0);
2091 }
2092
2093 /* If a context was created for STMT when it was scanned, return it. */
2094
2095 static omp_context *
2096 maybe_lookup_ctx (gimple stmt)
2097 {
2098 splay_tree_node n;
2099 n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
2100 return n ? (omp_context *) n->value : NULL;
2101 }
2102
2103
2104 /* Find the mapping for DECL in CTX or the immediately enclosing
2105 context that has a mapping for DECL.
2106
2107 If CTX is a nested parallel directive, we may have to use the decl
2108 mappings created in CTX's parent context. Suppose that we have the
2109 following parallel nesting (variable UIDs showed for clarity):
2110
2111 iD.1562 = 0;
2112 #omp parallel shared(iD.1562) -> outer parallel
2113 iD.1562 = iD.1562 + 1;
2114
2115 #omp parallel shared (iD.1562) -> inner parallel
2116 iD.1562 = iD.1562 - 1;
2117
2118 Each parallel structure will create a distinct .omp_data_s structure
2119 for copying iD.1562 in/out of the directive:
2120
2121 outer parallel .omp_data_s.1.i -> iD.1562
2122 inner parallel .omp_data_s.2.i -> iD.1562
2123
2124 A shared variable mapping will produce a copy-out operation before
2125 the parallel directive and a copy-in operation after it. So, in
2126 this case we would have:
2127
2128 iD.1562 = 0;
2129 .omp_data_o.1.i = iD.1562;
2130 #omp parallel shared(iD.1562) -> outer parallel
2131 .omp_data_i.1 = &.omp_data_o.1
2132 .omp_data_i.1->i = .omp_data_i.1->i + 1;
2133
2134 .omp_data_o.2.i = iD.1562; -> **
2135 #omp parallel shared(iD.1562) -> inner parallel
2136 .omp_data_i.2 = &.omp_data_o.2
2137 .omp_data_i.2->i = .omp_data_i.2->i - 1;
2138
2139
2140 ** This is a problem. The symbol iD.1562 cannot be referenced
2141 inside the body of the outer parallel region. But since we are
2142 emitting this copy operation while expanding the inner parallel
2143 directive, we need to access the CTX structure of the outer
2144 parallel directive to get the correct mapping:
2145
2146 .omp_data_o.2.i = .omp_data_i.1->i
2147
2148 Since there may be other workshare or parallel directives enclosing
2149 the parallel directive, it may be necessary to walk up the context
2150 parent chain. This is not a problem in general because nested
2151 parallelism happens only rarely. */
2152
2153 static tree
2154 lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
2155 {
2156 tree t;
2157 omp_context *up;
2158
2159 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
2160 t = maybe_lookup_decl (decl, up);
2161
2162 gcc_assert (!ctx->is_nested || t || is_global_var (decl));
2163
2164 return t ? t : decl;
2165 }
2166
2167
2168 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
2169 in outer contexts. */
2170
2171 static tree
2172 maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
2173 {
2174 tree t = NULL;
2175 omp_context *up;
2176
2177 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
2178 t = maybe_lookup_decl (decl, up);
2179
2180 return t ? t : decl;
2181 }
2182
2183
2184 /* Construct the initialization value for reduction CLAUSE. */
2185
2186 tree
2187 omp_reduction_init (tree clause, tree type)
2188 {
2189 location_t loc = OMP_CLAUSE_LOCATION (clause);
2190 switch (OMP_CLAUSE_REDUCTION_CODE (clause))
2191 {
2192 case PLUS_EXPR:
2193 case MINUS_EXPR:
2194 case BIT_IOR_EXPR:
2195 case BIT_XOR_EXPR:
2196 case TRUTH_OR_EXPR:
2197 case TRUTH_ORIF_EXPR:
2198 case TRUTH_XOR_EXPR:
2199 case NE_EXPR:
2200 return build_zero_cst (type);
2201
2202 case MULT_EXPR:
2203 case TRUTH_AND_EXPR:
2204 case TRUTH_ANDIF_EXPR:
2205 case EQ_EXPR:
2206 return fold_convert_loc (loc, type, integer_one_node);
2207
2208 case BIT_AND_EXPR:
2209 return fold_convert_loc (loc, type, integer_minus_one_node);
2210
2211 case MAX_EXPR:
2212 if (SCALAR_FLOAT_TYPE_P (type))
2213 {
2214 REAL_VALUE_TYPE max, min;
2215 if (HONOR_INFINITIES (TYPE_MODE (type)))
2216 {
2217 real_inf (&max);
2218 real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
2219 }
2220 else
2221 real_maxval (&min, 1, TYPE_MODE (type));
2222 return build_real (type, min);
2223 }
2224 else
2225 {
2226 gcc_assert (INTEGRAL_TYPE_P (type));
2227 return TYPE_MIN_VALUE (type);
2228 }
2229
2230 case MIN_EXPR:
2231 if (SCALAR_FLOAT_TYPE_P (type))
2232 {
2233 REAL_VALUE_TYPE max;
2234 if (HONOR_INFINITIES (TYPE_MODE (type)))
2235 real_inf (&max);
2236 else
2237 real_maxval (&max, 0, TYPE_MODE (type));
2238 return build_real (type, max);
2239 }
2240 else
2241 {
2242 gcc_assert (INTEGRAL_TYPE_P (type));
2243 return TYPE_MAX_VALUE (type);
2244 }
2245
2246 default:
2247 gcc_unreachable ();
2248 }
2249 }
2250
2251 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
2252 from the receiver (aka child) side and initializers for REFERENCE_TYPE
2253 private variables. Initialization statements go in ILIST, while calls
2254 to destructors go in DLIST. */
2255
2256 static void
2257 lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
2258 omp_context *ctx)
2259 {
2260 tree c, dtor, copyin_seq, x, ptr;
2261 bool copyin_by_ref = false;
2262 bool lastprivate_firstprivate = false;
2263 int pass;
2264
2265 copyin_seq = NULL;
2266
2267 /* Do all the fixed sized types in the first pass, and the variable sized
2268 types in the second pass. This makes sure that the scalar arguments to
2269 the variable sized types are processed before we use them in the
2270 variable sized operations. */
2271 for (pass = 0; pass < 2; ++pass)
2272 {
2273 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2274 {
2275 enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
2276 tree var, new_var;
2277 bool by_ref;
2278 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2279
2280 switch (c_kind)
2281 {
2282 case OMP_CLAUSE_PRIVATE:
2283 if (OMP_CLAUSE_PRIVATE_DEBUG (c))
2284 continue;
2285 break;
2286 case OMP_CLAUSE_SHARED:
2287 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
2288 {
2289 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c)));
2290 continue;
2291 }
2292 case OMP_CLAUSE_FIRSTPRIVATE:
2293 case OMP_CLAUSE_COPYIN:
2294 case OMP_CLAUSE_REDUCTION:
2295 break;
2296 case OMP_CLAUSE_LASTPRIVATE:
2297 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2298 {
2299 lastprivate_firstprivate = true;
2300 if (pass != 0)
2301 continue;
2302 }
2303 break;
2304 default:
2305 continue;
2306 }
2307
2308 new_var = var = OMP_CLAUSE_DECL (c);
2309 if (c_kind != OMP_CLAUSE_COPYIN)
2310 new_var = lookup_decl (var, ctx);
2311
2312 if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
2313 {
2314 if (pass != 0)
2315 continue;
2316 }
2317 else if (is_variable_sized (var))
2318 {
2319 /* For variable sized types, we need to allocate the
2320 actual storage here. Call alloca and store the
2321 result in the pointer decl that we created elsewhere. */
2322 if (pass == 0)
2323 continue;
2324
2325 if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
2326 {
2327 gimple stmt;
2328 tree tmp, atmp;
2329
2330 ptr = DECL_VALUE_EXPR (new_var);
2331 gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
2332 ptr = TREE_OPERAND (ptr, 0);
2333 gcc_assert (DECL_P (ptr));
2334 x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
2335
2336 /* void *tmp = __builtin_alloca */
2337 atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
2338 stmt = gimple_build_call (atmp, 1, x);
2339 tmp = create_tmp_var_raw (ptr_type_node, NULL);
2340 gimple_add_tmp_var (tmp);
2341 gimple_call_set_lhs (stmt, tmp);
2342
2343 gimple_seq_add_stmt (ilist, stmt);
2344
2345 x = fold_convert_loc (clause_loc, TREE_TYPE (ptr), tmp);
2346 gimplify_assign (ptr, x, ilist);
2347 }
2348 }
2349 else if (is_reference (var))
2350 {
2351 /* For references that are being privatized for Fortran,
2352 allocate new backing storage for the new pointer
2353 variable. This allows us to avoid changing all the
2354 code that expects a pointer to something that expects
2355 a direct variable. Note that this doesn't apply to
2356 C++, since reference types are disallowed in data
2357 sharing clauses there, except for NRV optimized
2358 return values. */
2359 if (pass == 0)
2360 continue;
2361
2362 x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
2363 if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
2364 {
2365 x = build_receiver_ref (var, false, ctx);
2366 x = build_fold_addr_expr_loc (clause_loc, x);
2367 }
2368 else if (TREE_CONSTANT (x))
2369 {
2370 const char *name = NULL;
2371 if (DECL_NAME (var))
2372 name = IDENTIFIER_POINTER (DECL_NAME (new_var));
2373
2374 x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
2375 name);
2376 gimple_add_tmp_var (x);
2377 TREE_ADDRESSABLE (x) = 1;
2378 x = build_fold_addr_expr_loc (clause_loc, x);
2379 }
2380 else
2381 {
2382 tree atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
2383 x = build_call_expr_loc (clause_loc, atmp, 1, x);
2384 }
2385
2386 x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
2387 gimplify_assign (new_var, x, ilist);
2388
2389 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2390 }
2391 else if (c_kind == OMP_CLAUSE_REDUCTION
2392 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2393 {
2394 if (pass == 0)
2395 continue;
2396 }
2397 else if (pass != 0)
2398 continue;
2399
2400 switch (OMP_CLAUSE_CODE (c))
2401 {
2402 case OMP_CLAUSE_SHARED:
2403 /* Shared global vars are just accessed directly. */
2404 if (is_global_var (new_var))
2405 break;
2406 /* Set up the DECL_VALUE_EXPR for shared variables now. This
2407 needs to be delayed until after fixup_child_record_type so
2408 that we get the correct type during the dereference. */
2409 by_ref = use_pointer_for_field (var, ctx);
2410 x = build_receiver_ref (var, by_ref, ctx);
2411 SET_DECL_VALUE_EXPR (new_var, x);
2412 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
2413
2414 /* ??? If VAR is not passed by reference, and the variable
2415 hasn't been initialized yet, then we'll get a warning for
2416 the store into the omp_data_s structure. Ideally, we'd be
2417 able to notice this and not store anything at all, but
2418 we're generating code too early. Suppress the warning. */
2419 if (!by_ref)
2420 TREE_NO_WARNING (var) = 1;
2421 break;
2422
2423 case OMP_CLAUSE_LASTPRIVATE:
2424 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2425 break;
2426 /* FALLTHRU */
2427
2428 case OMP_CLAUSE_PRIVATE:
2429 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE)
2430 x = build_outer_var_ref (var, ctx);
2431 else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
2432 {
2433 if (is_task_ctx (ctx))
2434 x = build_receiver_ref (var, false, ctx);
2435 else
2436 x = build_outer_var_ref (var, ctx);
2437 }
2438 else
2439 x = NULL;
2440 x = lang_hooks.decls.omp_clause_default_ctor (c, new_var, x);
2441 if (x)
2442 gimplify_and_add (x, ilist);
2443 /* FALLTHRU */
2444
2445 do_dtor:
2446 x = lang_hooks.decls.omp_clause_dtor (c, new_var);
2447 if (x)
2448 {
2449 gimple_seq tseq = NULL;
2450
2451 dtor = x;
2452 gimplify_stmt (&dtor, &tseq);
2453 gimple_seq_add_seq (dlist, tseq);
2454 }
2455 break;
2456
2457 case OMP_CLAUSE_FIRSTPRIVATE:
2458 if (is_task_ctx (ctx))
2459 {
2460 if (is_reference (var) || is_variable_sized (var))
2461 goto do_dtor;
2462 else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var,
2463 ctx))
2464 || use_pointer_for_field (var, NULL))
2465 {
2466 x = build_receiver_ref (var, false, ctx);
2467 SET_DECL_VALUE_EXPR (new_var, x);
2468 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
2469 goto do_dtor;
2470 }
2471 }
2472 x = build_outer_var_ref (var, ctx);
2473 x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
2474 gimplify_and_add (x, ilist);
2475 goto do_dtor;
2476 break;
2477
2478 case OMP_CLAUSE_COPYIN:
2479 by_ref = use_pointer_for_field (var, NULL);
2480 x = build_receiver_ref (var, by_ref, ctx);
2481 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
2482 append_to_statement_list (x, &copyin_seq);
2483 copyin_by_ref |= by_ref;
2484 break;
2485
2486 case OMP_CLAUSE_REDUCTION:
2487 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2488 {
2489 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
2490 x = build_outer_var_ref (var, ctx);
2491
2492 if (is_reference (var))
2493 x = build_fold_addr_expr_loc (clause_loc, x);
2494 SET_DECL_VALUE_EXPR (placeholder, x);
2495 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
2496 lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
2497 gimple_seq_add_seq (ilist,
2498 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
2499 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
2500 DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
2501 }
2502 else
2503 {
2504 x = omp_reduction_init (c, TREE_TYPE (new_var));
2505 gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
2506 gimplify_assign (new_var, x, ilist);
2507 }
2508 break;
2509
2510 default:
2511 gcc_unreachable ();
2512 }
2513 }
2514 }
2515
2516 /* The copyin sequence is not to be executed by the main thread, since
2517 that would result in self-copies. Perhaps not visible to scalars,
2518 but it certainly is to C++ operator=. */
2519 if (copyin_seq)
2520 {
2521 x = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM),
2522 0);
2523 x = build2 (NE_EXPR, boolean_type_node, x,
2524 build_int_cst (TREE_TYPE (x), 0));
2525 x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
2526 gimplify_and_add (x, ilist);
2527 }
2528
2529 /* If any copyin variable is passed by reference, we must ensure the
2530 master thread doesn't modify it before it is copied over in all
2531 threads. Similarly for variables in both firstprivate and
2532 lastprivate clauses we need to ensure the lastprivate copying
2533 happens after firstprivate copying in all threads. */
2534 if (copyin_by_ref || lastprivate_firstprivate)
2535 gimplify_and_add (build_omp_barrier (), ilist);
2536 }
2537
2538
2539 /* Generate code to implement the LASTPRIVATE clauses. This is used for
2540 both parallel and workshare constructs. PREDICATE may be NULL if it's
2541 always true. */
2542
2543 static void
2544 lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
2545 omp_context *ctx)
2546 {
2547 tree x, c, label = NULL;
2548 bool par_clauses = false;
2549
2550 /* Early exit if there are no lastprivate clauses. */
2551 clauses = find_omp_clause (clauses, OMP_CLAUSE_LASTPRIVATE);
2552 if (clauses == NULL)
2553 {
2554 /* If this was a workshare clause, see if it had been combined
2555 with its parallel. In that case, look for the clauses on the
2556 parallel statement itself. */
2557 if (is_parallel_ctx (ctx))
2558 return;
2559
2560 ctx = ctx->outer;
2561 if (ctx == NULL || !is_parallel_ctx (ctx))
2562 return;
2563
2564 clauses = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2565 OMP_CLAUSE_LASTPRIVATE);
2566 if (clauses == NULL)
2567 return;
2568 par_clauses = true;
2569 }
2570
2571 if (predicate)
2572 {
2573 gimple stmt;
2574 tree label_true, arm1, arm2;
2575
2576 label = create_artificial_label (UNKNOWN_LOCATION);
2577 label_true = create_artificial_label (UNKNOWN_LOCATION);
2578 arm1 = TREE_OPERAND (predicate, 0);
2579 arm2 = TREE_OPERAND (predicate, 1);
2580 gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
2581 gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
2582 stmt = gimple_build_cond (TREE_CODE (predicate), arm1, arm2,
2583 label_true, label);
2584 gimple_seq_add_stmt (stmt_list, stmt);
2585 gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
2586 }
2587
2588 for (c = clauses; c ;)
2589 {
2590 tree var, new_var;
2591 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2592
2593 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
2594 {
2595 var = OMP_CLAUSE_DECL (c);
2596 new_var = lookup_decl (var, ctx);
2597
2598 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
2599 {
2600 lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
2601 gimple_seq_add_seq (stmt_list,
2602 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
2603 }
2604 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
2605
2606 x = build_outer_var_ref (var, ctx);
2607 if (is_reference (var))
2608 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2609 x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
2610 gimplify_and_add (x, stmt_list);
2611 }
2612 c = OMP_CLAUSE_CHAIN (c);
2613 if (c == NULL && !par_clauses)
2614 {
2615 /* If this was a workshare clause, see if it had been combined
2616 with its parallel. In that case, continue looking for the
2617 clauses also on the parallel statement itself. */
2618 if (is_parallel_ctx (ctx))
2619 break;
2620
2621 ctx = ctx->outer;
2622 if (ctx == NULL || !is_parallel_ctx (ctx))
2623 break;
2624
2625 c = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2626 OMP_CLAUSE_LASTPRIVATE);
2627 par_clauses = true;
2628 }
2629 }
2630
2631 if (label)
2632 gimple_seq_add_stmt (stmt_list, gimple_build_label (label));
2633 }
2634
2635
2636 /* Generate code to implement the REDUCTION clauses. */
2637
2638 static void
2639 lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
2640 {
2641 gimple_seq sub_seq = NULL;
2642 gimple stmt;
2643 tree x, c;
2644 int count = 0;
2645
2646 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
2647 update in that case, otherwise use a lock. */
2648 for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
2649 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
2650 {
2651 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2652 {
2653 /* Never use OMP_ATOMIC for array reductions. */
2654 count = -1;
2655 break;
2656 }
2657 count++;
2658 }
2659
2660 if (count == 0)
2661 return;
2662
2663 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2664 {
2665 tree var, ref, new_var;
2666 enum tree_code code;
2667 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2668
2669 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
2670 continue;
2671
2672 var = OMP_CLAUSE_DECL (c);
2673 new_var = lookup_decl (var, ctx);
2674 if (is_reference (var))
2675 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2676 ref = build_outer_var_ref (var, ctx);
2677 code = OMP_CLAUSE_REDUCTION_CODE (c);
2678
2679 /* reduction(-:var) sums up the partial results, so it acts
2680 identically to reduction(+:var). */
2681 if (code == MINUS_EXPR)
2682 code = PLUS_EXPR;
2683
2684 if (count == 1)
2685 {
2686 tree addr = build_fold_addr_expr_loc (clause_loc, ref);
2687
2688 addr = save_expr (addr);
2689 ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
2690 x = fold_build2_loc (clause_loc, code, TREE_TYPE (ref), ref, new_var);
2691 x = build2 (OMP_ATOMIC, void_type_node, addr, x);
2692 gimplify_and_add (x, stmt_seqp);
2693 return;
2694 }
2695
2696 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2697 {
2698 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
2699
2700 if (is_reference (var))
2701 ref = build_fold_addr_expr_loc (clause_loc, ref);
2702 SET_DECL_VALUE_EXPR (placeholder, ref);
2703 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
2704 lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
2705 gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
2706 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
2707 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
2708 }
2709 else
2710 {
2711 x = build2 (code, TREE_TYPE (ref), ref, new_var);
2712 ref = build_outer_var_ref (var, ctx);
2713 gimplify_assign (ref, x, &sub_seq);
2714 }
2715 }
2716
2717 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START),
2718 0);
2719 gimple_seq_add_stmt (stmt_seqp, stmt);
2720
2721 gimple_seq_add_seq (stmt_seqp, sub_seq);
2722
2723 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END),
2724 0);
2725 gimple_seq_add_stmt (stmt_seqp, stmt);
2726 }
2727
2728
2729 /* Generate code to implement the COPYPRIVATE clauses. */
2730
2731 static void
2732 lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist,
2733 omp_context *ctx)
2734 {
2735 tree c;
2736
2737 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2738 {
2739 tree var, new_var, ref, x;
2740 bool by_ref;
2741 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2742
2743 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
2744 continue;
2745
2746 var = OMP_CLAUSE_DECL (c);
2747 by_ref = use_pointer_for_field (var, NULL);
2748
2749 ref = build_sender_ref (var, ctx);
2750 x = new_var = lookup_decl_in_outer_ctx (var, ctx);
2751 if (by_ref)
2752 {
2753 x = build_fold_addr_expr_loc (clause_loc, new_var);
2754 x = fold_convert_loc (clause_loc, TREE_TYPE (ref), x);
2755 }
2756 gimplify_assign (ref, x, slist);
2757
2758 ref = build_receiver_ref (var, false, ctx);
2759 if (by_ref)
2760 {
2761 ref = fold_convert_loc (clause_loc,
2762 build_pointer_type (TREE_TYPE (new_var)),
2763 ref);
2764 ref = build_fold_indirect_ref_loc (clause_loc, ref);
2765 }
2766 if (is_reference (var))
2767 {
2768 ref = fold_convert_loc (clause_loc, TREE_TYPE (new_var), ref);
2769 ref = build_simple_mem_ref_loc (clause_loc, ref);
2770 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2771 }
2772 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, ref);
2773 gimplify_and_add (x, rlist);
2774 }
2775 }
2776
2777
2778 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
2779 and REDUCTION from the sender (aka parent) side. */
2780
2781 static void
2782 lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist,
2783 omp_context *ctx)
2784 {
2785 tree c;
2786
2787 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2788 {
2789 tree val, ref, x, var;
2790 bool by_ref, do_in = false, do_out = false;
2791 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2792
2793 switch (OMP_CLAUSE_CODE (c))
2794 {
2795 case OMP_CLAUSE_PRIVATE:
2796 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
2797 break;
2798 continue;
2799 case OMP_CLAUSE_FIRSTPRIVATE:
2800 case OMP_CLAUSE_COPYIN:
2801 case OMP_CLAUSE_LASTPRIVATE:
2802 case OMP_CLAUSE_REDUCTION:
2803 break;
2804 default:
2805 continue;
2806 }
2807
2808 val = OMP_CLAUSE_DECL (c);
2809 var = lookup_decl_in_outer_ctx (val, ctx);
2810
2811 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
2812 && is_global_var (var))
2813 continue;
2814 if (is_variable_sized (val))
2815 continue;
2816 by_ref = use_pointer_for_field (val, NULL);
2817
2818 switch (OMP_CLAUSE_CODE (c))
2819 {
2820 case OMP_CLAUSE_PRIVATE:
2821 case OMP_CLAUSE_FIRSTPRIVATE:
2822 case OMP_CLAUSE_COPYIN:
2823 do_in = true;
2824 break;
2825
2826 case OMP_CLAUSE_LASTPRIVATE:
2827 if (by_ref || is_reference (val))
2828 {
2829 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2830 continue;
2831 do_in = true;
2832 }
2833 else
2834 {
2835 do_out = true;
2836 if (lang_hooks.decls.omp_private_outer_ref (val))
2837 do_in = true;
2838 }
2839 break;
2840
2841 case OMP_CLAUSE_REDUCTION:
2842 do_in = true;
2843 do_out = !(by_ref || is_reference (val));
2844 break;
2845
2846 default:
2847 gcc_unreachable ();
2848 }
2849
2850 if (do_in)
2851 {
2852 ref = build_sender_ref (val, ctx);
2853 x = by_ref ? build_fold_addr_expr_loc (clause_loc, var) : var;
2854 gimplify_assign (ref, x, ilist);
2855 if (is_task_ctx (ctx))
2856 DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref, 1)) = NULL;
2857 }
2858
2859 if (do_out)
2860 {
2861 ref = build_sender_ref (val, ctx);
2862 gimplify_assign (var, ref, olist);
2863 }
2864 }
2865 }
2866
2867 /* Generate code to implement SHARED from the sender (aka parent)
2868 side. This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
2869 list things that got automatically shared. */
2870
2871 static void
2872 lower_send_shared_vars (gimple_seq *ilist, gimple_seq *olist, omp_context *ctx)
2873 {
2874 tree var, ovar, nvar, f, x, record_type;
2875
2876 if (ctx->record_type == NULL)
2877 return;
2878
2879 record_type = ctx->srecord_type ? ctx->srecord_type : ctx->record_type;
2880 for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
2881 {
2882 ovar = DECL_ABSTRACT_ORIGIN (f);
2883 nvar = maybe_lookup_decl (ovar, ctx);
2884 if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
2885 continue;
2886
2887 /* If CTX is a nested parallel directive. Find the immediately
2888 enclosing parallel or workshare construct that contains a
2889 mapping for OVAR. */
2890 var = lookup_decl_in_outer_ctx (ovar, ctx);
2891
2892 if (use_pointer_for_field (ovar, ctx))
2893 {
2894 x = build_sender_ref (ovar, ctx);
2895 var = build_fold_addr_expr (var);
2896 gimplify_assign (x, var, ilist);
2897 }
2898 else
2899 {
2900 x = build_sender_ref (ovar, ctx);
2901 gimplify_assign (x, var, ilist);
2902
2903 if (!TREE_READONLY (var)
2904 /* We don't need to receive a new reference to a result
2905 or parm decl. In fact we may not store to it as we will
2906 invalidate any pending RSO and generate wrong gimple
2907 during inlining. */
2908 && !((TREE_CODE (var) == RESULT_DECL
2909 || TREE_CODE (var) == PARM_DECL)
2910 && DECL_BY_REFERENCE (var)))
2911 {
2912 x = build_sender_ref (ovar, ctx);
2913 gimplify_assign (var, x, olist);
2914 }
2915 }
2916 }
2917 }
2918
2919
2920 /* A convenience function to build an empty GIMPLE_COND with just the
2921 condition. */
2922
2923 static gimple
2924 gimple_build_cond_empty (tree cond)
2925 {
2926 enum tree_code pred_code;
2927 tree lhs, rhs;
2928
2929 gimple_cond_get_ops_from_tree (cond, &pred_code, &lhs, &rhs);
2930 return gimple_build_cond (pred_code, lhs, rhs, NULL_TREE, NULL_TREE);
2931 }
2932
2933
2934 /* Build the function calls to GOMP_parallel_start etc to actually
2935 generate the parallel operation. REGION is the parallel region
2936 being expanded. BB is the block where to insert the code. WS_ARGS
2937 will be set if this is a call to a combined parallel+workshare
2938 construct, it contains the list of additional arguments needed by
2939 the workshare construct. */
2940
2941 static void
2942 expand_parallel_call (struct omp_region *region, basic_block bb,
2943 gimple entry_stmt, VEC(tree,gc) *ws_args)
2944 {
2945 tree t, t1, t2, val, cond, c, clauses;
2946 gimple_stmt_iterator gsi;
2947 gimple stmt;
2948 enum built_in_function start_ix;
2949 int start_ix2;
2950 location_t clause_loc;
2951 VEC(tree,gc) *args;
2952
2953 clauses = gimple_omp_parallel_clauses (entry_stmt);
2954
2955 /* Determine what flavor of GOMP_parallel_start we will be
2956 emitting. */
2957 start_ix = BUILT_IN_GOMP_PARALLEL_START;
2958 if (is_combined_parallel (region))
2959 {
2960 switch (region->inner->type)
2961 {
2962 case GIMPLE_OMP_FOR:
2963 gcc_assert (region->inner->sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
2964 start_ix2 = ((int)BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
2965 + (region->inner->sched_kind
2966 == OMP_CLAUSE_SCHEDULE_RUNTIME
2967 ? 3 : region->inner->sched_kind));
2968 start_ix = (enum built_in_function)start_ix2;
2969 break;
2970 case GIMPLE_OMP_SECTIONS:
2971 start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS_START;
2972 break;
2973 default:
2974 gcc_unreachable ();
2975 }
2976 }
2977
2978 /* By default, the value of NUM_THREADS is zero (selected at run time)
2979 and there is no conditional. */
2980 cond = NULL_TREE;
2981 val = build_int_cst (unsigned_type_node, 0);
2982
2983 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
2984 if (c)
2985 cond = OMP_CLAUSE_IF_EXPR (c);
2986
2987 c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
2988 if (c)
2989 {
2990 val = OMP_CLAUSE_NUM_THREADS_EXPR (c);
2991 clause_loc = OMP_CLAUSE_LOCATION (c);
2992 }
2993 else
2994 clause_loc = gimple_location (entry_stmt);
2995
2996 /* Ensure 'val' is of the correct type. */
2997 val = fold_convert_loc (clause_loc, unsigned_type_node, val);
2998
2999 /* If we found the clause 'if (cond)', build either
3000 (cond != 0) or (cond ? val : 1u). */
3001 if (cond)
3002 {
3003 gimple_stmt_iterator gsi;
3004
3005 cond = gimple_boolify (cond);
3006
3007 if (integer_zerop (val))
3008 val = fold_build2_loc (clause_loc,
3009 EQ_EXPR, unsigned_type_node, cond,
3010 build_int_cst (TREE_TYPE (cond), 0));
3011 else
3012 {
3013 basic_block cond_bb, then_bb, else_bb;
3014 edge e, e_then, e_else;
3015 tree tmp_then, tmp_else, tmp_join, tmp_var;
3016
3017 tmp_var = create_tmp_var (TREE_TYPE (val), NULL);
3018 if (gimple_in_ssa_p (cfun))
3019 {
3020 tmp_then = make_ssa_name (tmp_var, NULL);
3021 tmp_else = make_ssa_name (tmp_var, NULL);
3022 tmp_join = make_ssa_name (tmp_var, NULL);
3023 }
3024 else
3025 {
3026 tmp_then = tmp_var;
3027 tmp_else = tmp_var;
3028 tmp_join = tmp_var;
3029 }
3030
3031 e = split_block (bb, NULL);
3032 cond_bb = e->src;
3033 bb = e->dest;
3034 remove_edge (e);
3035
3036 then_bb = create_empty_bb (cond_bb);
3037 else_bb = create_empty_bb (then_bb);
3038 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
3039 set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
3040
3041 stmt = gimple_build_cond_empty (cond);
3042 gsi = gsi_start_bb (cond_bb);
3043 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3044
3045 gsi = gsi_start_bb (then_bb);
3046 stmt = gimple_build_assign (tmp_then, val);
3047 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3048
3049 gsi = gsi_start_bb (else_bb);
3050 stmt = gimple_build_assign
3051 (tmp_else, build_int_cst (unsigned_type_node, 1));
3052 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3053
3054 make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
3055 make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
3056 e_then = make_edge (then_bb, bb, EDGE_FALLTHRU);
3057 e_else = make_edge (else_bb, bb, EDGE_FALLTHRU);
3058
3059 if (gimple_in_ssa_p (cfun))
3060 {
3061 gimple phi = create_phi_node (tmp_join, bb);
3062 add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION);
3063 add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION);
3064 }
3065
3066 val = tmp_join;
3067 }
3068
3069 gsi = gsi_start_bb (bb);
3070 val = force_gimple_operand_gsi (&gsi, val, true, NULL_TREE,
3071 false, GSI_CONTINUE_LINKING);
3072 }
3073
3074 gsi = gsi_last_bb (bb);
3075 t = gimple_omp_parallel_data_arg (entry_stmt);
3076 if (t == NULL)
3077 t1 = null_pointer_node;
3078 else
3079 t1 = build_fold_addr_expr (t);
3080 t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
3081
3082 args = VEC_alloc (tree, gc, 3 + VEC_length (tree, ws_args));
3083 VEC_quick_push (tree, args, t2);
3084 VEC_quick_push (tree, args, t1);
3085 VEC_quick_push (tree, args, val);
3086 VEC_splice (tree, args, ws_args);
3087
3088 t = build_call_expr_loc_vec (UNKNOWN_LOCATION,
3089 builtin_decl_explicit (start_ix), args);
3090
3091 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3092 false, GSI_CONTINUE_LINKING);
3093
3094 t = gimple_omp_parallel_data_arg (entry_stmt);
3095 if (t == NULL)
3096 t = null_pointer_node;
3097 else
3098 t = build_fold_addr_expr (t);
3099 t = build_call_expr_loc (gimple_location (entry_stmt),
3100 gimple_omp_parallel_child_fn (entry_stmt), 1, t);
3101 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3102 false, GSI_CONTINUE_LINKING);
3103
3104 t = build_call_expr_loc (gimple_location (entry_stmt),
3105 builtin_decl_explicit (BUILT_IN_GOMP_PARALLEL_END),
3106 0);
3107 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3108 false, GSI_CONTINUE_LINKING);
3109 }
3110
3111
3112 /* Build the function call to GOMP_task to actually
3113 generate the task operation. BB is the block where to insert the code. */
3114
3115 static void
3116 expand_task_call (basic_block bb, gimple entry_stmt)
3117 {
3118 tree t, t1, t2, t3, flags, cond, c, c2, clauses;
3119 gimple_stmt_iterator gsi;
3120 location_t loc = gimple_location (entry_stmt);
3121
3122 clauses = gimple_omp_task_clauses (entry_stmt);
3123
3124 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
3125 if (c)
3126 cond = gimple_boolify (OMP_CLAUSE_IF_EXPR (c));
3127 else
3128 cond = boolean_true_node;
3129
3130 c = find_omp_clause (clauses, OMP_CLAUSE_UNTIED);
3131 c2 = find_omp_clause (clauses, OMP_CLAUSE_MERGEABLE);
3132 flags = build_int_cst (unsigned_type_node,
3133 (c ? 1 : 0) + (c2 ? 4 : 0));
3134
3135 c = find_omp_clause (clauses, OMP_CLAUSE_FINAL);
3136 if (c)
3137 {
3138 c = gimple_boolify (OMP_CLAUSE_FINAL_EXPR (c));
3139 c = fold_build3_loc (loc, COND_EXPR, unsigned_type_node, c,
3140 build_int_cst (unsigned_type_node, 2),
3141 build_int_cst (unsigned_type_node, 0));
3142 flags = fold_build2_loc (loc, PLUS_EXPR, unsigned_type_node, flags, c);
3143 }
3144
3145 gsi = gsi_last_bb (bb);
3146 t = gimple_omp_task_data_arg (entry_stmt);
3147 if (t == NULL)
3148 t2 = null_pointer_node;
3149 else
3150 t2 = build_fold_addr_expr_loc (loc, t);
3151 t1 = build_fold_addr_expr_loc (loc, gimple_omp_task_child_fn (entry_stmt));
3152 t = gimple_omp_task_copy_fn (entry_stmt);
3153 if (t == NULL)
3154 t3 = null_pointer_node;
3155 else
3156 t3 = build_fold_addr_expr_loc (loc, t);
3157
3158 t = build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_TASK),
3159 7, t1, t2, t3,
3160 gimple_omp_task_arg_size (entry_stmt),
3161 gimple_omp_task_arg_align (entry_stmt), cond, flags);
3162
3163 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3164 false, GSI_CONTINUE_LINKING);
3165 }
3166
3167
3168 /* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
3169 catch handler and return it. This prevents programs from violating the
3170 structured block semantics with throws. */
3171
3172 static gimple_seq
3173 maybe_catch_exception (gimple_seq body)
3174 {
3175 gimple g;
3176 tree decl;
3177
3178 if (!flag_exceptions)
3179 return body;
3180
3181 if (lang_hooks.eh_protect_cleanup_actions != NULL)
3182 decl = lang_hooks.eh_protect_cleanup_actions ();
3183 else
3184 decl = builtin_decl_explicit (BUILT_IN_TRAP);
3185
3186 g = gimple_build_eh_must_not_throw (decl);
3187 g = gimple_build_try (body, gimple_seq_alloc_with_stmt (g),
3188 GIMPLE_TRY_CATCH);
3189
3190 return gimple_seq_alloc_with_stmt (g);
3191 }
3192
3193 /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
3194
3195 static tree
3196 vec2chain (VEC(tree,gc) *v)
3197 {
3198 tree chain = NULL_TREE, t;
3199 unsigned ix;
3200
3201 FOR_EACH_VEC_ELT_REVERSE (tree, v, ix, t)
3202 {
3203 DECL_CHAIN (t) = chain;
3204 chain = t;
3205 }
3206
3207 return chain;
3208 }
3209
3210
3211 /* Remove barriers in REGION->EXIT's block. Note that this is only
3212 valid for GIMPLE_OMP_PARALLEL regions. Since the end of a parallel region
3213 is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
3214 left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
3215 removed. */
3216
3217 static void
3218 remove_exit_barrier (struct omp_region *region)
3219 {
3220 gimple_stmt_iterator gsi;
3221 basic_block exit_bb;
3222 edge_iterator ei;
3223 edge e;
3224 gimple stmt;
3225 int any_addressable_vars = -1;
3226
3227 exit_bb = region->exit;
3228
3229 /* If the parallel region doesn't return, we don't have REGION->EXIT
3230 block at all. */
3231 if (! exit_bb)
3232 return;
3233
3234 /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN. The
3235 workshare's GIMPLE_OMP_RETURN will be in a preceding block. The kinds of
3236 statements that can appear in between are extremely limited -- no
3237 memory operations at all. Here, we allow nothing at all, so the
3238 only thing we allow to precede this GIMPLE_OMP_RETURN is a label. */
3239 gsi = gsi_last_bb (exit_bb);
3240 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
3241 gsi_prev (&gsi);
3242 if (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
3243 return;
3244
3245 FOR_EACH_EDGE (e, ei, exit_bb->preds)
3246 {
3247 gsi = gsi_last_bb (e->src);
3248 if (gsi_end_p (gsi))
3249 continue;
3250 stmt = gsi_stmt (gsi);
3251 if (gimple_code (stmt) == GIMPLE_OMP_RETURN
3252 && !gimple_omp_return_nowait_p (stmt))
3253 {
3254 /* OpenMP 3.0 tasks unfortunately prevent this optimization
3255 in many cases. If there could be tasks queued, the barrier
3256 might be needed to let the tasks run before some local
3257 variable of the parallel that the task uses as shared
3258 runs out of scope. The task can be spawned either
3259 from within current function (this would be easy to check)
3260 or from some function it calls and gets passed an address
3261 of such a variable. */
3262 if (any_addressable_vars < 0)
3263 {
3264 gimple parallel_stmt = last_stmt (region->entry);
3265 tree child_fun = gimple_omp_parallel_child_fn (parallel_stmt);
3266 tree local_decls, block, decl;
3267 unsigned ix;
3268
3269 any_addressable_vars = 0;
3270 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (child_fun), ix, decl)
3271 if (TREE_ADDRESSABLE (decl))
3272 {
3273 any_addressable_vars = 1;
3274 break;
3275 }
3276 for (block = gimple_block (stmt);
3277 !any_addressable_vars
3278 && block
3279 && TREE_CODE (block) == BLOCK;
3280 block = BLOCK_SUPERCONTEXT (block))
3281 {
3282 for (local_decls = BLOCK_VARS (block);
3283 local_decls;
3284 local_decls = DECL_CHAIN (local_decls))
3285 if (TREE_ADDRESSABLE (local_decls))
3286 {
3287 any_addressable_vars = 1;
3288 break;
3289 }
3290 if (block == gimple_block (parallel_stmt))
3291 break;
3292 }
3293 }
3294 if (!any_addressable_vars)
3295 gimple_omp_return_set_nowait (stmt);
3296 }
3297 }
3298 }
3299
3300 static void
3301 remove_exit_barriers (struct omp_region *region)
3302 {
3303 if (region->type == GIMPLE_OMP_PARALLEL)
3304 remove_exit_barrier (region);
3305
3306 if (region->inner)
3307 {
3308 region = region->inner;
3309 remove_exit_barriers (region);
3310 while (region->next)
3311 {
3312 region = region->next;
3313 remove_exit_barriers (region);
3314 }
3315 }
3316 }
3317
3318 /* Optimize omp_get_thread_num () and omp_get_num_threads ()
3319 calls. These can't be declared as const functions, but
3320 within one parallel body they are constant, so they can be
3321 transformed there into __builtin_omp_get_{thread_num,num_threads} ()
3322 which are declared const. Similarly for task body, except
3323 that in untied task omp_get_thread_num () can change at any task
3324 scheduling point. */
3325
3326 static void
3327 optimize_omp_library_calls (gimple entry_stmt)
3328 {
3329 basic_block bb;
3330 gimple_stmt_iterator gsi;
3331 tree thr_num_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
3332 tree thr_num_id = DECL_ASSEMBLER_NAME (thr_num_tree);
3333 tree num_thr_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
3334 tree num_thr_id = DECL_ASSEMBLER_NAME (num_thr_tree);
3335 bool untied_task = (gimple_code (entry_stmt) == GIMPLE_OMP_TASK
3336 && find_omp_clause (gimple_omp_task_clauses (entry_stmt),
3337 OMP_CLAUSE_UNTIED) != NULL);
3338
3339 FOR_EACH_BB (bb)
3340 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3341 {
3342 gimple call = gsi_stmt (gsi);
3343 tree decl;
3344
3345 if (is_gimple_call (call)
3346 && (decl = gimple_call_fndecl (call))
3347 && DECL_EXTERNAL (decl)
3348 && TREE_PUBLIC (decl)
3349 && DECL_INITIAL (decl) == NULL)
3350 {
3351 tree built_in;
3352
3353 if (DECL_NAME (decl) == thr_num_id)
3354 {
3355 /* In #pragma omp task untied omp_get_thread_num () can change
3356 during the execution of the task region. */
3357 if (untied_task)
3358 continue;
3359 built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
3360 }
3361 else if (DECL_NAME (decl) == num_thr_id)
3362 built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
3363 else
3364 continue;
3365
3366 if (DECL_ASSEMBLER_NAME (decl) != DECL_ASSEMBLER_NAME (built_in)
3367 || gimple_call_num_args (call) != 0)
3368 continue;
3369
3370 if (flag_exceptions && !TREE_NOTHROW (decl))
3371 continue;
3372
3373 if (TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE
3374 || !types_compatible_p (TREE_TYPE (TREE_TYPE (decl)),
3375 TREE_TYPE (TREE_TYPE (built_in))))
3376 continue;
3377
3378 gimple_call_set_fndecl (call, built_in);
3379 }
3380 }
3381 }
3382
3383 /* Expand the OpenMP parallel or task directive starting at REGION. */
3384
3385 static void
3386 expand_omp_taskreg (struct omp_region *region)
3387 {
3388 basic_block entry_bb, exit_bb, new_bb;
3389 struct function *child_cfun;
3390 tree child_fn, block, t;
3391 tree save_current;
3392 gimple_stmt_iterator gsi;
3393 gimple entry_stmt, stmt;
3394 edge e;
3395 VEC(tree,gc) *ws_args;
3396
3397 entry_stmt = last_stmt (region->entry);
3398 child_fn = gimple_omp_taskreg_child_fn (entry_stmt);
3399 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
3400
3401 entry_bb = region->entry;
3402 exit_bb = region->exit;
3403
3404 if (is_combined_parallel (region))
3405 ws_args = region->ws_args;
3406 else
3407 ws_args = NULL;
3408
3409 if (child_cfun->cfg)
3410 {
3411 /* Due to inlining, it may happen that we have already outlined
3412 the region, in which case all we need to do is make the
3413 sub-graph unreachable and emit the parallel call. */
3414 edge entry_succ_e, exit_succ_e;
3415 gimple_stmt_iterator gsi;
3416
3417 entry_succ_e = single_succ_edge (entry_bb);
3418
3419 gsi = gsi_last_bb (entry_bb);
3420 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_PARALLEL
3421 || gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_TASK);
3422 gsi_remove (&gsi, true);
3423
3424 new_bb = entry_bb;
3425 if (exit_bb)
3426 {
3427 exit_succ_e = single_succ_edge (exit_bb);
3428 make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
3429 }
3430 remove_edge_and_dominated_blocks (entry_succ_e);
3431 }
3432 else
3433 {
3434 unsigned srcidx, dstidx, num;
3435
3436 /* If the parallel region needs data sent from the parent
3437 function, then the very first statement (except possible
3438 tree profile counter updates) of the parallel body
3439 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
3440 &.OMP_DATA_O is passed as an argument to the child function,
3441 we need to replace it with the argument as seen by the child
3442 function.
3443
3444 In most cases, this will end up being the identity assignment
3445 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
3446 a function call that has been inlined, the original PARM_DECL
3447 .OMP_DATA_I may have been converted into a different local
3448 variable. In which case, we need to keep the assignment. */
3449 if (gimple_omp_taskreg_data_arg (entry_stmt))
3450 {
3451 basic_block entry_succ_bb = single_succ (entry_bb);
3452 gimple_stmt_iterator gsi;
3453 tree arg, narg;
3454 gimple parcopy_stmt = NULL;
3455
3456 for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
3457 {
3458 gimple stmt;
3459
3460 gcc_assert (!gsi_end_p (gsi));
3461 stmt = gsi_stmt (gsi);
3462 if (gimple_code (stmt) != GIMPLE_ASSIGN)
3463 continue;
3464
3465 if (gimple_num_ops (stmt) == 2)
3466 {
3467 tree arg = gimple_assign_rhs1 (stmt);
3468
3469 /* We're ignore the subcode because we're
3470 effectively doing a STRIP_NOPS. */
3471
3472 if (TREE_CODE (arg) == ADDR_EXPR
3473 && TREE_OPERAND (arg, 0)
3474 == gimple_omp_taskreg_data_arg (entry_stmt))
3475 {
3476 parcopy_stmt = stmt;
3477 break;
3478 }
3479 }
3480 }
3481
3482 gcc_assert (parcopy_stmt != NULL);
3483 arg = DECL_ARGUMENTS (child_fn);
3484
3485 if (!gimple_in_ssa_p (cfun))
3486 {
3487 if (gimple_assign_lhs (parcopy_stmt) == arg)
3488 gsi_remove (&gsi, true);
3489 else
3490 {
3491 /* ?? Is setting the subcode really necessary ?? */
3492 gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (arg));
3493 gimple_assign_set_rhs1 (parcopy_stmt, arg);
3494 }
3495 }
3496 else
3497 {
3498 /* If we are in ssa form, we must load the value from the default
3499 definition of the argument. That should not be defined now,
3500 since the argument is not used uninitialized. */
3501 gcc_assert (ssa_default_def (cfun, arg) == NULL);
3502 narg = make_ssa_name (arg, gimple_build_nop ());
3503 set_ssa_default_def (cfun, arg, narg);
3504 /* ?? Is setting the subcode really necessary ?? */
3505 gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (narg));
3506 gimple_assign_set_rhs1 (parcopy_stmt, narg);
3507 update_stmt (parcopy_stmt);
3508 }
3509 }
3510
3511 /* Declare local variables needed in CHILD_CFUN. */
3512 block = DECL_INITIAL (child_fn);
3513 BLOCK_VARS (block) = vec2chain (child_cfun->local_decls);
3514 /* The gimplifier could record temporaries in parallel/task block
3515 rather than in containing function's local_decls chain,
3516 which would mean cgraph missed finalizing them. Do it now. */
3517 for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
3518 if (TREE_CODE (t) == VAR_DECL
3519 && TREE_STATIC (t)
3520 && !DECL_EXTERNAL (t))
3521 varpool_finalize_decl (t);
3522 DECL_SAVED_TREE (child_fn) = NULL;
3523 /* We'll create a CFG for child_fn, so no gimple body is needed. */
3524 gimple_set_body (child_fn, NULL);
3525 TREE_USED (block) = 1;
3526
3527 /* Reset DECL_CONTEXT on function arguments. */
3528 for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
3529 DECL_CONTEXT (t) = child_fn;
3530
3531 /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
3532 so that it can be moved to the child function. */
3533 gsi = gsi_last_bb (entry_bb);
3534 stmt = gsi_stmt (gsi);
3535 gcc_assert (stmt && (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
3536 || gimple_code (stmt) == GIMPLE_OMP_TASK));
3537 gsi_remove (&gsi, true);
3538 e = split_block (entry_bb, stmt);
3539 entry_bb = e->dest;
3540 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3541
3542 /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
3543 if (exit_bb)
3544 {
3545 gsi = gsi_last_bb (exit_bb);
3546 gcc_assert (!gsi_end_p (gsi)
3547 && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
3548 stmt = gimple_build_return (NULL);
3549 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
3550 gsi_remove (&gsi, true);
3551 }
3552
3553 /* Move the parallel region into CHILD_CFUN. */
3554
3555 if (gimple_in_ssa_p (cfun))
3556 {
3557 init_tree_ssa (child_cfun);
3558 init_ssa_operands (child_cfun);
3559 child_cfun->gimple_df->in_ssa_p = true;
3560 block = NULL_TREE;
3561 }
3562 else
3563 block = gimple_block (entry_stmt);
3564
3565 new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
3566 if (exit_bb)
3567 single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
3568
3569 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
3570 num = VEC_length (tree, child_cfun->local_decls);
3571 for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
3572 {
3573 t = VEC_index (tree, child_cfun->local_decls, srcidx);
3574 if (DECL_CONTEXT (t) == cfun->decl)
3575 continue;
3576 if (srcidx != dstidx)
3577 VEC_replace (tree, child_cfun->local_decls, dstidx, t);
3578 dstidx++;
3579 }
3580 if (dstidx != num)
3581 VEC_truncate (tree, child_cfun->local_decls, dstidx);
3582
3583 /* Inform the callgraph about the new function. */
3584 DECL_STRUCT_FUNCTION (child_fn)->curr_properties
3585 = cfun->curr_properties & ~PROP_loops;
3586 cgraph_add_new_function (child_fn, true);
3587
3588 /* Fix the callgraph edges for child_cfun. Those for cfun will be
3589 fixed in a following pass. */
3590 push_cfun (child_cfun);
3591 save_current = current_function_decl;
3592 current_function_decl = child_fn;
3593 if (optimize)
3594 optimize_omp_library_calls (entry_stmt);
3595 rebuild_cgraph_edges ();
3596
3597 /* Some EH regions might become dead, see PR34608. If
3598 pass_cleanup_cfg isn't the first pass to happen with the
3599 new child, these dead EH edges might cause problems.
3600 Clean them up now. */
3601 if (flag_exceptions)
3602 {
3603 basic_block bb;
3604 bool changed = false;
3605
3606 FOR_EACH_BB (bb)
3607 changed |= gimple_purge_dead_eh_edges (bb);
3608 if (changed)
3609 cleanup_tree_cfg ();
3610 }
3611 if (gimple_in_ssa_p (cfun))
3612 update_ssa (TODO_update_ssa);
3613 current_function_decl = save_current;
3614 pop_cfun ();
3615 }
3616
3617 /* Emit a library call to launch the children threads. */
3618 if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
3619 expand_parallel_call (region, new_bb, entry_stmt, ws_args);
3620 else
3621 expand_task_call (new_bb, entry_stmt);
3622 if (gimple_in_ssa_p (cfun))
3623 update_ssa (TODO_update_ssa_only_virtuals);
3624 }
3625
3626
3627 /* A subroutine of expand_omp_for. Generate code for a parallel
3628 loop with any schedule. Given parameters:
3629
3630 for (V = N1; V cond N2; V += STEP) BODY;
3631
3632 where COND is "<" or ">", we generate pseudocode
3633
3634 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
3635 if (more) goto L0; else goto L3;
3636 L0:
3637 V = istart0;
3638 iend = iend0;
3639 L1:
3640 BODY;
3641 V += STEP;
3642 if (V cond iend) goto L1; else goto L2;
3643 L2:
3644 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3645 L3:
3646
3647 If this is a combined omp parallel loop, instead of the call to
3648 GOMP_loop_foo_start, we call GOMP_loop_foo_next.
3649
3650 For collapsed loops, given parameters:
3651 collapse(3)
3652 for (V1 = N11; V1 cond1 N12; V1 += STEP1)
3653 for (V2 = N21; V2 cond2 N22; V2 += STEP2)
3654 for (V3 = N31; V3 cond3 N32; V3 += STEP3)
3655 BODY;
3656
3657 we generate pseudocode
3658
3659 if (cond3 is <)
3660 adj = STEP3 - 1;
3661 else
3662 adj = STEP3 + 1;
3663 count3 = (adj + N32 - N31) / STEP3;
3664 if (cond2 is <)
3665 adj = STEP2 - 1;
3666 else
3667 adj = STEP2 + 1;
3668 count2 = (adj + N22 - N21) / STEP2;
3669 if (cond1 is <)
3670 adj = STEP1 - 1;
3671 else
3672 adj = STEP1 + 1;
3673 count1 = (adj + N12 - N11) / STEP1;
3674 count = count1 * count2 * count3;
3675 more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
3676 if (more) goto L0; else goto L3;
3677 L0:
3678 V = istart0;
3679 T = V;
3680 V3 = N31 + (T % count3) * STEP3;
3681 T = T / count3;
3682 V2 = N21 + (T % count2) * STEP2;
3683 T = T / count2;
3684 V1 = N11 + T * STEP1;
3685 iend = iend0;
3686 L1:
3687 BODY;
3688 V += 1;
3689 if (V < iend) goto L10; else goto L2;
3690 L10:
3691 V3 += STEP3;
3692 if (V3 cond3 N32) goto L1; else goto L11;
3693 L11:
3694 V3 = N31;
3695 V2 += STEP2;
3696 if (V2 cond2 N22) goto L1; else goto L12;
3697 L12:
3698 V2 = N21;
3699 V1 += STEP1;
3700 goto L1;
3701 L2:
3702 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3703 L3:
3704
3705 */
3706
3707 static void
3708 expand_omp_for_generic (struct omp_region *region,
3709 struct omp_for_data *fd,
3710 enum built_in_function start_fn,
3711 enum built_in_function next_fn)
3712 {
3713 tree type, istart0, iend0, iend;
3714 tree t, vmain, vback, bias = NULL_TREE;
3715 basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, collapse_bb;
3716 basic_block l2_bb = NULL, l3_bb = NULL;
3717 gimple_stmt_iterator gsi;
3718 gimple stmt;
3719 bool in_combined_parallel = is_combined_parallel (region);
3720 bool broken_loop = region->cont == NULL;
3721 edge e, ne;
3722 tree *counts = NULL;
3723 int i;
3724
3725 gcc_assert (!broken_loop || !in_combined_parallel);
3726 gcc_assert (fd->iter_type == long_integer_type_node
3727 || !in_combined_parallel);
3728
3729 type = TREE_TYPE (fd->loop.v);
3730 istart0 = create_tmp_var (fd->iter_type, ".istart0");
3731 iend0 = create_tmp_var (fd->iter_type, ".iend0");
3732 TREE_ADDRESSABLE (istart0) = 1;
3733 TREE_ADDRESSABLE (iend0) = 1;
3734
3735 /* See if we need to bias by LLONG_MIN. */
3736 if (fd->iter_type == long_long_unsigned_type_node
3737 && TREE_CODE (type) == INTEGER_TYPE
3738 && !TYPE_UNSIGNED (type))
3739 {
3740 tree n1, n2;
3741
3742 if (fd->loop.cond_code == LT_EXPR)
3743 {
3744 n1 = fd->loop.n1;
3745 n2 = fold_build2 (PLUS_EXPR, type, fd->loop.n2, fd->loop.step);
3746 }
3747 else
3748 {
3749 n1 = fold_build2 (MINUS_EXPR, type, fd->loop.n2, fd->loop.step);
3750 n2 = fd->loop.n1;
3751 }
3752 if (TREE_CODE (n1) != INTEGER_CST
3753 || TREE_CODE (n2) != INTEGER_CST
3754 || ((tree_int_cst_sgn (n1) < 0) ^ (tree_int_cst_sgn (n2) < 0)))
3755 bias = fold_convert (fd->iter_type, TYPE_MIN_VALUE (type));
3756 }
3757
3758 entry_bb = region->entry;
3759 cont_bb = region->cont;
3760 collapse_bb = NULL;
3761 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
3762 gcc_assert (broken_loop
3763 || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
3764 l0_bb = split_edge (FALLTHRU_EDGE (entry_bb));
3765 l1_bb = single_succ (l0_bb);
3766 if (!broken_loop)
3767 {
3768 l2_bb = create_empty_bb (cont_bb);
3769 gcc_assert (BRANCH_EDGE (cont_bb)->dest == l1_bb);
3770 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
3771 }
3772 else
3773 l2_bb = NULL;
3774 l3_bb = BRANCH_EDGE (entry_bb)->dest;
3775 exit_bb = region->exit;
3776
3777 gsi = gsi_last_bb (entry_bb);
3778
3779 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
3780 if (fd->collapse > 1)
3781 {
3782 /* collapsed loops need work for expansion in SSA form. */
3783 gcc_assert (!gimple_in_ssa_p (cfun));
3784 counts = (tree *) alloca (fd->collapse * sizeof (tree));
3785 for (i = 0; i < fd->collapse; i++)
3786 {
3787 tree itype = TREE_TYPE (fd->loops[i].v);
3788
3789 if (POINTER_TYPE_P (itype))
3790 itype = signed_type_for (itype);
3791 t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR
3792 ? -1 : 1));
3793 t = fold_build2 (PLUS_EXPR, itype,
3794 fold_convert (itype, fd->loops[i].step), t);
3795 t = fold_build2 (PLUS_EXPR, itype, t,
3796 fold_convert (itype, fd->loops[i].n2));
3797 t = fold_build2 (MINUS_EXPR, itype, t,
3798 fold_convert (itype, fd->loops[i].n1));
3799 if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
3800 t = fold_build2 (TRUNC_DIV_EXPR, itype,
3801 fold_build1 (NEGATE_EXPR, itype, t),
3802 fold_build1 (NEGATE_EXPR, itype,
3803 fold_convert (itype,
3804 fd->loops[i].step)));
3805 else
3806 t = fold_build2 (TRUNC_DIV_EXPR, itype, t,
3807 fold_convert (itype, fd->loops[i].step));
3808 t = fold_convert (type, t);
3809 if (TREE_CODE (t) == INTEGER_CST)
3810 counts[i] = t;
3811 else
3812 {
3813 counts[i] = create_tmp_reg (type, ".count");
3814 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3815 true, GSI_SAME_STMT);
3816 stmt = gimple_build_assign (counts[i], t);
3817 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3818 }
3819 if (SSA_VAR_P (fd->loop.n2))
3820 {
3821 if (i == 0)
3822 t = counts[0];
3823 else
3824 {
3825 t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
3826 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3827 true, GSI_SAME_STMT);
3828 }
3829 stmt = gimple_build_assign (fd->loop.n2, t);
3830 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3831 }
3832 }
3833 }
3834 if (in_combined_parallel)
3835 {
3836 /* In a combined parallel loop, emit a call to
3837 GOMP_loop_foo_next. */
3838 t = build_call_expr (builtin_decl_explicit (next_fn), 2,
3839 build_fold_addr_expr (istart0),
3840 build_fold_addr_expr (iend0));
3841 }
3842 else
3843 {
3844 tree t0, t1, t2, t3, t4;
3845 /* If this is not a combined parallel loop, emit a call to
3846 GOMP_loop_foo_start in ENTRY_BB. */
3847 t4 = build_fold_addr_expr (iend0);
3848 t3 = build_fold_addr_expr (istart0);
3849 t2 = fold_convert (fd->iter_type, fd->loop.step);
3850 if (POINTER_TYPE_P (type)
3851 && TYPE_PRECISION (type) != TYPE_PRECISION (fd->iter_type))
3852 {
3853 /* Avoid casting pointers to integer of a different size. */
3854 tree itype = signed_type_for (type);
3855 t1 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n2));
3856 t0 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n1));
3857 }
3858 else
3859 {
3860 t1 = fold_convert (fd->iter_type, fd->loop.n2);
3861 t0 = fold_convert (fd->iter_type, fd->loop.n1);
3862 }
3863 if (bias)
3864 {
3865 t1 = fold_build2 (PLUS_EXPR, fd->iter_type, t1, bias);
3866 t0 = fold_build2 (PLUS_EXPR, fd->iter_type, t0, bias);
3867 }
3868 if (fd->iter_type == long_integer_type_node)
3869 {
3870 if (fd->chunk_size)
3871 {
3872 t = fold_convert (fd->iter_type, fd->chunk_size);
3873 t = build_call_expr (builtin_decl_explicit (start_fn),
3874 6, t0, t1, t2, t, t3, t4);
3875 }
3876 else
3877 t = build_call_expr (builtin_decl_explicit (start_fn),
3878 5, t0, t1, t2, t3, t4);
3879 }
3880 else
3881 {
3882 tree t5;
3883 tree c_bool_type;
3884 tree bfn_decl;
3885
3886 /* The GOMP_loop_ull_*start functions have additional boolean
3887 argument, true for < loops and false for > loops.
3888 In Fortran, the C bool type can be different from
3889 boolean_type_node. */
3890 bfn_decl = builtin_decl_explicit (start_fn);
3891 c_bool_type = TREE_TYPE (TREE_TYPE (bfn_decl));
3892 t5 = build_int_cst (c_bool_type,
3893 fd->loop.cond_code == LT_EXPR ? 1 : 0);
3894 if (fd->chunk_size)
3895 {
3896 tree bfn_decl = builtin_decl_explicit (start_fn);
3897 t = fold_convert (fd->iter_type, fd->chunk_size);
3898 t = build_call_expr (bfn_decl, 7, t5, t0, t1, t2, t, t3, t4);
3899 }
3900 else
3901 t = build_call_expr (builtin_decl_explicit (start_fn),
3902 6, t5, t0, t1, t2, t3, t4);
3903 }
3904 }
3905 if (TREE_TYPE (t) != boolean_type_node)
3906 t = fold_build2 (NE_EXPR, boolean_type_node,
3907 t, build_int_cst (TREE_TYPE (t), 0));
3908 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3909 true, GSI_SAME_STMT);
3910 gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
3911
3912 /* Remove the GIMPLE_OMP_FOR statement. */
3913 gsi_remove (&gsi, true);
3914
3915 /* Iteration setup for sequential loop goes in L0_BB. */
3916 gsi = gsi_start_bb (l0_bb);
3917 t = istart0;
3918 if (bias)
3919 t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
3920 if (POINTER_TYPE_P (type))
3921 t = fold_convert (signed_type_for (type), t);
3922 t = fold_convert (type, t);
3923 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3924 false, GSI_CONTINUE_LINKING);
3925 stmt = gimple_build_assign (fd->loop.v, t);
3926 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3927
3928 t = iend0;
3929 if (bias)
3930 t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
3931 if (POINTER_TYPE_P (type))
3932 t = fold_convert (signed_type_for (type), t);
3933 t = fold_convert (type, t);
3934 iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3935 false, GSI_CONTINUE_LINKING);
3936 if (fd->collapse > 1)
3937 {
3938 tree tem = create_tmp_reg (type, ".tem");
3939 stmt = gimple_build_assign (tem, fd->loop.v);
3940 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3941 for (i = fd->collapse - 1; i >= 0; i--)
3942 {
3943 tree vtype = TREE_TYPE (fd->loops[i].v), itype;
3944 itype = vtype;
3945 if (POINTER_TYPE_P (vtype))
3946 itype = signed_type_for (vtype);
3947 t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
3948 t = fold_convert (itype, t);
3949 t = fold_build2 (MULT_EXPR, itype, t,
3950 fold_convert (itype, fd->loops[i].step));
3951 if (POINTER_TYPE_P (vtype))
3952 t = fold_build_pointer_plus (fd->loops[i].n1, t);
3953 else
3954 t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
3955 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3956 false, GSI_CONTINUE_LINKING);
3957 stmt = gimple_build_assign (fd->loops[i].v, t);
3958 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3959 if (i != 0)
3960 {
3961 t = fold_build2 (TRUNC_DIV_EXPR, type, tem, counts[i]);
3962 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3963 false, GSI_CONTINUE_LINKING);
3964 stmt = gimple_build_assign (tem, t);
3965 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3966 }
3967 }
3968 }
3969
3970 if (!broken_loop)
3971 {
3972 /* Code to control the increment and predicate for the sequential
3973 loop goes in the CONT_BB. */
3974 gsi = gsi_last_bb (cont_bb);
3975 stmt = gsi_stmt (gsi);
3976 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
3977 vmain = gimple_omp_continue_control_use (stmt);
3978 vback = gimple_omp_continue_control_def (stmt);
3979
3980 if (POINTER_TYPE_P (type))
3981 t = fold_build_pointer_plus (vmain, fd->loop.step);
3982 else
3983 t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
3984 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3985 true, GSI_SAME_STMT);
3986 stmt = gimple_build_assign (vback, t);
3987 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3988
3989 t = build2 (fd->loop.cond_code, boolean_type_node, vback, iend);
3990 stmt = gimple_build_cond_empty (t);
3991 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3992
3993 /* Remove GIMPLE_OMP_CONTINUE. */
3994 gsi_remove (&gsi, true);
3995
3996 if (fd->collapse > 1)
3997 {
3998 basic_block last_bb, bb;
3999
4000 last_bb = cont_bb;
4001 for (i = fd->collapse - 1; i >= 0; i--)
4002 {
4003 tree vtype = TREE_TYPE (fd->loops[i].v);
4004
4005 bb = create_empty_bb (last_bb);
4006 gsi = gsi_start_bb (bb);
4007
4008 if (i < fd->collapse - 1)
4009 {
4010 e = make_edge (last_bb, bb, EDGE_FALSE_VALUE);
4011 e->probability = REG_BR_PROB_BASE / 8;
4012
4013 t = fd->loops[i + 1].n1;
4014 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4015 false, GSI_CONTINUE_LINKING);
4016 stmt = gimple_build_assign (fd->loops[i + 1].v, t);
4017 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4018 }
4019 else
4020 collapse_bb = bb;
4021
4022 set_immediate_dominator (CDI_DOMINATORS, bb, last_bb);
4023
4024 if (POINTER_TYPE_P (vtype))
4025 t = fold_build_pointer_plus (fd->loops[i].v, fd->loops[i].step);
4026 else
4027 t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v,
4028 fd->loops[i].step);
4029 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4030 false, GSI_CONTINUE_LINKING);
4031 stmt = gimple_build_assign (fd->loops[i].v, t);
4032 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4033
4034 if (i > 0)
4035 {
4036 t = fd->loops[i].n2;
4037 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4038 false, GSI_CONTINUE_LINKING);
4039 t = fold_build2 (fd->loops[i].cond_code, boolean_type_node,
4040 fd->loops[i].v, t);
4041 stmt = gimple_build_cond_empty (t);
4042 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4043 e = make_edge (bb, l1_bb, EDGE_TRUE_VALUE);
4044 e->probability = REG_BR_PROB_BASE * 7 / 8;
4045 }
4046 else
4047 make_edge (bb, l1_bb, EDGE_FALLTHRU);
4048 last_bb = bb;
4049 }
4050 }
4051
4052 /* Emit code to get the next parallel iteration in L2_BB. */
4053 gsi = gsi_start_bb (l2_bb);
4054
4055 t = build_call_expr (builtin_decl_explicit (next_fn), 2,
4056 build_fold_addr_expr (istart0),
4057 build_fold_addr_expr (iend0));
4058 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4059 false, GSI_CONTINUE_LINKING);
4060 if (TREE_TYPE (t) != boolean_type_node)
4061 t = fold_build2 (NE_EXPR, boolean_type_node,
4062 t, build_int_cst (TREE_TYPE (t), 0));
4063 stmt = gimple_build_cond_empty (t);
4064 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4065 }
4066
4067 /* Add the loop cleanup function. */
4068 gsi = gsi_last_bb (exit_bb);
4069 if (gimple_omp_return_nowait_p (gsi_stmt (gsi)))
4070 t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_NOWAIT);
4071 else
4072 t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END);
4073 stmt = gimple_build_call (t, 0);
4074 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
4075 gsi_remove (&gsi, true);
4076
4077 /* Connect the new blocks. */
4078 find_edge (entry_bb, l0_bb)->flags = EDGE_TRUE_VALUE;
4079 find_edge (entry_bb, l3_bb)->flags = EDGE_FALSE_VALUE;
4080
4081 if (!broken_loop)
4082 {
4083 gimple_seq phis;
4084
4085 e = find_edge (cont_bb, l3_bb);
4086 ne = make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
4087
4088 phis = phi_nodes (l3_bb);
4089 for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
4090 {
4091 gimple phi = gsi_stmt (gsi);
4092 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, ne),
4093 PHI_ARG_DEF_FROM_EDGE (phi, e));
4094 }
4095 remove_edge (e);
4096
4097 make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
4098 if (fd->collapse > 1)
4099 {
4100 e = find_edge (cont_bb, l1_bb);
4101 remove_edge (e);
4102 e = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
4103 }
4104 else
4105 {
4106 e = find_edge (cont_bb, l1_bb);
4107 e->flags = EDGE_TRUE_VALUE;
4108 }
4109 e->probability = REG_BR_PROB_BASE * 7 / 8;
4110 find_edge (cont_bb, l2_bb)->probability = REG_BR_PROB_BASE / 8;
4111 make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
4112
4113 set_immediate_dominator (CDI_DOMINATORS, l2_bb,
4114 recompute_dominator (CDI_DOMINATORS, l2_bb));
4115 set_immediate_dominator (CDI_DOMINATORS, l3_bb,
4116 recompute_dominator (CDI_DOMINATORS, l3_bb));
4117 set_immediate_dominator (CDI_DOMINATORS, l0_bb,
4118 recompute_dominator (CDI_DOMINATORS, l0_bb));
4119 set_immediate_dominator (CDI_DOMINATORS, l1_bb,
4120 recompute_dominator (CDI_DOMINATORS, l1_bb));
4121 }
4122 }
4123
4124
4125 /* A subroutine of expand_omp_for. Generate code for a parallel
4126 loop with static schedule and no specified chunk size. Given
4127 parameters:
4128
4129 for (V = N1; V cond N2; V += STEP) BODY;
4130
4131 where COND is "<" or ">", we generate pseudocode
4132
4133 if (cond is <)
4134 adj = STEP - 1;
4135 else
4136 adj = STEP + 1;
4137 if ((__typeof (V)) -1 > 0 && cond is >)
4138 n = -(adj + N2 - N1) / -STEP;
4139 else
4140 n = (adj + N2 - N1) / STEP;
4141 q = n / nthreads;
4142 tt = n % nthreads;
4143 if (threadid < tt) goto L3; else goto L4;
4144 L3:
4145 tt = 0;
4146 q = q + 1;
4147 L4:
4148 s0 = q * threadid + tt;
4149 e0 = s0 + q;
4150 V = s0 * STEP + N1;
4151 if (s0 >= e0) goto L2; else goto L0;
4152 L0:
4153 e = e0 * STEP + N1;
4154 L1:
4155 BODY;
4156 V += STEP;
4157 if (V cond e) goto L1;
4158 L2:
4159 */
4160
4161 static void
4162 expand_omp_for_static_nochunk (struct omp_region *region,
4163 struct omp_for_data *fd)
4164 {
4165 tree n, q, s0, e0, e, t, tt, nthreads, threadid;
4166 tree type, itype, vmain, vback;
4167 basic_block entry_bb, second_bb, third_bb, exit_bb, seq_start_bb;
4168 basic_block body_bb, cont_bb;
4169 basic_block fin_bb;
4170 gimple_stmt_iterator gsi;
4171 gimple stmt;
4172 edge ep;
4173
4174 itype = type = TREE_TYPE (fd->loop.v);
4175 if (POINTER_TYPE_P (type))
4176 itype = signed_type_for (type);
4177
4178 entry_bb = region->entry;
4179 cont_bb = region->cont;
4180 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
4181 gcc_assert (BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
4182 seq_start_bb = split_edge (FALLTHRU_EDGE (entry_bb));
4183 body_bb = single_succ (seq_start_bb);
4184 gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
4185 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
4186 fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
4187 exit_bb = region->exit;
4188
4189 /* Iteration space partitioning goes in ENTRY_BB. */
4190 gsi = gsi_last_bb (entry_bb);
4191 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
4192
4193 t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS), 0);
4194 t = fold_convert (itype, t);
4195 nthreads = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4196 true, GSI_SAME_STMT);
4197
4198 t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM), 0);
4199 t = fold_convert (itype, t);
4200 threadid = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4201 true, GSI_SAME_STMT);
4202
4203 fd->loop.n1
4204 = force_gimple_operand_gsi (&gsi, fold_convert (type, fd->loop.n1),
4205 true, NULL_TREE, true, GSI_SAME_STMT);
4206 fd->loop.n2
4207 = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->loop.n2),
4208 true, NULL_TREE, true, GSI_SAME_STMT);
4209 fd->loop.step
4210 = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->loop.step),
4211 true, NULL_TREE, true, GSI_SAME_STMT);
4212
4213 t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
4214 t = fold_build2 (PLUS_EXPR, itype, fd->loop.step, t);
4215 t = fold_build2 (PLUS_EXPR, itype, t, fd->loop.n2);
4216 t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, fd->loop.n1));
4217 if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
4218 t = fold_build2 (TRUNC_DIV_EXPR, itype,
4219 fold_build1 (NEGATE_EXPR, itype, t),
4220 fold_build1 (NEGATE_EXPR, itype, fd->loop.step));
4221 else
4222 t = fold_build2 (TRUNC_DIV_EXPR, itype, t, fd->loop.step);
4223 t = fold_convert (itype, t);
4224 n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4225
4226 q = create_tmp_reg (itype, "q");
4227 t = fold_build2 (TRUNC_DIV_EXPR, itype, n, nthreads);
4228 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
4229 gsi_insert_before (&gsi, gimple_build_assign (q, t), GSI_SAME_STMT);
4230
4231 tt = create_tmp_reg (itype, "tt");
4232 t = fold_build2 (TRUNC_MOD_EXPR, itype, n, nthreads);
4233 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
4234 gsi_insert_before (&gsi, gimple_build_assign (tt, t), GSI_SAME_STMT);
4235
4236 t = build2 (LT_EXPR, boolean_type_node, threadid, tt);
4237 stmt = gimple_build_cond_empty (t);
4238 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4239
4240 second_bb = split_block (entry_bb, stmt)->dest;
4241 gsi = gsi_last_bb (second_bb);
4242 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
4243
4244 gsi_insert_before (&gsi, gimple_build_assign (tt, build_int_cst (itype, 0)),
4245 GSI_SAME_STMT);
4246 stmt = gimple_build_assign_with_ops (PLUS_EXPR, q, q,
4247 build_int_cst (itype, 1));
4248 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4249
4250 third_bb = split_block (second_bb, stmt)->dest;
4251 gsi = gsi_last_bb (third_bb);
4252 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
4253
4254 t = build2 (MULT_EXPR, itype, q, threadid);
4255 t = build2 (PLUS_EXPR, itype, t, tt);
4256 s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4257
4258 t = fold_build2 (PLUS_EXPR, itype, s0, q);
4259 e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4260
4261 t = build2 (GE_EXPR, boolean_type_node, s0, e0);
4262 gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
4263
4264 /* Remove the GIMPLE_OMP_FOR statement. */
4265 gsi_remove (&gsi, true);
4266
4267 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4268 gsi = gsi_start_bb (seq_start_bb);
4269
4270 t = fold_convert (itype, s0);
4271 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4272 if (POINTER_TYPE_P (type))
4273 t = fold_build_pointer_plus (fd->loop.n1, t);
4274 else
4275 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4276 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4277 false, GSI_CONTINUE_LINKING);
4278 stmt = gimple_build_assign (fd->loop.v, t);
4279 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4280
4281 t = fold_convert (itype, e0);
4282 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4283 if (POINTER_TYPE_P (type))
4284 t = fold_build_pointer_plus (fd->loop.n1, t);
4285 else
4286 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4287 e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4288 false, GSI_CONTINUE_LINKING);
4289
4290 /* The code controlling the sequential loop replaces the
4291 GIMPLE_OMP_CONTINUE. */
4292 gsi = gsi_last_bb (cont_bb);
4293 stmt = gsi_stmt (gsi);
4294 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
4295 vmain = gimple_omp_continue_control_use (stmt);
4296 vback = gimple_omp_continue_control_def (stmt);
4297
4298 if (POINTER_TYPE_P (type))
4299 t = fold_build_pointer_plus (vmain, fd->loop.step);
4300 else
4301 t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
4302 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4303 true, GSI_SAME_STMT);
4304 stmt = gimple_build_assign (vback, t);
4305 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4306
4307 t = build2 (fd->loop.cond_code, boolean_type_node, vback, e);
4308 gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
4309
4310 /* Remove the GIMPLE_OMP_CONTINUE statement. */
4311 gsi_remove (&gsi, true);
4312
4313 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4314 gsi = gsi_last_bb (exit_bb);
4315 if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
4316 force_gimple_operand_gsi (&gsi, build_omp_barrier (), false, NULL_TREE,
4317 false, GSI_SAME_STMT);
4318 gsi_remove (&gsi, true);
4319
4320 /* Connect all the blocks. */
4321 ep = make_edge (entry_bb, third_bb, EDGE_FALSE_VALUE);
4322 ep->probability = REG_BR_PROB_BASE / 4 * 3;
4323 ep = find_edge (entry_bb, second_bb);
4324 ep->flags = EDGE_TRUE_VALUE;
4325 ep->probability = REG_BR_PROB_BASE / 4;
4326 find_edge (third_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
4327 find_edge (third_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
4328
4329 find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
4330 find_edge (cont_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
4331
4332 set_immediate_dominator (CDI_DOMINATORS, second_bb, entry_bb);
4333 set_immediate_dominator (CDI_DOMINATORS, third_bb, entry_bb);
4334 set_immediate_dominator (CDI_DOMINATORS, seq_start_bb, third_bb);
4335 set_immediate_dominator (CDI_DOMINATORS, body_bb,
4336 recompute_dominator (CDI_DOMINATORS, body_bb));
4337 set_immediate_dominator (CDI_DOMINATORS, fin_bb,
4338 recompute_dominator (CDI_DOMINATORS, fin_bb));
4339 }
4340
4341
4342 /* A subroutine of expand_omp_for. Generate code for a parallel
4343 loop with static schedule and a specified chunk size. Given
4344 parameters:
4345
4346 for (V = N1; V cond N2; V += STEP) BODY;
4347
4348 where COND is "<" or ">", we generate pseudocode
4349
4350 if (cond is <)
4351 adj = STEP - 1;
4352 else
4353 adj = STEP + 1;
4354 if ((__typeof (V)) -1 > 0 && cond is >)
4355 n = -(adj + N2 - N1) / -STEP;
4356 else
4357 n = (adj + N2 - N1) / STEP;
4358 trip = 0;
4359 V = threadid * CHUNK * STEP + N1; -- this extra definition of V is
4360 here so that V is defined
4361 if the loop is not entered
4362 L0:
4363 s0 = (trip * nthreads + threadid) * CHUNK;
4364 e0 = min(s0 + CHUNK, n);
4365 if (s0 < n) goto L1; else goto L4;
4366 L1:
4367 V = s0 * STEP + N1;
4368 e = e0 * STEP + N1;
4369 L2:
4370 BODY;
4371 V += STEP;
4372 if (V cond e) goto L2; else goto L3;
4373 L3:
4374 trip += 1;
4375 goto L0;
4376 L4:
4377 */
4378
4379 static void
4380 expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
4381 {
4382 tree n, s0, e0, e, t;
4383 tree trip_var, trip_init, trip_main, trip_back, nthreads, threadid;
4384 tree type, itype, v_main, v_back, v_extra;
4385 basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
4386 basic_block trip_update_bb, cont_bb, fin_bb;
4387 gimple_stmt_iterator si;
4388 gimple stmt;
4389 edge se;
4390
4391 itype = type = TREE_TYPE (fd->loop.v);
4392 if (POINTER_TYPE_P (type))
4393 itype = signed_type_for (type);
4394
4395 entry_bb = region->entry;
4396 se = split_block (entry_bb, last_stmt (entry_bb));
4397 entry_bb = se->src;
4398 iter_part_bb = se->dest;
4399 cont_bb = region->cont;
4400 gcc_assert (EDGE_COUNT (iter_part_bb->succs) == 2);
4401 gcc_assert (BRANCH_EDGE (iter_part_bb)->dest
4402 == FALLTHRU_EDGE (cont_bb)->dest);
4403 seq_start_bb = split_edge (FALLTHRU_EDGE (iter_part_bb));
4404 body_bb = single_succ (seq_start_bb);
4405 gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
4406 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
4407 fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
4408 trip_update_bb = split_edge (FALLTHRU_EDGE (cont_bb));
4409 exit_bb = region->exit;
4410
4411 /* Trip and adjustment setup goes in ENTRY_BB. */
4412 si = gsi_last_bb (entry_bb);
4413 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_FOR);
4414
4415 t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS), 0);
4416 t = fold_convert (itype, t);
4417 nthreads = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4418 true, GSI_SAME_STMT);
4419
4420 t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM), 0);
4421 t = fold_convert (itype, t);
4422 threadid = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4423 true, GSI_SAME_STMT);
4424
4425 fd->loop.n1
4426 = force_gimple_operand_gsi (&si, fold_convert (type, fd->loop.n1),
4427 true, NULL_TREE, true, GSI_SAME_STMT);
4428 fd->loop.n2
4429 = force_gimple_operand_gsi (&si, fold_convert (itype, fd->loop.n2),
4430 true, NULL_TREE, true, GSI_SAME_STMT);
4431 fd->loop.step
4432 = force_gimple_operand_gsi (&si, fold_convert (itype, fd->loop.step),
4433 true, NULL_TREE, true, GSI_SAME_STMT);
4434 fd->chunk_size
4435 = force_gimple_operand_gsi (&si, fold_convert (itype, fd->chunk_size),
4436 true, NULL_TREE, true, GSI_SAME_STMT);
4437
4438 t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
4439 t = fold_build2 (PLUS_EXPR, itype, fd->loop.step, t);
4440 t = fold_build2 (PLUS_EXPR, itype, t, fd->loop.n2);
4441 t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, fd->loop.n1));
4442 if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
4443 t = fold_build2 (TRUNC_DIV_EXPR, itype,
4444 fold_build1 (NEGATE_EXPR, itype, t),
4445 fold_build1 (NEGATE_EXPR, itype, fd->loop.step));
4446 else
4447 t = fold_build2 (TRUNC_DIV_EXPR, itype, t, fd->loop.step);
4448 t = fold_convert (itype, t);
4449 n = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4450 true, GSI_SAME_STMT);
4451
4452 trip_var = create_tmp_reg (itype, ".trip");
4453 if (gimple_in_ssa_p (cfun))
4454 {
4455 trip_init = make_ssa_name (trip_var, NULL);
4456 trip_main = make_ssa_name (trip_var, NULL);
4457 trip_back = make_ssa_name (trip_var, NULL);
4458 }
4459 else
4460 {
4461 trip_init = trip_var;
4462 trip_main = trip_var;
4463 trip_back = trip_var;
4464 }
4465
4466 stmt = gimple_build_assign (trip_init, build_int_cst (itype, 0));
4467 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
4468
4469 t = fold_build2 (MULT_EXPR, itype, threadid, fd->chunk_size);
4470 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4471 if (POINTER_TYPE_P (type))
4472 t = fold_build_pointer_plus (fd->loop.n1, t);
4473 else
4474 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4475 v_extra = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4476 true, GSI_SAME_STMT);
4477
4478 /* Remove the GIMPLE_OMP_FOR. */
4479 gsi_remove (&si, true);
4480
4481 /* Iteration space partitioning goes in ITER_PART_BB. */
4482 si = gsi_last_bb (iter_part_bb);
4483
4484 t = fold_build2 (MULT_EXPR, itype, trip_main, nthreads);
4485 t = fold_build2 (PLUS_EXPR, itype, t, threadid);
4486 t = fold_build2 (MULT_EXPR, itype, t, fd->chunk_size);
4487 s0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4488 false, GSI_CONTINUE_LINKING);
4489
4490 t = fold_build2 (PLUS_EXPR, itype, s0, fd->chunk_size);
4491 t = fold_build2 (MIN_EXPR, itype, t, n);
4492 e0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4493 false, GSI_CONTINUE_LINKING);
4494
4495 t = build2 (LT_EXPR, boolean_type_node, s0, n);
4496 gsi_insert_after (&si, gimple_build_cond_empty (t), GSI_CONTINUE_LINKING);
4497
4498 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4499 si = gsi_start_bb (seq_start_bb);
4500
4501 t = fold_convert (itype, s0);
4502 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4503 if (POINTER_TYPE_P (type))
4504 t = fold_build_pointer_plus (fd->loop.n1, t);
4505 else
4506 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4507 t = force_gimple_operand_gsi (&si, t, false, NULL_TREE,
4508 false, GSI_CONTINUE_LINKING);
4509 stmt = gimple_build_assign (fd->loop.v, t);
4510 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4511
4512 t = fold_convert (itype, e0);
4513 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4514 if (POINTER_TYPE_P (type))
4515 t = fold_build_pointer_plus (fd->loop.n1, t);
4516 else
4517 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4518 e = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4519 false, GSI_CONTINUE_LINKING);
4520
4521 /* The code controlling the sequential loop goes in CONT_BB,
4522 replacing the GIMPLE_OMP_CONTINUE. */
4523 si = gsi_last_bb (cont_bb);
4524 stmt = gsi_stmt (si);
4525 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
4526 v_main = gimple_omp_continue_control_use (stmt);
4527 v_back = gimple_omp_continue_control_def (stmt);
4528
4529 if (POINTER_TYPE_P (type))
4530 t = fold_build_pointer_plus (v_main, fd->loop.step);
4531 else
4532 t = fold_build2 (PLUS_EXPR, type, v_main, fd->loop.step);
4533 stmt = gimple_build_assign (v_back, t);
4534 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
4535
4536 t = build2 (fd->loop.cond_code, boolean_type_node, v_back, e);
4537 gsi_insert_before (&si, gimple_build_cond_empty (t), GSI_SAME_STMT);
4538
4539 /* Remove GIMPLE_OMP_CONTINUE. */
4540 gsi_remove (&si, true);
4541
4542 /* Trip update code goes into TRIP_UPDATE_BB. */
4543 si = gsi_start_bb (trip_update_bb);
4544
4545 t = build_int_cst (itype, 1);
4546 t = build2 (PLUS_EXPR, itype, trip_main, t);
4547 stmt = gimple_build_assign (trip_back, t);
4548 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4549
4550 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4551 si = gsi_last_bb (exit_bb);
4552 if (!gimple_omp_return_nowait_p (gsi_stmt (si)))
4553 force_gimple_operand_gsi (&si, build_omp_barrier (), false, NULL_TREE,
4554 false, GSI_SAME_STMT);
4555 gsi_remove (&si, true);
4556
4557 /* Connect the new blocks. */
4558 find_edge (iter_part_bb, seq_start_bb)->flags = EDGE_TRUE_VALUE;
4559 find_edge (iter_part_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
4560
4561 find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
4562 find_edge (cont_bb, trip_update_bb)->flags = EDGE_FALSE_VALUE;
4563
4564 redirect_edge_and_branch (single_succ_edge (trip_update_bb), iter_part_bb);
4565
4566 if (gimple_in_ssa_p (cfun))
4567 {
4568 gimple_stmt_iterator psi;
4569 gimple phi;
4570 edge re, ene;
4571 edge_var_map_vector head;
4572 edge_var_map *vm;
4573 size_t i;
4574
4575 /* When we redirect the edge from trip_update_bb to iter_part_bb, we
4576 remove arguments of the phi nodes in fin_bb. We need to create
4577 appropriate phi nodes in iter_part_bb instead. */
4578 se = single_pred_edge (fin_bb);
4579 re = single_succ_edge (trip_update_bb);
4580 head = redirect_edge_var_map_vector (re);
4581 ene = single_succ_edge (entry_bb);
4582
4583 psi = gsi_start_phis (fin_bb);
4584 for (i = 0; !gsi_end_p (psi) && VEC_iterate (edge_var_map, head, i, vm);
4585 gsi_next (&psi), ++i)
4586 {
4587 gimple nphi;
4588 source_location locus;
4589
4590 phi = gsi_stmt (psi);
4591 t = gimple_phi_result (phi);
4592 gcc_assert (t == redirect_edge_var_map_result (vm));
4593 nphi = create_phi_node (t, iter_part_bb);
4594
4595 t = PHI_ARG_DEF_FROM_EDGE (phi, se);
4596 locus = gimple_phi_arg_location_from_edge (phi, se);
4597
4598 /* A special case -- fd->loop.v is not yet computed in
4599 iter_part_bb, we need to use v_extra instead. */
4600 if (t == fd->loop.v)
4601 t = v_extra;
4602 add_phi_arg (nphi, t, ene, locus);
4603 locus = redirect_edge_var_map_location (vm);
4604 add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus);
4605 }
4606 gcc_assert (!gsi_end_p (psi) && i == VEC_length (edge_var_map, head));
4607 redirect_edge_var_map_clear (re);
4608 while (1)
4609 {
4610 psi = gsi_start_phis (fin_bb);
4611 if (gsi_end_p (psi))
4612 break;
4613 remove_phi_node (&psi, false);
4614 }
4615
4616 /* Make phi node for trip. */
4617 phi = create_phi_node (trip_main, iter_part_bb);
4618 add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb),
4619 UNKNOWN_LOCATION);
4620 add_phi_arg (phi, trip_init, single_succ_edge (entry_bb),
4621 UNKNOWN_LOCATION);
4622 }
4623
4624 set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
4625 set_immediate_dominator (CDI_DOMINATORS, iter_part_bb,
4626 recompute_dominator (CDI_DOMINATORS, iter_part_bb));
4627 set_immediate_dominator (CDI_DOMINATORS, fin_bb,
4628 recompute_dominator (CDI_DOMINATORS, fin_bb));
4629 set_immediate_dominator (CDI_DOMINATORS, seq_start_bb,
4630 recompute_dominator (CDI_DOMINATORS, seq_start_bb));
4631 set_immediate_dominator (CDI_DOMINATORS, body_bb,
4632 recompute_dominator (CDI_DOMINATORS, body_bb));
4633 }
4634
4635
4636 /* Expand the OpenMP loop defined by REGION. */
4637
4638 static void
4639 expand_omp_for (struct omp_region *region)
4640 {
4641 struct omp_for_data fd;
4642 struct omp_for_data_loop *loops;
4643
4644 loops
4645 = (struct omp_for_data_loop *)
4646 alloca (gimple_omp_for_collapse (last_stmt (region->entry))
4647 * sizeof (struct omp_for_data_loop));
4648 extract_omp_for_data (last_stmt (region->entry), &fd, loops);
4649 region->sched_kind = fd.sched_kind;
4650
4651 gcc_assert (EDGE_COUNT (region->entry->succs) == 2);
4652 BRANCH_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
4653 FALLTHRU_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
4654 if (region->cont)
4655 {
4656 gcc_assert (EDGE_COUNT (region->cont->succs) == 2);
4657 BRANCH_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
4658 FALLTHRU_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
4659 }
4660
4661 if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
4662 && !fd.have_ordered
4663 && fd.collapse == 1
4664 && region->cont != NULL)
4665 {
4666 if (fd.chunk_size == NULL)
4667 expand_omp_for_static_nochunk (region, &fd);
4668 else
4669 expand_omp_for_static_chunk (region, &fd);
4670 }
4671 else
4672 {
4673 int fn_index, start_ix, next_ix;
4674
4675 if (fd.chunk_size == NULL
4676 && fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
4677 fd.chunk_size = integer_zero_node;
4678 gcc_assert (fd.sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
4679 fn_index = (fd.sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
4680 ? 3 : fd.sched_kind;
4681 fn_index += fd.have_ordered * 4;
4682 start_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_START) + fn_index;
4683 next_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_NEXT) + fn_index;
4684 if (fd.iter_type == long_long_unsigned_type_node)
4685 {
4686 start_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_START
4687 - (int)BUILT_IN_GOMP_LOOP_STATIC_START);
4688 next_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT
4689 - (int)BUILT_IN_GOMP_LOOP_STATIC_NEXT);
4690 }
4691 expand_omp_for_generic (region, &fd, (enum built_in_function) start_ix,
4692 (enum built_in_function) next_ix);
4693 }
4694
4695 if (gimple_in_ssa_p (cfun))
4696 update_ssa (TODO_update_ssa_only_virtuals);
4697 }
4698
4699
4700 /* Expand code for an OpenMP sections directive. In pseudo code, we generate
4701
4702 v = GOMP_sections_start (n);
4703 L0:
4704 switch (v)
4705 {
4706 case 0:
4707 goto L2;
4708 case 1:
4709 section 1;
4710 goto L1;
4711 case 2:
4712 ...
4713 case n:
4714 ...
4715 default:
4716 abort ();
4717 }
4718 L1:
4719 v = GOMP_sections_next ();
4720 goto L0;
4721 L2:
4722 reduction;
4723
4724 If this is a combined parallel sections, replace the call to
4725 GOMP_sections_start with call to GOMP_sections_next. */
4726
4727 static void
4728 expand_omp_sections (struct omp_region *region)
4729 {
4730 tree t, u, vin = NULL, vmain, vnext, l2;
4731 VEC (tree,heap) *label_vec;
4732 unsigned len;
4733 basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
4734 gimple_stmt_iterator si, switch_si;
4735 gimple sections_stmt, stmt, cont;
4736 edge_iterator ei;
4737 edge e;
4738 struct omp_region *inner;
4739 unsigned i, casei;
4740 bool exit_reachable = region->cont != NULL;
4741
4742 gcc_assert (region->exit != NULL);
4743 entry_bb = region->entry;
4744 l0_bb = single_succ (entry_bb);
4745 l1_bb = region->cont;
4746 l2_bb = region->exit;
4747 if (single_pred_p (l2_bb) && single_pred (l2_bb) == l0_bb)
4748 l2 = gimple_block_label (l2_bb);
4749 else
4750 {
4751 /* This can happen if there are reductions. */
4752 len = EDGE_COUNT (l0_bb->succs);
4753 gcc_assert (len > 0);
4754 e = EDGE_SUCC (l0_bb, len - 1);
4755 si = gsi_last_bb (e->dest);
4756 l2 = NULL_TREE;
4757 if (gsi_end_p (si)
4758 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
4759 l2 = gimple_block_label (e->dest);
4760 else
4761 FOR_EACH_EDGE (e, ei, l0_bb->succs)
4762 {
4763 si = gsi_last_bb (e->dest);
4764 if (gsi_end_p (si)
4765 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
4766 {
4767 l2 = gimple_block_label (e->dest);
4768 break;
4769 }
4770 }
4771 }
4772 if (exit_reachable)
4773 default_bb = create_empty_bb (l1_bb->prev_bb);
4774 else
4775 default_bb = create_empty_bb (l0_bb);
4776
4777 /* We will build a switch() with enough cases for all the
4778 GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
4779 and a default case to abort if something goes wrong. */
4780 len = EDGE_COUNT (l0_bb->succs);
4781
4782 /* Use VEC_quick_push on label_vec throughout, since we know the size
4783 in advance. */
4784 label_vec = VEC_alloc (tree, heap, len);
4785
4786 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
4787 GIMPLE_OMP_SECTIONS statement. */
4788 si = gsi_last_bb (entry_bb);
4789 sections_stmt = gsi_stmt (si);
4790 gcc_assert (gimple_code (sections_stmt) == GIMPLE_OMP_SECTIONS);
4791 vin = gimple_omp_sections_control (sections_stmt);
4792 if (!is_combined_parallel (region))
4793 {
4794 /* If we are not inside a combined parallel+sections region,
4795 call GOMP_sections_start. */
4796 t = build_int_cst (unsigned_type_node,
4797 exit_reachable ? len - 1 : len);
4798 u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START);
4799 stmt = gimple_build_call (u, 1, t);
4800 }
4801 else
4802 {
4803 /* Otherwise, call GOMP_sections_next. */
4804 u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
4805 stmt = gimple_build_call (u, 0);
4806 }
4807 gimple_call_set_lhs (stmt, vin);
4808 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4809 gsi_remove (&si, true);
4810
4811 /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
4812 L0_BB. */
4813 switch_si = gsi_last_bb (l0_bb);
4814 gcc_assert (gimple_code (gsi_stmt (switch_si)) == GIMPLE_OMP_SECTIONS_SWITCH);
4815 if (exit_reachable)
4816 {
4817 cont = last_stmt (l1_bb);
4818 gcc_assert (gimple_code (cont) == GIMPLE_OMP_CONTINUE);
4819 vmain = gimple_omp_continue_control_use (cont);
4820 vnext = gimple_omp_continue_control_def (cont);
4821 }
4822 else
4823 {
4824 vmain = vin;
4825 vnext = NULL_TREE;
4826 }
4827
4828 t = build_case_label (build_int_cst (unsigned_type_node, 0), NULL, l2);
4829 VEC_quick_push (tree, label_vec, t);
4830 i = 1;
4831
4832 /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR. */
4833 for (inner = region->inner, casei = 1;
4834 inner;
4835 inner = inner->next, i++, casei++)
4836 {
4837 basic_block s_entry_bb, s_exit_bb;
4838
4839 /* Skip optional reduction region. */
4840 if (inner->type == GIMPLE_OMP_ATOMIC_LOAD)
4841 {
4842 --i;
4843 --casei;
4844 continue;
4845 }
4846
4847 s_entry_bb = inner->entry;
4848 s_exit_bb = inner->exit;
4849
4850 t = gimple_block_label (s_entry_bb);
4851 u = build_int_cst (unsigned_type_node, casei);
4852 u = build_case_label (u, NULL, t);
4853 VEC_quick_push (tree, label_vec, u);
4854
4855 si = gsi_last_bb (s_entry_bb);
4856 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SECTION);
4857 gcc_assert (i < len || gimple_omp_section_last_p (gsi_stmt (si)));
4858 gsi_remove (&si, true);
4859 single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
4860
4861 if (s_exit_bb == NULL)
4862 continue;
4863
4864 si = gsi_last_bb (s_exit_bb);
4865 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
4866 gsi_remove (&si, true);
4867
4868 single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
4869 }
4870
4871 /* Error handling code goes in DEFAULT_BB. */
4872 t = gimple_block_label (default_bb);
4873 u = build_case_label (NULL, NULL, t);
4874 make_edge (l0_bb, default_bb, 0);
4875
4876 stmt = gimple_build_switch_vec (vmain, u, label_vec);
4877 gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
4878 gsi_remove (&switch_si, true);
4879 VEC_free (tree, heap, label_vec);
4880
4881 si = gsi_start_bb (default_bb);
4882 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
4883 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4884
4885 if (exit_reachable)
4886 {
4887 tree bfn_decl;
4888
4889 /* Code to get the next section goes in L1_BB. */
4890 si = gsi_last_bb (l1_bb);
4891 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CONTINUE);
4892
4893 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
4894 stmt = gimple_build_call (bfn_decl, 0);
4895 gimple_call_set_lhs (stmt, vnext);
4896 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4897 gsi_remove (&si, true);
4898
4899 single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
4900 }
4901
4902 /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB. */
4903 si = gsi_last_bb (l2_bb);
4904 if (gimple_omp_return_nowait_p (gsi_stmt (si)))
4905 t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT);
4906 else
4907 t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END);
4908 stmt = gimple_build_call (t, 0);
4909 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4910 gsi_remove (&si, true);
4911
4912 set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb);
4913 }
4914
4915
4916 /* Expand code for an OpenMP single directive. We've already expanded
4917 much of the code, here we simply place the GOMP_barrier call. */
4918
4919 static void
4920 expand_omp_single (struct omp_region *region)
4921 {
4922 basic_block entry_bb, exit_bb;
4923 gimple_stmt_iterator si;
4924 bool need_barrier = false;
4925
4926 entry_bb = region->entry;
4927 exit_bb = region->exit;
4928
4929 si = gsi_last_bb (entry_bb);
4930 /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
4931 be removed. We need to ensure that the thread that entered the single
4932 does not exit before the data is copied out by the other threads. */
4933 if (find_omp_clause (gimple_omp_single_clauses (gsi_stmt (si)),
4934 OMP_CLAUSE_COPYPRIVATE))
4935 need_barrier = true;
4936 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE);
4937 gsi_remove (&si, true);
4938 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
4939
4940 si = gsi_last_bb (exit_bb);
4941 if (!gimple_omp_return_nowait_p (gsi_stmt (si)) || need_barrier)
4942 force_gimple_operand_gsi (&si, build_omp_barrier (), false, NULL_TREE,
4943 false, GSI_SAME_STMT);
4944 gsi_remove (&si, true);
4945 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
4946 }
4947
4948
4949 /* Generic expansion for OpenMP synchronization directives: master,
4950 ordered and critical. All we need to do here is remove the entry
4951 and exit markers for REGION. */
4952
4953 static void
4954 expand_omp_synch (struct omp_region *region)
4955 {
4956 basic_block entry_bb, exit_bb;
4957 gimple_stmt_iterator si;
4958
4959 entry_bb = region->entry;
4960 exit_bb = region->exit;
4961
4962 si = gsi_last_bb (entry_bb);
4963 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE
4964 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASTER
4965 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ORDERED
4966 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CRITICAL);
4967 gsi_remove (&si, true);
4968 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
4969
4970 if (exit_bb)
4971 {
4972 si = gsi_last_bb (exit_bb);
4973 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
4974 gsi_remove (&si, true);
4975 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
4976 }
4977 }
4978
4979 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
4980 operation as a normal volatile load. */
4981
4982 static bool
4983 expand_omp_atomic_load (basic_block load_bb, tree addr,
4984 tree loaded_val, int index)
4985 {
4986 enum built_in_function tmpbase;
4987 gimple_stmt_iterator gsi;
4988 basic_block store_bb;
4989 location_t loc;
4990 gimple stmt;
4991 tree decl, call, type, itype;
4992
4993 gsi = gsi_last_bb (load_bb);
4994 stmt = gsi_stmt (gsi);
4995 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
4996 loc = gimple_location (stmt);
4997
4998 /* ??? If the target does not implement atomic_load_optab[mode], and mode
4999 is smaller than word size, then expand_atomic_load assumes that the load
5000 is atomic. We could avoid the builtin entirely in this case. */
5001
5002 tmpbase = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
5003 decl = builtin_decl_explicit (tmpbase);
5004 if (decl == NULL_TREE)
5005 return false;
5006
5007 type = TREE_TYPE (loaded_val);
5008 itype = TREE_TYPE (TREE_TYPE (decl));
5009
5010 call = build_call_expr_loc (loc, decl, 2, addr,
5011 build_int_cst (NULL, MEMMODEL_RELAXED));
5012 if (!useless_type_conversion_p (type, itype))
5013 call = fold_build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
5014 call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
5015
5016 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5017 gsi_remove (&gsi, true);
5018
5019 store_bb = single_succ (load_bb);
5020 gsi = gsi_last_bb (store_bb);
5021 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
5022 gsi_remove (&gsi, true);
5023
5024 if (gimple_in_ssa_p (cfun))
5025 update_ssa (TODO_update_ssa_no_phi);
5026
5027 return true;
5028 }
5029
5030 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5031 operation as a normal volatile store. */
5032
5033 static bool
5034 expand_omp_atomic_store (basic_block load_bb, tree addr,
5035 tree loaded_val, tree stored_val, int index)
5036 {
5037 enum built_in_function tmpbase;
5038 gimple_stmt_iterator gsi;
5039 basic_block store_bb = single_succ (load_bb);
5040 location_t loc;
5041 gimple stmt;
5042 tree decl, call, type, itype;
5043 enum machine_mode imode;
5044 bool exchange;
5045
5046 gsi = gsi_last_bb (load_bb);
5047 stmt = gsi_stmt (gsi);
5048 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
5049
5050 /* If the load value is needed, then this isn't a store but an exchange. */
5051 exchange = gimple_omp_atomic_need_value_p (stmt);
5052
5053 gsi = gsi_last_bb (store_bb);
5054 stmt = gsi_stmt (gsi);
5055 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE);
5056 loc = gimple_location (stmt);
5057
5058 /* ??? If the target does not implement atomic_store_optab[mode], and mode
5059 is smaller than word size, then expand_atomic_store assumes that the store
5060 is atomic. We could avoid the builtin entirely in this case. */
5061
5062 tmpbase = (exchange ? BUILT_IN_ATOMIC_EXCHANGE_N : BUILT_IN_ATOMIC_STORE_N);
5063 tmpbase = (enum built_in_function) ((int) tmpbase + index + 1);
5064 decl = builtin_decl_explicit (tmpbase);
5065 if (decl == NULL_TREE)
5066 return false;
5067
5068 type = TREE_TYPE (stored_val);
5069
5070 /* Dig out the type of the function's second argument. */
5071 itype = TREE_TYPE (decl);
5072 itype = TYPE_ARG_TYPES (itype);
5073 itype = TREE_CHAIN (itype);
5074 itype = TREE_VALUE (itype);
5075 imode = TYPE_MODE (itype);
5076
5077 if (exchange && !can_atomic_exchange_p (imode, true))
5078 return false;
5079
5080 if (!useless_type_conversion_p (itype, type))
5081 stored_val = fold_build1_loc (loc, VIEW_CONVERT_EXPR, itype, stored_val);
5082 call = build_call_expr_loc (loc, decl, 3, addr, stored_val,
5083 build_int_cst (NULL, MEMMODEL_RELAXED));
5084 if (exchange)
5085 {
5086 if (!useless_type_conversion_p (type, itype))
5087 call = build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
5088 call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
5089 }
5090
5091 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5092 gsi_remove (&gsi, true);
5093
5094 /* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above. */
5095 gsi = gsi_last_bb (load_bb);
5096 gsi_remove (&gsi, true);
5097
5098 if (gimple_in_ssa_p (cfun))
5099 update_ssa (TODO_update_ssa_no_phi);
5100
5101 return true;
5102 }
5103
5104 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5105 operation as a __atomic_fetch_op builtin. INDEX is log2 of the
5106 size of the data type, and thus usable to find the index of the builtin
5107 decl. Returns false if the expression is not of the proper form. */
5108
5109 static bool
5110 expand_omp_atomic_fetch_op (basic_block load_bb,
5111 tree addr, tree loaded_val,
5112 tree stored_val, int index)
5113 {
5114 enum built_in_function oldbase, newbase, tmpbase;
5115 tree decl, itype, call;
5116 tree lhs, rhs;
5117 basic_block store_bb = single_succ (load_bb);
5118 gimple_stmt_iterator gsi;
5119 gimple stmt;
5120 location_t loc;
5121 enum tree_code code;
5122 bool need_old, need_new;
5123 enum machine_mode imode;
5124
5125 /* We expect to find the following sequences:
5126
5127 load_bb:
5128 GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
5129
5130 store_bb:
5131 val = tmp OP something; (or: something OP tmp)
5132 GIMPLE_OMP_STORE (val)
5133
5134 ???FIXME: Allow a more flexible sequence.
5135 Perhaps use data flow to pick the statements.
5136
5137 */
5138
5139 gsi = gsi_after_labels (store_bb);
5140 stmt = gsi_stmt (gsi);
5141 loc = gimple_location (stmt);
5142 if (!is_gimple_assign (stmt))
5143 return false;
5144 gsi_next (&gsi);
5145 if (gimple_code (gsi_stmt (gsi)) != GIMPLE_OMP_ATOMIC_STORE)
5146 return false;
5147 need_new = gimple_omp_atomic_need_value_p (gsi_stmt (gsi));
5148 need_old = gimple_omp_atomic_need_value_p (last_stmt (load_bb));
5149 gcc_checking_assert (!need_old || !need_new);
5150
5151 if (!operand_equal_p (gimple_assign_lhs (stmt), stored_val, 0))
5152 return false;
5153
5154 /* Check for one of the supported fetch-op operations. */
5155 code = gimple_assign_rhs_code (stmt);
5156 switch (code)
5157 {
5158 case PLUS_EXPR:
5159 case POINTER_PLUS_EXPR:
5160 oldbase = BUILT_IN_ATOMIC_FETCH_ADD_N;
5161 newbase = BUILT_IN_ATOMIC_ADD_FETCH_N;
5162 break;
5163 case MINUS_EXPR:
5164 oldbase = BUILT_IN_ATOMIC_FETCH_SUB_N;
5165 newbase = BUILT_IN_ATOMIC_SUB_FETCH_N;
5166 break;
5167 case BIT_AND_EXPR:
5168 oldbase = BUILT_IN_ATOMIC_FETCH_AND_N;
5169 newbase = BUILT_IN_ATOMIC_AND_FETCH_N;
5170 break;
5171 case BIT_IOR_EXPR:
5172 oldbase = BUILT_IN_ATOMIC_FETCH_OR_N;
5173 newbase = BUILT_IN_ATOMIC_OR_FETCH_N;
5174 break;
5175 case BIT_XOR_EXPR:
5176 oldbase = BUILT_IN_ATOMIC_FETCH_XOR_N;
5177 newbase = BUILT_IN_ATOMIC_XOR_FETCH_N;
5178 break;
5179 default:
5180 return false;
5181 }
5182
5183 /* Make sure the expression is of the proper form. */
5184 if (operand_equal_p (gimple_assign_rhs1 (stmt), loaded_val, 0))
5185 rhs = gimple_assign_rhs2 (stmt);
5186 else if (commutative_tree_code (gimple_assign_rhs_code (stmt))
5187 && operand_equal_p (gimple_assign_rhs2 (stmt), loaded_val, 0))
5188 rhs = gimple_assign_rhs1 (stmt);
5189 else
5190 return false;
5191
5192 tmpbase = ((enum built_in_function)
5193 ((need_new ? newbase : oldbase) + index + 1));
5194 decl = builtin_decl_explicit (tmpbase);
5195 if (decl == NULL_TREE)
5196 return false;
5197 itype = TREE_TYPE (TREE_TYPE (decl));
5198 imode = TYPE_MODE (itype);
5199
5200 /* We could test all of the various optabs involved, but the fact of the
5201 matter is that (with the exception of i486 vs i586 and xadd) all targets
5202 that support any atomic operaton optab also implements compare-and-swap.
5203 Let optabs.c take care of expanding any compare-and-swap loop. */
5204 if (!can_compare_and_swap_p (imode, true))
5205 return false;
5206
5207 gsi = gsi_last_bb (load_bb);
5208 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_LOAD);
5209
5210 /* OpenMP does not imply any barrier-like semantics on its atomic ops.
5211 It only requires that the operation happen atomically. Thus we can
5212 use the RELAXED memory model. */
5213 call = build_call_expr_loc (loc, decl, 3, addr,
5214 fold_convert_loc (loc, itype, rhs),
5215 build_int_cst (NULL, MEMMODEL_RELAXED));
5216
5217 if (need_old || need_new)
5218 {
5219 lhs = need_old ? loaded_val : stored_val;
5220 call = fold_convert_loc (loc, TREE_TYPE (lhs), call);
5221 call = build2_loc (loc, MODIFY_EXPR, void_type_node, lhs, call);
5222 }
5223 else
5224 call = fold_convert_loc (loc, void_type_node, call);
5225 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5226 gsi_remove (&gsi, true);
5227
5228 gsi = gsi_last_bb (store_bb);
5229 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
5230 gsi_remove (&gsi, true);
5231 gsi = gsi_last_bb (store_bb);
5232 gsi_remove (&gsi, true);
5233
5234 if (gimple_in_ssa_p (cfun))
5235 update_ssa (TODO_update_ssa_no_phi);
5236
5237 return true;
5238 }
5239
5240 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5241
5242 oldval = *addr;
5243 repeat:
5244 newval = rhs; // with oldval replacing *addr in rhs
5245 oldval = __sync_val_compare_and_swap (addr, oldval, newval);
5246 if (oldval != newval)
5247 goto repeat;
5248
5249 INDEX is log2 of the size of the data type, and thus usable to find the
5250 index of the builtin decl. */
5251
5252 static bool
5253 expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
5254 tree addr, tree loaded_val, tree stored_val,
5255 int index)
5256 {
5257 tree loadedi, storedi, initial, new_storedi, old_vali;
5258 tree type, itype, cmpxchg, iaddr;
5259 gimple_stmt_iterator si;
5260 basic_block loop_header = single_succ (load_bb);
5261 gimple phi, stmt;
5262 edge e;
5263 enum built_in_function fncode;
5264
5265 /* ??? We need a non-pointer interface to __atomic_compare_exchange in
5266 order to use the RELAXED memory model effectively. */
5267 fncode = (enum built_in_function)((int)BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
5268 + index + 1);
5269 cmpxchg = builtin_decl_explicit (fncode);
5270 if (cmpxchg == NULL_TREE)
5271 return false;
5272 type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5273 itype = TREE_TYPE (TREE_TYPE (cmpxchg));
5274
5275 if (!can_compare_and_swap_p (TYPE_MODE (itype), true))
5276 return false;
5277
5278 /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */
5279 si = gsi_last_bb (load_bb);
5280 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
5281
5282 /* For floating-point values, we'll need to view-convert them to integers
5283 so that we can perform the atomic compare and swap. Simplify the
5284 following code by always setting up the "i"ntegral variables. */
5285 if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
5286 {
5287 tree iaddr_val;
5288
5289 iaddr = create_tmp_reg (build_pointer_type_for_mode (itype, ptr_mode,
5290 true), NULL);
5291 iaddr_val
5292 = force_gimple_operand_gsi (&si,
5293 fold_convert (TREE_TYPE (iaddr), addr),
5294 false, NULL_TREE, true, GSI_SAME_STMT);
5295 stmt = gimple_build_assign (iaddr, iaddr_val);
5296 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5297 loadedi = create_tmp_var (itype, NULL);
5298 if (gimple_in_ssa_p (cfun))
5299 loadedi = make_ssa_name (loadedi, NULL);
5300 }
5301 else
5302 {
5303 iaddr = addr;
5304 loadedi = loaded_val;
5305 }
5306
5307 initial
5308 = force_gimple_operand_gsi (&si,
5309 build2 (MEM_REF, TREE_TYPE (TREE_TYPE (iaddr)),
5310 iaddr,
5311 build_int_cst (TREE_TYPE (iaddr), 0)),
5312 true, NULL_TREE, true, GSI_SAME_STMT);
5313
5314 /* Move the value to the LOADEDI temporary. */
5315 if (gimple_in_ssa_p (cfun))
5316 {
5317 gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header)));
5318 phi = create_phi_node (loadedi, loop_header);
5319 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (load_bb)),
5320 initial);
5321 }
5322 else
5323 gsi_insert_before (&si,
5324 gimple_build_assign (loadedi, initial),
5325 GSI_SAME_STMT);
5326 if (loadedi != loaded_val)
5327 {
5328 gimple_stmt_iterator gsi2;
5329 tree x;
5330
5331 x = build1 (VIEW_CONVERT_EXPR, type, loadedi);
5332 gsi2 = gsi_start_bb (loop_header);
5333 if (gimple_in_ssa_p (cfun))
5334 {
5335 gimple stmt;
5336 x = force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
5337 true, GSI_SAME_STMT);
5338 stmt = gimple_build_assign (loaded_val, x);
5339 gsi_insert_before (&gsi2, stmt, GSI_SAME_STMT);
5340 }
5341 else
5342 {
5343 x = build2 (MODIFY_EXPR, TREE_TYPE (loaded_val), loaded_val, x);
5344 force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
5345 true, GSI_SAME_STMT);
5346 }
5347 }
5348 gsi_remove (&si, true);
5349
5350 si = gsi_last_bb (store_bb);
5351 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
5352
5353 if (iaddr == addr)
5354 storedi = stored_val;
5355 else
5356 storedi =
5357 force_gimple_operand_gsi (&si,
5358 build1 (VIEW_CONVERT_EXPR, itype,
5359 stored_val), true, NULL_TREE, true,
5360 GSI_SAME_STMT);
5361
5362 /* Build the compare&swap statement. */
5363 new_storedi = build_call_expr (cmpxchg, 3, iaddr, loadedi, storedi);
5364 new_storedi = force_gimple_operand_gsi (&si,
5365 fold_convert (TREE_TYPE (loadedi),
5366 new_storedi),
5367 true, NULL_TREE,
5368 true, GSI_SAME_STMT);
5369
5370 if (gimple_in_ssa_p (cfun))
5371 old_vali = loadedi;
5372 else
5373 {
5374 old_vali = create_tmp_var (TREE_TYPE (loadedi), NULL);
5375 stmt = gimple_build_assign (old_vali, loadedi);
5376 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5377
5378 stmt = gimple_build_assign (loadedi, new_storedi);
5379 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5380 }
5381
5382 /* Note that we always perform the comparison as an integer, even for
5383 floating point. This allows the atomic operation to properly
5384 succeed even with NaNs and -0.0. */
5385 stmt = gimple_build_cond_empty
5386 (build2 (NE_EXPR, boolean_type_node,
5387 new_storedi, old_vali));
5388 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5389
5390 /* Update cfg. */
5391 e = single_succ_edge (store_bb);
5392 e->flags &= ~EDGE_FALLTHRU;
5393 e->flags |= EDGE_FALSE_VALUE;
5394
5395 e = make_edge (store_bb, loop_header, EDGE_TRUE_VALUE);
5396
5397 /* Copy the new value to loadedi (we already did that before the condition
5398 if we are not in SSA). */
5399 if (gimple_in_ssa_p (cfun))
5400 {
5401 phi = gimple_seq_first_stmt (phi_nodes (loop_header));
5402 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), new_storedi);
5403 }
5404
5405 /* Remove GIMPLE_OMP_ATOMIC_STORE. */
5406 gsi_remove (&si, true);
5407
5408 if (gimple_in_ssa_p (cfun))
5409 update_ssa (TODO_update_ssa_no_phi);
5410
5411 return true;
5412 }
5413
5414 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5415
5416 GOMP_atomic_start ();
5417 *addr = rhs;
5418 GOMP_atomic_end ();
5419
5420 The result is not globally atomic, but works so long as all parallel
5421 references are within #pragma omp atomic directives. According to
5422 responses received from omp@openmp.org, appears to be within spec.
5423 Which makes sense, since that's how several other compilers handle
5424 this situation as well.
5425 LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
5426 expanding. STORED_VAL is the operand of the matching
5427 GIMPLE_OMP_ATOMIC_STORE.
5428
5429 We replace
5430 GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
5431 loaded_val = *addr;
5432
5433 and replace
5434 GIMPLE_OMP_ATOMIC_STORE (stored_val) with
5435 *addr = stored_val;
5436 */
5437
5438 static bool
5439 expand_omp_atomic_mutex (basic_block load_bb, basic_block store_bb,
5440 tree addr, tree loaded_val, tree stored_val)
5441 {
5442 gimple_stmt_iterator si;
5443 gimple stmt;
5444 tree t;
5445
5446 si = gsi_last_bb (load_bb);
5447 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
5448
5449 t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
5450 t = build_call_expr (t, 0);
5451 force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
5452
5453 stmt = gimple_build_assign (loaded_val, build_simple_mem_ref (addr));
5454 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5455 gsi_remove (&si, true);
5456
5457 si = gsi_last_bb (store_bb);
5458 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
5459
5460 stmt = gimple_build_assign (build_simple_mem_ref (unshare_expr (addr)),
5461 stored_val);
5462 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5463
5464 t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
5465 t = build_call_expr (t, 0);
5466 force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
5467 gsi_remove (&si, true);
5468
5469 if (gimple_in_ssa_p (cfun))
5470 update_ssa (TODO_update_ssa_no_phi);
5471 return true;
5472 }
5473
5474 /* Expand an GIMPLE_OMP_ATOMIC statement. We try to expand
5475 using expand_omp_atomic_fetch_op. If it failed, we try to
5476 call expand_omp_atomic_pipeline, and if it fails too, the
5477 ultimate fallback is wrapping the operation in a mutex
5478 (expand_omp_atomic_mutex). REGION is the atomic region built
5479 by build_omp_regions_1(). */
5480
5481 static void
5482 expand_omp_atomic (struct omp_region *region)
5483 {
5484 basic_block load_bb = region->entry, store_bb = region->exit;
5485 gimple load = last_stmt (load_bb), store = last_stmt (store_bb);
5486 tree loaded_val = gimple_omp_atomic_load_lhs (load);
5487 tree addr = gimple_omp_atomic_load_rhs (load);
5488 tree stored_val = gimple_omp_atomic_store_val (store);
5489 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5490 HOST_WIDE_INT index;
5491
5492 /* Make sure the type is one of the supported sizes. */
5493 index = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5494 index = exact_log2 (index);
5495 if (index >= 0 && index <= 4)
5496 {
5497 unsigned int align = TYPE_ALIGN_UNIT (type);
5498
5499 /* __sync builtins require strict data alignment. */
5500 if (exact_log2 (align) >= index)
5501 {
5502 /* Atomic load. */
5503 if (loaded_val == stored_val
5504 && (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
5505 || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
5506 && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
5507 && expand_omp_atomic_load (load_bb, addr, loaded_val, index))
5508 return;
5509
5510 /* Atomic store. */
5511 if ((GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
5512 || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
5513 && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
5514 && store_bb == single_succ (load_bb)
5515 && first_stmt (store_bb) == store
5516 && expand_omp_atomic_store (load_bb, addr, loaded_val,
5517 stored_val, index))
5518 return;
5519
5520 /* When possible, use specialized atomic update functions. */
5521 if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
5522 && store_bb == single_succ (load_bb)
5523 && expand_omp_atomic_fetch_op (load_bb, addr,
5524 loaded_val, stored_val, index))
5525 return;
5526
5527 /* If we don't have specialized __sync builtins, try and implement
5528 as a compare and swap loop. */
5529 if (expand_omp_atomic_pipeline (load_bb, store_bb, addr,
5530 loaded_val, stored_val, index))
5531 return;
5532 }
5533 }
5534
5535 /* The ultimate fallback is wrapping the operation in a mutex. */
5536 expand_omp_atomic_mutex (load_bb, store_bb, addr, loaded_val, stored_val);
5537 }
5538
5539
5540 /* Expand the parallel region tree rooted at REGION. Expansion
5541 proceeds in depth-first order. Innermost regions are expanded
5542 first. This way, parallel regions that require a new function to
5543 be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
5544 internal dependencies in their body. */
5545
5546 static void
5547 expand_omp (struct omp_region *region)
5548 {
5549 while (region)
5550 {
5551 location_t saved_location;
5552
5553 /* First, determine whether this is a combined parallel+workshare
5554 region. */
5555 if (region->type == GIMPLE_OMP_PARALLEL)
5556 determine_parallel_type (region);
5557
5558 if (region->inner)
5559 expand_omp (region->inner);
5560
5561 saved_location = input_location;
5562 if (gimple_has_location (last_stmt (region->entry)))
5563 input_location = gimple_location (last_stmt (region->entry));
5564
5565 switch (region->type)
5566 {
5567 case GIMPLE_OMP_PARALLEL:
5568 case GIMPLE_OMP_TASK:
5569 expand_omp_taskreg (region);
5570 break;
5571
5572 case GIMPLE_OMP_FOR:
5573 expand_omp_for (region);
5574 break;
5575
5576 case GIMPLE_OMP_SECTIONS:
5577 expand_omp_sections (region);
5578 break;
5579
5580 case GIMPLE_OMP_SECTION:
5581 /* Individual omp sections are handled together with their
5582 parent GIMPLE_OMP_SECTIONS region. */
5583 break;
5584
5585 case GIMPLE_OMP_SINGLE:
5586 expand_omp_single (region);
5587 break;
5588
5589 case GIMPLE_OMP_MASTER:
5590 case GIMPLE_OMP_ORDERED:
5591 case GIMPLE_OMP_CRITICAL:
5592 expand_omp_synch (region);
5593 break;
5594
5595 case GIMPLE_OMP_ATOMIC_LOAD:
5596 expand_omp_atomic (region);
5597 break;
5598
5599 default:
5600 gcc_unreachable ();
5601 }
5602
5603 input_location = saved_location;
5604 region = region->next;
5605 }
5606 }
5607
5608
5609 /* Helper for build_omp_regions. Scan the dominator tree starting at
5610 block BB. PARENT is the region that contains BB. If SINGLE_TREE is
5611 true, the function ends once a single tree is built (otherwise, whole
5612 forest of OMP constructs may be built). */
5613
5614 static void
5615 build_omp_regions_1 (basic_block bb, struct omp_region *parent,
5616 bool single_tree)
5617 {
5618 gimple_stmt_iterator gsi;
5619 gimple stmt;
5620 basic_block son;
5621
5622 gsi = gsi_last_bb (bb);
5623 if (!gsi_end_p (gsi) && is_gimple_omp (gsi_stmt (gsi)))
5624 {
5625 struct omp_region *region;
5626 enum gimple_code code;
5627
5628 stmt = gsi_stmt (gsi);
5629 code = gimple_code (stmt);
5630 if (code == GIMPLE_OMP_RETURN)
5631 {
5632 /* STMT is the return point out of region PARENT. Mark it
5633 as the exit point and make PARENT the immediately
5634 enclosing region. */
5635 gcc_assert (parent);
5636 region = parent;
5637 region->exit = bb;
5638 parent = parent->outer;
5639 }
5640 else if (code == GIMPLE_OMP_ATOMIC_STORE)
5641 {
5642 /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
5643 GIMPLE_OMP_RETURN, but matches with
5644 GIMPLE_OMP_ATOMIC_LOAD. */
5645 gcc_assert (parent);
5646 gcc_assert (parent->type == GIMPLE_OMP_ATOMIC_LOAD);
5647 region = parent;
5648 region->exit = bb;
5649 parent = parent->outer;
5650 }
5651
5652 else if (code == GIMPLE_OMP_CONTINUE)
5653 {
5654 gcc_assert (parent);
5655 parent->cont = bb;
5656 }
5657 else if (code == GIMPLE_OMP_SECTIONS_SWITCH)
5658 {
5659 /* GIMPLE_OMP_SECTIONS_SWITCH is part of
5660 GIMPLE_OMP_SECTIONS, and we do nothing for it. */
5661 ;
5662 }
5663 else
5664 {
5665 /* Otherwise, this directive becomes the parent for a new
5666 region. */
5667 region = new_omp_region (bb, code, parent);
5668 parent = region;
5669 }
5670 }
5671
5672 if (single_tree && !parent)
5673 return;
5674
5675 for (son = first_dom_son (CDI_DOMINATORS, bb);
5676 son;
5677 son = next_dom_son (CDI_DOMINATORS, son))
5678 build_omp_regions_1 (son, parent, single_tree);
5679 }
5680
5681 /* Builds the tree of OMP regions rooted at ROOT, storing it to
5682 root_omp_region. */
5683
5684 static void
5685 build_omp_regions_root (basic_block root)
5686 {
5687 gcc_assert (root_omp_region == NULL);
5688 build_omp_regions_1 (root, NULL, true);
5689 gcc_assert (root_omp_region != NULL);
5690 }
5691
5692 /* Expands omp construct (and its subconstructs) starting in HEAD. */
5693
5694 void
5695 omp_expand_local (basic_block head)
5696 {
5697 build_omp_regions_root (head);
5698 if (dump_file && (dump_flags & TDF_DETAILS))
5699 {
5700 fprintf (dump_file, "\nOMP region tree\n\n");
5701 dump_omp_region (dump_file, root_omp_region, 0);
5702 fprintf (dump_file, "\n");
5703 }
5704
5705 remove_exit_barriers (root_omp_region);
5706 expand_omp (root_omp_region);
5707
5708 free_omp_regions ();
5709 }
5710
5711 /* Scan the CFG and build a tree of OMP regions. Return the root of
5712 the OMP region tree. */
5713
5714 static void
5715 build_omp_regions (void)
5716 {
5717 gcc_assert (root_omp_region == NULL);
5718 calculate_dominance_info (CDI_DOMINATORS);
5719 build_omp_regions_1 (ENTRY_BLOCK_PTR, NULL, false);
5720 }
5721
5722 /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
5723
5724 static unsigned int
5725 execute_expand_omp (void)
5726 {
5727 build_omp_regions ();
5728
5729 if (!root_omp_region)
5730 return 0;
5731
5732 if (dump_file)
5733 {
5734 fprintf (dump_file, "\nOMP region tree\n\n");
5735 dump_omp_region (dump_file, root_omp_region, 0);
5736 fprintf (dump_file, "\n");
5737 }
5738
5739 remove_exit_barriers (root_omp_region);
5740
5741 expand_omp (root_omp_region);
5742
5743 cleanup_tree_cfg ();
5744
5745 free_omp_regions ();
5746
5747 return 0;
5748 }
5749
5750 /* OMP expansion -- the default pass, run before creation of SSA form. */
5751
5752 static bool
5753 gate_expand_omp (void)
5754 {
5755 return (flag_openmp != 0 && !seen_error ());
5756 }
5757
5758 struct gimple_opt_pass pass_expand_omp =
5759 {
5760 {
5761 GIMPLE_PASS,
5762 "ompexp", /* name */
5763 gate_expand_omp, /* gate */
5764 execute_expand_omp, /* execute */
5765 NULL, /* sub */
5766 NULL, /* next */
5767 0, /* static_pass_number */
5768 TV_NONE, /* tv_id */
5769 PROP_gimple_any, /* properties_required */
5770 0, /* properties_provided */
5771 0, /* properties_destroyed */
5772 0, /* todo_flags_start */
5773 0 /* todo_flags_finish */
5774 }
5775 };
5776 \f
5777 /* Routines to lower OpenMP directives into OMP-GIMPLE. */
5778
5779 /* Lower the OpenMP sections directive in the current statement in GSI_P.
5780 CTX is the enclosing OMP context for the current statement. */
5781
5782 static void
5783 lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
5784 {
5785 tree block, control;
5786 gimple_stmt_iterator tgsi;
5787 gimple stmt, new_stmt, bind, t;
5788 gimple_seq ilist, dlist, olist, new_body;
5789 struct gimplify_ctx gctx;
5790
5791 stmt = gsi_stmt (*gsi_p);
5792
5793 push_gimplify_context (&gctx);
5794
5795 dlist = NULL;
5796 ilist = NULL;
5797 lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
5798 &ilist, &dlist, ctx);
5799
5800 new_body = gimple_omp_body (stmt);
5801 gimple_omp_set_body (stmt, NULL);
5802 tgsi = gsi_start (new_body);
5803 for (; !gsi_end_p (tgsi); gsi_next (&tgsi))
5804 {
5805 omp_context *sctx;
5806 gimple sec_start;
5807
5808 sec_start = gsi_stmt (tgsi);
5809 sctx = maybe_lookup_ctx (sec_start);
5810 gcc_assert (sctx);
5811
5812 lower_omp (gimple_omp_body_ptr (sec_start), sctx);
5813 gsi_insert_seq_after (&tgsi, gimple_omp_body (sec_start),
5814 GSI_CONTINUE_LINKING);
5815 gimple_omp_set_body (sec_start, NULL);
5816
5817 if (gsi_one_before_end_p (tgsi))
5818 {
5819 gimple_seq l = NULL;
5820 lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
5821 &l, ctx);
5822 gsi_insert_seq_after (&tgsi, l, GSI_CONTINUE_LINKING);
5823 gimple_omp_section_set_last (sec_start);
5824 }
5825
5826 gsi_insert_after (&tgsi, gimple_build_omp_return (false),
5827 GSI_CONTINUE_LINKING);
5828 }
5829
5830 block = make_node (BLOCK);
5831 bind = gimple_build_bind (NULL, new_body, block);
5832
5833 olist = NULL;
5834 lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
5835
5836 block = make_node (BLOCK);
5837 new_stmt = gimple_build_bind (NULL, NULL, block);
5838 gsi_replace (gsi_p, new_stmt, true);
5839
5840 pop_gimplify_context (new_stmt);
5841 gimple_bind_append_vars (new_stmt, ctx->block_vars);
5842 BLOCK_VARS (block) = gimple_bind_vars (bind);
5843 if (BLOCK_VARS (block))
5844 TREE_USED (block) = 1;
5845
5846 new_body = NULL;
5847 gimple_seq_add_seq (&new_body, ilist);
5848 gimple_seq_add_stmt (&new_body, stmt);
5849 gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
5850 gimple_seq_add_stmt (&new_body, bind);
5851
5852 control = create_tmp_var (unsigned_type_node, ".section");
5853 t = gimple_build_omp_continue (control, control);
5854 gimple_omp_sections_set_control (stmt, control);
5855 gimple_seq_add_stmt (&new_body, t);
5856
5857 gimple_seq_add_seq (&new_body, olist);
5858 gimple_seq_add_seq (&new_body, dlist);
5859
5860 new_body = maybe_catch_exception (new_body);
5861
5862 t = gimple_build_omp_return
5863 (!!find_omp_clause (gimple_omp_sections_clauses (stmt),
5864 OMP_CLAUSE_NOWAIT));
5865 gimple_seq_add_stmt (&new_body, t);
5866
5867 gimple_bind_set_body (new_stmt, new_body);
5868 }
5869
5870
5871 /* A subroutine of lower_omp_single. Expand the simple form of
5872 a GIMPLE_OMP_SINGLE, without a copyprivate clause:
5873
5874 if (GOMP_single_start ())
5875 BODY;
5876 [ GOMP_barrier (); ] -> unless 'nowait' is present.
5877
5878 FIXME. It may be better to delay expanding the logic of this until
5879 pass_expand_omp. The expanded logic may make the job more difficult
5880 to a synchronization analysis pass. */
5881
5882 static void
5883 lower_omp_single_simple (gimple single_stmt, gimple_seq *pre_p)
5884 {
5885 location_t loc = gimple_location (single_stmt);
5886 tree tlabel = create_artificial_label (loc);
5887 tree flabel = create_artificial_label (loc);
5888 gimple call, cond;
5889 tree lhs, decl;
5890
5891 decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START);
5892 lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)), NULL);
5893 call = gimple_build_call (decl, 0);
5894 gimple_call_set_lhs (call, lhs);
5895 gimple_seq_add_stmt (pre_p, call);
5896
5897 cond = gimple_build_cond (EQ_EXPR, lhs,
5898 fold_convert_loc (loc, TREE_TYPE (lhs),
5899 boolean_true_node),
5900 tlabel, flabel);
5901 gimple_seq_add_stmt (pre_p, cond);
5902 gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
5903 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
5904 gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
5905 }
5906
5907
5908 /* A subroutine of lower_omp_single. Expand the simple form of
5909 a GIMPLE_OMP_SINGLE, with a copyprivate clause:
5910
5911 #pragma omp single copyprivate (a, b, c)
5912
5913 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
5914
5915 {
5916 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
5917 {
5918 BODY;
5919 copyout.a = a;
5920 copyout.b = b;
5921 copyout.c = c;
5922 GOMP_single_copy_end (&copyout);
5923 }
5924 else
5925 {
5926 a = copyout_p->a;
5927 b = copyout_p->b;
5928 c = copyout_p->c;
5929 }
5930 GOMP_barrier ();
5931 }
5932
5933 FIXME. It may be better to delay expanding the logic of this until
5934 pass_expand_omp. The expanded logic may make the job more difficult
5935 to a synchronization analysis pass. */
5936
5937 static void
5938 lower_omp_single_copy (gimple single_stmt, gimple_seq *pre_p, omp_context *ctx)
5939 {
5940 tree ptr_type, t, l0, l1, l2, bfn_decl;
5941 gimple_seq copyin_seq;
5942 location_t loc = gimple_location (single_stmt);
5943
5944 ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
5945
5946 ptr_type = build_pointer_type (ctx->record_type);
5947 ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
5948
5949 l0 = create_artificial_label (loc);
5950 l1 = create_artificial_label (loc);
5951 l2 = create_artificial_label (loc);
5952
5953 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START);
5954 t = build_call_expr_loc (loc, bfn_decl, 0);
5955 t = fold_convert_loc (loc, ptr_type, t);
5956 gimplify_assign (ctx->receiver_decl, t, pre_p);
5957
5958 t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
5959 build_int_cst (ptr_type, 0));
5960 t = build3 (COND_EXPR, void_type_node, t,
5961 build_and_jump (&l0), build_and_jump (&l1));
5962 gimplify_and_add (t, pre_p);
5963
5964 gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
5965
5966 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
5967
5968 copyin_seq = NULL;
5969 lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
5970 &copyin_seq, ctx);
5971
5972 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
5973 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END);
5974 t = build_call_expr_loc (loc, bfn_decl, 1, t);
5975 gimplify_and_add (t, pre_p);
5976
5977 t = build_and_jump (&l2);
5978 gimplify_and_add (t, pre_p);
5979
5980 gimple_seq_add_stmt (pre_p, gimple_build_label (l1));
5981
5982 gimple_seq_add_seq (pre_p, copyin_seq);
5983
5984 gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
5985 }
5986
5987
5988 /* Expand code for an OpenMP single directive. */
5989
5990 static void
5991 lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
5992 {
5993 tree block;
5994 gimple t, bind, single_stmt = gsi_stmt (*gsi_p);
5995 gimple_seq bind_body, dlist;
5996 struct gimplify_ctx gctx;
5997
5998 push_gimplify_context (&gctx);
5999
6000 block = make_node (BLOCK);
6001 bind = gimple_build_bind (NULL, NULL, block);
6002 gsi_replace (gsi_p, bind, true);
6003 bind_body = NULL;
6004 dlist = NULL;
6005 lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
6006 &bind_body, &dlist, ctx);
6007 lower_omp (gimple_omp_body_ptr (single_stmt), ctx);
6008
6009 gimple_seq_add_stmt (&bind_body, single_stmt);
6010
6011 if (ctx->record_type)
6012 lower_omp_single_copy (single_stmt, &bind_body, ctx);
6013 else
6014 lower_omp_single_simple (single_stmt, &bind_body);
6015
6016 gimple_omp_set_body (single_stmt, NULL);
6017
6018 gimple_seq_add_seq (&bind_body, dlist);
6019
6020 bind_body = maybe_catch_exception (bind_body);
6021
6022 t = gimple_build_omp_return
6023 (!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
6024 OMP_CLAUSE_NOWAIT));
6025 gimple_seq_add_stmt (&bind_body, t);
6026 gimple_bind_set_body (bind, bind_body);
6027
6028 pop_gimplify_context (bind);
6029
6030 gimple_bind_append_vars (bind, ctx->block_vars);
6031 BLOCK_VARS (block) = ctx->block_vars;
6032 if (BLOCK_VARS (block))
6033 TREE_USED (block) = 1;
6034 }
6035
6036
6037 /* Expand code for an OpenMP master directive. */
6038
6039 static void
6040 lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6041 {
6042 tree block, lab = NULL, x, bfn_decl;
6043 gimple stmt = gsi_stmt (*gsi_p), bind;
6044 location_t loc = gimple_location (stmt);
6045 gimple_seq tseq;
6046 struct gimplify_ctx gctx;
6047
6048 push_gimplify_context (&gctx);
6049
6050 block = make_node (BLOCK);
6051 bind = gimple_build_bind (NULL, NULL, block);
6052 gsi_replace (gsi_p, bind, true);
6053 gimple_bind_add_stmt (bind, stmt);
6054
6055 bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
6056 x = build_call_expr_loc (loc, bfn_decl, 0);
6057 x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
6058 x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
6059 tseq = NULL;
6060 gimplify_and_add (x, &tseq);
6061 gimple_bind_add_seq (bind, tseq);
6062
6063 lower_omp (gimple_omp_body_ptr (stmt), ctx);
6064 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6065 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6066 gimple_omp_set_body (stmt, NULL);
6067
6068 gimple_bind_add_stmt (bind, gimple_build_label (lab));
6069
6070 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6071
6072 pop_gimplify_context (bind);
6073
6074 gimple_bind_append_vars (bind, ctx->block_vars);
6075 BLOCK_VARS (block) = ctx->block_vars;
6076 }
6077
6078
6079 /* Expand code for an OpenMP ordered directive. */
6080
6081 static void
6082 lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6083 {
6084 tree block;
6085 gimple stmt = gsi_stmt (*gsi_p), bind, x;
6086 struct gimplify_ctx gctx;
6087
6088 push_gimplify_context (&gctx);
6089
6090 block = make_node (BLOCK);
6091 bind = gimple_build_bind (NULL, NULL, block);
6092 gsi_replace (gsi_p, bind, true);
6093 gimple_bind_add_stmt (bind, stmt);
6094
6095 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
6096 0);
6097 gimple_bind_add_stmt (bind, x);
6098
6099 lower_omp (gimple_omp_body_ptr (stmt), ctx);
6100 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6101 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6102 gimple_omp_set_body (stmt, NULL);
6103
6104 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END), 0);
6105 gimple_bind_add_stmt (bind, x);
6106
6107 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6108
6109 pop_gimplify_context (bind);
6110
6111 gimple_bind_append_vars (bind, ctx->block_vars);
6112 BLOCK_VARS (block) = gimple_bind_vars (bind);
6113 }
6114
6115
6116 /* Gimplify a GIMPLE_OMP_CRITICAL statement. This is a relatively simple
6117 substitution of a couple of function calls. But in the NAMED case,
6118 requires that languages coordinate a symbol name. It is therefore
6119 best put here in common code. */
6120
6121 static GTY((param1_is (tree), param2_is (tree)))
6122 splay_tree critical_name_mutexes;
6123
6124 static void
6125 lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6126 {
6127 tree block;
6128 tree name, lock, unlock;
6129 gimple stmt = gsi_stmt (*gsi_p), bind;
6130 location_t loc = gimple_location (stmt);
6131 gimple_seq tbody;
6132 struct gimplify_ctx gctx;
6133
6134 name = gimple_omp_critical_name (stmt);
6135 if (name)
6136 {
6137 tree decl;
6138 splay_tree_node n;
6139
6140 if (!critical_name_mutexes)
6141 critical_name_mutexes
6142 = splay_tree_new_ggc (splay_tree_compare_pointers,
6143 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_s,
6144 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_node_s);
6145
6146 n = splay_tree_lookup (critical_name_mutexes, (splay_tree_key) name);
6147 if (n == NULL)
6148 {
6149 char *new_str;
6150
6151 decl = create_tmp_var_raw (ptr_type_node, NULL);
6152
6153 new_str = ACONCAT ((".gomp_critical_user_",
6154 IDENTIFIER_POINTER (name), NULL));
6155 DECL_NAME (decl) = get_identifier (new_str);
6156 TREE_PUBLIC (decl) = 1;
6157 TREE_STATIC (decl) = 1;
6158 DECL_COMMON (decl) = 1;
6159 DECL_ARTIFICIAL (decl) = 1;
6160 DECL_IGNORED_P (decl) = 1;
6161 varpool_finalize_decl (decl);
6162
6163 splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
6164 (splay_tree_value) decl);
6165 }
6166 else
6167 decl = (tree) n->value;
6168
6169 lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START);
6170 lock = build_call_expr_loc (loc, lock, 1, build_fold_addr_expr_loc (loc, decl));
6171
6172 unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END);
6173 unlock = build_call_expr_loc (loc, unlock, 1,
6174 build_fold_addr_expr_loc (loc, decl));
6175 }
6176 else
6177 {
6178 lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START);
6179 lock = build_call_expr_loc (loc, lock, 0);
6180
6181 unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END);
6182 unlock = build_call_expr_loc (loc, unlock, 0);
6183 }
6184
6185 push_gimplify_context (&gctx);
6186
6187 block = make_node (BLOCK);
6188 bind = gimple_build_bind (NULL, NULL, block);
6189 gsi_replace (gsi_p, bind, true);
6190 gimple_bind_add_stmt (bind, stmt);
6191
6192 tbody = gimple_bind_body (bind);
6193 gimplify_and_add (lock, &tbody);
6194 gimple_bind_set_body (bind, tbody);
6195
6196 lower_omp (gimple_omp_body_ptr (stmt), ctx);
6197 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6198 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6199 gimple_omp_set_body (stmt, NULL);
6200
6201 tbody = gimple_bind_body (bind);
6202 gimplify_and_add (unlock, &tbody);
6203 gimple_bind_set_body (bind, tbody);
6204
6205 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6206
6207 pop_gimplify_context (bind);
6208 gimple_bind_append_vars (bind, ctx->block_vars);
6209 BLOCK_VARS (block) = gimple_bind_vars (bind);
6210 }
6211
6212
6213 /* A subroutine of lower_omp_for. Generate code to emit the predicate
6214 for a lastprivate clause. Given a loop control predicate of (V
6215 cond N2), we gate the clause on (!(V cond N2)). The lowered form
6216 is appended to *DLIST, iterator initialization is appended to
6217 *BODY_P. */
6218
6219 static void
6220 lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
6221 gimple_seq *dlist, struct omp_context *ctx)
6222 {
6223 tree clauses, cond, vinit;
6224 enum tree_code cond_code;
6225 gimple_seq stmts;
6226
6227 cond_code = fd->loop.cond_code;
6228 cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
6229
6230 /* When possible, use a strict equality expression. This can let VRP
6231 type optimizations deduce the value and remove a copy. */
6232 if (host_integerp (fd->loop.step, 0))
6233 {
6234 HOST_WIDE_INT step = TREE_INT_CST_LOW (fd->loop.step);
6235 if (step == 1 || step == -1)
6236 cond_code = EQ_EXPR;
6237 }
6238
6239 cond = build2 (cond_code, boolean_type_node, fd->loop.v, fd->loop.n2);
6240
6241 clauses = gimple_omp_for_clauses (fd->for_stmt);
6242 stmts = NULL;
6243 lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
6244 if (!gimple_seq_empty_p (stmts))
6245 {
6246 gimple_seq_add_seq (&stmts, *dlist);
6247 *dlist = stmts;
6248
6249 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
6250 vinit = fd->loop.n1;
6251 if (cond_code == EQ_EXPR
6252 && host_integerp (fd->loop.n2, 0)
6253 && ! integer_zerop (fd->loop.n2))
6254 vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
6255
6256 /* Initialize the iterator variable, so that threads that don't execute
6257 any iterations don't execute the lastprivate clauses by accident. */
6258 gimplify_assign (fd->loop.v, vinit, body_p);
6259 }
6260 }
6261
6262
6263 /* Lower code for an OpenMP loop directive. */
6264
6265 static void
6266 lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6267 {
6268 tree *rhs_p, block;
6269 struct omp_for_data fd;
6270 gimple stmt = gsi_stmt (*gsi_p), new_stmt;
6271 gimple_seq omp_for_body, body, dlist;
6272 size_t i;
6273 struct gimplify_ctx gctx;
6274
6275 push_gimplify_context (&gctx);
6276
6277 lower_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
6278 lower_omp (gimple_omp_body_ptr (stmt), ctx);
6279
6280 block = make_node (BLOCK);
6281 new_stmt = gimple_build_bind (NULL, NULL, block);
6282 /* Replace at gsi right away, so that 'stmt' is no member
6283 of a sequence anymore as we're going to add to to a different
6284 one below. */
6285 gsi_replace (gsi_p, new_stmt, true);
6286
6287 /* Move declaration of temporaries in the loop body before we make
6288 it go away. */
6289 omp_for_body = gimple_omp_body (stmt);
6290 if (!gimple_seq_empty_p (omp_for_body)
6291 && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
6292 {
6293 tree vars = gimple_bind_vars (gimple_seq_first_stmt (omp_for_body));
6294 gimple_bind_append_vars (new_stmt, vars);
6295 }
6296
6297 /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR. */
6298 dlist = NULL;
6299 body = NULL;
6300 lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx);
6301 gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
6302
6303 /* Lower the header expressions. At this point, we can assume that
6304 the header is of the form:
6305
6306 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
6307
6308 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
6309 using the .omp_data_s mapping, if needed. */
6310 for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
6311 {
6312 rhs_p = gimple_omp_for_initial_ptr (stmt, i);
6313 if (!is_gimple_min_invariant (*rhs_p))
6314 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6315
6316 rhs_p = gimple_omp_for_final_ptr (stmt, i);
6317 if (!is_gimple_min_invariant (*rhs_p))
6318 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6319
6320 rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
6321 if (!is_gimple_min_invariant (*rhs_p))
6322 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6323 }
6324
6325 /* Once lowered, extract the bounds and clauses. */
6326 extract_omp_for_data (stmt, &fd, NULL);
6327
6328 lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
6329
6330 gimple_seq_add_stmt (&body, stmt);
6331 gimple_seq_add_seq (&body, gimple_omp_body (stmt));
6332
6333 gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
6334 fd.loop.v));
6335
6336 /* After the loop, add exit clauses. */
6337 lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, ctx);
6338 gimple_seq_add_seq (&body, dlist);
6339
6340 body = maybe_catch_exception (body);
6341
6342 /* Region exit marker goes at the end of the loop body. */
6343 gimple_seq_add_stmt (&body, gimple_build_omp_return (fd.have_nowait));
6344
6345 pop_gimplify_context (new_stmt);
6346
6347 gimple_bind_append_vars (new_stmt, ctx->block_vars);
6348 BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
6349 if (BLOCK_VARS (block))
6350 TREE_USED (block) = 1;
6351
6352 gimple_bind_set_body (new_stmt, body);
6353 gimple_omp_set_body (stmt, NULL);
6354 gimple_omp_for_set_pre_body (stmt, NULL);
6355 }
6356
6357 /* Callback for walk_stmts. Check if the current statement only contains
6358 GIMPLE_OMP_FOR or GIMPLE_OMP_PARALLEL. */
6359
6360 static tree
6361 check_combined_parallel (gimple_stmt_iterator *gsi_p,
6362 bool *handled_ops_p,
6363 struct walk_stmt_info *wi)
6364 {
6365 int *info = (int *) wi->info;
6366 gimple stmt = gsi_stmt (*gsi_p);
6367
6368 *handled_ops_p = true;
6369 switch (gimple_code (stmt))
6370 {
6371 WALK_SUBSTMTS;
6372
6373 case GIMPLE_OMP_FOR:
6374 case GIMPLE_OMP_SECTIONS:
6375 *info = *info == 0 ? 1 : -1;
6376 break;
6377 default:
6378 *info = -1;
6379 break;
6380 }
6381 return NULL;
6382 }
6383
6384 struct omp_taskcopy_context
6385 {
6386 /* This field must be at the beginning, as we do "inheritance": Some
6387 callback functions for tree-inline.c (e.g., omp_copy_decl)
6388 receive a copy_body_data pointer that is up-casted to an
6389 omp_context pointer. */
6390 copy_body_data cb;
6391 omp_context *ctx;
6392 };
6393
6394 static tree
6395 task_copyfn_copy_decl (tree var, copy_body_data *cb)
6396 {
6397 struct omp_taskcopy_context *tcctx = (struct omp_taskcopy_context *) cb;
6398
6399 if (splay_tree_lookup (tcctx->ctx->sfield_map, (splay_tree_key) var))
6400 return create_tmp_var (TREE_TYPE (var), NULL);
6401
6402 return var;
6403 }
6404
6405 static tree
6406 task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
6407 {
6408 tree name, new_fields = NULL, type, f;
6409
6410 type = lang_hooks.types.make_type (RECORD_TYPE);
6411 name = DECL_NAME (TYPE_NAME (orig_type));
6412 name = build_decl (gimple_location (tcctx->ctx->stmt),
6413 TYPE_DECL, name, type);
6414 TYPE_NAME (type) = name;
6415
6416 for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
6417 {
6418 tree new_f = copy_node (f);
6419 DECL_CONTEXT (new_f) = type;
6420 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
6421 TREE_CHAIN (new_f) = new_fields;
6422 walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6423 walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6424 walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
6425 &tcctx->cb, NULL);
6426 new_fields = new_f;
6427 *pointer_map_insert (tcctx->cb.decl_map, f) = new_f;
6428 }
6429 TYPE_FIELDS (type) = nreverse (new_fields);
6430 layout_type (type);
6431 return type;
6432 }
6433
6434 /* Create task copyfn. */
6435
6436 static void
6437 create_task_copyfn (gimple task_stmt, omp_context *ctx)
6438 {
6439 struct function *child_cfun;
6440 tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
6441 tree record_type, srecord_type, bind, list;
6442 bool record_needs_remap = false, srecord_needs_remap = false;
6443 splay_tree_node n;
6444 struct omp_taskcopy_context tcctx;
6445 struct gimplify_ctx gctx;
6446 location_t loc = gimple_location (task_stmt);
6447
6448 child_fn = gimple_omp_task_copy_fn (task_stmt);
6449 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
6450 gcc_assert (child_cfun->cfg == NULL);
6451 DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();
6452
6453 /* Reset DECL_CONTEXT on function arguments. */
6454 for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
6455 DECL_CONTEXT (t) = child_fn;
6456
6457 /* Populate the function. */
6458 push_gimplify_context (&gctx);
6459 current_function_decl = child_fn;
6460
6461 bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
6462 TREE_SIDE_EFFECTS (bind) = 1;
6463 list = NULL;
6464 DECL_SAVED_TREE (child_fn) = bind;
6465 DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);
6466
6467 /* Remap src and dst argument types if needed. */
6468 record_type = ctx->record_type;
6469 srecord_type = ctx->srecord_type;
6470 for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
6471 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6472 {
6473 record_needs_remap = true;
6474 break;
6475 }
6476 for (f = TYPE_FIELDS (srecord_type); f ; f = DECL_CHAIN (f))
6477 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6478 {
6479 srecord_needs_remap = true;
6480 break;
6481 }
6482
6483 if (record_needs_remap || srecord_needs_remap)
6484 {
6485 memset (&tcctx, '\0', sizeof (tcctx));
6486 tcctx.cb.src_fn = ctx->cb.src_fn;
6487 tcctx.cb.dst_fn = child_fn;
6488 tcctx.cb.src_node = cgraph_get_node (tcctx.cb.src_fn);
6489 gcc_checking_assert (tcctx.cb.src_node);
6490 tcctx.cb.dst_node = tcctx.cb.src_node;
6491 tcctx.cb.src_cfun = ctx->cb.src_cfun;
6492 tcctx.cb.copy_decl = task_copyfn_copy_decl;
6493 tcctx.cb.eh_lp_nr = 0;
6494 tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
6495 tcctx.cb.decl_map = pointer_map_create ();
6496 tcctx.ctx = ctx;
6497
6498 if (record_needs_remap)
6499 record_type = task_copyfn_remap_type (&tcctx, record_type);
6500 if (srecord_needs_remap)
6501 srecord_type = task_copyfn_remap_type (&tcctx, srecord_type);
6502 }
6503 else
6504 tcctx.cb.decl_map = NULL;
6505
6506 push_cfun (child_cfun);
6507
6508 arg = DECL_ARGUMENTS (child_fn);
6509 TREE_TYPE (arg) = build_pointer_type (record_type);
6510 sarg = DECL_CHAIN (arg);
6511 TREE_TYPE (sarg) = build_pointer_type (srecord_type);
6512
6513 /* First pass: initialize temporaries used in record_type and srecord_type
6514 sizes and field offsets. */
6515 if (tcctx.cb.decl_map)
6516 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6517 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6518 {
6519 tree *p;
6520
6521 decl = OMP_CLAUSE_DECL (c);
6522 p = (tree *) pointer_map_contains (tcctx.cb.decl_map, decl);
6523 if (p == NULL)
6524 continue;
6525 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6526 sf = (tree) n->value;
6527 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6528 src = build_simple_mem_ref_loc (loc, sarg);
6529 src = omp_build_component_ref (src, sf);
6530 t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
6531 append_to_statement_list (t, &list);
6532 }
6533
6534 /* Second pass: copy shared var pointers and copy construct non-VLA
6535 firstprivate vars. */
6536 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6537 switch (OMP_CLAUSE_CODE (c))
6538 {
6539 case OMP_CLAUSE_SHARED:
6540 decl = OMP_CLAUSE_DECL (c);
6541 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6542 if (n == NULL)
6543 break;
6544 f = (tree) n->value;
6545 if (tcctx.cb.decl_map)
6546 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6547 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6548 sf = (tree) n->value;
6549 if (tcctx.cb.decl_map)
6550 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6551 src = build_simple_mem_ref_loc (loc, sarg);
6552 src = omp_build_component_ref (src, sf);
6553 dst = build_simple_mem_ref_loc (loc, arg);
6554 dst = omp_build_component_ref (dst, f);
6555 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6556 append_to_statement_list (t, &list);
6557 break;
6558 case OMP_CLAUSE_FIRSTPRIVATE:
6559 decl = OMP_CLAUSE_DECL (c);
6560 if (is_variable_sized (decl))
6561 break;
6562 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6563 if (n == NULL)
6564 break;
6565 f = (tree) n->value;
6566 if (tcctx.cb.decl_map)
6567 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6568 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6569 if (n != NULL)
6570 {
6571 sf = (tree) n->value;
6572 if (tcctx.cb.decl_map)
6573 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6574 src = build_simple_mem_ref_loc (loc, sarg);
6575 src = omp_build_component_ref (src, sf);
6576 if (use_pointer_for_field (decl, NULL) || is_reference (decl))
6577 src = build_simple_mem_ref_loc (loc, src);
6578 }
6579 else
6580 src = decl;
6581 dst = build_simple_mem_ref_loc (loc, arg);
6582 dst = omp_build_component_ref (dst, f);
6583 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6584 append_to_statement_list (t, &list);
6585 break;
6586 case OMP_CLAUSE_PRIVATE:
6587 if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c))
6588 break;
6589 decl = OMP_CLAUSE_DECL (c);
6590 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6591 f = (tree) n->value;
6592 if (tcctx.cb.decl_map)
6593 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6594 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6595 if (n != NULL)
6596 {
6597 sf = (tree) n->value;
6598 if (tcctx.cb.decl_map)
6599 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6600 src = build_simple_mem_ref_loc (loc, sarg);
6601 src = omp_build_component_ref (src, sf);
6602 if (use_pointer_for_field (decl, NULL))
6603 src = build_simple_mem_ref_loc (loc, src);
6604 }
6605 else
6606 src = decl;
6607 dst = build_simple_mem_ref_loc (loc, arg);
6608 dst = omp_build_component_ref (dst, f);
6609 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6610 append_to_statement_list (t, &list);
6611 break;
6612 default:
6613 break;
6614 }
6615
6616 /* Last pass: handle VLA firstprivates. */
6617 if (tcctx.cb.decl_map)
6618 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6619 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6620 {
6621 tree ind, ptr, df;
6622
6623 decl = OMP_CLAUSE_DECL (c);
6624 if (!is_variable_sized (decl))
6625 continue;
6626 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6627 if (n == NULL)
6628 continue;
6629 f = (tree) n->value;
6630 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6631 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
6632 ind = DECL_VALUE_EXPR (decl);
6633 gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
6634 gcc_assert (DECL_P (TREE_OPERAND (ind, 0)));
6635 n = splay_tree_lookup (ctx->sfield_map,
6636 (splay_tree_key) TREE_OPERAND (ind, 0));
6637 sf = (tree) n->value;
6638 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6639 src = build_simple_mem_ref_loc (loc, sarg);
6640 src = omp_build_component_ref (src, sf);
6641 src = build_simple_mem_ref_loc (loc, src);
6642 dst = build_simple_mem_ref_loc (loc, arg);
6643 dst = omp_build_component_ref (dst, f);
6644 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6645 append_to_statement_list (t, &list);
6646 n = splay_tree_lookup (ctx->field_map,
6647 (splay_tree_key) TREE_OPERAND (ind, 0));
6648 df = (tree) n->value;
6649 df = *(tree *) pointer_map_contains (tcctx.cb.decl_map, df);
6650 ptr = build_simple_mem_ref_loc (loc, arg);
6651 ptr = omp_build_component_ref (ptr, df);
6652 t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
6653 build_fold_addr_expr_loc (loc, dst));
6654 append_to_statement_list (t, &list);
6655 }
6656
6657 t = build1 (RETURN_EXPR, void_type_node, NULL);
6658 append_to_statement_list (t, &list);
6659
6660 if (tcctx.cb.decl_map)
6661 pointer_map_destroy (tcctx.cb.decl_map);
6662 pop_gimplify_context (NULL);
6663 BIND_EXPR_BODY (bind) = list;
6664 pop_cfun ();
6665 current_function_decl = ctx->cb.src_fn;
6666 }
6667
6668 /* Lower the OpenMP parallel or task directive in the current statement
6669 in GSI_P. CTX holds context information for the directive. */
6670
6671 static void
6672 lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6673 {
6674 tree clauses;
6675 tree child_fn, t;
6676 gimple stmt = gsi_stmt (*gsi_p);
6677 gimple par_bind, bind;
6678 gimple_seq par_body, olist, ilist, par_olist, par_ilist, new_body;
6679 struct gimplify_ctx gctx;
6680 location_t loc = gimple_location (stmt);
6681
6682 clauses = gimple_omp_taskreg_clauses (stmt);
6683 par_bind = gimple_seq_first_stmt (gimple_omp_body (stmt));
6684 par_body = gimple_bind_body (par_bind);
6685 child_fn = ctx->cb.dst_fn;
6686 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
6687 && !gimple_omp_parallel_combined_p (stmt))
6688 {
6689 struct walk_stmt_info wi;
6690 int ws_num = 0;
6691
6692 memset (&wi, 0, sizeof (wi));
6693 wi.info = &ws_num;
6694 wi.val_only = true;
6695 walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
6696 if (ws_num == 1)
6697 gimple_omp_parallel_set_combined_p (stmt, true);
6698 }
6699 if (ctx->srecord_type)
6700 create_task_copyfn (stmt, ctx);
6701
6702 push_gimplify_context (&gctx);
6703
6704 par_olist = NULL;
6705 par_ilist = NULL;
6706 lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
6707 lower_omp (&par_body, ctx);
6708 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
6709 lower_reduction_clauses (clauses, &par_olist, ctx);
6710
6711 /* Declare all the variables created by mapping and the variables
6712 declared in the scope of the parallel body. */
6713 record_vars_into (ctx->block_vars, child_fn);
6714 record_vars_into (gimple_bind_vars (par_bind), child_fn);
6715
6716 if (ctx->record_type)
6717 {
6718 ctx->sender_decl
6719 = create_tmp_var (ctx->srecord_type ? ctx->srecord_type
6720 : ctx->record_type, ".omp_data_o");
6721 DECL_NAMELESS (ctx->sender_decl) = 1;
6722 TREE_ADDRESSABLE (ctx->sender_decl) = 1;
6723 gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
6724 }
6725
6726 olist = NULL;
6727 ilist = NULL;
6728 lower_send_clauses (clauses, &ilist, &olist, ctx);
6729 lower_send_shared_vars (&ilist, &olist, ctx);
6730
6731 /* Once all the expansions are done, sequence all the different
6732 fragments inside gimple_omp_body. */
6733
6734 new_body = NULL;
6735
6736 if (ctx->record_type)
6737 {
6738 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
6739 /* fixup_child_record_type might have changed receiver_decl's type. */
6740 t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
6741 gimple_seq_add_stmt (&new_body,
6742 gimple_build_assign (ctx->receiver_decl, t));
6743 }
6744
6745 gimple_seq_add_seq (&new_body, par_ilist);
6746 gimple_seq_add_seq (&new_body, par_body);
6747 gimple_seq_add_seq (&new_body, par_olist);
6748 new_body = maybe_catch_exception (new_body);
6749 gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
6750 gimple_omp_set_body (stmt, new_body);
6751
6752 bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
6753 gsi_replace (gsi_p, bind, true);
6754 gimple_bind_add_seq (bind, ilist);
6755 gimple_bind_add_stmt (bind, stmt);
6756 gimple_bind_add_seq (bind, olist);
6757
6758 pop_gimplify_context (NULL);
6759 }
6760
6761 /* Callback for lower_omp_1. Return non-NULL if *tp needs to be
6762 regimplified. If DATA is non-NULL, lower_omp_1 is outside
6763 of OpenMP context, but with task_shared_vars set. */
6764
6765 static tree
6766 lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
6767 void *data)
6768 {
6769 tree t = *tp;
6770
6771 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
6772 if (TREE_CODE (t) == VAR_DECL && data == NULL && DECL_HAS_VALUE_EXPR_P (t))
6773 return t;
6774
6775 if (task_shared_vars
6776 && DECL_P (t)
6777 && bitmap_bit_p (task_shared_vars, DECL_UID (t)))
6778 return t;
6779
6780 /* If a global variable has been privatized, TREE_CONSTANT on
6781 ADDR_EXPR might be wrong. */
6782 if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
6783 recompute_tree_invariant_for_addr_expr (t);
6784
6785 *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
6786 return NULL_TREE;
6787 }
6788
6789 static void
6790 lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6791 {
6792 gimple stmt = gsi_stmt (*gsi_p);
6793 struct walk_stmt_info wi;
6794
6795 if (gimple_has_location (stmt))
6796 input_location = gimple_location (stmt);
6797
6798 if (task_shared_vars)
6799 memset (&wi, '\0', sizeof (wi));
6800
6801 /* If we have issued syntax errors, avoid doing any heavy lifting.
6802 Just replace the OpenMP directives with a NOP to avoid
6803 confusing RTL expansion. */
6804 if (seen_error () && is_gimple_omp (stmt))
6805 {
6806 gsi_replace (gsi_p, gimple_build_nop (), true);
6807 return;
6808 }
6809
6810 switch (gimple_code (stmt))
6811 {
6812 case GIMPLE_COND:
6813 if ((ctx || task_shared_vars)
6814 && (walk_tree (gimple_cond_lhs_ptr (stmt), lower_omp_regimplify_p,
6815 ctx ? NULL : &wi, NULL)
6816 || walk_tree (gimple_cond_rhs_ptr (stmt), lower_omp_regimplify_p,
6817 ctx ? NULL : &wi, NULL)))
6818 gimple_regimplify_operands (stmt, gsi_p);
6819 break;
6820 case GIMPLE_CATCH:
6821 lower_omp (gimple_catch_handler_ptr (stmt), ctx);
6822 break;
6823 case GIMPLE_EH_FILTER:
6824 lower_omp (gimple_eh_filter_failure_ptr (stmt), ctx);
6825 break;
6826 case GIMPLE_TRY:
6827 lower_omp (gimple_try_eval_ptr (stmt), ctx);
6828 lower_omp (gimple_try_cleanup_ptr (stmt), ctx);
6829 break;
6830 case GIMPLE_TRANSACTION:
6831 lower_omp (gimple_transaction_body_ptr (stmt), ctx);
6832 break;
6833 case GIMPLE_BIND:
6834 lower_omp (gimple_bind_body_ptr (stmt), ctx);
6835 break;
6836 case GIMPLE_OMP_PARALLEL:
6837 case GIMPLE_OMP_TASK:
6838 ctx = maybe_lookup_ctx (stmt);
6839 lower_omp_taskreg (gsi_p, ctx);
6840 break;
6841 case GIMPLE_OMP_FOR:
6842 ctx = maybe_lookup_ctx (stmt);
6843 gcc_assert (ctx);
6844 lower_omp_for (gsi_p, ctx);
6845 break;
6846 case GIMPLE_OMP_SECTIONS:
6847 ctx = maybe_lookup_ctx (stmt);
6848 gcc_assert (ctx);
6849 lower_omp_sections (gsi_p, ctx);
6850 break;
6851 case GIMPLE_OMP_SINGLE:
6852 ctx = maybe_lookup_ctx (stmt);
6853 gcc_assert (ctx);
6854 lower_omp_single (gsi_p, ctx);
6855 break;
6856 case GIMPLE_OMP_MASTER:
6857 ctx = maybe_lookup_ctx (stmt);
6858 gcc_assert (ctx);
6859 lower_omp_master (gsi_p, ctx);
6860 break;
6861 case GIMPLE_OMP_ORDERED:
6862 ctx = maybe_lookup_ctx (stmt);
6863 gcc_assert (ctx);
6864 lower_omp_ordered (gsi_p, ctx);
6865 break;
6866 case GIMPLE_OMP_CRITICAL:
6867 ctx = maybe_lookup_ctx (stmt);
6868 gcc_assert (ctx);
6869 lower_omp_critical (gsi_p, ctx);
6870 break;
6871 case GIMPLE_OMP_ATOMIC_LOAD:
6872 if ((ctx || task_shared_vars)
6873 && walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt),
6874 lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
6875 gimple_regimplify_operands (stmt, gsi_p);
6876 break;
6877 default:
6878 if ((ctx || task_shared_vars)
6879 && walk_gimple_op (stmt, lower_omp_regimplify_p,
6880 ctx ? NULL : &wi))
6881 gimple_regimplify_operands (stmt, gsi_p);
6882 break;
6883 }
6884 }
6885
6886 static void
6887 lower_omp (gimple_seq *body, omp_context *ctx)
6888 {
6889 location_t saved_location = input_location;
6890 gimple_stmt_iterator gsi;
6891 for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
6892 lower_omp_1 (&gsi, ctx);
6893 input_location = saved_location;
6894 }
6895 \f
6896 /* Main entry point. */
6897
6898 static unsigned int
6899 execute_lower_omp (void)
6900 {
6901 gimple_seq body;
6902
6903 /* This pass always runs, to provide PROP_gimple_lomp.
6904 But there is nothing to do unless -fopenmp is given. */
6905 if (flag_openmp == 0)
6906 return 0;
6907
6908 all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
6909 delete_omp_context);
6910
6911 body = gimple_body (current_function_decl);
6912 scan_omp (&body, NULL);
6913 gcc_assert (taskreg_nesting_level == 0);
6914
6915 if (all_contexts->root)
6916 {
6917 struct gimplify_ctx gctx;
6918
6919 if (task_shared_vars)
6920 push_gimplify_context (&gctx);
6921 lower_omp (&body, NULL);
6922 if (task_shared_vars)
6923 pop_gimplify_context (NULL);
6924 }
6925
6926 if (all_contexts)
6927 {
6928 splay_tree_delete (all_contexts);
6929 all_contexts = NULL;
6930 }
6931 BITMAP_FREE (task_shared_vars);
6932 return 0;
6933 }
6934
6935 struct gimple_opt_pass pass_lower_omp =
6936 {
6937 {
6938 GIMPLE_PASS,
6939 "omplower", /* name */
6940 NULL, /* gate */
6941 execute_lower_omp, /* execute */
6942 NULL, /* sub */
6943 NULL, /* next */
6944 0, /* static_pass_number */
6945 TV_NONE, /* tv_id */
6946 PROP_gimple_any, /* properties_required */
6947 PROP_gimple_lomp, /* properties_provided */
6948 0, /* properties_destroyed */
6949 0, /* todo_flags_start */
6950 0 /* todo_flags_finish */
6951 }
6952 };
6953 \f
6954 /* The following is a utility to diagnose OpenMP structured block violations.
6955 It is not part of the "omplower" pass, as that's invoked too late. It
6956 should be invoked by the respective front ends after gimplification. */
6957
6958 static splay_tree all_labels;
6959
6960 /* Check for mismatched contexts and generate an error if needed. Return
6961 true if an error is detected. */
6962
6963 static bool
6964 diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
6965 gimple branch_ctx, gimple label_ctx)
6966 {
6967 if (label_ctx == branch_ctx)
6968 return false;
6969
6970
6971 /*
6972 Previously we kept track of the label's entire context in diagnose_sb_[12]
6973 so we could traverse it and issue a correct "exit" or "enter" error
6974 message upon a structured block violation.
6975
6976 We built the context by building a list with tree_cons'ing, but there is
6977 no easy counterpart in gimple tuples. It seems like far too much work
6978 for issuing exit/enter error messages. If someone really misses the
6979 distinct error message... patches welcome.
6980 */
6981
6982 #if 0
6983 /* Try to avoid confusing the user by producing and error message
6984 with correct "exit" or "enter" verbiage. We prefer "exit"
6985 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
6986 if (branch_ctx == NULL)
6987 exit_p = false;
6988 else
6989 {
6990 while (label_ctx)
6991 {
6992 if (TREE_VALUE (label_ctx) == branch_ctx)
6993 {
6994 exit_p = false;
6995 break;
6996 }
6997 label_ctx = TREE_CHAIN (label_ctx);
6998 }
6999 }
7000
7001 if (exit_p)
7002 error ("invalid exit from OpenMP structured block");
7003 else
7004 error ("invalid entry to OpenMP structured block");
7005 #endif
7006
7007 /* If it's obvious we have an invalid entry, be specific about the error. */
7008 if (branch_ctx == NULL)
7009 error ("invalid entry to OpenMP structured block");
7010 else
7011 /* Otherwise, be vague and lazy, but efficient. */
7012 error ("invalid branch to/from an OpenMP structured block");
7013
7014 gsi_replace (gsi_p, gimple_build_nop (), false);
7015 return true;
7016 }
7017
7018 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
7019 where each label is found. */
7020
7021 static tree
7022 diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
7023 struct walk_stmt_info *wi)
7024 {
7025 gimple context = (gimple) wi->info;
7026 gimple inner_context;
7027 gimple stmt = gsi_stmt (*gsi_p);
7028
7029 *handled_ops_p = true;
7030
7031 switch (gimple_code (stmt))
7032 {
7033 WALK_SUBSTMTS;
7034
7035 case GIMPLE_OMP_PARALLEL:
7036 case GIMPLE_OMP_TASK:
7037 case GIMPLE_OMP_SECTIONS:
7038 case GIMPLE_OMP_SINGLE:
7039 case GIMPLE_OMP_SECTION:
7040 case GIMPLE_OMP_MASTER:
7041 case GIMPLE_OMP_ORDERED:
7042 case GIMPLE_OMP_CRITICAL:
7043 /* The minimal context here is just the current OMP construct. */
7044 inner_context = stmt;
7045 wi->info = inner_context;
7046 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
7047 wi->info = context;
7048 break;
7049
7050 case GIMPLE_OMP_FOR:
7051 inner_context = stmt;
7052 wi->info = inner_context;
7053 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7054 walk them. */
7055 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
7056 diagnose_sb_1, NULL, wi);
7057 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
7058 wi->info = context;
7059 break;
7060
7061 case GIMPLE_LABEL:
7062 splay_tree_insert (all_labels, (splay_tree_key) gimple_label_label (stmt),
7063 (splay_tree_value) context);
7064 break;
7065
7066 default:
7067 break;
7068 }
7069
7070 return NULL_TREE;
7071 }
7072
7073 /* Pass 2: Check each branch and see if its context differs from that of
7074 the destination label's context. */
7075
7076 static tree
7077 diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
7078 struct walk_stmt_info *wi)
7079 {
7080 gimple context = (gimple) wi->info;
7081 splay_tree_node n;
7082 gimple stmt = gsi_stmt (*gsi_p);
7083
7084 *handled_ops_p = true;
7085
7086 switch (gimple_code (stmt))
7087 {
7088 WALK_SUBSTMTS;
7089
7090 case GIMPLE_OMP_PARALLEL:
7091 case GIMPLE_OMP_TASK:
7092 case GIMPLE_OMP_SECTIONS:
7093 case GIMPLE_OMP_SINGLE:
7094 case GIMPLE_OMP_SECTION:
7095 case GIMPLE_OMP_MASTER:
7096 case GIMPLE_OMP_ORDERED:
7097 case GIMPLE_OMP_CRITICAL:
7098 wi->info = stmt;
7099 walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
7100 wi->info = context;
7101 break;
7102
7103 case GIMPLE_OMP_FOR:
7104 wi->info = stmt;
7105 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7106 walk them. */
7107 walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt),
7108 diagnose_sb_2, NULL, wi);
7109 walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
7110 wi->info = context;
7111 break;
7112
7113 case GIMPLE_COND:
7114 {
7115 tree lab = gimple_cond_true_label (stmt);
7116 if (lab)
7117 {
7118 n = splay_tree_lookup (all_labels,
7119 (splay_tree_key) lab);
7120 diagnose_sb_0 (gsi_p, context,
7121 n ? (gimple) n->value : NULL);
7122 }
7123 lab = gimple_cond_false_label (stmt);
7124 if (lab)
7125 {
7126 n = splay_tree_lookup (all_labels,
7127 (splay_tree_key) lab);
7128 diagnose_sb_0 (gsi_p, context,
7129 n ? (gimple) n->value : NULL);
7130 }
7131 }
7132 break;
7133
7134 case GIMPLE_GOTO:
7135 {
7136 tree lab = gimple_goto_dest (stmt);
7137 if (TREE_CODE (lab) != LABEL_DECL)
7138 break;
7139
7140 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
7141 diagnose_sb_0 (gsi_p, context, n ? (gimple) n->value : NULL);
7142 }
7143 break;
7144
7145 case GIMPLE_SWITCH:
7146 {
7147 unsigned int i;
7148 for (i = 0; i < gimple_switch_num_labels (stmt); ++i)
7149 {
7150 tree lab = CASE_LABEL (gimple_switch_label (stmt, i));
7151 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
7152 if (n && diagnose_sb_0 (gsi_p, context, (gimple) n->value))
7153 break;
7154 }
7155 }
7156 break;
7157
7158 case GIMPLE_RETURN:
7159 diagnose_sb_0 (gsi_p, context, NULL);
7160 break;
7161
7162 default:
7163 break;
7164 }
7165
7166 return NULL_TREE;
7167 }
7168
7169 static unsigned int
7170 diagnose_omp_structured_block_errors (void)
7171 {
7172 struct walk_stmt_info wi;
7173 gimple_seq body = gimple_body (current_function_decl);
7174
7175 all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
7176
7177 memset (&wi, 0, sizeof (wi));
7178 walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);
7179
7180 memset (&wi, 0, sizeof (wi));
7181 wi.want_locations = true;
7182 walk_gimple_seq_mod (&body, diagnose_sb_2, NULL, &wi);
7183
7184 gimple_set_body (current_function_decl, body);
7185
7186 splay_tree_delete (all_labels);
7187 all_labels = NULL;
7188
7189 return 0;
7190 }
7191
7192 static bool
7193 gate_diagnose_omp_blocks (void)
7194 {
7195 return flag_openmp != 0;
7196 }
7197
7198 struct gimple_opt_pass pass_diagnose_omp_blocks =
7199 {
7200 {
7201 GIMPLE_PASS,
7202 "*diagnose_omp_blocks", /* name */
7203 gate_diagnose_omp_blocks, /* gate */
7204 diagnose_omp_structured_block_errors, /* execute */
7205 NULL, /* sub */
7206 NULL, /* next */
7207 0, /* static_pass_number */
7208 TV_NONE, /* tv_id */
7209 PROP_gimple_any, /* properties_required */
7210 0, /* properties_provided */
7211 0, /* properties_destroyed */
7212 0, /* todo_flags_start */
7213 0, /* todo_flags_finish */
7214 }
7215 };
7216
7217 #include "gt-omp-low.h"