lto-cgraph.c (output_profile_summary, [...]): Use gcov streaming; stream hot bb thres...
[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-2013 Free Software Foundation, Inc.
7
8 This file is part of GCC.
9
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
14
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
23
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "tree.h"
29 #include "rtl.h"
30 #include "gimple.h"
31 #include "tree-iterator.h"
32 #include "tree-inline.h"
33 #include "langhooks.h"
34 #include "diagnostic-core.h"
35 #include "tree-flow.h"
36 #include "flags.h"
37 #include "function.h"
38 #include "expr.h"
39 #include "tree-pass.h"
40 #include "ggc.h"
41 #include "except.h"
42 #include "splay-tree.h"
43 #include "optabs.h"
44 #include "cfgloop.h"
45
46
47 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
48 phases. The first phase scans the function looking for OMP statements
49 and then for variables that must be replaced to satisfy data sharing
50 clauses. The second phase expands code for the constructs, as well as
51 re-gimplifying things when variables have been replaced with complex
52 expressions.
53
54 Final code generation is done by pass_expand_omp. The flowgraph is
55 scanned for parallel regions which are then moved to a new
56 function, to be invoked by the thread library. */
57
58 /* Context structure. Used to store information about each parallel
59 directive in the code. */
60
61 typedef struct omp_context
62 {
63 /* This field must be at the beginning, as we do "inheritance": Some
64 callback functions for tree-inline.c (e.g., omp_copy_decl)
65 receive a copy_body_data pointer that is up-casted to an
66 omp_context pointer. */
67 copy_body_data cb;
68
69 /* The tree of contexts corresponding to the encountered constructs. */
70 struct omp_context *outer;
71 gimple stmt;
72
73 /* Map variables to fields in a structure that allows communication
74 between sending and receiving threads. */
75 splay_tree field_map;
76 tree record_type;
77 tree sender_decl;
78 tree receiver_decl;
79
80 /* These are used just by task contexts, if task firstprivate fn is
81 needed. srecord_type is used to communicate from the thread
82 that encountered the task construct to task firstprivate fn,
83 record_type is allocated by GOMP_task, initialized by task firstprivate
84 fn and passed to the task body fn. */
85 splay_tree sfield_map;
86 tree srecord_type;
87
88 /* A chain of variables to add to the top-level block surrounding the
89 construct. In the case of a parallel, this is in the child function. */
90 tree block_vars;
91
92 /* What to do with variables with implicitly determined sharing
93 attributes. */
94 enum omp_clause_default_kind default_kind;
95
96 /* Nesting depth of this context. Used to beautify error messages re
97 invalid gotos. The outermost ctx is depth 1, with depth 0 being
98 reserved for the main body of the function. */
99 int depth;
100
101 /* True if this parallel directive is nested within another. */
102 bool is_nested;
103 } omp_context;
104
105
106 struct omp_for_data_loop
107 {
108 tree v, n1, n2, step;
109 enum tree_code cond_code;
110 };
111
112 /* A structure describing the main elements of a parallel loop. */
113
114 struct omp_for_data
115 {
116 struct omp_for_data_loop loop;
117 tree chunk_size;
118 gimple for_stmt;
119 tree pre, iter_type;
120 int collapse;
121 bool have_nowait, have_ordered;
122 enum omp_clause_schedule_kind sched_kind;
123 struct omp_for_data_loop *loops;
124 };
125
126
127 static splay_tree all_contexts;
128 static int taskreg_nesting_level;
129 struct omp_region *root_omp_region;
130 static bitmap task_shared_vars;
131
132 static void scan_omp (gimple_seq *, omp_context *);
133 static tree scan_omp_1_op (tree *, int *, void *);
134
135 #define WALK_SUBSTMTS \
136 case GIMPLE_BIND: \
137 case GIMPLE_TRY: \
138 case GIMPLE_CATCH: \
139 case GIMPLE_EH_FILTER: \
140 case GIMPLE_TRANSACTION: \
141 /* The sub-statements for these should be walked. */ \
142 *handled_ops_p = false; \
143 break;
144
145 /* Convenience function for calling scan_omp_1_op on tree operands. */
146
147 static inline tree
148 scan_omp_op (tree *tp, omp_context *ctx)
149 {
150 struct walk_stmt_info wi;
151
152 memset (&wi, 0, sizeof (wi));
153 wi.info = ctx;
154 wi.want_locations = true;
155
156 return walk_tree (tp, scan_omp_1_op, &wi, NULL);
157 }
158
159 static void lower_omp (gimple_seq *, omp_context *);
160 static tree lookup_decl_in_outer_ctx (tree, omp_context *);
161 static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
162
163 /* Find an OpenMP clause of type KIND within CLAUSES. */
164
165 tree
166 find_omp_clause (tree clauses, enum omp_clause_code kind)
167 {
168 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
169 if (OMP_CLAUSE_CODE (clauses) == kind)
170 return clauses;
171
172 return NULL_TREE;
173 }
174
175 /* Return true if CTX is for an omp parallel. */
176
177 static inline bool
178 is_parallel_ctx (omp_context *ctx)
179 {
180 return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL;
181 }
182
183
184 /* Return true if CTX is for an omp task. */
185
186 static inline bool
187 is_task_ctx (omp_context *ctx)
188 {
189 return gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
190 }
191
192
193 /* Return true if CTX is for an omp parallel or omp task. */
194
195 static inline bool
196 is_taskreg_ctx (omp_context *ctx)
197 {
198 return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL
199 || gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
200 }
201
202
203 /* Return true if REGION is a combined parallel+workshare region. */
204
205 static inline bool
206 is_combined_parallel (struct omp_region *region)
207 {
208 return region->is_combined_parallel;
209 }
210
211
212 /* Extract the header elements of parallel loop FOR_STMT and store
213 them into *FD. */
214
215 static void
216 extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
217 struct omp_for_data_loop *loops)
218 {
219 tree t, var, *collapse_iter, *collapse_count;
220 tree count = NULL_TREE, iter_type = long_integer_type_node;
221 struct omp_for_data_loop *loop;
222 int i;
223 struct omp_for_data_loop dummy_loop;
224 location_t loc = gimple_location (for_stmt);
225
226 fd->for_stmt = for_stmt;
227 fd->pre = NULL;
228 fd->collapse = gimple_omp_for_collapse (for_stmt);
229 if (fd->collapse > 1)
230 fd->loops = loops;
231 else
232 fd->loops = &fd->loop;
233
234 fd->have_nowait = fd->have_ordered = false;
235 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
236 fd->chunk_size = NULL_TREE;
237 collapse_iter = NULL;
238 collapse_count = NULL;
239
240 for (t = gimple_omp_for_clauses (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
241 switch (OMP_CLAUSE_CODE (t))
242 {
243 case OMP_CLAUSE_NOWAIT:
244 fd->have_nowait = true;
245 break;
246 case OMP_CLAUSE_ORDERED:
247 fd->have_ordered = true;
248 break;
249 case OMP_CLAUSE_SCHEDULE:
250 fd->sched_kind = OMP_CLAUSE_SCHEDULE_KIND (t);
251 fd->chunk_size = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t);
252 break;
253 case OMP_CLAUSE_COLLAPSE:
254 if (fd->collapse > 1)
255 {
256 collapse_iter = &OMP_CLAUSE_COLLAPSE_ITERVAR (t);
257 collapse_count = &OMP_CLAUSE_COLLAPSE_COUNT (t);
258 }
259 default:
260 break;
261 }
262
263 /* FIXME: for now map schedule(auto) to schedule(static).
264 There should be analysis to determine whether all iterations
265 are approximately the same amount of work (then schedule(static)
266 is best) or if it varies (then schedule(dynamic,N) is better). */
267 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_AUTO)
268 {
269 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
270 gcc_assert (fd->chunk_size == NULL);
271 }
272 gcc_assert (fd->collapse == 1 || collapse_iter != NULL);
273 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
274 gcc_assert (fd->chunk_size == NULL);
275 else if (fd->chunk_size == NULL)
276 {
277 /* We only need to compute a default chunk size for ordered
278 static loops and dynamic loops. */
279 if (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
280 || fd->have_ordered
281 || fd->collapse > 1)
282 fd->chunk_size = (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
283 ? integer_zero_node : integer_one_node;
284 }
285
286 for (i = 0; i < fd->collapse; i++)
287 {
288 if (fd->collapse == 1)
289 loop = &fd->loop;
290 else if (loops != NULL)
291 loop = loops + i;
292 else
293 loop = &dummy_loop;
294
295
296 loop->v = gimple_omp_for_index (for_stmt, i);
297 gcc_assert (SSA_VAR_P (loop->v));
298 gcc_assert (TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
299 || TREE_CODE (TREE_TYPE (loop->v)) == POINTER_TYPE);
300 var = TREE_CODE (loop->v) == SSA_NAME ? SSA_NAME_VAR (loop->v) : loop->v;
301 loop->n1 = gimple_omp_for_initial (for_stmt, i);
302
303 loop->cond_code = gimple_omp_for_cond (for_stmt, i);
304 loop->n2 = gimple_omp_for_final (for_stmt, i);
305 switch (loop->cond_code)
306 {
307 case LT_EXPR:
308 case GT_EXPR:
309 break;
310 case LE_EXPR:
311 if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
312 loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, 1);
313 else
314 loop->n2 = fold_build2_loc (loc,
315 PLUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
316 build_int_cst (TREE_TYPE (loop->n2), 1));
317 loop->cond_code = LT_EXPR;
318 break;
319 case GE_EXPR:
320 if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
321 loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, -1);
322 else
323 loop->n2 = fold_build2_loc (loc,
324 MINUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
325 build_int_cst (TREE_TYPE (loop->n2), 1));
326 loop->cond_code = GT_EXPR;
327 break;
328 default:
329 gcc_unreachable ();
330 }
331
332 t = gimple_omp_for_incr (for_stmt, i);
333 gcc_assert (TREE_OPERAND (t, 0) == var);
334 switch (TREE_CODE (t))
335 {
336 case PLUS_EXPR:
337 loop->step = TREE_OPERAND (t, 1);
338 break;
339 case POINTER_PLUS_EXPR:
340 loop->step = fold_convert (ssizetype, TREE_OPERAND (t, 1));
341 break;
342 case MINUS_EXPR:
343 loop->step = TREE_OPERAND (t, 1);
344 loop->step = fold_build1_loc (loc,
345 NEGATE_EXPR, TREE_TYPE (loop->step),
346 loop->step);
347 break;
348 default:
349 gcc_unreachable ();
350 }
351
352 if (iter_type != long_long_unsigned_type_node)
353 {
354 if (POINTER_TYPE_P (TREE_TYPE (loop->v)))
355 iter_type = long_long_unsigned_type_node;
356 else if (TYPE_UNSIGNED (TREE_TYPE (loop->v))
357 && TYPE_PRECISION (TREE_TYPE (loop->v))
358 >= TYPE_PRECISION (iter_type))
359 {
360 tree n;
361
362 if (loop->cond_code == LT_EXPR)
363 n = fold_build2_loc (loc,
364 PLUS_EXPR, TREE_TYPE (loop->v),
365 loop->n2, loop->step);
366 else
367 n = loop->n1;
368 if (TREE_CODE (n) != INTEGER_CST
369 || tree_int_cst_lt (TYPE_MAX_VALUE (iter_type), n))
370 iter_type = long_long_unsigned_type_node;
371 }
372 else if (TYPE_PRECISION (TREE_TYPE (loop->v))
373 > TYPE_PRECISION (iter_type))
374 {
375 tree n1, n2;
376
377 if (loop->cond_code == LT_EXPR)
378 {
379 n1 = loop->n1;
380 n2 = fold_build2_loc (loc,
381 PLUS_EXPR, TREE_TYPE (loop->v),
382 loop->n2, loop->step);
383 }
384 else
385 {
386 n1 = fold_build2_loc (loc,
387 MINUS_EXPR, TREE_TYPE (loop->v),
388 loop->n2, loop->step);
389 n2 = loop->n1;
390 }
391 if (TREE_CODE (n1) != INTEGER_CST
392 || TREE_CODE (n2) != INTEGER_CST
393 || !tree_int_cst_lt (TYPE_MIN_VALUE (iter_type), n1)
394 || !tree_int_cst_lt (n2, TYPE_MAX_VALUE (iter_type)))
395 iter_type = long_long_unsigned_type_node;
396 }
397 }
398
399 if (collapse_count && *collapse_count == NULL)
400 {
401 if ((i == 0 || count != NULL_TREE)
402 && TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
403 && TREE_CONSTANT (loop->n1)
404 && TREE_CONSTANT (loop->n2)
405 && TREE_CODE (loop->step) == INTEGER_CST)
406 {
407 tree itype = TREE_TYPE (loop->v);
408
409 if (POINTER_TYPE_P (itype))
410 itype = signed_type_for (itype);
411 t = build_int_cst (itype, (loop->cond_code == LT_EXPR ? -1 : 1));
412 t = fold_build2_loc (loc,
413 PLUS_EXPR, itype,
414 fold_convert_loc (loc, itype, loop->step), t);
415 t = fold_build2_loc (loc, PLUS_EXPR, itype, t,
416 fold_convert_loc (loc, itype, loop->n2));
417 t = fold_build2_loc (loc, MINUS_EXPR, itype, t,
418 fold_convert_loc (loc, itype, loop->n1));
419 if (TYPE_UNSIGNED (itype) && loop->cond_code == GT_EXPR)
420 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
421 fold_build1_loc (loc, NEGATE_EXPR, itype, t),
422 fold_build1_loc (loc, NEGATE_EXPR, itype,
423 fold_convert_loc (loc, itype,
424 loop->step)));
425 else
426 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
427 fold_convert_loc (loc, itype, loop->step));
428 t = fold_convert_loc (loc, long_long_unsigned_type_node, t);
429 if (count != NULL_TREE)
430 count = fold_build2_loc (loc,
431 MULT_EXPR, long_long_unsigned_type_node,
432 count, t);
433 else
434 count = t;
435 if (TREE_CODE (count) != INTEGER_CST)
436 count = NULL_TREE;
437 }
438 else
439 count = NULL_TREE;
440 }
441 }
442
443 if (count)
444 {
445 if (!tree_int_cst_lt (count, TYPE_MAX_VALUE (long_integer_type_node)))
446 iter_type = long_long_unsigned_type_node;
447 else
448 iter_type = long_integer_type_node;
449 }
450 else if (collapse_iter && *collapse_iter != NULL)
451 iter_type = TREE_TYPE (*collapse_iter);
452 fd->iter_type = iter_type;
453 if (collapse_iter && *collapse_iter == NULL)
454 *collapse_iter = create_tmp_var (iter_type, ".iter");
455 if (collapse_count && *collapse_count == NULL)
456 {
457 if (count)
458 *collapse_count = fold_convert_loc (loc, iter_type, count);
459 else
460 *collapse_count = create_tmp_var (iter_type, ".count");
461 }
462
463 if (fd->collapse > 1)
464 {
465 fd->loop.v = *collapse_iter;
466 fd->loop.n1 = build_int_cst (TREE_TYPE (fd->loop.v), 0);
467 fd->loop.n2 = *collapse_count;
468 fd->loop.step = build_int_cst (TREE_TYPE (fd->loop.v), 1);
469 fd->loop.cond_code = LT_EXPR;
470 }
471 }
472
473
474 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
475 is the immediate dominator of PAR_ENTRY_BB, return true if there
476 are no data dependencies that would prevent expanding the parallel
477 directive at PAR_ENTRY_BB as a combined parallel+workshare region.
478
479 When expanding a combined parallel+workshare region, the call to
480 the child function may need additional arguments in the case of
481 GIMPLE_OMP_FOR regions. In some cases, these arguments are
482 computed out of variables passed in from the parent to the child
483 via 'struct .omp_data_s'. For instance:
484
485 #pragma omp parallel for schedule (guided, i * 4)
486 for (j ...)
487
488 Is lowered into:
489
490 # BLOCK 2 (PAR_ENTRY_BB)
491 .omp_data_o.i = i;
492 #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
493
494 # BLOCK 3 (WS_ENTRY_BB)
495 .omp_data_i = &.omp_data_o;
496 D.1667 = .omp_data_i->i;
497 D.1598 = D.1667 * 4;
498 #pragma omp for schedule (guided, D.1598)
499
500 When we outline the parallel region, the call to the child function
501 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
502 that value is computed *after* the call site. So, in principle we
503 cannot do the transformation.
504
505 To see whether the code in WS_ENTRY_BB blocks the combined
506 parallel+workshare call, we collect all the variables used in the
507 GIMPLE_OMP_FOR header check whether they appear on the LHS of any
508 statement in WS_ENTRY_BB. If so, then we cannot emit the combined
509 call.
510
511 FIXME. If we had the SSA form built at this point, we could merely
512 hoist the code in block 3 into block 2 and be done with it. But at
513 this point we don't have dataflow information and though we could
514 hack something up here, it is really not worth the aggravation. */
515
516 static bool
517 workshare_safe_to_combine_p (basic_block ws_entry_bb)
518 {
519 struct omp_for_data fd;
520 gimple ws_stmt = last_stmt (ws_entry_bb);
521
522 if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
523 return true;
524
525 gcc_assert (gimple_code (ws_stmt) == GIMPLE_OMP_FOR);
526
527 extract_omp_for_data (ws_stmt, &fd, NULL);
528
529 if (fd.collapse > 1 && TREE_CODE (fd.loop.n2) != INTEGER_CST)
530 return false;
531 if (fd.iter_type != long_integer_type_node)
532 return false;
533
534 /* FIXME. We give up too easily here. If any of these arguments
535 are not constants, they will likely involve variables that have
536 been mapped into fields of .omp_data_s for sharing with the child
537 function. With appropriate data flow, it would be possible to
538 see through this. */
539 if (!is_gimple_min_invariant (fd.loop.n1)
540 || !is_gimple_min_invariant (fd.loop.n2)
541 || !is_gimple_min_invariant (fd.loop.step)
542 || (fd.chunk_size && !is_gimple_min_invariant (fd.chunk_size)))
543 return false;
544
545 return true;
546 }
547
548
549 /* Collect additional arguments needed to emit a combined
550 parallel+workshare call. WS_STMT is the workshare directive being
551 expanded. */
552
553 static vec<tree, va_gc> *
554 get_ws_args_for (gimple ws_stmt)
555 {
556 tree t;
557 location_t loc = gimple_location (ws_stmt);
558 vec<tree, va_gc> *ws_args;
559
560 if (gimple_code (ws_stmt) == GIMPLE_OMP_FOR)
561 {
562 struct omp_for_data fd;
563
564 extract_omp_for_data (ws_stmt, &fd, NULL);
565
566 vec_alloc (ws_args, 3 + (fd.chunk_size != 0));
567
568 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n1);
569 ws_args->quick_push (t);
570
571 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n2);
572 ws_args->quick_push (t);
573
574 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.step);
575 ws_args->quick_push (t);
576
577 if (fd.chunk_size)
578 {
579 t = fold_convert_loc (loc, long_integer_type_node, fd.chunk_size);
580 ws_args->quick_push (t);
581 }
582
583 return ws_args;
584 }
585 else if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
586 {
587 /* Number of sections is equal to the number of edges from the
588 GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
589 the exit of the sections region. */
590 basic_block bb = single_succ (gimple_bb (ws_stmt));
591 t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
592 vec_alloc (ws_args, 1);
593 ws_args->quick_push (t);
594 return ws_args;
595 }
596
597 gcc_unreachable ();
598 }
599
600
601 /* Discover whether REGION is a combined parallel+workshare region. */
602
603 static void
604 determine_parallel_type (struct omp_region *region)
605 {
606 basic_block par_entry_bb, par_exit_bb;
607 basic_block ws_entry_bb, ws_exit_bb;
608
609 if (region == NULL || region->inner == NULL
610 || region->exit == NULL || region->inner->exit == NULL
611 || region->inner->cont == NULL)
612 return;
613
614 /* We only support parallel+for and parallel+sections. */
615 if (region->type != GIMPLE_OMP_PARALLEL
616 || (region->inner->type != GIMPLE_OMP_FOR
617 && region->inner->type != GIMPLE_OMP_SECTIONS))
618 return;
619
620 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
621 WS_EXIT_BB -> PAR_EXIT_BB. */
622 par_entry_bb = region->entry;
623 par_exit_bb = region->exit;
624 ws_entry_bb = region->inner->entry;
625 ws_exit_bb = region->inner->exit;
626
627 if (single_succ (par_entry_bb) == ws_entry_bb
628 && single_succ (ws_exit_bb) == par_exit_bb
629 && workshare_safe_to_combine_p (ws_entry_bb)
630 && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb))
631 || (last_and_only_stmt (ws_entry_bb)
632 && last_and_only_stmt (par_exit_bb))))
633 {
634 gimple ws_stmt = last_stmt (ws_entry_bb);
635
636 if (region->inner->type == GIMPLE_OMP_FOR)
637 {
638 /* If this is a combined parallel loop, we need to determine
639 whether or not to use the combined library calls. There
640 are two cases where we do not apply the transformation:
641 static loops and any kind of ordered loop. In the first
642 case, we already open code the loop so there is no need
643 to do anything else. In the latter case, the combined
644 parallel loop call would still need extra synchronization
645 to implement ordered semantics, so there would not be any
646 gain in using the combined call. */
647 tree clauses = gimple_omp_for_clauses (ws_stmt);
648 tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
649 if (c == NULL
650 || OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_STATIC
651 || find_omp_clause (clauses, OMP_CLAUSE_ORDERED))
652 {
653 region->is_combined_parallel = false;
654 region->inner->is_combined_parallel = false;
655 return;
656 }
657 }
658
659 region->is_combined_parallel = true;
660 region->inner->is_combined_parallel = true;
661 region->ws_args = get_ws_args_for (ws_stmt);
662 }
663 }
664
665
666 /* Return true if EXPR is variable sized. */
667
668 static inline bool
669 is_variable_sized (const_tree expr)
670 {
671 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
672 }
673
674 /* Return true if DECL is a reference type. */
675
676 static inline bool
677 is_reference (tree decl)
678 {
679 return lang_hooks.decls.omp_privatize_by_reference (decl);
680 }
681
682 /* Lookup variables in the decl or field splay trees. The "maybe" form
683 allows for the variable form to not have been entered, otherwise we
684 assert that the variable must have been entered. */
685
686 static inline tree
687 lookup_decl (tree var, omp_context *ctx)
688 {
689 tree *n;
690 n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
691 return *n;
692 }
693
694 static inline tree
695 maybe_lookup_decl (const_tree var, omp_context *ctx)
696 {
697 tree *n;
698 n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
699 return n ? *n : NULL_TREE;
700 }
701
702 static inline tree
703 lookup_field (tree var, omp_context *ctx)
704 {
705 splay_tree_node n;
706 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
707 return (tree) n->value;
708 }
709
710 static inline tree
711 lookup_sfield (tree var, omp_context *ctx)
712 {
713 splay_tree_node n;
714 n = splay_tree_lookup (ctx->sfield_map
715 ? ctx->sfield_map : ctx->field_map,
716 (splay_tree_key) var);
717 return (tree) n->value;
718 }
719
720 static inline tree
721 maybe_lookup_field (tree var, omp_context *ctx)
722 {
723 splay_tree_node n;
724 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
725 return n ? (tree) n->value : NULL_TREE;
726 }
727
728 /* Return true if DECL should be copied by pointer. SHARED_CTX is
729 the parallel context if DECL is to be shared. */
730
731 static bool
732 use_pointer_for_field (tree decl, omp_context *shared_ctx)
733 {
734 if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
735 return true;
736
737 /* We can only use copy-in/copy-out semantics for shared variables
738 when we know the value is not accessible from an outer scope. */
739 if (shared_ctx)
740 {
741 /* ??? Trivially accessible from anywhere. But why would we even
742 be passing an address in this case? Should we simply assert
743 this to be false, or should we have a cleanup pass that removes
744 these from the list of mappings? */
745 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
746 return true;
747
748 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
749 without analyzing the expression whether or not its location
750 is accessible to anyone else. In the case of nested parallel
751 regions it certainly may be. */
752 if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
753 return true;
754
755 /* Do not use copy-in/copy-out for variables that have their
756 address taken. */
757 if (TREE_ADDRESSABLE (decl))
758 return true;
759
760 /* lower_send_shared_vars only uses copy-in, but not copy-out
761 for these. */
762 if (TREE_READONLY (decl)
763 || ((TREE_CODE (decl) == RESULT_DECL
764 || TREE_CODE (decl) == PARM_DECL)
765 && DECL_BY_REFERENCE (decl)))
766 return false;
767
768 /* Disallow copy-in/out in nested parallel if
769 decl is shared in outer parallel, otherwise
770 each thread could store the shared variable
771 in its own copy-in location, making the
772 variable no longer really shared. */
773 if (shared_ctx->is_nested)
774 {
775 omp_context *up;
776
777 for (up = shared_ctx->outer; up; up = up->outer)
778 if (is_taskreg_ctx (up) && maybe_lookup_decl (decl, up))
779 break;
780
781 if (up)
782 {
783 tree c;
784
785 for (c = gimple_omp_taskreg_clauses (up->stmt);
786 c; c = OMP_CLAUSE_CHAIN (c))
787 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
788 && OMP_CLAUSE_DECL (c) == decl)
789 break;
790
791 if (c)
792 goto maybe_mark_addressable_and_ret;
793 }
794 }
795
796 /* For tasks avoid using copy-in/out. As tasks can be
797 deferred or executed in different thread, when GOMP_task
798 returns, the task hasn't necessarily terminated. */
799 if (is_task_ctx (shared_ctx))
800 {
801 tree outer;
802 maybe_mark_addressable_and_ret:
803 outer = maybe_lookup_decl_in_outer_ctx (decl, shared_ctx);
804 if (is_gimple_reg (outer))
805 {
806 /* Taking address of OUTER in lower_send_shared_vars
807 might need regimplification of everything that uses the
808 variable. */
809 if (!task_shared_vars)
810 task_shared_vars = BITMAP_ALLOC (NULL);
811 bitmap_set_bit (task_shared_vars, DECL_UID (outer));
812 TREE_ADDRESSABLE (outer) = 1;
813 }
814 return true;
815 }
816 }
817
818 return false;
819 }
820
821 /* Create a new VAR_DECL and copy information from VAR to it. */
822
823 tree
824 copy_var_decl (tree var, tree name, tree type)
825 {
826 tree copy = build_decl (DECL_SOURCE_LOCATION (var), VAR_DECL, name, type);
827
828 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
829 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (var);
830 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
831 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
832 DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
833 DECL_CONTEXT (copy) = DECL_CONTEXT (var);
834 TREE_USED (copy) = 1;
835 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
836
837 return copy;
838 }
839
840 /* Construct a new automatic decl similar to VAR. */
841
842 static tree
843 omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
844 {
845 tree copy = copy_var_decl (var, name, type);
846
847 DECL_CONTEXT (copy) = current_function_decl;
848 DECL_CHAIN (copy) = ctx->block_vars;
849 ctx->block_vars = copy;
850
851 return copy;
852 }
853
854 static tree
855 omp_copy_decl_1 (tree var, omp_context *ctx)
856 {
857 return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
858 }
859
860 /* Build COMPONENT_REF and set TREE_THIS_VOLATILE and TREE_READONLY on it
861 as appropriate. */
862 static tree
863 omp_build_component_ref (tree obj, tree field)
864 {
865 tree ret = build3 (COMPONENT_REF, TREE_TYPE (field), obj, field, NULL);
866 if (TREE_THIS_VOLATILE (field))
867 TREE_THIS_VOLATILE (ret) |= 1;
868 if (TREE_READONLY (field))
869 TREE_READONLY (ret) |= 1;
870 return ret;
871 }
872
873 /* Build tree nodes to access the field for VAR on the receiver side. */
874
875 static tree
876 build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
877 {
878 tree x, field = lookup_field (var, ctx);
879
880 /* If the receiver record type was remapped in the child function,
881 remap the field into the new record type. */
882 x = maybe_lookup_field (field, ctx);
883 if (x != NULL)
884 field = x;
885
886 x = build_simple_mem_ref (ctx->receiver_decl);
887 x = omp_build_component_ref (x, field);
888 if (by_ref)
889 x = build_simple_mem_ref (x);
890
891 return x;
892 }
893
894 /* Build tree nodes to access VAR in the scope outer to CTX. In the case
895 of a parallel, this is a component reference; for workshare constructs
896 this is some variable. */
897
898 static tree
899 build_outer_var_ref (tree var, omp_context *ctx)
900 {
901 tree x;
902
903 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
904 x = var;
905 else if (is_variable_sized (var))
906 {
907 x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
908 x = build_outer_var_ref (x, ctx);
909 x = build_simple_mem_ref (x);
910 }
911 else if (is_taskreg_ctx (ctx))
912 {
913 bool by_ref = use_pointer_for_field (var, NULL);
914 x = build_receiver_ref (var, by_ref, ctx);
915 }
916 else if (ctx->outer)
917 x = lookup_decl (var, ctx->outer);
918 else if (is_reference (var))
919 /* This can happen with orphaned constructs. If var is reference, it is
920 possible it is shared and as such valid. */
921 x = var;
922 else
923 gcc_unreachable ();
924
925 if (is_reference (var))
926 x = build_simple_mem_ref (x);
927
928 return x;
929 }
930
931 /* Build tree nodes to access the field for VAR on the sender side. */
932
933 static tree
934 build_sender_ref (tree var, omp_context *ctx)
935 {
936 tree field = lookup_sfield (var, ctx);
937 return omp_build_component_ref (ctx->sender_decl, field);
938 }
939
940 /* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
941
942 static void
943 install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
944 {
945 tree field, type, sfield = NULL_TREE;
946
947 gcc_assert ((mask & 1) == 0
948 || !splay_tree_lookup (ctx->field_map, (splay_tree_key) var));
949 gcc_assert ((mask & 2) == 0 || !ctx->sfield_map
950 || !splay_tree_lookup (ctx->sfield_map, (splay_tree_key) var));
951
952 type = TREE_TYPE (var);
953 if (by_ref)
954 type = build_pointer_type (type);
955 else if ((mask & 3) == 1 && is_reference (var))
956 type = TREE_TYPE (type);
957
958 field = build_decl (DECL_SOURCE_LOCATION (var),
959 FIELD_DECL, DECL_NAME (var), type);
960
961 /* Remember what variable this field was created for. This does have a
962 side effect of making dwarf2out ignore this member, so for helpful
963 debugging we clear it later in delete_omp_context. */
964 DECL_ABSTRACT_ORIGIN (field) = var;
965 if (type == TREE_TYPE (var))
966 {
967 DECL_ALIGN (field) = DECL_ALIGN (var);
968 DECL_USER_ALIGN (field) = DECL_USER_ALIGN (var);
969 TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (var);
970 }
971 else
972 DECL_ALIGN (field) = TYPE_ALIGN (type);
973
974 if ((mask & 3) == 3)
975 {
976 insert_field_into_struct (ctx->record_type, field);
977 if (ctx->srecord_type)
978 {
979 sfield = build_decl (DECL_SOURCE_LOCATION (var),
980 FIELD_DECL, DECL_NAME (var), type);
981 DECL_ABSTRACT_ORIGIN (sfield) = var;
982 DECL_ALIGN (sfield) = DECL_ALIGN (field);
983 DECL_USER_ALIGN (sfield) = DECL_USER_ALIGN (field);
984 TREE_THIS_VOLATILE (sfield) = TREE_THIS_VOLATILE (field);
985 insert_field_into_struct (ctx->srecord_type, sfield);
986 }
987 }
988 else
989 {
990 if (ctx->srecord_type == NULL_TREE)
991 {
992 tree t;
993
994 ctx->srecord_type = lang_hooks.types.make_type (RECORD_TYPE);
995 ctx->sfield_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
996 for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
997 {
998 sfield = build_decl (DECL_SOURCE_LOCATION (var),
999 FIELD_DECL, DECL_NAME (t), TREE_TYPE (t));
1000 DECL_ABSTRACT_ORIGIN (sfield) = DECL_ABSTRACT_ORIGIN (t);
1001 insert_field_into_struct (ctx->srecord_type, sfield);
1002 splay_tree_insert (ctx->sfield_map,
1003 (splay_tree_key) DECL_ABSTRACT_ORIGIN (t),
1004 (splay_tree_value) sfield);
1005 }
1006 }
1007 sfield = field;
1008 insert_field_into_struct ((mask & 1) ? ctx->record_type
1009 : ctx->srecord_type, field);
1010 }
1011
1012 if (mask & 1)
1013 splay_tree_insert (ctx->field_map, (splay_tree_key) var,
1014 (splay_tree_value) field);
1015 if ((mask & 2) && ctx->sfield_map)
1016 splay_tree_insert (ctx->sfield_map, (splay_tree_key) var,
1017 (splay_tree_value) sfield);
1018 }
1019
1020 static tree
1021 install_var_local (tree var, omp_context *ctx)
1022 {
1023 tree new_var = omp_copy_decl_1 (var, ctx);
1024 insert_decl_map (&ctx->cb, var, new_var);
1025 return new_var;
1026 }
1027
1028 /* Adjust the replacement for DECL in CTX for the new context. This means
1029 copying the DECL_VALUE_EXPR, and fixing up the type. */
1030
1031 static void
1032 fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
1033 {
1034 tree new_decl, size;
1035
1036 new_decl = lookup_decl (decl, ctx);
1037
1038 TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
1039
1040 if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
1041 && DECL_HAS_VALUE_EXPR_P (decl))
1042 {
1043 tree ve = DECL_VALUE_EXPR (decl);
1044 walk_tree (&ve, copy_tree_body_r, &ctx->cb, NULL);
1045 SET_DECL_VALUE_EXPR (new_decl, ve);
1046 DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
1047 }
1048
1049 if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
1050 {
1051 size = remap_decl (DECL_SIZE (decl), &ctx->cb);
1052 if (size == error_mark_node)
1053 size = TYPE_SIZE (TREE_TYPE (new_decl));
1054 DECL_SIZE (new_decl) = size;
1055
1056 size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
1057 if (size == error_mark_node)
1058 size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
1059 DECL_SIZE_UNIT (new_decl) = size;
1060 }
1061 }
1062
1063 /* The callback for remap_decl. Search all containing contexts for a
1064 mapping of the variable; this avoids having to duplicate the splay
1065 tree ahead of time. We know a mapping doesn't already exist in the
1066 given context. Create new mappings to implement default semantics. */
1067
1068 static tree
1069 omp_copy_decl (tree var, copy_body_data *cb)
1070 {
1071 omp_context *ctx = (omp_context *) cb;
1072 tree new_var;
1073
1074 if (TREE_CODE (var) == LABEL_DECL)
1075 {
1076 new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
1077 DECL_CONTEXT (new_var) = current_function_decl;
1078 insert_decl_map (&ctx->cb, var, new_var);
1079 return new_var;
1080 }
1081
1082 while (!is_taskreg_ctx (ctx))
1083 {
1084 ctx = ctx->outer;
1085 if (ctx == NULL)
1086 return var;
1087 new_var = maybe_lookup_decl (var, ctx);
1088 if (new_var)
1089 return new_var;
1090 }
1091
1092 if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
1093 return var;
1094
1095 return error_mark_node;
1096 }
1097
1098
1099 /* Return the parallel region associated with STMT. */
1100
1101 /* Debugging dumps for parallel regions. */
1102 void dump_omp_region (FILE *, struct omp_region *, int);
1103 void debug_omp_region (struct omp_region *);
1104 void debug_all_omp_regions (void);
1105
1106 /* Dump the parallel region tree rooted at REGION. */
1107
1108 void
1109 dump_omp_region (FILE *file, struct omp_region *region, int indent)
1110 {
1111 fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
1112 gimple_code_name[region->type]);
1113
1114 if (region->inner)
1115 dump_omp_region (file, region->inner, indent + 4);
1116
1117 if (region->cont)
1118 {
1119 fprintf (file, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent, "",
1120 region->cont->index);
1121 }
1122
1123 if (region->exit)
1124 fprintf (file, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent, "",
1125 region->exit->index);
1126 else
1127 fprintf (file, "%*s[no exit marker]\n", indent, "");
1128
1129 if (region->next)
1130 dump_omp_region (file, region->next, indent);
1131 }
1132
1133 DEBUG_FUNCTION void
1134 debug_omp_region (struct omp_region *region)
1135 {
1136 dump_omp_region (stderr, region, 0);
1137 }
1138
1139 DEBUG_FUNCTION void
1140 debug_all_omp_regions (void)
1141 {
1142 dump_omp_region (stderr, root_omp_region, 0);
1143 }
1144
1145
1146 /* Create a new parallel region starting at STMT inside region PARENT. */
1147
1148 struct omp_region *
1149 new_omp_region (basic_block bb, enum gimple_code type,
1150 struct omp_region *parent)
1151 {
1152 struct omp_region *region = XCNEW (struct omp_region);
1153
1154 region->outer = parent;
1155 region->entry = bb;
1156 region->type = type;
1157
1158 if (parent)
1159 {
1160 /* This is a nested region. Add it to the list of inner
1161 regions in PARENT. */
1162 region->next = parent->inner;
1163 parent->inner = region;
1164 }
1165 else
1166 {
1167 /* This is a toplevel region. Add it to the list of toplevel
1168 regions in ROOT_OMP_REGION. */
1169 region->next = root_omp_region;
1170 root_omp_region = region;
1171 }
1172
1173 return region;
1174 }
1175
1176 /* Release the memory associated with the region tree rooted at REGION. */
1177
1178 static void
1179 free_omp_region_1 (struct omp_region *region)
1180 {
1181 struct omp_region *i, *n;
1182
1183 for (i = region->inner; i ; i = n)
1184 {
1185 n = i->next;
1186 free_omp_region_1 (i);
1187 }
1188
1189 free (region);
1190 }
1191
1192 /* Release the memory for the entire omp region tree. */
1193
1194 void
1195 free_omp_regions (void)
1196 {
1197 struct omp_region *r, *n;
1198 for (r = root_omp_region; r ; r = n)
1199 {
1200 n = r->next;
1201 free_omp_region_1 (r);
1202 }
1203 root_omp_region = NULL;
1204 }
1205
1206
1207 /* Create a new context, with OUTER_CTX being the surrounding context. */
1208
1209 static omp_context *
1210 new_omp_context (gimple stmt, omp_context *outer_ctx)
1211 {
1212 omp_context *ctx = XCNEW (omp_context);
1213
1214 splay_tree_insert (all_contexts, (splay_tree_key) stmt,
1215 (splay_tree_value) ctx);
1216 ctx->stmt = stmt;
1217
1218 if (outer_ctx)
1219 {
1220 ctx->outer = outer_ctx;
1221 ctx->cb = outer_ctx->cb;
1222 ctx->cb.block = NULL;
1223 ctx->depth = outer_ctx->depth + 1;
1224 }
1225 else
1226 {
1227 ctx->cb.src_fn = current_function_decl;
1228 ctx->cb.dst_fn = current_function_decl;
1229 ctx->cb.src_node = cgraph_get_node (current_function_decl);
1230 gcc_checking_assert (ctx->cb.src_node);
1231 ctx->cb.dst_node = ctx->cb.src_node;
1232 ctx->cb.src_cfun = cfun;
1233 ctx->cb.copy_decl = omp_copy_decl;
1234 ctx->cb.eh_lp_nr = 0;
1235 ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
1236 ctx->depth = 1;
1237 }
1238
1239 ctx->cb.decl_map = pointer_map_create ();
1240
1241 return ctx;
1242 }
1243
1244 static gimple_seq maybe_catch_exception (gimple_seq);
1245
1246 /* Finalize task copyfn. */
1247
1248 static void
1249 finalize_task_copyfn (gimple task_stmt)
1250 {
1251 struct function *child_cfun;
1252 tree child_fn;
1253 gimple_seq seq = NULL, new_seq;
1254 gimple bind;
1255
1256 child_fn = gimple_omp_task_copy_fn (task_stmt);
1257 if (child_fn == NULL_TREE)
1258 return;
1259
1260 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
1261
1262 /* Inform the callgraph about the new function. */
1263 DECL_STRUCT_FUNCTION (child_fn)->curr_properties
1264 = cfun->curr_properties & ~PROP_loops;
1265
1266 push_cfun (child_cfun);
1267 bind = gimplify_body (child_fn, false);
1268 gimple_seq_add_stmt (&seq, bind);
1269 new_seq = maybe_catch_exception (seq);
1270 if (new_seq != seq)
1271 {
1272 bind = gimple_build_bind (NULL, new_seq, NULL);
1273 seq = NULL;
1274 gimple_seq_add_stmt (&seq, bind);
1275 }
1276 gimple_set_body (child_fn, seq);
1277 pop_cfun ();
1278
1279 cgraph_add_new_function (child_fn, false);
1280 }
1281
1282 /* Destroy a omp_context data structures. Called through the splay tree
1283 value delete callback. */
1284
1285 static void
1286 delete_omp_context (splay_tree_value value)
1287 {
1288 omp_context *ctx = (omp_context *) value;
1289
1290 pointer_map_destroy (ctx->cb.decl_map);
1291
1292 if (ctx->field_map)
1293 splay_tree_delete (ctx->field_map);
1294 if (ctx->sfield_map)
1295 splay_tree_delete (ctx->sfield_map);
1296
1297 /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
1298 it produces corrupt debug information. */
1299 if (ctx->record_type)
1300 {
1301 tree t;
1302 for (t = TYPE_FIELDS (ctx->record_type); t ; t = DECL_CHAIN (t))
1303 DECL_ABSTRACT_ORIGIN (t) = NULL;
1304 }
1305 if (ctx->srecord_type)
1306 {
1307 tree t;
1308 for (t = TYPE_FIELDS (ctx->srecord_type); t ; t = DECL_CHAIN (t))
1309 DECL_ABSTRACT_ORIGIN (t) = NULL;
1310 }
1311
1312 if (is_task_ctx (ctx))
1313 finalize_task_copyfn (ctx->stmt);
1314
1315 XDELETE (ctx);
1316 }
1317
1318 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
1319 context. */
1320
1321 static void
1322 fixup_child_record_type (omp_context *ctx)
1323 {
1324 tree f, type = ctx->record_type;
1325
1326 /* ??? It isn't sufficient to just call remap_type here, because
1327 variably_modified_type_p doesn't work the way we expect for
1328 record types. Testing each field for whether it needs remapping
1329 and creating a new record by hand works, however. */
1330 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
1331 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
1332 break;
1333 if (f)
1334 {
1335 tree name, new_fields = NULL;
1336
1337 type = lang_hooks.types.make_type (RECORD_TYPE);
1338 name = DECL_NAME (TYPE_NAME (ctx->record_type));
1339 name = build_decl (DECL_SOURCE_LOCATION (ctx->receiver_decl),
1340 TYPE_DECL, name, type);
1341 TYPE_NAME (type) = name;
1342
1343 for (f = TYPE_FIELDS (ctx->record_type); f ; f = DECL_CHAIN (f))
1344 {
1345 tree new_f = copy_node (f);
1346 DECL_CONTEXT (new_f) = type;
1347 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
1348 DECL_CHAIN (new_f) = new_fields;
1349 walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &ctx->cb, NULL);
1350 walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r,
1351 &ctx->cb, NULL);
1352 walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
1353 &ctx->cb, NULL);
1354 new_fields = new_f;
1355
1356 /* Arrange to be able to look up the receiver field
1357 given the sender field. */
1358 splay_tree_insert (ctx->field_map, (splay_tree_key) f,
1359 (splay_tree_value) new_f);
1360 }
1361 TYPE_FIELDS (type) = nreverse (new_fields);
1362 layout_type (type);
1363 }
1364
1365 TREE_TYPE (ctx->receiver_decl) = build_pointer_type (type);
1366 }
1367
1368 /* Instantiate decls as necessary in CTX to satisfy the data sharing
1369 specified by CLAUSES. */
1370
1371 static void
1372 scan_sharing_clauses (tree clauses, omp_context *ctx)
1373 {
1374 tree c, decl;
1375 bool scan_array_reductions = false;
1376
1377 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1378 {
1379 bool by_ref;
1380
1381 switch (OMP_CLAUSE_CODE (c))
1382 {
1383 case OMP_CLAUSE_PRIVATE:
1384 decl = OMP_CLAUSE_DECL (c);
1385 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
1386 goto do_private;
1387 else if (!is_variable_sized (decl))
1388 install_var_local (decl, ctx);
1389 break;
1390
1391 case OMP_CLAUSE_SHARED:
1392 gcc_assert (is_taskreg_ctx (ctx));
1393 decl = OMP_CLAUSE_DECL (c);
1394 gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl))
1395 || !is_variable_sized (decl));
1396 /* Global variables don't need to be copied,
1397 the receiver side will use them directly. */
1398 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1399 break;
1400 by_ref = use_pointer_for_field (decl, ctx);
1401 if (! TREE_READONLY (decl)
1402 || TREE_ADDRESSABLE (decl)
1403 || by_ref
1404 || is_reference (decl))
1405 {
1406 install_var_field (decl, by_ref, 3, ctx);
1407 install_var_local (decl, ctx);
1408 break;
1409 }
1410 /* We don't need to copy const scalar vars back. */
1411 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
1412 goto do_private;
1413
1414 case OMP_CLAUSE_LASTPRIVATE:
1415 /* Let the corresponding firstprivate clause create
1416 the variable. */
1417 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1418 break;
1419 /* FALLTHRU */
1420
1421 case OMP_CLAUSE_FIRSTPRIVATE:
1422 case OMP_CLAUSE_REDUCTION:
1423 decl = OMP_CLAUSE_DECL (c);
1424 do_private:
1425 if (is_variable_sized (decl))
1426 {
1427 if (is_task_ctx (ctx))
1428 install_var_field (decl, false, 1, ctx);
1429 break;
1430 }
1431 else if (is_taskreg_ctx (ctx))
1432 {
1433 bool global
1434 = is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx));
1435 by_ref = use_pointer_for_field (decl, NULL);
1436
1437 if (is_task_ctx (ctx)
1438 && (global || by_ref || is_reference (decl)))
1439 {
1440 install_var_field (decl, false, 1, ctx);
1441 if (!global)
1442 install_var_field (decl, by_ref, 2, ctx);
1443 }
1444 else if (!global)
1445 install_var_field (decl, by_ref, 3, ctx);
1446 }
1447 install_var_local (decl, ctx);
1448 break;
1449
1450 case OMP_CLAUSE_COPYPRIVATE:
1451 case OMP_CLAUSE_COPYIN:
1452 decl = OMP_CLAUSE_DECL (c);
1453 by_ref = use_pointer_for_field (decl, NULL);
1454 install_var_field (decl, by_ref, 3, ctx);
1455 break;
1456
1457 case OMP_CLAUSE_DEFAULT:
1458 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
1459 break;
1460
1461 case OMP_CLAUSE_FINAL:
1462 case OMP_CLAUSE_IF:
1463 case OMP_CLAUSE_NUM_THREADS:
1464 case OMP_CLAUSE_SCHEDULE:
1465 if (ctx->outer)
1466 scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
1467 break;
1468
1469 case OMP_CLAUSE_NOWAIT:
1470 case OMP_CLAUSE_ORDERED:
1471 case OMP_CLAUSE_COLLAPSE:
1472 case OMP_CLAUSE_UNTIED:
1473 case OMP_CLAUSE_MERGEABLE:
1474 break;
1475
1476 default:
1477 gcc_unreachable ();
1478 }
1479 }
1480
1481 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1482 {
1483 switch (OMP_CLAUSE_CODE (c))
1484 {
1485 case OMP_CLAUSE_LASTPRIVATE:
1486 /* Let the corresponding firstprivate clause create
1487 the variable. */
1488 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
1489 scan_array_reductions = true;
1490 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1491 break;
1492 /* FALLTHRU */
1493
1494 case OMP_CLAUSE_PRIVATE:
1495 case OMP_CLAUSE_FIRSTPRIVATE:
1496 case OMP_CLAUSE_REDUCTION:
1497 decl = OMP_CLAUSE_DECL (c);
1498 if (is_variable_sized (decl))
1499 install_var_local (decl, ctx);
1500 fixup_remapped_decl (decl, ctx,
1501 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
1502 && OMP_CLAUSE_PRIVATE_DEBUG (c));
1503 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1504 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1505 scan_array_reductions = true;
1506 break;
1507
1508 case OMP_CLAUSE_SHARED:
1509 decl = OMP_CLAUSE_DECL (c);
1510 if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1511 fixup_remapped_decl (decl, ctx, false);
1512 break;
1513
1514 case OMP_CLAUSE_COPYPRIVATE:
1515 case OMP_CLAUSE_COPYIN:
1516 case OMP_CLAUSE_DEFAULT:
1517 case OMP_CLAUSE_IF:
1518 case OMP_CLAUSE_NUM_THREADS:
1519 case OMP_CLAUSE_SCHEDULE:
1520 case OMP_CLAUSE_NOWAIT:
1521 case OMP_CLAUSE_ORDERED:
1522 case OMP_CLAUSE_COLLAPSE:
1523 case OMP_CLAUSE_UNTIED:
1524 case OMP_CLAUSE_FINAL:
1525 case OMP_CLAUSE_MERGEABLE:
1526 break;
1527
1528 default:
1529 gcc_unreachable ();
1530 }
1531 }
1532
1533 if (scan_array_reductions)
1534 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1535 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1536 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1537 {
1538 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
1539 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
1540 }
1541 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
1542 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
1543 scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
1544 }
1545
1546 /* Create a new name for omp child function. Returns an identifier. */
1547
1548 static GTY(()) unsigned int tmp_ompfn_id_num;
1549
1550 static tree
1551 create_omp_child_function_name (bool task_copy)
1552 {
1553 return (clone_function_name (current_function_decl,
1554 task_copy ? "_omp_cpyfn" : "_omp_fn"));
1555 }
1556
1557 /* Build a decl for the omp child function. It'll not contain a body
1558 yet, just the bare decl. */
1559
1560 static void
1561 create_omp_child_function (omp_context *ctx, bool task_copy)
1562 {
1563 tree decl, type, name, t;
1564
1565 name = create_omp_child_function_name (task_copy);
1566 if (task_copy)
1567 type = build_function_type_list (void_type_node, ptr_type_node,
1568 ptr_type_node, NULL_TREE);
1569 else
1570 type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
1571
1572 decl = build_decl (gimple_location (ctx->stmt),
1573 FUNCTION_DECL, name, type);
1574
1575 if (!task_copy)
1576 ctx->cb.dst_fn = decl;
1577 else
1578 gimple_omp_task_set_copy_fn (ctx->stmt, decl);
1579
1580 TREE_STATIC (decl) = 1;
1581 TREE_USED (decl) = 1;
1582 DECL_ARTIFICIAL (decl) = 1;
1583 DECL_NAMELESS (decl) = 1;
1584 DECL_IGNORED_P (decl) = 0;
1585 TREE_PUBLIC (decl) = 0;
1586 DECL_UNINLINABLE (decl) = 1;
1587 DECL_EXTERNAL (decl) = 0;
1588 DECL_CONTEXT (decl) = NULL_TREE;
1589 DECL_INITIAL (decl) = make_node (BLOCK);
1590
1591 t = build_decl (DECL_SOURCE_LOCATION (decl),
1592 RESULT_DECL, NULL_TREE, void_type_node);
1593 DECL_ARTIFICIAL (t) = 1;
1594 DECL_IGNORED_P (t) = 1;
1595 DECL_CONTEXT (t) = decl;
1596 DECL_RESULT (decl) = t;
1597
1598 t = build_decl (DECL_SOURCE_LOCATION (decl),
1599 PARM_DECL, get_identifier (".omp_data_i"), ptr_type_node);
1600 DECL_ARTIFICIAL (t) = 1;
1601 DECL_NAMELESS (t) = 1;
1602 DECL_ARG_TYPE (t) = ptr_type_node;
1603 DECL_CONTEXT (t) = current_function_decl;
1604 TREE_USED (t) = 1;
1605 DECL_ARGUMENTS (decl) = t;
1606 if (!task_copy)
1607 ctx->receiver_decl = t;
1608 else
1609 {
1610 t = build_decl (DECL_SOURCE_LOCATION (decl),
1611 PARM_DECL, get_identifier (".omp_data_o"),
1612 ptr_type_node);
1613 DECL_ARTIFICIAL (t) = 1;
1614 DECL_NAMELESS (t) = 1;
1615 DECL_ARG_TYPE (t) = ptr_type_node;
1616 DECL_CONTEXT (t) = current_function_decl;
1617 TREE_USED (t) = 1;
1618 TREE_ADDRESSABLE (t) = 1;
1619 DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
1620 DECL_ARGUMENTS (decl) = t;
1621 }
1622
1623 /* Allocate memory for the function structure. The call to
1624 allocate_struct_function clobbers CFUN, so we need to restore
1625 it afterward. */
1626 push_struct_function (decl);
1627 cfun->function_end_locus = gimple_location (ctx->stmt);
1628 pop_cfun ();
1629 }
1630
1631
1632 /* Scan an OpenMP parallel directive. */
1633
1634 static void
1635 scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
1636 {
1637 omp_context *ctx;
1638 tree name;
1639 gimple stmt = gsi_stmt (*gsi);
1640
1641 /* Ignore parallel directives with empty bodies, unless there
1642 are copyin clauses. */
1643 if (optimize > 0
1644 && empty_body_p (gimple_omp_body (stmt))
1645 && find_omp_clause (gimple_omp_parallel_clauses (stmt),
1646 OMP_CLAUSE_COPYIN) == NULL)
1647 {
1648 gsi_replace (gsi, gimple_build_nop (), false);
1649 return;
1650 }
1651
1652 ctx = new_omp_context (stmt, outer_ctx);
1653 if (taskreg_nesting_level > 1)
1654 ctx->is_nested = true;
1655 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1656 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
1657 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1658 name = create_tmp_var_name (".omp_data_s");
1659 name = build_decl (gimple_location (stmt),
1660 TYPE_DECL, name, ctx->record_type);
1661 DECL_ARTIFICIAL (name) = 1;
1662 DECL_NAMELESS (name) = 1;
1663 TYPE_NAME (ctx->record_type) = name;
1664 create_omp_child_function (ctx, false);
1665 gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
1666
1667 scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
1668 scan_omp (gimple_omp_body_ptr (stmt), ctx);
1669
1670 if (TYPE_FIELDS (ctx->record_type) == NULL)
1671 ctx->record_type = ctx->receiver_decl = NULL;
1672 else
1673 {
1674 layout_type (ctx->record_type);
1675 fixup_child_record_type (ctx);
1676 }
1677 }
1678
1679 /* Scan an OpenMP task directive. */
1680
1681 static void
1682 scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
1683 {
1684 omp_context *ctx;
1685 tree name, t;
1686 gimple stmt = gsi_stmt (*gsi);
1687 location_t loc = gimple_location (stmt);
1688
1689 /* Ignore task directives with empty bodies. */
1690 if (optimize > 0
1691 && empty_body_p (gimple_omp_body (stmt)))
1692 {
1693 gsi_replace (gsi, gimple_build_nop (), false);
1694 return;
1695 }
1696
1697 ctx = new_omp_context (stmt, outer_ctx);
1698 if (taskreg_nesting_level > 1)
1699 ctx->is_nested = true;
1700 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1701 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
1702 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1703 name = create_tmp_var_name (".omp_data_s");
1704 name = build_decl (gimple_location (stmt),
1705 TYPE_DECL, name, ctx->record_type);
1706 DECL_ARTIFICIAL (name) = 1;
1707 DECL_NAMELESS (name) = 1;
1708 TYPE_NAME (ctx->record_type) = name;
1709 create_omp_child_function (ctx, false);
1710 gimple_omp_task_set_child_fn (stmt, ctx->cb.dst_fn);
1711
1712 scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);
1713
1714 if (ctx->srecord_type)
1715 {
1716 name = create_tmp_var_name (".omp_data_a");
1717 name = build_decl (gimple_location (stmt),
1718 TYPE_DECL, name, ctx->srecord_type);
1719 DECL_ARTIFICIAL (name) = 1;
1720 DECL_NAMELESS (name) = 1;
1721 TYPE_NAME (ctx->srecord_type) = name;
1722 create_omp_child_function (ctx, true);
1723 }
1724
1725 scan_omp (gimple_omp_body_ptr (stmt), ctx);
1726
1727 if (TYPE_FIELDS (ctx->record_type) == NULL)
1728 {
1729 ctx->record_type = ctx->receiver_decl = NULL;
1730 t = build_int_cst (long_integer_type_node, 0);
1731 gimple_omp_task_set_arg_size (stmt, t);
1732 t = build_int_cst (long_integer_type_node, 1);
1733 gimple_omp_task_set_arg_align (stmt, t);
1734 }
1735 else
1736 {
1737 tree *p, vla_fields = NULL_TREE, *q = &vla_fields;
1738 /* Move VLA fields to the end. */
1739 p = &TYPE_FIELDS (ctx->record_type);
1740 while (*p)
1741 if (!TYPE_SIZE_UNIT (TREE_TYPE (*p))
1742 || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p))))
1743 {
1744 *q = *p;
1745 *p = TREE_CHAIN (*p);
1746 TREE_CHAIN (*q) = NULL_TREE;
1747 q = &TREE_CHAIN (*q);
1748 }
1749 else
1750 p = &DECL_CHAIN (*p);
1751 *p = vla_fields;
1752 layout_type (ctx->record_type);
1753 fixup_child_record_type (ctx);
1754 if (ctx->srecord_type)
1755 layout_type (ctx->srecord_type);
1756 t = fold_convert_loc (loc, long_integer_type_node,
1757 TYPE_SIZE_UNIT (ctx->record_type));
1758 gimple_omp_task_set_arg_size (stmt, t);
1759 t = build_int_cst (long_integer_type_node,
1760 TYPE_ALIGN_UNIT (ctx->record_type));
1761 gimple_omp_task_set_arg_align (stmt, t);
1762 }
1763 }
1764
1765
1766 /* Scan an OpenMP loop directive. */
1767
1768 static void
1769 scan_omp_for (gimple stmt, omp_context *outer_ctx)
1770 {
1771 omp_context *ctx;
1772 size_t i;
1773
1774 ctx = new_omp_context (stmt, outer_ctx);
1775
1776 scan_sharing_clauses (gimple_omp_for_clauses (stmt), ctx);
1777
1778 scan_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
1779 for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
1780 {
1781 scan_omp_op (gimple_omp_for_index_ptr (stmt, i), ctx);
1782 scan_omp_op (gimple_omp_for_initial_ptr (stmt, i), ctx);
1783 scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
1784 scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
1785 }
1786 scan_omp (gimple_omp_body_ptr (stmt), ctx);
1787 }
1788
1789 /* Scan an OpenMP sections directive. */
1790
1791 static void
1792 scan_omp_sections (gimple stmt, omp_context *outer_ctx)
1793 {
1794 omp_context *ctx;
1795
1796 ctx = new_omp_context (stmt, outer_ctx);
1797 scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
1798 scan_omp (gimple_omp_body_ptr (stmt), ctx);
1799 }
1800
1801 /* Scan an OpenMP single directive. */
1802
1803 static void
1804 scan_omp_single (gimple stmt, omp_context *outer_ctx)
1805 {
1806 omp_context *ctx;
1807 tree name;
1808
1809 ctx = new_omp_context (stmt, outer_ctx);
1810 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1811 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1812 name = create_tmp_var_name (".omp_copy_s");
1813 name = build_decl (gimple_location (stmt),
1814 TYPE_DECL, name, ctx->record_type);
1815 TYPE_NAME (ctx->record_type) = name;
1816
1817 scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
1818 scan_omp (gimple_omp_body_ptr (stmt), ctx);
1819
1820 if (TYPE_FIELDS (ctx->record_type) == NULL)
1821 ctx->record_type = NULL;
1822 else
1823 layout_type (ctx->record_type);
1824 }
1825
1826
1827 /* Check OpenMP nesting restrictions. */
1828 static bool
1829 check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
1830 {
1831 switch (gimple_code (stmt))
1832 {
1833 case GIMPLE_OMP_FOR:
1834 case GIMPLE_OMP_SECTIONS:
1835 case GIMPLE_OMP_SINGLE:
1836 case GIMPLE_CALL:
1837 for (; ctx != NULL; ctx = ctx->outer)
1838 switch (gimple_code (ctx->stmt))
1839 {
1840 case GIMPLE_OMP_FOR:
1841 case GIMPLE_OMP_SECTIONS:
1842 case GIMPLE_OMP_SINGLE:
1843 case GIMPLE_OMP_ORDERED:
1844 case GIMPLE_OMP_MASTER:
1845 case GIMPLE_OMP_TASK:
1846 if (is_gimple_call (stmt))
1847 {
1848 error_at (gimple_location (stmt),
1849 "barrier region may not be closely nested inside "
1850 "of work-sharing, critical, ordered, master or "
1851 "explicit task region");
1852 return false;
1853 }
1854 error_at (gimple_location (stmt),
1855 "work-sharing region may not be closely nested inside "
1856 "of work-sharing, critical, ordered, master or explicit "
1857 "task region");
1858 return false;
1859 case GIMPLE_OMP_PARALLEL:
1860 return true;
1861 default:
1862 break;
1863 }
1864 break;
1865 case GIMPLE_OMP_MASTER:
1866 for (; ctx != NULL; ctx = ctx->outer)
1867 switch (gimple_code (ctx->stmt))
1868 {
1869 case GIMPLE_OMP_FOR:
1870 case GIMPLE_OMP_SECTIONS:
1871 case GIMPLE_OMP_SINGLE:
1872 case GIMPLE_OMP_TASK:
1873 error_at (gimple_location (stmt),
1874 "master region may not be closely nested inside "
1875 "of work-sharing or explicit task region");
1876 return false;
1877 case GIMPLE_OMP_PARALLEL:
1878 return true;
1879 default:
1880 break;
1881 }
1882 break;
1883 case GIMPLE_OMP_ORDERED:
1884 for (; ctx != NULL; ctx = ctx->outer)
1885 switch (gimple_code (ctx->stmt))
1886 {
1887 case GIMPLE_OMP_CRITICAL:
1888 case GIMPLE_OMP_TASK:
1889 error_at (gimple_location (stmt),
1890 "ordered region may not be closely nested inside "
1891 "of critical or explicit task region");
1892 return false;
1893 case GIMPLE_OMP_FOR:
1894 if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
1895 OMP_CLAUSE_ORDERED) == NULL)
1896 {
1897 error_at (gimple_location (stmt),
1898 "ordered region must be closely nested inside "
1899 "a loop region with an ordered clause");
1900 return false;
1901 }
1902 return true;
1903 case GIMPLE_OMP_PARALLEL:
1904 return true;
1905 default:
1906 break;
1907 }
1908 break;
1909 case GIMPLE_OMP_CRITICAL:
1910 for (; ctx != NULL; ctx = ctx->outer)
1911 if (gimple_code (ctx->stmt) == GIMPLE_OMP_CRITICAL
1912 && (gimple_omp_critical_name (stmt)
1913 == gimple_omp_critical_name (ctx->stmt)))
1914 {
1915 error_at (gimple_location (stmt),
1916 "critical region may not be nested inside a critical "
1917 "region with the same name");
1918 return false;
1919 }
1920 break;
1921 default:
1922 break;
1923 }
1924 return true;
1925 }
1926
1927
1928 /* Helper function scan_omp.
1929
1930 Callback for walk_tree or operators in walk_gimple_stmt used to
1931 scan for OpenMP directives in TP. */
1932
1933 static tree
1934 scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
1935 {
1936 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
1937 omp_context *ctx = (omp_context *) wi->info;
1938 tree t = *tp;
1939
1940 switch (TREE_CODE (t))
1941 {
1942 case VAR_DECL:
1943 case PARM_DECL:
1944 case LABEL_DECL:
1945 case RESULT_DECL:
1946 if (ctx)
1947 *tp = remap_decl (t, &ctx->cb);
1948 break;
1949
1950 default:
1951 if (ctx && TYPE_P (t))
1952 *tp = remap_type (t, &ctx->cb);
1953 else if (!DECL_P (t))
1954 {
1955 *walk_subtrees = 1;
1956 if (ctx)
1957 {
1958 tree tem = remap_type (TREE_TYPE (t), &ctx->cb);
1959 if (tem != TREE_TYPE (t))
1960 {
1961 if (TREE_CODE (t) == INTEGER_CST)
1962 *tp = build_int_cst_wide (tem,
1963 TREE_INT_CST_LOW (t),
1964 TREE_INT_CST_HIGH (t));
1965 else
1966 TREE_TYPE (t) = tem;
1967 }
1968 }
1969 }
1970 break;
1971 }
1972
1973 return NULL_TREE;
1974 }
1975
1976
1977 /* Helper function for scan_omp.
1978
1979 Callback for walk_gimple_stmt used to scan for OpenMP directives in
1980 the current statement in GSI. */
1981
1982 static tree
1983 scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
1984 struct walk_stmt_info *wi)
1985 {
1986 gimple stmt = gsi_stmt (*gsi);
1987 omp_context *ctx = (omp_context *) wi->info;
1988
1989 if (gimple_has_location (stmt))
1990 input_location = gimple_location (stmt);
1991
1992 /* Check the OpenMP nesting restrictions. */
1993 if (ctx != NULL)
1994 {
1995 bool remove = false;
1996 if (is_gimple_omp (stmt))
1997 remove = !check_omp_nesting_restrictions (stmt, ctx);
1998 else if (is_gimple_call (stmt))
1999 {
2000 tree fndecl = gimple_call_fndecl (stmt);
2001 if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
2002 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER)
2003 remove = !check_omp_nesting_restrictions (stmt, ctx);
2004 }
2005 if (remove)
2006 {
2007 stmt = gimple_build_nop ();
2008 gsi_replace (gsi, stmt, false);
2009 }
2010 }
2011
2012 *handled_ops_p = true;
2013
2014 switch (gimple_code (stmt))
2015 {
2016 case GIMPLE_OMP_PARALLEL:
2017 taskreg_nesting_level++;
2018 scan_omp_parallel (gsi, ctx);
2019 taskreg_nesting_level--;
2020 break;
2021
2022 case GIMPLE_OMP_TASK:
2023 taskreg_nesting_level++;
2024 scan_omp_task (gsi, ctx);
2025 taskreg_nesting_level--;
2026 break;
2027
2028 case GIMPLE_OMP_FOR:
2029 scan_omp_for (stmt, ctx);
2030 break;
2031
2032 case GIMPLE_OMP_SECTIONS:
2033 scan_omp_sections (stmt, ctx);
2034 break;
2035
2036 case GIMPLE_OMP_SINGLE:
2037 scan_omp_single (stmt, ctx);
2038 break;
2039
2040 case GIMPLE_OMP_SECTION:
2041 case GIMPLE_OMP_MASTER:
2042 case GIMPLE_OMP_ORDERED:
2043 case GIMPLE_OMP_CRITICAL:
2044 ctx = new_omp_context (stmt, ctx);
2045 scan_omp (gimple_omp_body_ptr (stmt), ctx);
2046 break;
2047
2048 case GIMPLE_BIND:
2049 {
2050 tree var;
2051
2052 *handled_ops_p = false;
2053 if (ctx)
2054 for (var = gimple_bind_vars (stmt); var ; var = DECL_CHAIN (var))
2055 insert_decl_map (&ctx->cb, var, var);
2056 }
2057 break;
2058 default:
2059 *handled_ops_p = false;
2060 break;
2061 }
2062
2063 return NULL_TREE;
2064 }
2065
2066
2067 /* Scan all the statements starting at the current statement. CTX
2068 contains context information about the OpenMP directives and
2069 clauses found during the scan. */
2070
2071 static void
2072 scan_omp (gimple_seq *body_p, omp_context *ctx)
2073 {
2074 location_t saved_location;
2075 struct walk_stmt_info wi;
2076
2077 memset (&wi, 0, sizeof (wi));
2078 wi.info = ctx;
2079 wi.want_locations = true;
2080
2081 saved_location = input_location;
2082 walk_gimple_seq_mod (body_p, scan_omp_1_stmt, scan_omp_1_op, &wi);
2083 input_location = saved_location;
2084 }
2085 \f
2086 /* Re-gimplification and code generation routines. */
2087
2088 /* Build a call to GOMP_barrier. */
2089
2090 static tree
2091 build_omp_barrier (void)
2092 {
2093 return build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_BARRIER), 0);
2094 }
2095
2096 /* If a context was created for STMT when it was scanned, return it. */
2097
2098 static omp_context *
2099 maybe_lookup_ctx (gimple stmt)
2100 {
2101 splay_tree_node n;
2102 n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
2103 return n ? (omp_context *) n->value : NULL;
2104 }
2105
2106
2107 /* Find the mapping for DECL in CTX or the immediately enclosing
2108 context that has a mapping for DECL.
2109
2110 If CTX is a nested parallel directive, we may have to use the decl
2111 mappings created in CTX's parent context. Suppose that we have the
2112 following parallel nesting (variable UIDs showed for clarity):
2113
2114 iD.1562 = 0;
2115 #omp parallel shared(iD.1562) -> outer parallel
2116 iD.1562 = iD.1562 + 1;
2117
2118 #omp parallel shared (iD.1562) -> inner parallel
2119 iD.1562 = iD.1562 - 1;
2120
2121 Each parallel structure will create a distinct .omp_data_s structure
2122 for copying iD.1562 in/out of the directive:
2123
2124 outer parallel .omp_data_s.1.i -> iD.1562
2125 inner parallel .omp_data_s.2.i -> iD.1562
2126
2127 A shared variable mapping will produce a copy-out operation before
2128 the parallel directive and a copy-in operation after it. So, in
2129 this case we would have:
2130
2131 iD.1562 = 0;
2132 .omp_data_o.1.i = iD.1562;
2133 #omp parallel shared(iD.1562) -> outer parallel
2134 .omp_data_i.1 = &.omp_data_o.1
2135 .omp_data_i.1->i = .omp_data_i.1->i + 1;
2136
2137 .omp_data_o.2.i = iD.1562; -> **
2138 #omp parallel shared(iD.1562) -> inner parallel
2139 .omp_data_i.2 = &.omp_data_o.2
2140 .omp_data_i.2->i = .omp_data_i.2->i - 1;
2141
2142
2143 ** This is a problem. The symbol iD.1562 cannot be referenced
2144 inside the body of the outer parallel region. But since we are
2145 emitting this copy operation while expanding the inner parallel
2146 directive, we need to access the CTX structure of the outer
2147 parallel directive to get the correct mapping:
2148
2149 .omp_data_o.2.i = .omp_data_i.1->i
2150
2151 Since there may be other workshare or parallel directives enclosing
2152 the parallel directive, it may be necessary to walk up the context
2153 parent chain. This is not a problem in general because nested
2154 parallelism happens only rarely. */
2155
2156 static tree
2157 lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
2158 {
2159 tree t;
2160 omp_context *up;
2161
2162 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
2163 t = maybe_lookup_decl (decl, up);
2164
2165 gcc_assert (!ctx->is_nested || t || is_global_var (decl));
2166
2167 return t ? t : decl;
2168 }
2169
2170
2171 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
2172 in outer contexts. */
2173
2174 static tree
2175 maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
2176 {
2177 tree t = NULL;
2178 omp_context *up;
2179
2180 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
2181 t = maybe_lookup_decl (decl, up);
2182
2183 return t ? t : decl;
2184 }
2185
2186
2187 /* Construct the initialization value for reduction CLAUSE. */
2188
2189 tree
2190 omp_reduction_init (tree clause, tree type)
2191 {
2192 location_t loc = OMP_CLAUSE_LOCATION (clause);
2193 switch (OMP_CLAUSE_REDUCTION_CODE (clause))
2194 {
2195 case PLUS_EXPR:
2196 case MINUS_EXPR:
2197 case BIT_IOR_EXPR:
2198 case BIT_XOR_EXPR:
2199 case TRUTH_OR_EXPR:
2200 case TRUTH_ORIF_EXPR:
2201 case TRUTH_XOR_EXPR:
2202 case NE_EXPR:
2203 return build_zero_cst (type);
2204
2205 case MULT_EXPR:
2206 case TRUTH_AND_EXPR:
2207 case TRUTH_ANDIF_EXPR:
2208 case EQ_EXPR:
2209 return fold_convert_loc (loc, type, integer_one_node);
2210
2211 case BIT_AND_EXPR:
2212 return fold_convert_loc (loc, type, integer_minus_one_node);
2213
2214 case MAX_EXPR:
2215 if (SCALAR_FLOAT_TYPE_P (type))
2216 {
2217 REAL_VALUE_TYPE max, min;
2218 if (HONOR_INFINITIES (TYPE_MODE (type)))
2219 {
2220 real_inf (&max);
2221 real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
2222 }
2223 else
2224 real_maxval (&min, 1, TYPE_MODE (type));
2225 return build_real (type, min);
2226 }
2227 else
2228 {
2229 gcc_assert (INTEGRAL_TYPE_P (type));
2230 return TYPE_MIN_VALUE (type);
2231 }
2232
2233 case MIN_EXPR:
2234 if (SCALAR_FLOAT_TYPE_P (type))
2235 {
2236 REAL_VALUE_TYPE max;
2237 if (HONOR_INFINITIES (TYPE_MODE (type)))
2238 real_inf (&max);
2239 else
2240 real_maxval (&max, 0, TYPE_MODE (type));
2241 return build_real (type, max);
2242 }
2243 else
2244 {
2245 gcc_assert (INTEGRAL_TYPE_P (type));
2246 return TYPE_MAX_VALUE (type);
2247 }
2248
2249 default:
2250 gcc_unreachable ();
2251 }
2252 }
2253
2254 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
2255 from the receiver (aka child) side and initializers for REFERENCE_TYPE
2256 private variables. Initialization statements go in ILIST, while calls
2257 to destructors go in DLIST. */
2258
2259 static void
2260 lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
2261 omp_context *ctx)
2262 {
2263 tree c, dtor, copyin_seq, x, ptr;
2264 bool copyin_by_ref = false;
2265 bool lastprivate_firstprivate = false;
2266 int pass;
2267
2268 copyin_seq = NULL;
2269
2270 /* Do all the fixed sized types in the first pass, and the variable sized
2271 types in the second pass. This makes sure that the scalar arguments to
2272 the variable sized types are processed before we use them in the
2273 variable sized operations. */
2274 for (pass = 0; pass < 2; ++pass)
2275 {
2276 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2277 {
2278 enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
2279 tree var, new_var;
2280 bool by_ref;
2281 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2282
2283 switch (c_kind)
2284 {
2285 case OMP_CLAUSE_PRIVATE:
2286 if (OMP_CLAUSE_PRIVATE_DEBUG (c))
2287 continue;
2288 break;
2289 case OMP_CLAUSE_SHARED:
2290 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
2291 {
2292 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c)));
2293 continue;
2294 }
2295 case OMP_CLAUSE_FIRSTPRIVATE:
2296 case OMP_CLAUSE_COPYIN:
2297 case OMP_CLAUSE_REDUCTION:
2298 break;
2299 case OMP_CLAUSE_LASTPRIVATE:
2300 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2301 {
2302 lastprivate_firstprivate = true;
2303 if (pass != 0)
2304 continue;
2305 }
2306 break;
2307 default:
2308 continue;
2309 }
2310
2311 new_var = var = OMP_CLAUSE_DECL (c);
2312 if (c_kind != OMP_CLAUSE_COPYIN)
2313 new_var = lookup_decl (var, ctx);
2314
2315 if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
2316 {
2317 if (pass != 0)
2318 continue;
2319 }
2320 else if (is_variable_sized (var))
2321 {
2322 /* For variable sized types, we need to allocate the
2323 actual storage here. Call alloca and store the
2324 result in the pointer decl that we created elsewhere. */
2325 if (pass == 0)
2326 continue;
2327
2328 if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
2329 {
2330 gimple stmt;
2331 tree tmp, atmp;
2332
2333 ptr = DECL_VALUE_EXPR (new_var);
2334 gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
2335 ptr = TREE_OPERAND (ptr, 0);
2336 gcc_assert (DECL_P (ptr));
2337 x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
2338
2339 /* void *tmp = __builtin_alloca */
2340 atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
2341 stmt = gimple_build_call (atmp, 1, x);
2342 tmp = create_tmp_var_raw (ptr_type_node, NULL);
2343 gimple_add_tmp_var (tmp);
2344 gimple_call_set_lhs (stmt, tmp);
2345
2346 gimple_seq_add_stmt (ilist, stmt);
2347
2348 x = fold_convert_loc (clause_loc, TREE_TYPE (ptr), tmp);
2349 gimplify_assign (ptr, x, ilist);
2350 }
2351 }
2352 else if (is_reference (var))
2353 {
2354 /* For references that are being privatized for Fortran,
2355 allocate new backing storage for the new pointer
2356 variable. This allows us to avoid changing all the
2357 code that expects a pointer to something that expects
2358 a direct variable. Note that this doesn't apply to
2359 C++, since reference types are disallowed in data
2360 sharing clauses there, except for NRV optimized
2361 return values. */
2362 if (pass == 0)
2363 continue;
2364
2365 x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
2366 if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
2367 {
2368 x = build_receiver_ref (var, false, ctx);
2369 x = build_fold_addr_expr_loc (clause_loc, x);
2370 }
2371 else if (TREE_CONSTANT (x))
2372 {
2373 const char *name = NULL;
2374 if (DECL_NAME (var))
2375 name = IDENTIFIER_POINTER (DECL_NAME (new_var));
2376
2377 x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
2378 name);
2379 gimple_add_tmp_var (x);
2380 TREE_ADDRESSABLE (x) = 1;
2381 x = build_fold_addr_expr_loc (clause_loc, x);
2382 }
2383 else
2384 {
2385 tree atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
2386 x = build_call_expr_loc (clause_loc, atmp, 1, x);
2387 }
2388
2389 x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
2390 gimplify_assign (new_var, x, ilist);
2391
2392 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2393 }
2394 else if (c_kind == OMP_CLAUSE_REDUCTION
2395 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2396 {
2397 if (pass == 0)
2398 continue;
2399 }
2400 else if (pass != 0)
2401 continue;
2402
2403 switch (OMP_CLAUSE_CODE (c))
2404 {
2405 case OMP_CLAUSE_SHARED:
2406 /* Shared global vars are just accessed directly. */
2407 if (is_global_var (new_var))
2408 break;
2409 /* Set up the DECL_VALUE_EXPR for shared variables now. This
2410 needs to be delayed until after fixup_child_record_type so
2411 that we get the correct type during the dereference. */
2412 by_ref = use_pointer_for_field (var, ctx);
2413 x = build_receiver_ref (var, by_ref, ctx);
2414 SET_DECL_VALUE_EXPR (new_var, x);
2415 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
2416
2417 /* ??? If VAR is not passed by reference, and the variable
2418 hasn't been initialized yet, then we'll get a warning for
2419 the store into the omp_data_s structure. Ideally, we'd be
2420 able to notice this and not store anything at all, but
2421 we're generating code too early. Suppress the warning. */
2422 if (!by_ref)
2423 TREE_NO_WARNING (var) = 1;
2424 break;
2425
2426 case OMP_CLAUSE_LASTPRIVATE:
2427 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2428 break;
2429 /* FALLTHRU */
2430
2431 case OMP_CLAUSE_PRIVATE:
2432 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE)
2433 x = build_outer_var_ref (var, ctx);
2434 else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
2435 {
2436 if (is_task_ctx (ctx))
2437 x = build_receiver_ref (var, false, ctx);
2438 else
2439 x = build_outer_var_ref (var, ctx);
2440 }
2441 else
2442 x = NULL;
2443 x = lang_hooks.decls.omp_clause_default_ctor (c, new_var, x);
2444 if (x)
2445 gimplify_and_add (x, ilist);
2446 /* FALLTHRU */
2447
2448 do_dtor:
2449 x = lang_hooks.decls.omp_clause_dtor (c, new_var);
2450 if (x)
2451 {
2452 gimple_seq tseq = NULL;
2453
2454 dtor = x;
2455 gimplify_stmt (&dtor, &tseq);
2456 gimple_seq_add_seq (dlist, tseq);
2457 }
2458 break;
2459
2460 case OMP_CLAUSE_FIRSTPRIVATE:
2461 if (is_task_ctx (ctx))
2462 {
2463 if (is_reference (var) || is_variable_sized (var))
2464 goto do_dtor;
2465 else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var,
2466 ctx))
2467 || use_pointer_for_field (var, NULL))
2468 {
2469 x = build_receiver_ref (var, false, ctx);
2470 SET_DECL_VALUE_EXPR (new_var, x);
2471 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
2472 goto do_dtor;
2473 }
2474 }
2475 x = build_outer_var_ref (var, ctx);
2476 x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
2477 gimplify_and_add (x, ilist);
2478 goto do_dtor;
2479 break;
2480
2481 case OMP_CLAUSE_COPYIN:
2482 by_ref = use_pointer_for_field (var, NULL);
2483 x = build_receiver_ref (var, by_ref, ctx);
2484 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
2485 append_to_statement_list (x, &copyin_seq);
2486 copyin_by_ref |= by_ref;
2487 break;
2488
2489 case OMP_CLAUSE_REDUCTION:
2490 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2491 {
2492 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
2493 x = build_outer_var_ref (var, ctx);
2494
2495 if (is_reference (var))
2496 x = build_fold_addr_expr_loc (clause_loc, x);
2497 SET_DECL_VALUE_EXPR (placeholder, x);
2498 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
2499 lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
2500 gimple_seq_add_seq (ilist,
2501 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
2502 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
2503 DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
2504 }
2505 else
2506 {
2507 x = omp_reduction_init (c, TREE_TYPE (new_var));
2508 gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
2509 gimplify_assign (new_var, x, ilist);
2510 }
2511 break;
2512
2513 default:
2514 gcc_unreachable ();
2515 }
2516 }
2517 }
2518
2519 /* The copyin sequence is not to be executed by the main thread, since
2520 that would result in self-copies. Perhaps not visible to scalars,
2521 but it certainly is to C++ operator=. */
2522 if (copyin_seq)
2523 {
2524 x = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM),
2525 0);
2526 x = build2 (NE_EXPR, boolean_type_node, x,
2527 build_int_cst (TREE_TYPE (x), 0));
2528 x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
2529 gimplify_and_add (x, ilist);
2530 }
2531
2532 /* If any copyin variable is passed by reference, we must ensure the
2533 master thread doesn't modify it before it is copied over in all
2534 threads. Similarly for variables in both firstprivate and
2535 lastprivate clauses we need to ensure the lastprivate copying
2536 happens after firstprivate copying in all threads. */
2537 if (copyin_by_ref || lastprivate_firstprivate)
2538 gimplify_and_add (build_omp_barrier (), ilist);
2539 }
2540
2541
2542 /* Generate code to implement the LASTPRIVATE clauses. This is used for
2543 both parallel and workshare constructs. PREDICATE may be NULL if it's
2544 always true. */
2545
2546 static void
2547 lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
2548 omp_context *ctx)
2549 {
2550 tree x, c, label = NULL;
2551 bool par_clauses = false;
2552
2553 /* Early exit if there are no lastprivate clauses. */
2554 clauses = find_omp_clause (clauses, OMP_CLAUSE_LASTPRIVATE);
2555 if (clauses == NULL)
2556 {
2557 /* If this was a workshare clause, see if it had been combined
2558 with its parallel. In that case, look for the clauses on the
2559 parallel statement itself. */
2560 if (is_parallel_ctx (ctx))
2561 return;
2562
2563 ctx = ctx->outer;
2564 if (ctx == NULL || !is_parallel_ctx (ctx))
2565 return;
2566
2567 clauses = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2568 OMP_CLAUSE_LASTPRIVATE);
2569 if (clauses == NULL)
2570 return;
2571 par_clauses = true;
2572 }
2573
2574 if (predicate)
2575 {
2576 gimple stmt;
2577 tree label_true, arm1, arm2;
2578
2579 label = create_artificial_label (UNKNOWN_LOCATION);
2580 label_true = create_artificial_label (UNKNOWN_LOCATION);
2581 arm1 = TREE_OPERAND (predicate, 0);
2582 arm2 = TREE_OPERAND (predicate, 1);
2583 gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
2584 gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
2585 stmt = gimple_build_cond (TREE_CODE (predicate), arm1, arm2,
2586 label_true, label);
2587 gimple_seq_add_stmt (stmt_list, stmt);
2588 gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
2589 }
2590
2591 for (c = clauses; c ;)
2592 {
2593 tree var, new_var;
2594 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2595
2596 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
2597 {
2598 var = OMP_CLAUSE_DECL (c);
2599 new_var = lookup_decl (var, ctx);
2600
2601 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
2602 {
2603 lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
2604 gimple_seq_add_seq (stmt_list,
2605 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
2606 }
2607 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
2608
2609 x = build_outer_var_ref (var, ctx);
2610 if (is_reference (var))
2611 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2612 x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
2613 gimplify_and_add (x, stmt_list);
2614 }
2615 c = OMP_CLAUSE_CHAIN (c);
2616 if (c == NULL && !par_clauses)
2617 {
2618 /* If this was a workshare clause, see if it had been combined
2619 with its parallel. In that case, continue looking for the
2620 clauses also on the parallel statement itself. */
2621 if (is_parallel_ctx (ctx))
2622 break;
2623
2624 ctx = ctx->outer;
2625 if (ctx == NULL || !is_parallel_ctx (ctx))
2626 break;
2627
2628 c = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2629 OMP_CLAUSE_LASTPRIVATE);
2630 par_clauses = true;
2631 }
2632 }
2633
2634 if (label)
2635 gimple_seq_add_stmt (stmt_list, gimple_build_label (label));
2636 }
2637
2638
2639 /* Generate code to implement the REDUCTION clauses. */
2640
2641 static void
2642 lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
2643 {
2644 gimple_seq sub_seq = NULL;
2645 gimple stmt;
2646 tree x, c;
2647 int count = 0;
2648
2649 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
2650 update in that case, otherwise use a lock. */
2651 for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
2652 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
2653 {
2654 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2655 {
2656 /* Never use OMP_ATOMIC for array reductions. */
2657 count = -1;
2658 break;
2659 }
2660 count++;
2661 }
2662
2663 if (count == 0)
2664 return;
2665
2666 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2667 {
2668 tree var, ref, new_var;
2669 enum tree_code code;
2670 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2671
2672 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
2673 continue;
2674
2675 var = OMP_CLAUSE_DECL (c);
2676 new_var = lookup_decl (var, ctx);
2677 if (is_reference (var))
2678 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2679 ref = build_outer_var_ref (var, ctx);
2680 code = OMP_CLAUSE_REDUCTION_CODE (c);
2681
2682 /* reduction(-:var) sums up the partial results, so it acts
2683 identically to reduction(+:var). */
2684 if (code == MINUS_EXPR)
2685 code = PLUS_EXPR;
2686
2687 if (count == 1)
2688 {
2689 tree addr = build_fold_addr_expr_loc (clause_loc, ref);
2690
2691 addr = save_expr (addr);
2692 ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
2693 x = fold_build2_loc (clause_loc, code, TREE_TYPE (ref), ref, new_var);
2694 x = build2 (OMP_ATOMIC, void_type_node, addr, x);
2695 gimplify_and_add (x, stmt_seqp);
2696 return;
2697 }
2698
2699 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2700 {
2701 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
2702
2703 if (is_reference (var))
2704 ref = build_fold_addr_expr_loc (clause_loc, ref);
2705 SET_DECL_VALUE_EXPR (placeholder, ref);
2706 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
2707 lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
2708 gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
2709 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
2710 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
2711 }
2712 else
2713 {
2714 x = build2 (code, TREE_TYPE (ref), ref, new_var);
2715 ref = build_outer_var_ref (var, ctx);
2716 gimplify_assign (ref, x, &sub_seq);
2717 }
2718 }
2719
2720 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START),
2721 0);
2722 gimple_seq_add_stmt (stmt_seqp, stmt);
2723
2724 gimple_seq_add_seq (stmt_seqp, sub_seq);
2725
2726 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END),
2727 0);
2728 gimple_seq_add_stmt (stmt_seqp, stmt);
2729 }
2730
2731
2732 /* Generate code to implement the COPYPRIVATE clauses. */
2733
2734 static void
2735 lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist,
2736 omp_context *ctx)
2737 {
2738 tree c;
2739
2740 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2741 {
2742 tree var, new_var, ref, x;
2743 bool by_ref;
2744 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2745
2746 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
2747 continue;
2748
2749 var = OMP_CLAUSE_DECL (c);
2750 by_ref = use_pointer_for_field (var, NULL);
2751
2752 ref = build_sender_ref (var, ctx);
2753 x = new_var = lookup_decl_in_outer_ctx (var, ctx);
2754 if (by_ref)
2755 {
2756 x = build_fold_addr_expr_loc (clause_loc, new_var);
2757 x = fold_convert_loc (clause_loc, TREE_TYPE (ref), x);
2758 }
2759 gimplify_assign (ref, x, slist);
2760
2761 ref = build_receiver_ref (var, false, ctx);
2762 if (by_ref)
2763 {
2764 ref = fold_convert_loc (clause_loc,
2765 build_pointer_type (TREE_TYPE (new_var)),
2766 ref);
2767 ref = build_fold_indirect_ref_loc (clause_loc, ref);
2768 }
2769 if (is_reference (var))
2770 {
2771 ref = fold_convert_loc (clause_loc, TREE_TYPE (new_var), ref);
2772 ref = build_simple_mem_ref_loc (clause_loc, ref);
2773 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2774 }
2775 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, ref);
2776 gimplify_and_add (x, rlist);
2777 }
2778 }
2779
2780
2781 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
2782 and REDUCTION from the sender (aka parent) side. */
2783
2784 static void
2785 lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist,
2786 omp_context *ctx)
2787 {
2788 tree c;
2789
2790 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2791 {
2792 tree val, ref, x, var;
2793 bool by_ref, do_in = false, do_out = false;
2794 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2795
2796 switch (OMP_CLAUSE_CODE (c))
2797 {
2798 case OMP_CLAUSE_PRIVATE:
2799 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
2800 break;
2801 continue;
2802 case OMP_CLAUSE_FIRSTPRIVATE:
2803 case OMP_CLAUSE_COPYIN:
2804 case OMP_CLAUSE_LASTPRIVATE:
2805 case OMP_CLAUSE_REDUCTION:
2806 break;
2807 default:
2808 continue;
2809 }
2810
2811 val = OMP_CLAUSE_DECL (c);
2812 var = lookup_decl_in_outer_ctx (val, ctx);
2813
2814 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
2815 && is_global_var (var))
2816 continue;
2817 if (is_variable_sized (val))
2818 continue;
2819 by_ref = use_pointer_for_field (val, NULL);
2820
2821 switch (OMP_CLAUSE_CODE (c))
2822 {
2823 case OMP_CLAUSE_PRIVATE:
2824 case OMP_CLAUSE_FIRSTPRIVATE:
2825 case OMP_CLAUSE_COPYIN:
2826 do_in = true;
2827 break;
2828
2829 case OMP_CLAUSE_LASTPRIVATE:
2830 if (by_ref || is_reference (val))
2831 {
2832 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2833 continue;
2834 do_in = true;
2835 }
2836 else
2837 {
2838 do_out = true;
2839 if (lang_hooks.decls.omp_private_outer_ref (val))
2840 do_in = true;
2841 }
2842 break;
2843
2844 case OMP_CLAUSE_REDUCTION:
2845 do_in = true;
2846 do_out = !(by_ref || is_reference (val));
2847 break;
2848
2849 default:
2850 gcc_unreachable ();
2851 }
2852
2853 if (do_in)
2854 {
2855 ref = build_sender_ref (val, ctx);
2856 x = by_ref ? build_fold_addr_expr_loc (clause_loc, var) : var;
2857 gimplify_assign (ref, x, ilist);
2858 if (is_task_ctx (ctx))
2859 DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref, 1)) = NULL;
2860 }
2861
2862 if (do_out)
2863 {
2864 ref = build_sender_ref (val, ctx);
2865 gimplify_assign (var, ref, olist);
2866 }
2867 }
2868 }
2869
2870 /* Generate code to implement SHARED from the sender (aka parent)
2871 side. This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
2872 list things that got automatically shared. */
2873
2874 static void
2875 lower_send_shared_vars (gimple_seq *ilist, gimple_seq *olist, omp_context *ctx)
2876 {
2877 tree var, ovar, nvar, f, x, record_type;
2878
2879 if (ctx->record_type == NULL)
2880 return;
2881
2882 record_type = ctx->srecord_type ? ctx->srecord_type : ctx->record_type;
2883 for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
2884 {
2885 ovar = DECL_ABSTRACT_ORIGIN (f);
2886 nvar = maybe_lookup_decl (ovar, ctx);
2887 if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
2888 continue;
2889
2890 /* If CTX is a nested parallel directive. Find the immediately
2891 enclosing parallel or workshare construct that contains a
2892 mapping for OVAR. */
2893 var = lookup_decl_in_outer_ctx (ovar, ctx);
2894
2895 if (use_pointer_for_field (ovar, ctx))
2896 {
2897 x = build_sender_ref (ovar, ctx);
2898 var = build_fold_addr_expr (var);
2899 gimplify_assign (x, var, ilist);
2900 }
2901 else
2902 {
2903 x = build_sender_ref (ovar, ctx);
2904 gimplify_assign (x, var, ilist);
2905
2906 if (!TREE_READONLY (var)
2907 /* We don't need to receive a new reference to a result
2908 or parm decl. In fact we may not store to it as we will
2909 invalidate any pending RSO and generate wrong gimple
2910 during inlining. */
2911 && !((TREE_CODE (var) == RESULT_DECL
2912 || TREE_CODE (var) == PARM_DECL)
2913 && DECL_BY_REFERENCE (var)))
2914 {
2915 x = build_sender_ref (ovar, ctx);
2916 gimplify_assign (var, x, olist);
2917 }
2918 }
2919 }
2920 }
2921
2922
2923 /* A convenience function to build an empty GIMPLE_COND with just the
2924 condition. */
2925
2926 static gimple
2927 gimple_build_cond_empty (tree cond)
2928 {
2929 enum tree_code pred_code;
2930 tree lhs, rhs;
2931
2932 gimple_cond_get_ops_from_tree (cond, &pred_code, &lhs, &rhs);
2933 return gimple_build_cond (pred_code, lhs, rhs, NULL_TREE, NULL_TREE);
2934 }
2935
2936
2937 /* Build the function calls to GOMP_parallel_start etc to actually
2938 generate the parallel operation. REGION is the parallel region
2939 being expanded. BB is the block where to insert the code. WS_ARGS
2940 will be set if this is a call to a combined parallel+workshare
2941 construct, it contains the list of additional arguments needed by
2942 the workshare construct. */
2943
2944 static void
2945 expand_parallel_call (struct omp_region *region, basic_block bb,
2946 gimple entry_stmt, vec<tree, va_gc> *ws_args)
2947 {
2948 tree t, t1, t2, val, cond, c, clauses;
2949 gimple_stmt_iterator gsi;
2950 gimple stmt;
2951 enum built_in_function start_ix;
2952 int start_ix2;
2953 location_t clause_loc;
2954 vec<tree, va_gc> *args;
2955
2956 clauses = gimple_omp_parallel_clauses (entry_stmt);
2957
2958 /* Determine what flavor of GOMP_parallel_start we will be
2959 emitting. */
2960 start_ix = BUILT_IN_GOMP_PARALLEL_START;
2961 if (is_combined_parallel (region))
2962 {
2963 switch (region->inner->type)
2964 {
2965 case GIMPLE_OMP_FOR:
2966 gcc_assert (region->inner->sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
2967 start_ix2 = ((int)BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
2968 + (region->inner->sched_kind
2969 == OMP_CLAUSE_SCHEDULE_RUNTIME
2970 ? 3 : region->inner->sched_kind));
2971 start_ix = (enum built_in_function)start_ix2;
2972 break;
2973 case GIMPLE_OMP_SECTIONS:
2974 start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS_START;
2975 break;
2976 default:
2977 gcc_unreachable ();
2978 }
2979 }
2980
2981 /* By default, the value of NUM_THREADS is zero (selected at run time)
2982 and there is no conditional. */
2983 cond = NULL_TREE;
2984 val = build_int_cst (unsigned_type_node, 0);
2985
2986 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
2987 if (c)
2988 cond = OMP_CLAUSE_IF_EXPR (c);
2989
2990 c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
2991 if (c)
2992 {
2993 val = OMP_CLAUSE_NUM_THREADS_EXPR (c);
2994 clause_loc = OMP_CLAUSE_LOCATION (c);
2995 }
2996 else
2997 clause_loc = gimple_location (entry_stmt);
2998
2999 /* Ensure 'val' is of the correct type. */
3000 val = fold_convert_loc (clause_loc, unsigned_type_node, val);
3001
3002 /* If we found the clause 'if (cond)', build either
3003 (cond != 0) or (cond ? val : 1u). */
3004 if (cond)
3005 {
3006 gimple_stmt_iterator gsi;
3007
3008 cond = gimple_boolify (cond);
3009
3010 if (integer_zerop (val))
3011 val = fold_build2_loc (clause_loc,
3012 EQ_EXPR, unsigned_type_node, cond,
3013 build_int_cst (TREE_TYPE (cond), 0));
3014 else
3015 {
3016 basic_block cond_bb, then_bb, else_bb;
3017 edge e, e_then, e_else;
3018 tree tmp_then, tmp_else, tmp_join, tmp_var;
3019
3020 tmp_var = create_tmp_var (TREE_TYPE (val), NULL);
3021 if (gimple_in_ssa_p (cfun))
3022 {
3023 tmp_then = make_ssa_name (tmp_var, NULL);
3024 tmp_else = make_ssa_name (tmp_var, NULL);
3025 tmp_join = make_ssa_name (tmp_var, NULL);
3026 }
3027 else
3028 {
3029 tmp_then = tmp_var;
3030 tmp_else = tmp_var;
3031 tmp_join = tmp_var;
3032 }
3033
3034 e = split_block (bb, NULL);
3035 cond_bb = e->src;
3036 bb = e->dest;
3037 remove_edge (e);
3038
3039 then_bb = create_empty_bb (cond_bb);
3040 else_bb = create_empty_bb (then_bb);
3041 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
3042 set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
3043
3044 stmt = gimple_build_cond_empty (cond);
3045 gsi = gsi_start_bb (cond_bb);
3046 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3047
3048 gsi = gsi_start_bb (then_bb);
3049 stmt = gimple_build_assign (tmp_then, val);
3050 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3051
3052 gsi = gsi_start_bb (else_bb);
3053 stmt = gimple_build_assign
3054 (tmp_else, build_int_cst (unsigned_type_node, 1));
3055 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3056
3057 make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
3058 make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
3059 e_then = make_edge (then_bb, bb, EDGE_FALLTHRU);
3060 e_else = make_edge (else_bb, bb, EDGE_FALLTHRU);
3061
3062 if (gimple_in_ssa_p (cfun))
3063 {
3064 gimple phi = create_phi_node (tmp_join, bb);
3065 add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION);
3066 add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION);
3067 }
3068
3069 val = tmp_join;
3070 }
3071
3072 gsi = gsi_start_bb (bb);
3073 val = force_gimple_operand_gsi (&gsi, val, true, NULL_TREE,
3074 false, GSI_CONTINUE_LINKING);
3075 }
3076
3077 gsi = gsi_last_bb (bb);
3078 t = gimple_omp_parallel_data_arg (entry_stmt);
3079 if (t == NULL)
3080 t1 = null_pointer_node;
3081 else
3082 t1 = build_fold_addr_expr (t);
3083 t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
3084
3085 vec_alloc (args, 3 + vec_safe_length (ws_args));
3086 args->quick_push (t2);
3087 args->quick_push (t1);
3088 args->quick_push (val);
3089 if (ws_args)
3090 args->splice (*ws_args);
3091
3092 t = build_call_expr_loc_vec (UNKNOWN_LOCATION,
3093 builtin_decl_explicit (start_ix), args);
3094
3095 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3096 false, GSI_CONTINUE_LINKING);
3097
3098 t = gimple_omp_parallel_data_arg (entry_stmt);
3099 if (t == NULL)
3100 t = null_pointer_node;
3101 else
3102 t = build_fold_addr_expr (t);
3103 t = build_call_expr_loc (gimple_location (entry_stmt),
3104 gimple_omp_parallel_child_fn (entry_stmt), 1, t);
3105 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3106 false, GSI_CONTINUE_LINKING);
3107
3108 t = build_call_expr_loc (gimple_location (entry_stmt),
3109 builtin_decl_explicit (BUILT_IN_GOMP_PARALLEL_END),
3110 0);
3111 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3112 false, GSI_CONTINUE_LINKING);
3113 }
3114
3115
3116 /* Build the function call to GOMP_task to actually
3117 generate the task operation. BB is the block where to insert the code. */
3118
3119 static void
3120 expand_task_call (basic_block bb, gimple entry_stmt)
3121 {
3122 tree t, t1, t2, t3, flags, cond, c, c2, clauses;
3123 gimple_stmt_iterator gsi;
3124 location_t loc = gimple_location (entry_stmt);
3125
3126 clauses = gimple_omp_task_clauses (entry_stmt);
3127
3128 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
3129 if (c)
3130 cond = gimple_boolify (OMP_CLAUSE_IF_EXPR (c));
3131 else
3132 cond = boolean_true_node;
3133
3134 c = find_omp_clause (clauses, OMP_CLAUSE_UNTIED);
3135 c2 = find_omp_clause (clauses, OMP_CLAUSE_MERGEABLE);
3136 flags = build_int_cst (unsigned_type_node,
3137 (c ? 1 : 0) + (c2 ? 4 : 0));
3138
3139 c = find_omp_clause (clauses, OMP_CLAUSE_FINAL);
3140 if (c)
3141 {
3142 c = gimple_boolify (OMP_CLAUSE_FINAL_EXPR (c));
3143 c = fold_build3_loc (loc, COND_EXPR, unsigned_type_node, c,
3144 build_int_cst (unsigned_type_node, 2),
3145 build_int_cst (unsigned_type_node, 0));
3146 flags = fold_build2_loc (loc, PLUS_EXPR, unsigned_type_node, flags, c);
3147 }
3148
3149 gsi = gsi_last_bb (bb);
3150 t = gimple_omp_task_data_arg (entry_stmt);
3151 if (t == NULL)
3152 t2 = null_pointer_node;
3153 else
3154 t2 = build_fold_addr_expr_loc (loc, t);
3155 t1 = build_fold_addr_expr_loc (loc, gimple_omp_task_child_fn (entry_stmt));
3156 t = gimple_omp_task_copy_fn (entry_stmt);
3157 if (t == NULL)
3158 t3 = null_pointer_node;
3159 else
3160 t3 = build_fold_addr_expr_loc (loc, t);
3161
3162 t = build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_TASK),
3163 7, t1, t2, t3,
3164 gimple_omp_task_arg_size (entry_stmt),
3165 gimple_omp_task_arg_align (entry_stmt), cond, flags);
3166
3167 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3168 false, GSI_CONTINUE_LINKING);
3169 }
3170
3171
3172 /* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
3173 catch handler and return it. This prevents programs from violating the
3174 structured block semantics with throws. */
3175
3176 static gimple_seq
3177 maybe_catch_exception (gimple_seq body)
3178 {
3179 gimple g;
3180 tree decl;
3181
3182 if (!flag_exceptions)
3183 return body;
3184
3185 if (lang_hooks.eh_protect_cleanup_actions != NULL)
3186 decl = lang_hooks.eh_protect_cleanup_actions ();
3187 else
3188 decl = builtin_decl_explicit (BUILT_IN_TRAP);
3189
3190 g = gimple_build_eh_must_not_throw (decl);
3191 g = gimple_build_try (body, gimple_seq_alloc_with_stmt (g),
3192 GIMPLE_TRY_CATCH);
3193
3194 return gimple_seq_alloc_with_stmt (g);
3195 }
3196
3197 /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
3198
3199 static tree
3200 vec2chain (vec<tree, va_gc> *v)
3201 {
3202 tree chain = NULL_TREE, t;
3203 unsigned ix;
3204
3205 FOR_EACH_VEC_SAFE_ELT_REVERSE (v, ix, t)
3206 {
3207 DECL_CHAIN (t) = chain;
3208 chain = t;
3209 }
3210
3211 return chain;
3212 }
3213
3214
3215 /* Remove barriers in REGION->EXIT's block. Note that this is only
3216 valid for GIMPLE_OMP_PARALLEL regions. Since the end of a parallel region
3217 is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
3218 left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
3219 removed. */
3220
3221 static void
3222 remove_exit_barrier (struct omp_region *region)
3223 {
3224 gimple_stmt_iterator gsi;
3225 basic_block exit_bb;
3226 edge_iterator ei;
3227 edge e;
3228 gimple stmt;
3229 int any_addressable_vars = -1;
3230
3231 exit_bb = region->exit;
3232
3233 /* If the parallel region doesn't return, we don't have REGION->EXIT
3234 block at all. */
3235 if (! exit_bb)
3236 return;
3237
3238 /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN. The
3239 workshare's GIMPLE_OMP_RETURN will be in a preceding block. The kinds of
3240 statements that can appear in between are extremely limited -- no
3241 memory operations at all. Here, we allow nothing at all, so the
3242 only thing we allow to precede this GIMPLE_OMP_RETURN is a label. */
3243 gsi = gsi_last_bb (exit_bb);
3244 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
3245 gsi_prev (&gsi);
3246 if (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
3247 return;
3248
3249 FOR_EACH_EDGE (e, ei, exit_bb->preds)
3250 {
3251 gsi = gsi_last_bb (e->src);
3252 if (gsi_end_p (gsi))
3253 continue;
3254 stmt = gsi_stmt (gsi);
3255 if (gimple_code (stmt) == GIMPLE_OMP_RETURN
3256 && !gimple_omp_return_nowait_p (stmt))
3257 {
3258 /* OpenMP 3.0 tasks unfortunately prevent this optimization
3259 in many cases. If there could be tasks queued, the barrier
3260 might be needed to let the tasks run before some local
3261 variable of the parallel that the task uses as shared
3262 runs out of scope. The task can be spawned either
3263 from within current function (this would be easy to check)
3264 or from some function it calls and gets passed an address
3265 of such a variable. */
3266 if (any_addressable_vars < 0)
3267 {
3268 gimple parallel_stmt = last_stmt (region->entry);
3269 tree child_fun = gimple_omp_parallel_child_fn (parallel_stmt);
3270 tree local_decls, block, decl;
3271 unsigned ix;
3272
3273 any_addressable_vars = 0;
3274 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (child_fun), ix, decl)
3275 if (TREE_ADDRESSABLE (decl))
3276 {
3277 any_addressable_vars = 1;
3278 break;
3279 }
3280 for (block = gimple_block (stmt);
3281 !any_addressable_vars
3282 && block
3283 && TREE_CODE (block) == BLOCK;
3284 block = BLOCK_SUPERCONTEXT (block))
3285 {
3286 for (local_decls = BLOCK_VARS (block);
3287 local_decls;
3288 local_decls = DECL_CHAIN (local_decls))
3289 if (TREE_ADDRESSABLE (local_decls))
3290 {
3291 any_addressable_vars = 1;
3292 break;
3293 }
3294 if (block == gimple_block (parallel_stmt))
3295 break;
3296 }
3297 }
3298 if (!any_addressable_vars)
3299 gimple_omp_return_set_nowait (stmt);
3300 }
3301 }
3302 }
3303
3304 static void
3305 remove_exit_barriers (struct omp_region *region)
3306 {
3307 if (region->type == GIMPLE_OMP_PARALLEL)
3308 remove_exit_barrier (region);
3309
3310 if (region->inner)
3311 {
3312 region = region->inner;
3313 remove_exit_barriers (region);
3314 while (region->next)
3315 {
3316 region = region->next;
3317 remove_exit_barriers (region);
3318 }
3319 }
3320 }
3321
3322 /* Optimize omp_get_thread_num () and omp_get_num_threads ()
3323 calls. These can't be declared as const functions, but
3324 within one parallel body they are constant, so they can be
3325 transformed there into __builtin_omp_get_{thread_num,num_threads} ()
3326 which are declared const. Similarly for task body, except
3327 that in untied task omp_get_thread_num () can change at any task
3328 scheduling point. */
3329
3330 static void
3331 optimize_omp_library_calls (gimple entry_stmt)
3332 {
3333 basic_block bb;
3334 gimple_stmt_iterator gsi;
3335 tree thr_num_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
3336 tree thr_num_id = DECL_ASSEMBLER_NAME (thr_num_tree);
3337 tree num_thr_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
3338 tree num_thr_id = DECL_ASSEMBLER_NAME (num_thr_tree);
3339 bool untied_task = (gimple_code (entry_stmt) == GIMPLE_OMP_TASK
3340 && find_omp_clause (gimple_omp_task_clauses (entry_stmt),
3341 OMP_CLAUSE_UNTIED) != NULL);
3342
3343 FOR_EACH_BB (bb)
3344 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3345 {
3346 gimple call = gsi_stmt (gsi);
3347 tree decl;
3348
3349 if (is_gimple_call (call)
3350 && (decl = gimple_call_fndecl (call))
3351 && DECL_EXTERNAL (decl)
3352 && TREE_PUBLIC (decl)
3353 && DECL_INITIAL (decl) == NULL)
3354 {
3355 tree built_in;
3356
3357 if (DECL_NAME (decl) == thr_num_id)
3358 {
3359 /* In #pragma omp task untied omp_get_thread_num () can change
3360 during the execution of the task region. */
3361 if (untied_task)
3362 continue;
3363 built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
3364 }
3365 else if (DECL_NAME (decl) == num_thr_id)
3366 built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
3367 else
3368 continue;
3369
3370 if (DECL_ASSEMBLER_NAME (decl) != DECL_ASSEMBLER_NAME (built_in)
3371 || gimple_call_num_args (call) != 0)
3372 continue;
3373
3374 if (flag_exceptions && !TREE_NOTHROW (decl))
3375 continue;
3376
3377 if (TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE
3378 || !types_compatible_p (TREE_TYPE (TREE_TYPE (decl)),
3379 TREE_TYPE (TREE_TYPE (built_in))))
3380 continue;
3381
3382 gimple_call_set_fndecl (call, built_in);
3383 }
3384 }
3385 }
3386
3387 /* Expand the OpenMP parallel or task directive starting at REGION. */
3388
3389 static void
3390 expand_omp_taskreg (struct omp_region *region)
3391 {
3392 basic_block entry_bb, exit_bb, new_bb;
3393 struct function *child_cfun;
3394 tree child_fn, block, t;
3395 gimple_stmt_iterator gsi;
3396 gimple entry_stmt, stmt;
3397 edge e;
3398 vec<tree, va_gc> *ws_args;
3399
3400 entry_stmt = last_stmt (region->entry);
3401 child_fn = gimple_omp_taskreg_child_fn (entry_stmt);
3402 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
3403
3404 entry_bb = region->entry;
3405 exit_bb = region->exit;
3406
3407 if (is_combined_parallel (region))
3408 ws_args = region->ws_args;
3409 else
3410 ws_args = NULL;
3411
3412 if (child_cfun->cfg)
3413 {
3414 /* Due to inlining, it may happen that we have already outlined
3415 the region, in which case all we need to do is make the
3416 sub-graph unreachable and emit the parallel call. */
3417 edge entry_succ_e, exit_succ_e;
3418 gimple_stmt_iterator gsi;
3419
3420 entry_succ_e = single_succ_edge (entry_bb);
3421
3422 gsi = gsi_last_bb (entry_bb);
3423 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_PARALLEL
3424 || gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_TASK);
3425 gsi_remove (&gsi, true);
3426
3427 new_bb = entry_bb;
3428 if (exit_bb)
3429 {
3430 exit_succ_e = single_succ_edge (exit_bb);
3431 make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
3432 }
3433 remove_edge_and_dominated_blocks (entry_succ_e);
3434 }
3435 else
3436 {
3437 unsigned srcidx, dstidx, num;
3438
3439 /* If the parallel region needs data sent from the parent
3440 function, then the very first statement (except possible
3441 tree profile counter updates) of the parallel body
3442 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
3443 &.OMP_DATA_O is passed as an argument to the child function,
3444 we need to replace it with the argument as seen by the child
3445 function.
3446
3447 In most cases, this will end up being the identity assignment
3448 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
3449 a function call that has been inlined, the original PARM_DECL
3450 .OMP_DATA_I may have been converted into a different local
3451 variable. In which case, we need to keep the assignment. */
3452 if (gimple_omp_taskreg_data_arg (entry_stmt))
3453 {
3454 basic_block entry_succ_bb = single_succ (entry_bb);
3455 gimple_stmt_iterator gsi;
3456 tree arg, narg;
3457 gimple parcopy_stmt = NULL;
3458
3459 for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
3460 {
3461 gimple stmt;
3462
3463 gcc_assert (!gsi_end_p (gsi));
3464 stmt = gsi_stmt (gsi);
3465 if (gimple_code (stmt) != GIMPLE_ASSIGN)
3466 continue;
3467
3468 if (gimple_num_ops (stmt) == 2)
3469 {
3470 tree arg = gimple_assign_rhs1 (stmt);
3471
3472 /* We're ignore the subcode because we're
3473 effectively doing a STRIP_NOPS. */
3474
3475 if (TREE_CODE (arg) == ADDR_EXPR
3476 && TREE_OPERAND (arg, 0)
3477 == gimple_omp_taskreg_data_arg (entry_stmt))
3478 {
3479 parcopy_stmt = stmt;
3480 break;
3481 }
3482 }
3483 }
3484
3485 gcc_assert (parcopy_stmt != NULL);
3486 arg = DECL_ARGUMENTS (child_fn);
3487
3488 if (!gimple_in_ssa_p (cfun))
3489 {
3490 if (gimple_assign_lhs (parcopy_stmt) == arg)
3491 gsi_remove (&gsi, true);
3492 else
3493 {
3494 /* ?? Is setting the subcode really necessary ?? */
3495 gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (arg));
3496 gimple_assign_set_rhs1 (parcopy_stmt, arg);
3497 }
3498 }
3499 else
3500 {
3501 /* If we are in ssa form, we must load the value from the default
3502 definition of the argument. That should not be defined now,
3503 since the argument is not used uninitialized. */
3504 gcc_assert (ssa_default_def (cfun, arg) == NULL);
3505 narg = make_ssa_name (arg, gimple_build_nop ());
3506 set_ssa_default_def (cfun, arg, narg);
3507 /* ?? Is setting the subcode really necessary ?? */
3508 gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (narg));
3509 gimple_assign_set_rhs1 (parcopy_stmt, narg);
3510 update_stmt (parcopy_stmt);
3511 }
3512 }
3513
3514 /* Declare local variables needed in CHILD_CFUN. */
3515 block = DECL_INITIAL (child_fn);
3516 BLOCK_VARS (block) = vec2chain (child_cfun->local_decls);
3517 /* The gimplifier could record temporaries in parallel/task block
3518 rather than in containing function's local_decls chain,
3519 which would mean cgraph missed finalizing them. Do it now. */
3520 for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
3521 if (TREE_CODE (t) == VAR_DECL
3522 && TREE_STATIC (t)
3523 && !DECL_EXTERNAL (t))
3524 varpool_finalize_decl (t);
3525 DECL_SAVED_TREE (child_fn) = NULL;
3526 /* We'll create a CFG for child_fn, so no gimple body is needed. */
3527 gimple_set_body (child_fn, NULL);
3528 TREE_USED (block) = 1;
3529
3530 /* Reset DECL_CONTEXT on function arguments. */
3531 for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
3532 DECL_CONTEXT (t) = child_fn;
3533
3534 /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
3535 so that it can be moved to the child function. */
3536 gsi = gsi_last_bb (entry_bb);
3537 stmt = gsi_stmt (gsi);
3538 gcc_assert (stmt && (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
3539 || gimple_code (stmt) == GIMPLE_OMP_TASK));
3540 gsi_remove (&gsi, true);
3541 e = split_block (entry_bb, stmt);
3542 entry_bb = e->dest;
3543 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3544
3545 /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
3546 if (exit_bb)
3547 {
3548 gsi = gsi_last_bb (exit_bb);
3549 gcc_assert (!gsi_end_p (gsi)
3550 && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
3551 stmt = gimple_build_return (NULL);
3552 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
3553 gsi_remove (&gsi, true);
3554 }
3555
3556 /* Move the parallel region into CHILD_CFUN. */
3557
3558 if (gimple_in_ssa_p (cfun))
3559 {
3560 init_tree_ssa (child_cfun);
3561 init_ssa_operands (child_cfun);
3562 child_cfun->gimple_df->in_ssa_p = true;
3563 block = NULL_TREE;
3564 }
3565 else
3566 block = gimple_block (entry_stmt);
3567
3568 new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
3569 if (exit_bb)
3570 single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
3571
3572 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
3573 num = vec_safe_length (child_cfun->local_decls);
3574 for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
3575 {
3576 t = (*child_cfun->local_decls)[srcidx];
3577 if (DECL_CONTEXT (t) == cfun->decl)
3578 continue;
3579 if (srcidx != dstidx)
3580 (*child_cfun->local_decls)[dstidx] = t;
3581 dstidx++;
3582 }
3583 if (dstidx != num)
3584 vec_safe_truncate (child_cfun->local_decls, dstidx);
3585
3586 /* Inform the callgraph about the new function. */
3587 DECL_STRUCT_FUNCTION (child_fn)->curr_properties
3588 = cfun->curr_properties & ~PROP_loops;
3589 cgraph_add_new_function (child_fn, true);
3590
3591 /* Fix the callgraph edges for child_cfun. Those for cfun will be
3592 fixed in a following pass. */
3593 push_cfun (child_cfun);
3594 if (optimize)
3595 optimize_omp_library_calls (entry_stmt);
3596 rebuild_cgraph_edges ();
3597
3598 /* Some EH regions might become dead, see PR34608. If
3599 pass_cleanup_cfg isn't the first pass to happen with the
3600 new child, these dead EH edges might cause problems.
3601 Clean them up now. */
3602 if (flag_exceptions)
3603 {
3604 basic_block bb;
3605 bool changed = false;
3606
3607 FOR_EACH_BB (bb)
3608 changed |= gimple_purge_dead_eh_edges (bb);
3609 if (changed)
3610 cleanup_tree_cfg ();
3611 }
3612 if (gimple_in_ssa_p (cfun))
3613 update_ssa (TODO_update_ssa);
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) && head->iterate (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 == head->length ());
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> 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.create (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 label_vec.quick_push (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 label_vec.quick_push (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 (vmain, u, label_vec);
4877 gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
4878 gsi_remove (&switch_si, true);
4879 label_vec.release ();
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 OPTGROUP_NONE, /* optinfo_flags */
5764 gate_expand_omp, /* gate */
5765 execute_expand_omp, /* execute */
5766 NULL, /* sub */
5767 NULL, /* next */
5768 0, /* static_pass_number */
5769 TV_NONE, /* tv_id */
5770 PROP_gimple_any, /* properties_required */
5771 0, /* properties_provided */
5772 0, /* properties_destroyed */
5773 0, /* todo_flags_start */
5774 0 /* todo_flags_finish */
5775 }
5776 };
5777 \f
5778 /* Routines to lower OpenMP directives into OMP-GIMPLE. */
5779
5780 /* Lower the OpenMP sections directive in the current statement in GSI_P.
5781 CTX is the enclosing OMP context for the current statement. */
5782
5783 static void
5784 lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
5785 {
5786 tree block, control;
5787 gimple_stmt_iterator tgsi;
5788 gimple stmt, new_stmt, bind, t;
5789 gimple_seq ilist, dlist, olist, new_body;
5790 struct gimplify_ctx gctx;
5791
5792 stmt = gsi_stmt (*gsi_p);
5793
5794 push_gimplify_context (&gctx);
5795
5796 dlist = NULL;
5797 ilist = NULL;
5798 lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
5799 &ilist, &dlist, ctx);
5800
5801 new_body = gimple_omp_body (stmt);
5802 gimple_omp_set_body (stmt, NULL);
5803 tgsi = gsi_start (new_body);
5804 for (; !gsi_end_p (tgsi); gsi_next (&tgsi))
5805 {
5806 omp_context *sctx;
5807 gimple sec_start;
5808
5809 sec_start = gsi_stmt (tgsi);
5810 sctx = maybe_lookup_ctx (sec_start);
5811 gcc_assert (sctx);
5812
5813 lower_omp (gimple_omp_body_ptr (sec_start), sctx);
5814 gsi_insert_seq_after (&tgsi, gimple_omp_body (sec_start),
5815 GSI_CONTINUE_LINKING);
5816 gimple_omp_set_body (sec_start, NULL);
5817
5818 if (gsi_one_before_end_p (tgsi))
5819 {
5820 gimple_seq l = NULL;
5821 lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
5822 &l, ctx);
5823 gsi_insert_seq_after (&tgsi, l, GSI_CONTINUE_LINKING);
5824 gimple_omp_section_set_last (sec_start);
5825 }
5826
5827 gsi_insert_after (&tgsi, gimple_build_omp_return (false),
5828 GSI_CONTINUE_LINKING);
5829 }
5830
5831 block = make_node (BLOCK);
5832 bind = gimple_build_bind (NULL, new_body, block);
5833
5834 olist = NULL;
5835 lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
5836
5837 block = make_node (BLOCK);
5838 new_stmt = gimple_build_bind (NULL, NULL, block);
5839 gsi_replace (gsi_p, new_stmt, true);
5840
5841 pop_gimplify_context (new_stmt);
5842 gimple_bind_append_vars (new_stmt, ctx->block_vars);
5843 BLOCK_VARS (block) = gimple_bind_vars (bind);
5844 if (BLOCK_VARS (block))
5845 TREE_USED (block) = 1;
5846
5847 new_body = NULL;
5848 gimple_seq_add_seq (&new_body, ilist);
5849 gimple_seq_add_stmt (&new_body, stmt);
5850 gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
5851 gimple_seq_add_stmt (&new_body, bind);
5852
5853 control = create_tmp_var (unsigned_type_node, ".section");
5854 t = gimple_build_omp_continue (control, control);
5855 gimple_omp_sections_set_control (stmt, control);
5856 gimple_seq_add_stmt (&new_body, t);
5857
5858 gimple_seq_add_seq (&new_body, olist);
5859 gimple_seq_add_seq (&new_body, dlist);
5860
5861 new_body = maybe_catch_exception (new_body);
5862
5863 t = gimple_build_omp_return
5864 (!!find_omp_clause (gimple_omp_sections_clauses (stmt),
5865 OMP_CLAUSE_NOWAIT));
5866 gimple_seq_add_stmt (&new_body, t);
5867
5868 gimple_bind_set_body (new_stmt, new_body);
5869 }
5870
5871
5872 /* A subroutine of lower_omp_single. Expand the simple form of
5873 a GIMPLE_OMP_SINGLE, without a copyprivate clause:
5874
5875 if (GOMP_single_start ())
5876 BODY;
5877 [ GOMP_barrier (); ] -> unless 'nowait' is present.
5878
5879 FIXME. It may be better to delay expanding the logic of this until
5880 pass_expand_omp. The expanded logic may make the job more difficult
5881 to a synchronization analysis pass. */
5882
5883 static void
5884 lower_omp_single_simple (gimple single_stmt, gimple_seq *pre_p)
5885 {
5886 location_t loc = gimple_location (single_stmt);
5887 tree tlabel = create_artificial_label (loc);
5888 tree flabel = create_artificial_label (loc);
5889 gimple call, cond;
5890 tree lhs, decl;
5891
5892 decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START);
5893 lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)), NULL);
5894 call = gimple_build_call (decl, 0);
5895 gimple_call_set_lhs (call, lhs);
5896 gimple_seq_add_stmt (pre_p, call);
5897
5898 cond = gimple_build_cond (EQ_EXPR, lhs,
5899 fold_convert_loc (loc, TREE_TYPE (lhs),
5900 boolean_true_node),
5901 tlabel, flabel);
5902 gimple_seq_add_stmt (pre_p, cond);
5903 gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
5904 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
5905 gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
5906 }
5907
5908
5909 /* A subroutine of lower_omp_single. Expand the simple form of
5910 a GIMPLE_OMP_SINGLE, with a copyprivate clause:
5911
5912 #pragma omp single copyprivate (a, b, c)
5913
5914 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
5915
5916 {
5917 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
5918 {
5919 BODY;
5920 copyout.a = a;
5921 copyout.b = b;
5922 copyout.c = c;
5923 GOMP_single_copy_end (&copyout);
5924 }
5925 else
5926 {
5927 a = copyout_p->a;
5928 b = copyout_p->b;
5929 c = copyout_p->c;
5930 }
5931 GOMP_barrier ();
5932 }
5933
5934 FIXME. It may be better to delay expanding the logic of this until
5935 pass_expand_omp. The expanded logic may make the job more difficult
5936 to a synchronization analysis pass. */
5937
5938 static void
5939 lower_omp_single_copy (gimple single_stmt, gimple_seq *pre_p, omp_context *ctx)
5940 {
5941 tree ptr_type, t, l0, l1, l2, bfn_decl;
5942 gimple_seq copyin_seq;
5943 location_t loc = gimple_location (single_stmt);
5944
5945 ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
5946
5947 ptr_type = build_pointer_type (ctx->record_type);
5948 ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
5949
5950 l0 = create_artificial_label (loc);
5951 l1 = create_artificial_label (loc);
5952 l2 = create_artificial_label (loc);
5953
5954 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START);
5955 t = build_call_expr_loc (loc, bfn_decl, 0);
5956 t = fold_convert_loc (loc, ptr_type, t);
5957 gimplify_assign (ctx->receiver_decl, t, pre_p);
5958
5959 t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
5960 build_int_cst (ptr_type, 0));
5961 t = build3 (COND_EXPR, void_type_node, t,
5962 build_and_jump (&l0), build_and_jump (&l1));
5963 gimplify_and_add (t, pre_p);
5964
5965 gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
5966
5967 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
5968
5969 copyin_seq = NULL;
5970 lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
5971 &copyin_seq, ctx);
5972
5973 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
5974 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END);
5975 t = build_call_expr_loc (loc, bfn_decl, 1, t);
5976 gimplify_and_add (t, pre_p);
5977
5978 t = build_and_jump (&l2);
5979 gimplify_and_add (t, pre_p);
5980
5981 gimple_seq_add_stmt (pre_p, gimple_build_label (l1));
5982
5983 gimple_seq_add_seq (pre_p, copyin_seq);
5984
5985 gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
5986 }
5987
5988
5989 /* Expand code for an OpenMP single directive. */
5990
5991 static void
5992 lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
5993 {
5994 tree block;
5995 gimple t, bind, single_stmt = gsi_stmt (*gsi_p);
5996 gimple_seq bind_body, dlist;
5997 struct gimplify_ctx gctx;
5998
5999 push_gimplify_context (&gctx);
6000
6001 block = make_node (BLOCK);
6002 bind = gimple_build_bind (NULL, NULL, block);
6003 gsi_replace (gsi_p, bind, true);
6004 bind_body = NULL;
6005 dlist = NULL;
6006 lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
6007 &bind_body, &dlist, ctx);
6008 lower_omp (gimple_omp_body_ptr (single_stmt), ctx);
6009
6010 gimple_seq_add_stmt (&bind_body, single_stmt);
6011
6012 if (ctx->record_type)
6013 lower_omp_single_copy (single_stmt, &bind_body, ctx);
6014 else
6015 lower_omp_single_simple (single_stmt, &bind_body);
6016
6017 gimple_omp_set_body (single_stmt, NULL);
6018
6019 gimple_seq_add_seq (&bind_body, dlist);
6020
6021 bind_body = maybe_catch_exception (bind_body);
6022
6023 t = gimple_build_omp_return
6024 (!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
6025 OMP_CLAUSE_NOWAIT));
6026 gimple_seq_add_stmt (&bind_body, t);
6027 gimple_bind_set_body (bind, bind_body);
6028
6029 pop_gimplify_context (bind);
6030
6031 gimple_bind_append_vars (bind, ctx->block_vars);
6032 BLOCK_VARS (block) = ctx->block_vars;
6033 if (BLOCK_VARS (block))
6034 TREE_USED (block) = 1;
6035 }
6036
6037
6038 /* Expand code for an OpenMP master directive. */
6039
6040 static void
6041 lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6042 {
6043 tree block, lab = NULL, x, bfn_decl;
6044 gimple stmt = gsi_stmt (*gsi_p), bind;
6045 location_t loc = gimple_location (stmt);
6046 gimple_seq tseq;
6047 struct gimplify_ctx gctx;
6048
6049 push_gimplify_context (&gctx);
6050
6051 block = make_node (BLOCK);
6052 bind = gimple_build_bind (NULL, NULL, block);
6053 gsi_replace (gsi_p, bind, true);
6054 gimple_bind_add_stmt (bind, stmt);
6055
6056 bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
6057 x = build_call_expr_loc (loc, bfn_decl, 0);
6058 x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
6059 x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
6060 tseq = NULL;
6061 gimplify_and_add (x, &tseq);
6062 gimple_bind_add_seq (bind, tseq);
6063
6064 lower_omp (gimple_omp_body_ptr (stmt), ctx);
6065 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6066 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6067 gimple_omp_set_body (stmt, NULL);
6068
6069 gimple_bind_add_stmt (bind, gimple_build_label (lab));
6070
6071 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6072
6073 pop_gimplify_context (bind);
6074
6075 gimple_bind_append_vars (bind, ctx->block_vars);
6076 BLOCK_VARS (block) = ctx->block_vars;
6077 }
6078
6079
6080 /* Expand code for an OpenMP ordered directive. */
6081
6082 static void
6083 lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6084 {
6085 tree block;
6086 gimple stmt = gsi_stmt (*gsi_p), bind, x;
6087 struct gimplify_ctx gctx;
6088
6089 push_gimplify_context (&gctx);
6090
6091 block = make_node (BLOCK);
6092 bind = gimple_build_bind (NULL, NULL, block);
6093 gsi_replace (gsi_p, bind, true);
6094 gimple_bind_add_stmt (bind, stmt);
6095
6096 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
6097 0);
6098 gimple_bind_add_stmt (bind, x);
6099
6100 lower_omp (gimple_omp_body_ptr (stmt), ctx);
6101 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6102 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6103 gimple_omp_set_body (stmt, NULL);
6104
6105 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END), 0);
6106 gimple_bind_add_stmt (bind, x);
6107
6108 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6109
6110 pop_gimplify_context (bind);
6111
6112 gimple_bind_append_vars (bind, ctx->block_vars);
6113 BLOCK_VARS (block) = gimple_bind_vars (bind);
6114 }
6115
6116
6117 /* Gimplify a GIMPLE_OMP_CRITICAL statement. This is a relatively simple
6118 substitution of a couple of function calls. But in the NAMED case,
6119 requires that languages coordinate a symbol name. It is therefore
6120 best put here in common code. */
6121
6122 static GTY((param1_is (tree), param2_is (tree)))
6123 splay_tree critical_name_mutexes;
6124
6125 static void
6126 lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6127 {
6128 tree block;
6129 tree name, lock, unlock;
6130 gimple stmt = gsi_stmt (*gsi_p), bind;
6131 location_t loc = gimple_location (stmt);
6132 gimple_seq tbody;
6133 struct gimplify_ctx gctx;
6134
6135 name = gimple_omp_critical_name (stmt);
6136 if (name)
6137 {
6138 tree decl;
6139 splay_tree_node n;
6140
6141 if (!critical_name_mutexes)
6142 critical_name_mutexes
6143 = splay_tree_new_ggc (splay_tree_compare_pointers,
6144 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_s,
6145 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_node_s);
6146
6147 n = splay_tree_lookup (critical_name_mutexes, (splay_tree_key) name);
6148 if (n == NULL)
6149 {
6150 char *new_str;
6151
6152 decl = create_tmp_var_raw (ptr_type_node, NULL);
6153
6154 new_str = ACONCAT ((".gomp_critical_user_",
6155 IDENTIFIER_POINTER (name), NULL));
6156 DECL_NAME (decl) = get_identifier (new_str);
6157 TREE_PUBLIC (decl) = 1;
6158 TREE_STATIC (decl) = 1;
6159 DECL_COMMON (decl) = 1;
6160 DECL_ARTIFICIAL (decl) = 1;
6161 DECL_IGNORED_P (decl) = 1;
6162 varpool_finalize_decl (decl);
6163
6164 splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
6165 (splay_tree_value) decl);
6166 }
6167 else
6168 decl = (tree) n->value;
6169
6170 lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START);
6171 lock = build_call_expr_loc (loc, lock, 1, build_fold_addr_expr_loc (loc, decl));
6172
6173 unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END);
6174 unlock = build_call_expr_loc (loc, unlock, 1,
6175 build_fold_addr_expr_loc (loc, decl));
6176 }
6177 else
6178 {
6179 lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START);
6180 lock = build_call_expr_loc (loc, lock, 0);
6181
6182 unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END);
6183 unlock = build_call_expr_loc (loc, unlock, 0);
6184 }
6185
6186 push_gimplify_context (&gctx);
6187
6188 block = make_node (BLOCK);
6189 bind = gimple_build_bind (NULL, NULL, block);
6190 gsi_replace (gsi_p, bind, true);
6191 gimple_bind_add_stmt (bind, stmt);
6192
6193 tbody = gimple_bind_body (bind);
6194 gimplify_and_add (lock, &tbody);
6195 gimple_bind_set_body (bind, tbody);
6196
6197 lower_omp (gimple_omp_body_ptr (stmt), ctx);
6198 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6199 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6200 gimple_omp_set_body (stmt, NULL);
6201
6202 tbody = gimple_bind_body (bind);
6203 gimplify_and_add (unlock, &tbody);
6204 gimple_bind_set_body (bind, tbody);
6205
6206 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6207
6208 pop_gimplify_context (bind);
6209 gimple_bind_append_vars (bind, ctx->block_vars);
6210 BLOCK_VARS (block) = gimple_bind_vars (bind);
6211 }
6212
6213
6214 /* A subroutine of lower_omp_for. Generate code to emit the predicate
6215 for a lastprivate clause. Given a loop control predicate of (V
6216 cond N2), we gate the clause on (!(V cond N2)). The lowered form
6217 is appended to *DLIST, iterator initialization is appended to
6218 *BODY_P. */
6219
6220 static void
6221 lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
6222 gimple_seq *dlist, struct omp_context *ctx)
6223 {
6224 tree clauses, cond, vinit;
6225 enum tree_code cond_code;
6226 gimple_seq stmts;
6227
6228 cond_code = fd->loop.cond_code;
6229 cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
6230
6231 /* When possible, use a strict equality expression. This can let VRP
6232 type optimizations deduce the value and remove a copy. */
6233 if (host_integerp (fd->loop.step, 0))
6234 {
6235 HOST_WIDE_INT step = TREE_INT_CST_LOW (fd->loop.step);
6236 if (step == 1 || step == -1)
6237 cond_code = EQ_EXPR;
6238 }
6239
6240 cond = build2 (cond_code, boolean_type_node, fd->loop.v, fd->loop.n2);
6241
6242 clauses = gimple_omp_for_clauses (fd->for_stmt);
6243 stmts = NULL;
6244 lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
6245 if (!gimple_seq_empty_p (stmts))
6246 {
6247 gimple_seq_add_seq (&stmts, *dlist);
6248 *dlist = stmts;
6249
6250 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
6251 vinit = fd->loop.n1;
6252 if (cond_code == EQ_EXPR
6253 && host_integerp (fd->loop.n2, 0)
6254 && ! integer_zerop (fd->loop.n2))
6255 vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
6256
6257 /* Initialize the iterator variable, so that threads that don't execute
6258 any iterations don't execute the lastprivate clauses by accident. */
6259 gimplify_assign (fd->loop.v, vinit, body_p);
6260 }
6261 }
6262
6263
6264 /* Lower code for an OpenMP loop directive. */
6265
6266 static void
6267 lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6268 {
6269 tree *rhs_p, block;
6270 struct omp_for_data fd;
6271 gimple stmt = gsi_stmt (*gsi_p), new_stmt;
6272 gimple_seq omp_for_body, body, dlist;
6273 size_t i;
6274 struct gimplify_ctx gctx;
6275
6276 push_gimplify_context (&gctx);
6277
6278 lower_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
6279 lower_omp (gimple_omp_body_ptr (stmt), ctx);
6280
6281 block = make_node (BLOCK);
6282 new_stmt = gimple_build_bind (NULL, NULL, block);
6283 /* Replace at gsi right away, so that 'stmt' is no member
6284 of a sequence anymore as we're going to add to to a different
6285 one below. */
6286 gsi_replace (gsi_p, new_stmt, true);
6287
6288 /* Move declaration of temporaries in the loop body before we make
6289 it go away. */
6290 omp_for_body = gimple_omp_body (stmt);
6291 if (!gimple_seq_empty_p (omp_for_body)
6292 && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
6293 {
6294 tree vars = gimple_bind_vars (gimple_seq_first_stmt (omp_for_body));
6295 gimple_bind_append_vars (new_stmt, vars);
6296 }
6297
6298 /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR. */
6299 dlist = NULL;
6300 body = NULL;
6301 lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx);
6302 gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
6303
6304 /* Lower the header expressions. At this point, we can assume that
6305 the header is of the form:
6306
6307 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
6308
6309 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
6310 using the .omp_data_s mapping, if needed. */
6311 for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
6312 {
6313 rhs_p = gimple_omp_for_initial_ptr (stmt, i);
6314 if (!is_gimple_min_invariant (*rhs_p))
6315 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6316
6317 rhs_p = gimple_omp_for_final_ptr (stmt, i);
6318 if (!is_gimple_min_invariant (*rhs_p))
6319 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6320
6321 rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
6322 if (!is_gimple_min_invariant (*rhs_p))
6323 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6324 }
6325
6326 /* Once lowered, extract the bounds and clauses. */
6327 extract_omp_for_data (stmt, &fd, NULL);
6328
6329 lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
6330
6331 gimple_seq_add_stmt (&body, stmt);
6332 gimple_seq_add_seq (&body, gimple_omp_body (stmt));
6333
6334 gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
6335 fd.loop.v));
6336
6337 /* After the loop, add exit clauses. */
6338 lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, ctx);
6339 gimple_seq_add_seq (&body, dlist);
6340
6341 body = maybe_catch_exception (body);
6342
6343 /* Region exit marker goes at the end of the loop body. */
6344 gimple_seq_add_stmt (&body, gimple_build_omp_return (fd.have_nowait));
6345
6346 pop_gimplify_context (new_stmt);
6347
6348 gimple_bind_append_vars (new_stmt, ctx->block_vars);
6349 BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
6350 if (BLOCK_VARS (block))
6351 TREE_USED (block) = 1;
6352
6353 gimple_bind_set_body (new_stmt, body);
6354 gimple_omp_set_body (stmt, NULL);
6355 gimple_omp_for_set_pre_body (stmt, NULL);
6356 }
6357
6358 /* Callback for walk_stmts. Check if the current statement only contains
6359 GIMPLE_OMP_FOR or GIMPLE_OMP_PARALLEL. */
6360
6361 static tree
6362 check_combined_parallel (gimple_stmt_iterator *gsi_p,
6363 bool *handled_ops_p,
6364 struct walk_stmt_info *wi)
6365 {
6366 int *info = (int *) wi->info;
6367 gimple stmt = gsi_stmt (*gsi_p);
6368
6369 *handled_ops_p = true;
6370 switch (gimple_code (stmt))
6371 {
6372 WALK_SUBSTMTS;
6373
6374 case GIMPLE_OMP_FOR:
6375 case GIMPLE_OMP_SECTIONS:
6376 *info = *info == 0 ? 1 : -1;
6377 break;
6378 default:
6379 *info = -1;
6380 break;
6381 }
6382 return NULL;
6383 }
6384
6385 struct omp_taskcopy_context
6386 {
6387 /* This field must be at the beginning, as we do "inheritance": Some
6388 callback functions for tree-inline.c (e.g., omp_copy_decl)
6389 receive a copy_body_data pointer that is up-casted to an
6390 omp_context pointer. */
6391 copy_body_data cb;
6392 omp_context *ctx;
6393 };
6394
6395 static tree
6396 task_copyfn_copy_decl (tree var, copy_body_data *cb)
6397 {
6398 struct omp_taskcopy_context *tcctx = (struct omp_taskcopy_context *) cb;
6399
6400 if (splay_tree_lookup (tcctx->ctx->sfield_map, (splay_tree_key) var))
6401 return create_tmp_var (TREE_TYPE (var), NULL);
6402
6403 return var;
6404 }
6405
6406 static tree
6407 task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
6408 {
6409 tree name, new_fields = NULL, type, f;
6410
6411 type = lang_hooks.types.make_type (RECORD_TYPE);
6412 name = DECL_NAME (TYPE_NAME (orig_type));
6413 name = build_decl (gimple_location (tcctx->ctx->stmt),
6414 TYPE_DECL, name, type);
6415 TYPE_NAME (type) = name;
6416
6417 for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
6418 {
6419 tree new_f = copy_node (f);
6420 DECL_CONTEXT (new_f) = type;
6421 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
6422 TREE_CHAIN (new_f) = new_fields;
6423 walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6424 walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6425 walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
6426 &tcctx->cb, NULL);
6427 new_fields = new_f;
6428 *pointer_map_insert (tcctx->cb.decl_map, f) = new_f;
6429 }
6430 TYPE_FIELDS (type) = nreverse (new_fields);
6431 layout_type (type);
6432 return type;
6433 }
6434
6435 /* Create task copyfn. */
6436
6437 static void
6438 create_task_copyfn (gimple task_stmt, omp_context *ctx)
6439 {
6440 struct function *child_cfun;
6441 tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
6442 tree record_type, srecord_type, bind, list;
6443 bool record_needs_remap = false, srecord_needs_remap = false;
6444 splay_tree_node n;
6445 struct omp_taskcopy_context tcctx;
6446 struct gimplify_ctx gctx;
6447 location_t loc = gimple_location (task_stmt);
6448
6449 child_fn = gimple_omp_task_copy_fn (task_stmt);
6450 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
6451 gcc_assert (child_cfun->cfg == NULL);
6452 DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();
6453
6454 /* Reset DECL_CONTEXT on function arguments. */
6455 for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
6456 DECL_CONTEXT (t) = child_fn;
6457
6458 /* Populate the function. */
6459 push_gimplify_context (&gctx);
6460 push_cfun (child_cfun);
6461
6462 bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
6463 TREE_SIDE_EFFECTS (bind) = 1;
6464 list = NULL;
6465 DECL_SAVED_TREE (child_fn) = bind;
6466 DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);
6467
6468 /* Remap src and dst argument types if needed. */
6469 record_type = ctx->record_type;
6470 srecord_type = ctx->srecord_type;
6471 for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
6472 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6473 {
6474 record_needs_remap = true;
6475 break;
6476 }
6477 for (f = TYPE_FIELDS (srecord_type); f ; f = DECL_CHAIN (f))
6478 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6479 {
6480 srecord_needs_remap = true;
6481 break;
6482 }
6483
6484 if (record_needs_remap || srecord_needs_remap)
6485 {
6486 memset (&tcctx, '\0', sizeof (tcctx));
6487 tcctx.cb.src_fn = ctx->cb.src_fn;
6488 tcctx.cb.dst_fn = child_fn;
6489 tcctx.cb.src_node = cgraph_get_node (tcctx.cb.src_fn);
6490 gcc_checking_assert (tcctx.cb.src_node);
6491 tcctx.cb.dst_node = tcctx.cb.src_node;
6492 tcctx.cb.src_cfun = ctx->cb.src_cfun;
6493 tcctx.cb.copy_decl = task_copyfn_copy_decl;
6494 tcctx.cb.eh_lp_nr = 0;
6495 tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
6496 tcctx.cb.decl_map = pointer_map_create ();
6497 tcctx.ctx = ctx;
6498
6499 if (record_needs_remap)
6500 record_type = task_copyfn_remap_type (&tcctx, record_type);
6501 if (srecord_needs_remap)
6502 srecord_type = task_copyfn_remap_type (&tcctx, srecord_type);
6503 }
6504 else
6505 tcctx.cb.decl_map = NULL;
6506
6507 arg = DECL_ARGUMENTS (child_fn);
6508 TREE_TYPE (arg) = build_pointer_type (record_type);
6509 sarg = DECL_CHAIN (arg);
6510 TREE_TYPE (sarg) = build_pointer_type (srecord_type);
6511
6512 /* First pass: initialize temporaries used in record_type and srecord_type
6513 sizes and field offsets. */
6514 if (tcctx.cb.decl_map)
6515 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6516 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6517 {
6518 tree *p;
6519
6520 decl = OMP_CLAUSE_DECL (c);
6521 p = (tree *) pointer_map_contains (tcctx.cb.decl_map, decl);
6522 if (p == NULL)
6523 continue;
6524 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6525 sf = (tree) n->value;
6526 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6527 src = build_simple_mem_ref_loc (loc, sarg);
6528 src = omp_build_component_ref (src, sf);
6529 t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
6530 append_to_statement_list (t, &list);
6531 }
6532
6533 /* Second pass: copy shared var pointers and copy construct non-VLA
6534 firstprivate vars. */
6535 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6536 switch (OMP_CLAUSE_CODE (c))
6537 {
6538 case OMP_CLAUSE_SHARED:
6539 decl = OMP_CLAUSE_DECL (c);
6540 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6541 if (n == NULL)
6542 break;
6543 f = (tree) n->value;
6544 if (tcctx.cb.decl_map)
6545 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6546 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6547 sf = (tree) n->value;
6548 if (tcctx.cb.decl_map)
6549 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6550 src = build_simple_mem_ref_loc (loc, sarg);
6551 src = omp_build_component_ref (src, sf);
6552 dst = build_simple_mem_ref_loc (loc, arg);
6553 dst = omp_build_component_ref (dst, f);
6554 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6555 append_to_statement_list (t, &list);
6556 break;
6557 case OMP_CLAUSE_FIRSTPRIVATE:
6558 decl = OMP_CLAUSE_DECL (c);
6559 if (is_variable_sized (decl))
6560 break;
6561 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6562 if (n == NULL)
6563 break;
6564 f = (tree) n->value;
6565 if (tcctx.cb.decl_map)
6566 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6567 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6568 if (n != NULL)
6569 {
6570 sf = (tree) n->value;
6571 if (tcctx.cb.decl_map)
6572 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6573 src = build_simple_mem_ref_loc (loc, sarg);
6574 src = omp_build_component_ref (src, sf);
6575 if (use_pointer_for_field (decl, NULL) || is_reference (decl))
6576 src = build_simple_mem_ref_loc (loc, src);
6577 }
6578 else
6579 src = decl;
6580 dst = build_simple_mem_ref_loc (loc, arg);
6581 dst = omp_build_component_ref (dst, f);
6582 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6583 append_to_statement_list (t, &list);
6584 break;
6585 case OMP_CLAUSE_PRIVATE:
6586 if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c))
6587 break;
6588 decl = OMP_CLAUSE_DECL (c);
6589 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6590 f = (tree) n->value;
6591 if (tcctx.cb.decl_map)
6592 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6593 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6594 if (n != NULL)
6595 {
6596 sf = (tree) n->value;
6597 if (tcctx.cb.decl_map)
6598 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6599 src = build_simple_mem_ref_loc (loc, sarg);
6600 src = omp_build_component_ref (src, sf);
6601 if (use_pointer_for_field (decl, NULL))
6602 src = build_simple_mem_ref_loc (loc, src);
6603 }
6604 else
6605 src = decl;
6606 dst = build_simple_mem_ref_loc (loc, arg);
6607 dst = omp_build_component_ref (dst, f);
6608 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6609 append_to_statement_list (t, &list);
6610 break;
6611 default:
6612 break;
6613 }
6614
6615 /* Last pass: handle VLA firstprivates. */
6616 if (tcctx.cb.decl_map)
6617 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6618 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6619 {
6620 tree ind, ptr, df;
6621
6622 decl = OMP_CLAUSE_DECL (c);
6623 if (!is_variable_sized (decl))
6624 continue;
6625 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6626 if (n == NULL)
6627 continue;
6628 f = (tree) n->value;
6629 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6630 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
6631 ind = DECL_VALUE_EXPR (decl);
6632 gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
6633 gcc_assert (DECL_P (TREE_OPERAND (ind, 0)));
6634 n = splay_tree_lookup (ctx->sfield_map,
6635 (splay_tree_key) TREE_OPERAND (ind, 0));
6636 sf = (tree) n->value;
6637 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6638 src = build_simple_mem_ref_loc (loc, sarg);
6639 src = omp_build_component_ref (src, sf);
6640 src = build_simple_mem_ref_loc (loc, src);
6641 dst = build_simple_mem_ref_loc (loc, arg);
6642 dst = omp_build_component_ref (dst, f);
6643 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6644 append_to_statement_list (t, &list);
6645 n = splay_tree_lookup (ctx->field_map,
6646 (splay_tree_key) TREE_OPERAND (ind, 0));
6647 df = (tree) n->value;
6648 df = *(tree *) pointer_map_contains (tcctx.cb.decl_map, df);
6649 ptr = build_simple_mem_ref_loc (loc, arg);
6650 ptr = omp_build_component_ref (ptr, df);
6651 t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
6652 build_fold_addr_expr_loc (loc, dst));
6653 append_to_statement_list (t, &list);
6654 }
6655
6656 t = build1 (RETURN_EXPR, void_type_node, NULL);
6657 append_to_statement_list (t, &list);
6658
6659 if (tcctx.cb.decl_map)
6660 pointer_map_destroy (tcctx.cb.decl_map);
6661 pop_gimplify_context (NULL);
6662 BIND_EXPR_BODY (bind) = list;
6663 pop_cfun ();
6664 }
6665
6666 /* Lower the OpenMP parallel or task directive in the current statement
6667 in GSI_P. CTX holds context information for the directive. */
6668
6669 static void
6670 lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6671 {
6672 tree clauses;
6673 tree child_fn, t;
6674 gimple stmt = gsi_stmt (*gsi_p);
6675 gimple par_bind, bind;
6676 gimple_seq par_body, olist, ilist, par_olist, par_ilist, new_body;
6677 struct gimplify_ctx gctx;
6678 location_t loc = gimple_location (stmt);
6679
6680 clauses = gimple_omp_taskreg_clauses (stmt);
6681 par_bind = gimple_seq_first_stmt (gimple_omp_body (stmt));
6682 par_body = gimple_bind_body (par_bind);
6683 child_fn = ctx->cb.dst_fn;
6684 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
6685 && !gimple_omp_parallel_combined_p (stmt))
6686 {
6687 struct walk_stmt_info wi;
6688 int ws_num = 0;
6689
6690 memset (&wi, 0, sizeof (wi));
6691 wi.info = &ws_num;
6692 wi.val_only = true;
6693 walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
6694 if (ws_num == 1)
6695 gimple_omp_parallel_set_combined_p (stmt, true);
6696 }
6697 if (ctx->srecord_type)
6698 create_task_copyfn (stmt, ctx);
6699
6700 push_gimplify_context (&gctx);
6701
6702 par_olist = NULL;
6703 par_ilist = NULL;
6704 lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
6705 lower_omp (&par_body, ctx);
6706 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
6707 lower_reduction_clauses (clauses, &par_olist, ctx);
6708
6709 /* Declare all the variables created by mapping and the variables
6710 declared in the scope of the parallel body. */
6711 record_vars_into (ctx->block_vars, child_fn);
6712 record_vars_into (gimple_bind_vars (par_bind), child_fn);
6713
6714 if (ctx->record_type)
6715 {
6716 ctx->sender_decl
6717 = create_tmp_var (ctx->srecord_type ? ctx->srecord_type
6718 : ctx->record_type, ".omp_data_o");
6719 DECL_NAMELESS (ctx->sender_decl) = 1;
6720 TREE_ADDRESSABLE (ctx->sender_decl) = 1;
6721 gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
6722 }
6723
6724 olist = NULL;
6725 ilist = NULL;
6726 lower_send_clauses (clauses, &ilist, &olist, ctx);
6727 lower_send_shared_vars (&ilist, &olist, ctx);
6728
6729 /* Once all the expansions are done, sequence all the different
6730 fragments inside gimple_omp_body. */
6731
6732 new_body = NULL;
6733
6734 if (ctx->record_type)
6735 {
6736 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
6737 /* fixup_child_record_type might have changed receiver_decl's type. */
6738 t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
6739 gimple_seq_add_stmt (&new_body,
6740 gimple_build_assign (ctx->receiver_decl, t));
6741 }
6742
6743 gimple_seq_add_seq (&new_body, par_ilist);
6744 gimple_seq_add_seq (&new_body, par_body);
6745 gimple_seq_add_seq (&new_body, par_olist);
6746 new_body = maybe_catch_exception (new_body);
6747 gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
6748 gimple_omp_set_body (stmt, new_body);
6749
6750 bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
6751 gsi_replace (gsi_p, bind, true);
6752 gimple_bind_add_seq (bind, ilist);
6753 gimple_bind_add_stmt (bind, stmt);
6754 gimple_bind_add_seq (bind, olist);
6755
6756 pop_gimplify_context (NULL);
6757 }
6758
6759 /* Callback for lower_omp_1. Return non-NULL if *tp needs to be
6760 regimplified. If DATA is non-NULL, lower_omp_1 is outside
6761 of OpenMP context, but with task_shared_vars set. */
6762
6763 static tree
6764 lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
6765 void *data)
6766 {
6767 tree t = *tp;
6768
6769 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
6770 if (TREE_CODE (t) == VAR_DECL && data == NULL && DECL_HAS_VALUE_EXPR_P (t))
6771 return t;
6772
6773 if (task_shared_vars
6774 && DECL_P (t)
6775 && bitmap_bit_p (task_shared_vars, DECL_UID (t)))
6776 return t;
6777
6778 /* If a global variable has been privatized, TREE_CONSTANT on
6779 ADDR_EXPR might be wrong. */
6780 if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
6781 recompute_tree_invariant_for_addr_expr (t);
6782
6783 *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
6784 return NULL_TREE;
6785 }
6786
6787 static void
6788 lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6789 {
6790 gimple stmt = gsi_stmt (*gsi_p);
6791 struct walk_stmt_info wi;
6792
6793 if (gimple_has_location (stmt))
6794 input_location = gimple_location (stmt);
6795
6796 if (task_shared_vars)
6797 memset (&wi, '\0', sizeof (wi));
6798
6799 /* If we have issued syntax errors, avoid doing any heavy lifting.
6800 Just replace the OpenMP directives with a NOP to avoid
6801 confusing RTL expansion. */
6802 if (seen_error () && is_gimple_omp (stmt))
6803 {
6804 gsi_replace (gsi_p, gimple_build_nop (), true);
6805 return;
6806 }
6807
6808 switch (gimple_code (stmt))
6809 {
6810 case GIMPLE_COND:
6811 if ((ctx || task_shared_vars)
6812 && (walk_tree (gimple_cond_lhs_ptr (stmt), lower_omp_regimplify_p,
6813 ctx ? NULL : &wi, NULL)
6814 || walk_tree (gimple_cond_rhs_ptr (stmt), lower_omp_regimplify_p,
6815 ctx ? NULL : &wi, NULL)))
6816 gimple_regimplify_operands (stmt, gsi_p);
6817 break;
6818 case GIMPLE_CATCH:
6819 lower_omp (gimple_catch_handler_ptr (stmt), ctx);
6820 break;
6821 case GIMPLE_EH_FILTER:
6822 lower_omp (gimple_eh_filter_failure_ptr (stmt), ctx);
6823 break;
6824 case GIMPLE_TRY:
6825 lower_omp (gimple_try_eval_ptr (stmt), ctx);
6826 lower_omp (gimple_try_cleanup_ptr (stmt), ctx);
6827 break;
6828 case GIMPLE_TRANSACTION:
6829 lower_omp (gimple_transaction_body_ptr (stmt), ctx);
6830 break;
6831 case GIMPLE_BIND:
6832 lower_omp (gimple_bind_body_ptr (stmt), ctx);
6833 break;
6834 case GIMPLE_OMP_PARALLEL:
6835 case GIMPLE_OMP_TASK:
6836 ctx = maybe_lookup_ctx (stmt);
6837 lower_omp_taskreg (gsi_p, ctx);
6838 break;
6839 case GIMPLE_OMP_FOR:
6840 ctx = maybe_lookup_ctx (stmt);
6841 gcc_assert (ctx);
6842 lower_omp_for (gsi_p, ctx);
6843 break;
6844 case GIMPLE_OMP_SECTIONS:
6845 ctx = maybe_lookup_ctx (stmt);
6846 gcc_assert (ctx);
6847 lower_omp_sections (gsi_p, ctx);
6848 break;
6849 case GIMPLE_OMP_SINGLE:
6850 ctx = maybe_lookup_ctx (stmt);
6851 gcc_assert (ctx);
6852 lower_omp_single (gsi_p, ctx);
6853 break;
6854 case GIMPLE_OMP_MASTER:
6855 ctx = maybe_lookup_ctx (stmt);
6856 gcc_assert (ctx);
6857 lower_omp_master (gsi_p, ctx);
6858 break;
6859 case GIMPLE_OMP_ORDERED:
6860 ctx = maybe_lookup_ctx (stmt);
6861 gcc_assert (ctx);
6862 lower_omp_ordered (gsi_p, ctx);
6863 break;
6864 case GIMPLE_OMP_CRITICAL:
6865 ctx = maybe_lookup_ctx (stmt);
6866 gcc_assert (ctx);
6867 lower_omp_critical (gsi_p, ctx);
6868 break;
6869 case GIMPLE_OMP_ATOMIC_LOAD:
6870 if ((ctx || task_shared_vars)
6871 && walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt),
6872 lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
6873 gimple_regimplify_operands (stmt, gsi_p);
6874 break;
6875 default:
6876 if ((ctx || task_shared_vars)
6877 && walk_gimple_op (stmt, lower_omp_regimplify_p,
6878 ctx ? NULL : &wi))
6879 gimple_regimplify_operands (stmt, gsi_p);
6880 break;
6881 }
6882 }
6883
6884 static void
6885 lower_omp (gimple_seq *body, omp_context *ctx)
6886 {
6887 location_t saved_location = input_location;
6888 gimple_stmt_iterator gsi;
6889 for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
6890 lower_omp_1 (&gsi, ctx);
6891 input_location = saved_location;
6892 }
6893 \f
6894 /* Main entry point. */
6895
6896 static unsigned int
6897 execute_lower_omp (void)
6898 {
6899 gimple_seq body;
6900
6901 /* This pass always runs, to provide PROP_gimple_lomp.
6902 But there is nothing to do unless -fopenmp is given. */
6903 if (flag_openmp == 0)
6904 return 0;
6905
6906 all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
6907 delete_omp_context);
6908
6909 body = gimple_body (current_function_decl);
6910 scan_omp (&body, NULL);
6911 gcc_assert (taskreg_nesting_level == 0);
6912
6913 if (all_contexts->root)
6914 {
6915 struct gimplify_ctx gctx;
6916
6917 if (task_shared_vars)
6918 push_gimplify_context (&gctx);
6919 lower_omp (&body, NULL);
6920 if (task_shared_vars)
6921 pop_gimplify_context (NULL);
6922 }
6923
6924 if (all_contexts)
6925 {
6926 splay_tree_delete (all_contexts);
6927 all_contexts = NULL;
6928 }
6929 BITMAP_FREE (task_shared_vars);
6930 return 0;
6931 }
6932
6933 struct gimple_opt_pass pass_lower_omp =
6934 {
6935 {
6936 GIMPLE_PASS,
6937 "omplower", /* name */
6938 OPTGROUP_NONE, /* optinfo_flags */
6939 NULL, /* gate */
6940 execute_lower_omp, /* execute */
6941 NULL, /* sub */
6942 NULL, /* next */
6943 0, /* static_pass_number */
6944 TV_NONE, /* tv_id */
6945 PROP_gimple_any, /* properties_required */
6946 PROP_gimple_lomp, /* properties_provided */
6947 0, /* properties_destroyed */
6948 0, /* todo_flags_start */
6949 0 /* todo_flags_finish */
6950 }
6951 };
6952 \f
6953 /* The following is a utility to diagnose OpenMP structured block violations.
6954 It is not part of the "omplower" pass, as that's invoked too late. It
6955 should be invoked by the respective front ends after gimplification. */
6956
6957 static splay_tree all_labels;
6958
6959 /* Check for mismatched contexts and generate an error if needed. Return
6960 true if an error is detected. */
6961
6962 static bool
6963 diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
6964 gimple branch_ctx, gimple label_ctx)
6965 {
6966 if (label_ctx == branch_ctx)
6967 return false;
6968
6969
6970 /*
6971 Previously we kept track of the label's entire context in diagnose_sb_[12]
6972 so we could traverse it and issue a correct "exit" or "enter" error
6973 message upon a structured block violation.
6974
6975 We built the context by building a list with tree_cons'ing, but there is
6976 no easy counterpart in gimple tuples. It seems like far too much work
6977 for issuing exit/enter error messages. If someone really misses the
6978 distinct error message... patches welcome.
6979 */
6980
6981 #if 0
6982 /* Try to avoid confusing the user by producing and error message
6983 with correct "exit" or "enter" verbiage. We prefer "exit"
6984 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
6985 if (branch_ctx == NULL)
6986 exit_p = false;
6987 else
6988 {
6989 while (label_ctx)
6990 {
6991 if (TREE_VALUE (label_ctx) == branch_ctx)
6992 {
6993 exit_p = false;
6994 break;
6995 }
6996 label_ctx = TREE_CHAIN (label_ctx);
6997 }
6998 }
6999
7000 if (exit_p)
7001 error ("invalid exit from OpenMP structured block");
7002 else
7003 error ("invalid entry to OpenMP structured block");
7004 #endif
7005
7006 /* If it's obvious we have an invalid entry, be specific about the error. */
7007 if (branch_ctx == NULL)
7008 error ("invalid entry to OpenMP structured block");
7009 else
7010 /* Otherwise, be vague and lazy, but efficient. */
7011 error ("invalid branch to/from an OpenMP structured block");
7012
7013 gsi_replace (gsi_p, gimple_build_nop (), false);
7014 return true;
7015 }
7016
7017 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
7018 where each label is found. */
7019
7020 static tree
7021 diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
7022 struct walk_stmt_info *wi)
7023 {
7024 gimple context = (gimple) wi->info;
7025 gimple inner_context;
7026 gimple stmt = gsi_stmt (*gsi_p);
7027
7028 *handled_ops_p = true;
7029
7030 switch (gimple_code (stmt))
7031 {
7032 WALK_SUBSTMTS;
7033
7034 case GIMPLE_OMP_PARALLEL:
7035 case GIMPLE_OMP_TASK:
7036 case GIMPLE_OMP_SECTIONS:
7037 case GIMPLE_OMP_SINGLE:
7038 case GIMPLE_OMP_SECTION:
7039 case GIMPLE_OMP_MASTER:
7040 case GIMPLE_OMP_ORDERED:
7041 case GIMPLE_OMP_CRITICAL:
7042 /* The minimal context here is just the current OMP construct. */
7043 inner_context = stmt;
7044 wi->info = inner_context;
7045 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
7046 wi->info = context;
7047 break;
7048
7049 case GIMPLE_OMP_FOR:
7050 inner_context = stmt;
7051 wi->info = inner_context;
7052 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7053 walk them. */
7054 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
7055 diagnose_sb_1, NULL, wi);
7056 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
7057 wi->info = context;
7058 break;
7059
7060 case GIMPLE_LABEL:
7061 splay_tree_insert (all_labels, (splay_tree_key) gimple_label_label (stmt),
7062 (splay_tree_value) context);
7063 break;
7064
7065 default:
7066 break;
7067 }
7068
7069 return NULL_TREE;
7070 }
7071
7072 /* Pass 2: Check each branch and see if its context differs from that of
7073 the destination label's context. */
7074
7075 static tree
7076 diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
7077 struct walk_stmt_info *wi)
7078 {
7079 gimple context = (gimple) wi->info;
7080 splay_tree_node n;
7081 gimple stmt = gsi_stmt (*gsi_p);
7082
7083 *handled_ops_p = true;
7084
7085 switch (gimple_code (stmt))
7086 {
7087 WALK_SUBSTMTS;
7088
7089 case GIMPLE_OMP_PARALLEL:
7090 case GIMPLE_OMP_TASK:
7091 case GIMPLE_OMP_SECTIONS:
7092 case GIMPLE_OMP_SINGLE:
7093 case GIMPLE_OMP_SECTION:
7094 case GIMPLE_OMP_MASTER:
7095 case GIMPLE_OMP_ORDERED:
7096 case GIMPLE_OMP_CRITICAL:
7097 wi->info = stmt;
7098 walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
7099 wi->info = context;
7100 break;
7101
7102 case GIMPLE_OMP_FOR:
7103 wi->info = stmt;
7104 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7105 walk them. */
7106 walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt),
7107 diagnose_sb_2, NULL, wi);
7108 walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
7109 wi->info = context;
7110 break;
7111
7112 case GIMPLE_COND:
7113 {
7114 tree lab = gimple_cond_true_label (stmt);
7115 if (lab)
7116 {
7117 n = splay_tree_lookup (all_labels,
7118 (splay_tree_key) lab);
7119 diagnose_sb_0 (gsi_p, context,
7120 n ? (gimple) n->value : NULL);
7121 }
7122 lab = gimple_cond_false_label (stmt);
7123 if (lab)
7124 {
7125 n = splay_tree_lookup (all_labels,
7126 (splay_tree_key) lab);
7127 diagnose_sb_0 (gsi_p, context,
7128 n ? (gimple) n->value : NULL);
7129 }
7130 }
7131 break;
7132
7133 case GIMPLE_GOTO:
7134 {
7135 tree lab = gimple_goto_dest (stmt);
7136 if (TREE_CODE (lab) != LABEL_DECL)
7137 break;
7138
7139 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
7140 diagnose_sb_0 (gsi_p, context, n ? (gimple) n->value : NULL);
7141 }
7142 break;
7143
7144 case GIMPLE_SWITCH:
7145 {
7146 unsigned int i;
7147 for (i = 0; i < gimple_switch_num_labels (stmt); ++i)
7148 {
7149 tree lab = CASE_LABEL (gimple_switch_label (stmt, i));
7150 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
7151 if (n && diagnose_sb_0 (gsi_p, context, (gimple) n->value))
7152 break;
7153 }
7154 }
7155 break;
7156
7157 case GIMPLE_RETURN:
7158 diagnose_sb_0 (gsi_p, context, NULL);
7159 break;
7160
7161 default:
7162 break;
7163 }
7164
7165 return NULL_TREE;
7166 }
7167
7168 static unsigned int
7169 diagnose_omp_structured_block_errors (void)
7170 {
7171 struct walk_stmt_info wi;
7172 gimple_seq body = gimple_body (current_function_decl);
7173
7174 all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
7175
7176 memset (&wi, 0, sizeof (wi));
7177 walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);
7178
7179 memset (&wi, 0, sizeof (wi));
7180 wi.want_locations = true;
7181 walk_gimple_seq_mod (&body, diagnose_sb_2, NULL, &wi);
7182
7183 gimple_set_body (current_function_decl, body);
7184
7185 splay_tree_delete (all_labels);
7186 all_labels = NULL;
7187
7188 return 0;
7189 }
7190
7191 static bool
7192 gate_diagnose_omp_blocks (void)
7193 {
7194 return flag_openmp != 0;
7195 }
7196
7197 struct gimple_opt_pass pass_diagnose_omp_blocks =
7198 {
7199 {
7200 GIMPLE_PASS,
7201 "*diagnose_omp_blocks", /* name */
7202 OPTGROUP_NONE, /* optinfo_flags */
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"