]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/omp-low.c
decl.c, [...]: Remove redundant enum from machine_mode.
[thirdparty/gcc.git] / gcc / omp-low.c
CommitLineData
953ff289
DN
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
23a5b65a 6 Copyright (C) 2005-2014 Free Software Foundation, Inc.
953ff289
DN
7
8This file is part of GCC.
9
10GCC is free software; you can redistribute it and/or modify it under
11the terms of the GNU General Public License as published by the Free
9dcd6f09 12Software Foundation; either version 3, or (at your option) any later
953ff289
DN
13version.
14
15GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16WARRANTY; without even the implied warranty of MERCHANTABILITY or
17FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18for more details.
19
20You should have received a copy of the GNU General Public License
9dcd6f09
NC
21along with GCC; see the file COPYING3. If not see
22<http://www.gnu.org/licenses/>. */
953ff289
DN
23
24#include "config.h"
25#include "system.h"
26#include "coretypes.h"
27#include "tm.h"
28#include "tree.h"
d8a2d370
DN
29#include "stringpool.h"
30#include "stor-layout.h"
953ff289 31#include "rtl.h"
60393bbc
AM
32#include "predict.h"
33#include "vec.h"
34#include "hashtab.h"
35#include "hash-set.h"
36#include "machmode.h"
37#include "hard-reg-set.h"
38#include "input.h"
39#include "function.h"
40#include "dominance.h"
41#include "cfg.h"
42#include "cfganal.h"
2fb9a547
AM
43#include "basic-block.h"
44#include "tree-ssa-alias.h"
45#include "internal-fn.h"
46#include "gimple-fold.h"
47#include "gimple-expr.h"
48#include "is-a.h"
18f429e2 49#include "gimple.h"
45b0be94 50#include "gimplify.h"
5be5c238 51#include "gimple-iterator.h"
18f429e2 52#include "gimplify-me.h"
5be5c238 53#include "gimple-walk.h"
726a989a 54#include "tree-iterator.h"
953ff289
DN
55#include "tree-inline.h"
56#include "langhooks.h"
1da2ed5f 57#include "diagnostic-core.h"
442b4905 58#include "gimple-ssa.h"
c582198b
AM
59#include "hash-map.h"
60#include "plugin-api.h"
61#include "ipa-ref.h"
442b4905
AM
62#include "cgraph.h"
63#include "tree-cfg.h"
64#include "tree-phinodes.h"
65#include "ssa-iterators.h"
66#include "tree-ssanames.h"
67#include "tree-into-ssa.h"
d8a2d370 68#include "expr.h"
442b4905 69#include "tree-dfa.h"
7a300452 70#include "tree-ssa.h"
953ff289 71#include "flags.h"
953ff289 72#include "expr.h"
953ff289 73#include "tree-pass.h"
953ff289 74#include "except.h"
6be42dd4 75#include "splay-tree.h"
a509ebb5
RL
76#include "optabs.h"
77#include "cfgloop.h"
74bf76ed 78#include "target.h"
0645c1a2 79#include "omp-low.h"
4484a35a
AM
80#include "gimple-low.h"
81#include "tree-cfgcleanup.h"
0136f8f0 82#include "pretty-print.h"
c582198b 83#include "alloc-pool.h"
0136f8f0 84#include "ipa-prop.h"
1fe37220 85#include "tree-nested.h"
0136f8f0 86#include "tree-eh.h"
9a771876 87#include "cilk.h"
953ff289 88
726a989a 89
b8698a0f 90/* Lowering of OpenMP parallel and workshare constructs proceeds in two
953ff289
DN
91 phases. The first phase scans the function looking for OMP statements
92 and then for variables that must be replaced to satisfy data sharing
93 clauses. The second phase expands code for the constructs, as well as
c0220ea4 94 re-gimplifying things when variables have been replaced with complex
953ff289
DN
95 expressions.
96
7ebaeab5
DN
97 Final code generation is done by pass_expand_omp. The flowgraph is
98 scanned for parallel regions which are then moved to a new
99 function, to be invoked by the thread library. */
953ff289 100
0645c1a2
AM
101/* Parallel region information. Every parallel and workshare
102 directive is enclosed between two markers, the OMP_* directive
103 and a corresponding OMP_RETURN statement. */
104
105struct omp_region
106{
107 /* The enclosing region. */
108 struct omp_region *outer;
109
110 /* First child region. */
111 struct omp_region *inner;
112
113 /* Next peer region. */
114 struct omp_region *next;
115
116 /* Block containing the omp directive as its last stmt. */
117 basic_block entry;
118
119 /* Block containing the OMP_RETURN as its last stmt. */
120 basic_block exit;
121
122 /* Block containing the OMP_CONTINUE as its last stmt. */
123 basic_block cont;
124
125 /* If this is a combined parallel+workshare region, this is a list
126 of additional arguments needed by the combined parallel+workshare
127 library call. */
128 vec<tree, va_gc> *ws_args;
129
130 /* The code for the omp directive of this region. */
131 enum gimple_code type;
132
133 /* Schedule kind, only used for OMP_FOR type regions. */
134 enum omp_clause_schedule_kind sched_kind;
135
136 /* True if this is a combined parallel+workshare region. */
137 bool is_combined_parallel;
138};
139
953ff289
DN
140/* Context structure. Used to store information about each parallel
141 directive in the code. */
142
143typedef struct omp_context
144{
145 /* This field must be at the beginning, as we do "inheritance": Some
146 callback functions for tree-inline.c (e.g., omp_copy_decl)
147 receive a copy_body_data pointer that is up-casted to an
148 omp_context pointer. */
149 copy_body_data cb;
150
151 /* The tree of contexts corresponding to the encountered constructs. */
152 struct omp_context *outer;
726a989a 153 gimple stmt;
953ff289 154
b8698a0f 155 /* Map variables to fields in a structure that allows communication
953ff289
DN
156 between sending and receiving threads. */
157 splay_tree field_map;
158 tree record_type;
159 tree sender_decl;
160 tree receiver_decl;
161
a68ab351
JJ
162 /* These are used just by task contexts, if task firstprivate fn is
163 needed. srecord_type is used to communicate from the thread
164 that encountered the task construct to task firstprivate fn,
165 record_type is allocated by GOMP_task, initialized by task firstprivate
166 fn and passed to the task body fn. */
167 splay_tree sfield_map;
168 tree srecord_type;
169
953ff289
DN
170 /* A chain of variables to add to the top-level block surrounding the
171 construct. In the case of a parallel, this is in the child function. */
172 tree block_vars;
173
acf0174b
JJ
174 /* Label to which GOMP_cancel{,llation_point} and explicit and implicit
175 barriers should jump to during omplower pass. */
176 tree cancel_label;
177
953ff289
DN
178 /* What to do with variables with implicitly determined sharing
179 attributes. */
180 enum omp_clause_default_kind default_kind;
181
182 /* Nesting depth of this context. Used to beautify error messages re
183 invalid gotos. The outermost ctx is depth 1, with depth 0 being
184 reserved for the main body of the function. */
185 int depth;
186
953ff289
DN
187 /* True if this parallel directive is nested within another. */
188 bool is_nested;
acf0174b
JJ
189
190 /* True if this construct can be cancelled. */
191 bool cancellable;
953ff289
DN
192} omp_context;
193
194
a68ab351
JJ
195struct omp_for_data_loop
196{
197 tree v, n1, n2, step;
198 enum tree_code cond_code;
199};
200
50674e96 201/* A structure describing the main elements of a parallel loop. */
953ff289 202
50674e96 203struct omp_for_data
953ff289 204{
a68ab351 205 struct omp_for_data_loop loop;
726a989a
RB
206 tree chunk_size;
207 gimple for_stmt;
a68ab351
JJ
208 tree pre, iter_type;
209 int collapse;
953ff289
DN
210 bool have_nowait, have_ordered;
211 enum omp_clause_schedule_kind sched_kind;
a68ab351 212 struct omp_for_data_loop *loops;
953ff289
DN
213};
214
50674e96 215
953ff289 216static splay_tree all_contexts;
a68ab351 217static int taskreg_nesting_level;
acf0174b 218static int target_nesting_level;
0645c1a2 219static struct omp_region *root_omp_region;
a68ab351 220static bitmap task_shared_vars;
5771c391 221static vec<omp_context *> taskreg_contexts;
953ff289 222
26127932 223static void scan_omp (gimple_seq *, omp_context *);
726a989a
RB
224static tree scan_omp_1_op (tree *, int *, void *);
225
226#define WALK_SUBSTMTS \
227 case GIMPLE_BIND: \
228 case GIMPLE_TRY: \
229 case GIMPLE_CATCH: \
230 case GIMPLE_EH_FILTER: \
0a35513e 231 case GIMPLE_TRANSACTION: \
726a989a
RB
232 /* The sub-statements for these should be walked. */ \
233 *handled_ops_p = false; \
234 break;
235
236/* Convenience function for calling scan_omp_1_op on tree operands. */
237
238static inline tree
239scan_omp_op (tree *tp, omp_context *ctx)
240{
241 struct walk_stmt_info wi;
242
243 memset (&wi, 0, sizeof (wi));
244 wi.info = ctx;
245 wi.want_locations = true;
246
247 return walk_tree (tp, scan_omp_1_op, &wi, NULL);
248}
249
355a7673 250static void lower_omp (gimple_seq *, omp_context *);
8ca5b2a2
JJ
251static tree lookup_decl_in_outer_ctx (tree, omp_context *);
252static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
953ff289
DN
253
254/* Find an OpenMP clause of type KIND within CLAUSES. */
255
917948d3 256tree
e0c68ce9 257find_omp_clause (tree clauses, enum omp_clause_code kind)
953ff289
DN
258{
259 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
aaf46ef9 260 if (OMP_CLAUSE_CODE (clauses) == kind)
953ff289
DN
261 return clauses;
262
263 return NULL_TREE;
264}
265
266/* Return true if CTX is for an omp parallel. */
267
268static inline bool
269is_parallel_ctx (omp_context *ctx)
270{
726a989a 271 return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL;
953ff289
DN
272}
273
50674e96 274
a68ab351
JJ
275/* Return true if CTX is for an omp task. */
276
277static inline bool
278is_task_ctx (omp_context *ctx)
279{
726a989a 280 return gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
a68ab351
JJ
281}
282
283
284/* Return true if CTX is for an omp parallel or omp task. */
285
286static inline bool
287is_taskreg_ctx (omp_context *ctx)
288{
726a989a
RB
289 return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL
290 || gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
a68ab351
JJ
291}
292
293
50674e96 294/* Return true if REGION is a combined parallel+workshare region. */
953ff289
DN
295
296static inline bool
50674e96
DN
297is_combined_parallel (struct omp_region *region)
298{
299 return region->is_combined_parallel;
300}
301
302
303/* Extract the header elements of parallel loop FOR_STMT and store
304 them into *FD. */
305
306static void
726a989a 307extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
a68ab351 308 struct omp_for_data_loop *loops)
50674e96 309{
a68ab351
JJ
310 tree t, var, *collapse_iter, *collapse_count;
311 tree count = NULL_TREE, iter_type = long_integer_type_node;
312 struct omp_for_data_loop *loop;
313 int i;
314 struct omp_for_data_loop dummy_loop;
db3927fb 315 location_t loc = gimple_location (for_stmt);
0aadce73 316 bool simd = gimple_omp_for_kind (for_stmt) & GF_OMP_FOR_SIMD;
acf0174b
JJ
317 bool distribute = gimple_omp_for_kind (for_stmt)
318 == GF_OMP_FOR_KIND_DISTRIBUTE;
50674e96
DN
319
320 fd->for_stmt = for_stmt;
321 fd->pre = NULL;
726a989a 322 fd->collapse = gimple_omp_for_collapse (for_stmt);
a68ab351
JJ
323 if (fd->collapse > 1)
324 fd->loops = loops;
325 else
326 fd->loops = &fd->loop;
50674e96 327
acf0174b
JJ
328 fd->have_nowait = distribute || simd;
329 fd->have_ordered = false;
50674e96
DN
330 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
331 fd->chunk_size = NULL_TREE;
9a771876
JJ
332 if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_CILKFOR)
333 fd->sched_kind = OMP_CLAUSE_SCHEDULE_CILKFOR;
a68ab351
JJ
334 collapse_iter = NULL;
335 collapse_count = NULL;
50674e96 336
726a989a 337 for (t = gimple_omp_for_clauses (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
aaf46ef9 338 switch (OMP_CLAUSE_CODE (t))
50674e96
DN
339 {
340 case OMP_CLAUSE_NOWAIT:
341 fd->have_nowait = true;
342 break;
343 case OMP_CLAUSE_ORDERED:
344 fd->have_ordered = true;
345 break;
346 case OMP_CLAUSE_SCHEDULE:
acf0174b 347 gcc_assert (!distribute);
50674e96
DN
348 fd->sched_kind = OMP_CLAUSE_SCHEDULE_KIND (t);
349 fd->chunk_size = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t);
350 break;
acf0174b
JJ
351 case OMP_CLAUSE_DIST_SCHEDULE:
352 gcc_assert (distribute);
353 fd->chunk_size = OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (t);
354 break;
a68ab351
JJ
355 case OMP_CLAUSE_COLLAPSE:
356 if (fd->collapse > 1)
357 {
358 collapse_iter = &OMP_CLAUSE_COLLAPSE_ITERVAR (t);
359 collapse_count = &OMP_CLAUSE_COLLAPSE_COUNT (t);
360 }
34f2124e 361 break;
50674e96
DN
362 default:
363 break;
364 }
365
a68ab351
JJ
366 /* FIXME: for now map schedule(auto) to schedule(static).
367 There should be analysis to determine whether all iterations
368 are approximately the same amount of work (then schedule(static)
1cbc62c0 369 is best) or if it varies (then schedule(dynamic,N) is better). */
a68ab351
JJ
370 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_AUTO)
371 {
372 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
373 gcc_assert (fd->chunk_size == NULL);
374 }
375 gcc_assert (fd->collapse == 1 || collapse_iter != NULL);
50674e96
DN
376 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
377 gcc_assert (fd->chunk_size == NULL);
378 else if (fd->chunk_size == NULL)
379 {
380 /* We only need to compute a default chunk size for ordered
381 static loops and dynamic loops. */
a68ab351 382 if (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
acf0174b 383 || fd->have_ordered)
50674e96
DN
384 fd->chunk_size = (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
385 ? integer_zero_node : integer_one_node;
386 }
a68ab351
JJ
387
388 for (i = 0; i < fd->collapse; i++)
389 {
390 if (fd->collapse == 1)
391 loop = &fd->loop;
392 else if (loops != NULL)
393 loop = loops + i;
394 else
395 loop = &dummy_loop;
396
726a989a 397 loop->v = gimple_omp_for_index (for_stmt, i);
a68ab351
JJ
398 gcc_assert (SSA_VAR_P (loop->v));
399 gcc_assert (TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
400 || TREE_CODE (TREE_TYPE (loop->v)) == POINTER_TYPE);
401 var = TREE_CODE (loop->v) == SSA_NAME ? SSA_NAME_VAR (loop->v) : loop->v;
726a989a 402 loop->n1 = gimple_omp_for_initial (for_stmt, i);
a68ab351 403
726a989a
RB
404 loop->cond_code = gimple_omp_for_cond (for_stmt, i);
405 loop->n2 = gimple_omp_for_final (for_stmt, i);
a68ab351
JJ
406 switch (loop->cond_code)
407 {
408 case LT_EXPR:
409 case GT_EXPR:
410 break;
c02065fc
AH
411 case NE_EXPR:
412 gcc_assert (gimple_omp_for_kind (for_stmt)
9a771876
JJ
413 == GF_OMP_FOR_KIND_CILKSIMD
414 || (gimple_omp_for_kind (for_stmt)
415 == GF_OMP_FOR_KIND_CILKFOR));
c02065fc 416 break;
a68ab351
JJ
417 case LE_EXPR:
418 if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
5d49b6a7 419 loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, 1);
a68ab351 420 else
db3927fb
AH
421 loop->n2 = fold_build2_loc (loc,
422 PLUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
a68ab351
JJ
423 build_int_cst (TREE_TYPE (loop->n2), 1));
424 loop->cond_code = LT_EXPR;
425 break;
426 case GE_EXPR:
427 if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
5d49b6a7 428 loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, -1);
a68ab351 429 else
db3927fb
AH
430 loop->n2 = fold_build2_loc (loc,
431 MINUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
a68ab351
JJ
432 build_int_cst (TREE_TYPE (loop->n2), 1));
433 loop->cond_code = GT_EXPR;
434 break;
435 default:
436 gcc_unreachable ();
437 }
438
726a989a 439 t = gimple_omp_for_incr (for_stmt, i);
a68ab351
JJ
440 gcc_assert (TREE_OPERAND (t, 0) == var);
441 switch (TREE_CODE (t))
442 {
443 case PLUS_EXPR:
a68ab351
JJ
444 loop->step = TREE_OPERAND (t, 1);
445 break;
56099f00
RG
446 case POINTER_PLUS_EXPR:
447 loop->step = fold_convert (ssizetype, TREE_OPERAND (t, 1));
448 break;
a68ab351
JJ
449 case MINUS_EXPR:
450 loop->step = TREE_OPERAND (t, 1);
db3927fb
AH
451 loop->step = fold_build1_loc (loc,
452 NEGATE_EXPR, TREE_TYPE (loop->step),
a68ab351
JJ
453 loop->step);
454 break;
455 default:
456 gcc_unreachable ();
457 }
458
acf0174b
JJ
459 if (simd
460 || (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
461 && !fd->have_ordered))
74bf76ed
JJ
462 {
463 if (fd->collapse == 1)
464 iter_type = TREE_TYPE (loop->v);
465 else if (i == 0
466 || TYPE_PRECISION (iter_type)
467 < TYPE_PRECISION (TREE_TYPE (loop->v)))
468 iter_type
469 = build_nonstandard_integer_type
acf0174b 470 (TYPE_PRECISION (TREE_TYPE (loop->v)), 1);
74bf76ed
JJ
471 }
472 else if (iter_type != long_long_unsigned_type_node)
a68ab351
JJ
473 {
474 if (POINTER_TYPE_P (TREE_TYPE (loop->v)))
475 iter_type = long_long_unsigned_type_node;
476 else if (TYPE_UNSIGNED (TREE_TYPE (loop->v))
477 && TYPE_PRECISION (TREE_TYPE (loop->v))
478 >= TYPE_PRECISION (iter_type))
479 {
480 tree n;
481
482 if (loop->cond_code == LT_EXPR)
db3927fb
AH
483 n = fold_build2_loc (loc,
484 PLUS_EXPR, TREE_TYPE (loop->v),
a68ab351
JJ
485 loop->n2, loop->step);
486 else
487 n = loop->n1;
488 if (TREE_CODE (n) != INTEGER_CST
489 || tree_int_cst_lt (TYPE_MAX_VALUE (iter_type), n))
490 iter_type = long_long_unsigned_type_node;
491 }
492 else if (TYPE_PRECISION (TREE_TYPE (loop->v))
493 > TYPE_PRECISION (iter_type))
494 {
495 tree n1, n2;
496
497 if (loop->cond_code == LT_EXPR)
498 {
499 n1 = loop->n1;
db3927fb
AH
500 n2 = fold_build2_loc (loc,
501 PLUS_EXPR, TREE_TYPE (loop->v),
a68ab351
JJ
502 loop->n2, loop->step);
503 }
504 else
505 {
db3927fb
AH
506 n1 = fold_build2_loc (loc,
507 MINUS_EXPR, TREE_TYPE (loop->v),
a68ab351
JJ
508 loop->n2, loop->step);
509 n2 = loop->n1;
510 }
511 if (TREE_CODE (n1) != INTEGER_CST
512 || TREE_CODE (n2) != INTEGER_CST
513 || !tree_int_cst_lt (TYPE_MIN_VALUE (iter_type), n1)
514 || !tree_int_cst_lt (n2, TYPE_MAX_VALUE (iter_type)))
515 iter_type = long_long_unsigned_type_node;
516 }
517 }
518
519 if (collapse_count && *collapse_count == NULL)
520 {
5a0f4dd3
JJ
521 t = fold_binary (loop->cond_code, boolean_type_node,
522 fold_convert (TREE_TYPE (loop->v), loop->n1),
523 fold_convert (TREE_TYPE (loop->v), loop->n2));
524 if (t && integer_zerop (t))
525 count = build_zero_cst (long_long_unsigned_type_node);
526 else if ((i == 0 || count != NULL_TREE)
527 && TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
528 && TREE_CONSTANT (loop->n1)
529 && TREE_CONSTANT (loop->n2)
530 && TREE_CODE (loop->step) == INTEGER_CST)
a68ab351
JJ
531 {
532 tree itype = TREE_TYPE (loop->v);
533
534 if (POINTER_TYPE_P (itype))
96f9265a 535 itype = signed_type_for (itype);
a68ab351 536 t = build_int_cst (itype, (loop->cond_code == LT_EXPR ? -1 : 1));
db3927fb
AH
537 t = fold_build2_loc (loc,
538 PLUS_EXPR, itype,
539 fold_convert_loc (loc, itype, loop->step), t);
540 t = fold_build2_loc (loc, PLUS_EXPR, itype, t,
541 fold_convert_loc (loc, itype, loop->n2));
542 t = fold_build2_loc (loc, MINUS_EXPR, itype, t,
543 fold_convert_loc (loc, itype, loop->n1));
a68ab351 544 if (TYPE_UNSIGNED (itype) && loop->cond_code == GT_EXPR)
db3927fb
AH
545 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
546 fold_build1_loc (loc, NEGATE_EXPR, itype, t),
547 fold_build1_loc (loc, NEGATE_EXPR, itype,
548 fold_convert_loc (loc, itype,
549 loop->step)));
a68ab351 550 else
db3927fb
AH
551 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
552 fold_convert_loc (loc, itype, loop->step));
553 t = fold_convert_loc (loc, long_long_unsigned_type_node, t);
a68ab351 554 if (count != NULL_TREE)
db3927fb
AH
555 count = fold_build2_loc (loc,
556 MULT_EXPR, long_long_unsigned_type_node,
a68ab351
JJ
557 count, t);
558 else
559 count = t;
560 if (TREE_CODE (count) != INTEGER_CST)
561 count = NULL_TREE;
562 }
5a0f4dd3 563 else if (count && !integer_zerop (count))
a68ab351
JJ
564 count = NULL_TREE;
565 }
566 }
567
74bf76ed 568 if (count
acf0174b
JJ
569 && !simd
570 && (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
571 || fd->have_ordered))
a68ab351
JJ
572 {
573 if (!tree_int_cst_lt (count, TYPE_MAX_VALUE (long_integer_type_node)))
574 iter_type = long_long_unsigned_type_node;
575 else
576 iter_type = long_integer_type_node;
577 }
578 else if (collapse_iter && *collapse_iter != NULL)
579 iter_type = TREE_TYPE (*collapse_iter);
580 fd->iter_type = iter_type;
581 if (collapse_iter && *collapse_iter == NULL)
582 *collapse_iter = create_tmp_var (iter_type, ".iter");
583 if (collapse_count && *collapse_count == NULL)
584 {
585 if (count)
db3927fb 586 *collapse_count = fold_convert_loc (loc, iter_type, count);
a68ab351
JJ
587 else
588 *collapse_count = create_tmp_var (iter_type, ".count");
589 }
590
591 if (fd->collapse > 1)
592 {
593 fd->loop.v = *collapse_iter;
594 fd->loop.n1 = build_int_cst (TREE_TYPE (fd->loop.v), 0);
595 fd->loop.n2 = *collapse_count;
596 fd->loop.step = build_int_cst (TREE_TYPE (fd->loop.v), 1);
597 fd->loop.cond_code = LT_EXPR;
598 }
50674e96
DN
599}
600
601
602/* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
603 is the immediate dominator of PAR_ENTRY_BB, return true if there
604 are no data dependencies that would prevent expanding the parallel
605 directive at PAR_ENTRY_BB as a combined parallel+workshare region.
606
607 When expanding a combined parallel+workshare region, the call to
608 the child function may need additional arguments in the case of
726a989a
RB
609 GIMPLE_OMP_FOR regions. In some cases, these arguments are
610 computed out of variables passed in from the parent to the child
611 via 'struct .omp_data_s'. For instance:
50674e96
DN
612
613 #pragma omp parallel for schedule (guided, i * 4)
614 for (j ...)
615
616 Is lowered into:
617
618 # BLOCK 2 (PAR_ENTRY_BB)
619 .omp_data_o.i = i;
620 #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
b8698a0f 621
50674e96
DN
622 # BLOCK 3 (WS_ENTRY_BB)
623 .omp_data_i = &.omp_data_o;
624 D.1667 = .omp_data_i->i;
625 D.1598 = D.1667 * 4;
626 #pragma omp for schedule (guided, D.1598)
627
628 When we outline the parallel region, the call to the child function
629 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
630 that value is computed *after* the call site. So, in principle we
631 cannot do the transformation.
632
633 To see whether the code in WS_ENTRY_BB blocks the combined
634 parallel+workshare call, we collect all the variables used in the
726a989a 635 GIMPLE_OMP_FOR header check whether they appear on the LHS of any
50674e96
DN
636 statement in WS_ENTRY_BB. If so, then we cannot emit the combined
637 call.
638
639 FIXME. If we had the SSA form built at this point, we could merely
640 hoist the code in block 3 into block 2 and be done with it. But at
641 this point we don't have dataflow information and though we could
642 hack something up here, it is really not worth the aggravation. */
643
644static bool
0f900dfa 645workshare_safe_to_combine_p (basic_block ws_entry_bb)
50674e96
DN
646{
647 struct omp_for_data fd;
0f900dfa 648 gimple ws_stmt = last_stmt (ws_entry_bb);
50674e96 649
726a989a 650 if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
50674e96
DN
651 return true;
652
726a989a 653 gcc_assert (gimple_code (ws_stmt) == GIMPLE_OMP_FOR);
50674e96 654
a68ab351
JJ
655 extract_omp_for_data (ws_stmt, &fd, NULL);
656
657 if (fd.collapse > 1 && TREE_CODE (fd.loop.n2) != INTEGER_CST)
658 return false;
659 if (fd.iter_type != long_integer_type_node)
660 return false;
50674e96
DN
661
662 /* FIXME. We give up too easily here. If any of these arguments
663 are not constants, they will likely involve variables that have
664 been mapped into fields of .omp_data_s for sharing with the child
665 function. With appropriate data flow, it would be possible to
666 see through this. */
a68ab351
JJ
667 if (!is_gimple_min_invariant (fd.loop.n1)
668 || !is_gimple_min_invariant (fd.loop.n2)
669 || !is_gimple_min_invariant (fd.loop.step)
50674e96
DN
670 || (fd.chunk_size && !is_gimple_min_invariant (fd.chunk_size)))
671 return false;
672
673 return true;
674}
675
676
677/* Collect additional arguments needed to emit a combined
678 parallel+workshare call. WS_STMT is the workshare directive being
679 expanded. */
680
9771b263 681static vec<tree, va_gc> *
acf0174b 682get_ws_args_for (gimple par_stmt, gimple ws_stmt)
50674e96
DN
683{
684 tree t;
db3927fb 685 location_t loc = gimple_location (ws_stmt);
9771b263 686 vec<tree, va_gc> *ws_args;
50674e96 687
726a989a 688 if (gimple_code (ws_stmt) == GIMPLE_OMP_FOR)
50674e96
DN
689 {
690 struct omp_for_data fd;
acf0174b 691 tree n1, n2;
50674e96 692
a68ab351 693 extract_omp_for_data (ws_stmt, &fd, NULL);
acf0174b
JJ
694 n1 = fd.loop.n1;
695 n2 = fd.loop.n2;
696
697 if (gimple_omp_for_combined_into_p (ws_stmt))
698 {
699 tree innerc
700 = find_omp_clause (gimple_omp_parallel_clauses (par_stmt),
701 OMP_CLAUSE__LOOPTEMP_);
702 gcc_assert (innerc);
703 n1 = OMP_CLAUSE_DECL (innerc);
704 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
705 OMP_CLAUSE__LOOPTEMP_);
706 gcc_assert (innerc);
707 n2 = OMP_CLAUSE_DECL (innerc);
708 }
50674e96 709
9771b263 710 vec_alloc (ws_args, 3 + (fd.chunk_size != 0));
50674e96 711
acf0174b 712 t = fold_convert_loc (loc, long_integer_type_node, n1);
9771b263 713 ws_args->quick_push (t);
50674e96 714
acf0174b 715 t = fold_convert_loc (loc, long_integer_type_node, n2);
9771b263 716 ws_args->quick_push (t);
50674e96 717
3bb06db4 718 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.step);
9771b263 719 ws_args->quick_push (t);
3bb06db4
NF
720
721 if (fd.chunk_size)
722 {
723 t = fold_convert_loc (loc, long_integer_type_node, fd.chunk_size);
9771b263 724 ws_args->quick_push (t);
3bb06db4 725 }
50674e96
DN
726
727 return ws_args;
728 }
726a989a 729 else if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
50674e96 730 {
e5c95afe 731 /* Number of sections is equal to the number of edges from the
726a989a
RB
732 GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
733 the exit of the sections region. */
734 basic_block bb = single_succ (gimple_bb (ws_stmt));
e5c95afe 735 t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
9771b263
DN
736 vec_alloc (ws_args, 1);
737 ws_args->quick_push (t);
3bb06db4 738 return ws_args;
50674e96
DN
739 }
740
741 gcc_unreachable ();
742}
743
744
745/* Discover whether REGION is a combined parallel+workshare region. */
746
747static void
748determine_parallel_type (struct omp_region *region)
953ff289 749{
50674e96
DN
750 basic_block par_entry_bb, par_exit_bb;
751 basic_block ws_entry_bb, ws_exit_bb;
752
d3c673c7 753 if (region == NULL || region->inner == NULL
e5c95afe
ZD
754 || region->exit == NULL || region->inner->exit == NULL
755 || region->inner->cont == NULL)
50674e96
DN
756 return;
757
758 /* We only support parallel+for and parallel+sections. */
726a989a
RB
759 if (region->type != GIMPLE_OMP_PARALLEL
760 || (region->inner->type != GIMPLE_OMP_FOR
761 && region->inner->type != GIMPLE_OMP_SECTIONS))
50674e96
DN
762 return;
763
764 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
765 WS_EXIT_BB -> PAR_EXIT_BB. */
777f7f9a
RH
766 par_entry_bb = region->entry;
767 par_exit_bb = region->exit;
768 ws_entry_bb = region->inner->entry;
769 ws_exit_bb = region->inner->exit;
50674e96
DN
770
771 if (single_succ (par_entry_bb) == ws_entry_bb
772 && single_succ (ws_exit_bb) == par_exit_bb
0f900dfa 773 && workshare_safe_to_combine_p (ws_entry_bb)
726a989a 774 && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb))
69f1837b
JJ
775 || (last_and_only_stmt (ws_entry_bb)
776 && last_and_only_stmt (par_exit_bb))))
50674e96 777 {
acf0174b 778 gimple par_stmt = last_stmt (par_entry_bb);
726a989a 779 gimple ws_stmt = last_stmt (ws_entry_bb);
777f7f9a 780
726a989a 781 if (region->inner->type == GIMPLE_OMP_FOR)
50674e96
DN
782 {
783 /* If this is a combined parallel loop, we need to determine
784 whether or not to use the combined library calls. There
785 are two cases where we do not apply the transformation:
786 static loops and any kind of ordered loop. In the first
787 case, we already open code the loop so there is no need
788 to do anything else. In the latter case, the combined
789 parallel loop call would still need extra synchronization
790 to implement ordered semantics, so there would not be any
791 gain in using the combined call. */
726a989a 792 tree clauses = gimple_omp_for_clauses (ws_stmt);
50674e96
DN
793 tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
794 if (c == NULL
795 || OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_STATIC
796 || find_omp_clause (clauses, OMP_CLAUSE_ORDERED))
797 {
798 region->is_combined_parallel = false;
799 region->inner->is_combined_parallel = false;
800 return;
801 }
802 }
803
804 region->is_combined_parallel = true;
805 region->inner->is_combined_parallel = true;
acf0174b 806 region->ws_args = get_ws_args_for (par_stmt, ws_stmt);
50674e96 807 }
953ff289
DN
808}
809
50674e96 810
953ff289
DN
811/* Return true if EXPR is variable sized. */
812
813static inline bool
22ea9ec0 814is_variable_sized (const_tree expr)
953ff289
DN
815{
816 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
817}
818
819/* Return true if DECL is a reference type. */
820
821static inline bool
822is_reference (tree decl)
823{
824 return lang_hooks.decls.omp_privatize_by_reference (decl);
825}
826
827/* Lookup variables in the decl or field splay trees. The "maybe" form
828 allows for the variable form to not have been entered, otherwise we
829 assert that the variable must have been entered. */
830
831static inline tree
832lookup_decl (tree var, omp_context *ctx)
833{
b787e7a2 834 tree *n = ctx->cb.decl_map->get (var);
6be42dd4 835 return *n;
953ff289
DN
836}
837
838static inline tree
7c8f7639 839maybe_lookup_decl (const_tree var, omp_context *ctx)
953ff289 840{
b787e7a2 841 tree *n = ctx->cb.decl_map->get (const_cast<tree> (var));
6be42dd4 842 return n ? *n : NULL_TREE;
953ff289
DN
843}
844
845static inline tree
846lookup_field (tree var, omp_context *ctx)
847{
848 splay_tree_node n;
849 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
850 return (tree) n->value;
851}
852
a68ab351
JJ
853static inline tree
854lookup_sfield (tree var, omp_context *ctx)
855{
856 splay_tree_node n;
857 n = splay_tree_lookup (ctx->sfield_map
858 ? ctx->sfield_map : ctx->field_map,
859 (splay_tree_key) var);
860 return (tree) n->value;
861}
862
953ff289
DN
863static inline tree
864maybe_lookup_field (tree var, omp_context *ctx)
865{
866 splay_tree_node n;
867 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
868 return n ? (tree) n->value : NULL_TREE;
869}
870
7c8f7639
JJ
871/* Return true if DECL should be copied by pointer. SHARED_CTX is
872 the parallel context if DECL is to be shared. */
953ff289
DN
873
874static bool
a68ab351 875use_pointer_for_field (tree decl, omp_context *shared_ctx)
953ff289
DN
876{
877 if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
878 return true;
879
6fc0bb99 880 /* We can only use copy-in/copy-out semantics for shared variables
953ff289 881 when we know the value is not accessible from an outer scope. */
7c8f7639 882 if (shared_ctx)
953ff289
DN
883 {
884 /* ??? Trivially accessible from anywhere. But why would we even
885 be passing an address in this case? Should we simply assert
886 this to be false, or should we have a cleanup pass that removes
887 these from the list of mappings? */
888 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
889 return true;
890
891 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
892 without analyzing the expression whether or not its location
893 is accessible to anyone else. In the case of nested parallel
894 regions it certainly may be. */
077b0dfb 895 if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
953ff289
DN
896 return true;
897
898 /* Do not use copy-in/copy-out for variables that have their
899 address taken. */
900 if (TREE_ADDRESSABLE (decl))
901 return true;
7c8f7639 902
6d840d99
JJ
903 /* lower_send_shared_vars only uses copy-in, but not copy-out
904 for these. */
905 if (TREE_READONLY (decl)
906 || ((TREE_CODE (decl) == RESULT_DECL
907 || TREE_CODE (decl) == PARM_DECL)
908 && DECL_BY_REFERENCE (decl)))
909 return false;
910
7c8f7639
JJ
911 /* Disallow copy-in/out in nested parallel if
912 decl is shared in outer parallel, otherwise
913 each thread could store the shared variable
914 in its own copy-in location, making the
915 variable no longer really shared. */
6d840d99 916 if (shared_ctx->is_nested)
7c8f7639
JJ
917 {
918 omp_context *up;
919
920 for (up = shared_ctx->outer; up; up = up->outer)
d9c194cb 921 if (is_taskreg_ctx (up) && maybe_lookup_decl (decl, up))
7c8f7639
JJ
922 break;
923
d9c194cb 924 if (up)
7c8f7639
JJ
925 {
926 tree c;
927
726a989a 928 for (c = gimple_omp_taskreg_clauses (up->stmt);
7c8f7639
JJ
929 c; c = OMP_CLAUSE_CHAIN (c))
930 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
931 && OMP_CLAUSE_DECL (c) == decl)
932 break;
933
934 if (c)
25142650 935 goto maybe_mark_addressable_and_ret;
7c8f7639
JJ
936 }
937 }
a68ab351 938
6d840d99 939 /* For tasks avoid using copy-in/out. As tasks can be
a68ab351
JJ
940 deferred or executed in different thread, when GOMP_task
941 returns, the task hasn't necessarily terminated. */
6d840d99 942 if (is_task_ctx (shared_ctx))
a68ab351 943 {
25142650
JJ
944 tree outer;
945 maybe_mark_addressable_and_ret:
946 outer = maybe_lookup_decl_in_outer_ctx (decl, shared_ctx);
a68ab351
JJ
947 if (is_gimple_reg (outer))
948 {
949 /* Taking address of OUTER in lower_send_shared_vars
950 might need regimplification of everything that uses the
951 variable. */
952 if (!task_shared_vars)
953 task_shared_vars = BITMAP_ALLOC (NULL);
954 bitmap_set_bit (task_shared_vars, DECL_UID (outer));
955 TREE_ADDRESSABLE (outer) = 1;
956 }
957 return true;
958 }
953ff289
DN
959 }
960
961 return false;
962}
963
917948d3
ZD
964/* Construct a new automatic decl similar to VAR. */
965
966static tree
967omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
968{
969 tree copy = copy_var_decl (var, name, type);
970
971 DECL_CONTEXT (copy) = current_function_decl;
910ad8de 972 DECL_CHAIN (copy) = ctx->block_vars;
953ff289
DN
973 ctx->block_vars = copy;
974
975 return copy;
976}
977
978static tree
979omp_copy_decl_1 (tree var, omp_context *ctx)
980{
981 return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
982}
983
a9a58711
JJ
984/* Build COMPONENT_REF and set TREE_THIS_VOLATILE and TREE_READONLY on it
985 as appropriate. */
986static tree
987omp_build_component_ref (tree obj, tree field)
988{
989 tree ret = build3 (COMPONENT_REF, TREE_TYPE (field), obj, field, NULL);
990 if (TREE_THIS_VOLATILE (field))
991 TREE_THIS_VOLATILE (ret) |= 1;
992 if (TREE_READONLY (field))
993 TREE_READONLY (ret) |= 1;
994 return ret;
995}
996
953ff289
DN
997/* Build tree nodes to access the field for VAR on the receiver side. */
998
999static tree
1000build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
1001{
1002 tree x, field = lookup_field (var, ctx);
1003
1004 /* If the receiver record type was remapped in the child function,
1005 remap the field into the new record type. */
1006 x = maybe_lookup_field (field, ctx);
1007 if (x != NULL)
1008 field = x;
1009
70f34814 1010 x = build_simple_mem_ref (ctx->receiver_decl);
a9a58711 1011 x = omp_build_component_ref (x, field);
953ff289 1012 if (by_ref)
70f34814 1013 x = build_simple_mem_ref (x);
953ff289
DN
1014
1015 return x;
1016}
1017
1018/* Build tree nodes to access VAR in the scope outer to CTX. In the case
1019 of a parallel, this is a component reference; for workshare constructs
1020 this is some variable. */
1021
1022static tree
1023build_outer_var_ref (tree var, omp_context *ctx)
1024{
1025 tree x;
1026
8ca5b2a2 1027 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
953ff289
DN
1028 x = var;
1029 else if (is_variable_sized (var))
1030 {
1031 x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
1032 x = build_outer_var_ref (x, ctx);
70f34814 1033 x = build_simple_mem_ref (x);
953ff289 1034 }
a68ab351 1035 else if (is_taskreg_ctx (ctx))
953ff289 1036 {
7c8f7639 1037 bool by_ref = use_pointer_for_field (var, NULL);
953ff289
DN
1038 x = build_receiver_ref (var, by_ref, ctx);
1039 }
74bf76ed 1040 else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
0aadce73 1041 && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
74bf76ed
JJ
1042 {
1043 /* #pragma omp simd isn't a worksharing construct, and can reference even
1044 private vars in its linear etc. clauses. */
1045 x = NULL_TREE;
1046 if (ctx->outer && is_taskreg_ctx (ctx))
1047 x = lookup_decl (var, ctx->outer);
1048 else if (ctx->outer)
f3b331d1 1049 x = maybe_lookup_decl_in_outer_ctx (var, ctx);
74bf76ed
JJ
1050 if (x == NULL_TREE)
1051 x = var;
1052 }
953ff289
DN
1053 else if (ctx->outer)
1054 x = lookup_decl (var, ctx->outer);
eeb1d9e0
JJ
1055 else if (is_reference (var))
1056 /* This can happen with orphaned constructs. If var is reference, it is
1057 possible it is shared and as such valid. */
1058 x = var;
953ff289
DN
1059 else
1060 gcc_unreachable ();
1061
1062 if (is_reference (var))
70f34814 1063 x = build_simple_mem_ref (x);
953ff289
DN
1064
1065 return x;
1066}
1067
1068/* Build tree nodes to access the field for VAR on the sender side. */
1069
1070static tree
1071build_sender_ref (tree var, omp_context *ctx)
1072{
a68ab351 1073 tree field = lookup_sfield (var, ctx);
a9a58711 1074 return omp_build_component_ref (ctx->sender_decl, field);
953ff289
DN
1075}
1076
1077/* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
1078
1079static void
a68ab351 1080install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
953ff289 1081{
a68ab351 1082 tree field, type, sfield = NULL_TREE;
953ff289 1083
a68ab351
JJ
1084 gcc_assert ((mask & 1) == 0
1085 || !splay_tree_lookup (ctx->field_map, (splay_tree_key) var));
1086 gcc_assert ((mask & 2) == 0 || !ctx->sfield_map
1087 || !splay_tree_lookup (ctx->sfield_map, (splay_tree_key) var));
953ff289
DN
1088
1089 type = TREE_TYPE (var);
acf0174b
JJ
1090 if (mask & 4)
1091 {
1092 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
1093 type = build_pointer_type (build_pointer_type (type));
1094 }
1095 else if (by_ref)
953ff289 1096 type = build_pointer_type (type);
a68ab351
JJ
1097 else if ((mask & 3) == 1 && is_reference (var))
1098 type = TREE_TYPE (type);
953ff289 1099
c2255bc4
AH
1100 field = build_decl (DECL_SOURCE_LOCATION (var),
1101 FIELD_DECL, DECL_NAME (var), type);
953ff289
DN
1102
1103 /* Remember what variable this field was created for. This does have a
1104 side effect of making dwarf2out ignore this member, so for helpful
1105 debugging we clear it later in delete_omp_context. */
1106 DECL_ABSTRACT_ORIGIN (field) = var;
a68ab351
JJ
1107 if (type == TREE_TYPE (var))
1108 {
1109 DECL_ALIGN (field) = DECL_ALIGN (var);
1110 DECL_USER_ALIGN (field) = DECL_USER_ALIGN (var);
1111 TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (var);
1112 }
1113 else
1114 DECL_ALIGN (field) = TYPE_ALIGN (type);
953ff289 1115
a68ab351
JJ
1116 if ((mask & 3) == 3)
1117 {
1118 insert_field_into_struct (ctx->record_type, field);
1119 if (ctx->srecord_type)
1120 {
c2255bc4
AH
1121 sfield = build_decl (DECL_SOURCE_LOCATION (var),
1122 FIELD_DECL, DECL_NAME (var), type);
a68ab351
JJ
1123 DECL_ABSTRACT_ORIGIN (sfield) = var;
1124 DECL_ALIGN (sfield) = DECL_ALIGN (field);
1125 DECL_USER_ALIGN (sfield) = DECL_USER_ALIGN (field);
1126 TREE_THIS_VOLATILE (sfield) = TREE_THIS_VOLATILE (field);
1127 insert_field_into_struct (ctx->srecord_type, sfield);
1128 }
1129 }
1130 else
1131 {
1132 if (ctx->srecord_type == NULL_TREE)
1133 {
1134 tree t;
1135
1136 ctx->srecord_type = lang_hooks.types.make_type (RECORD_TYPE);
1137 ctx->sfield_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1138 for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
1139 {
c2255bc4
AH
1140 sfield = build_decl (DECL_SOURCE_LOCATION (var),
1141 FIELD_DECL, DECL_NAME (t), TREE_TYPE (t));
a68ab351
JJ
1142 DECL_ABSTRACT_ORIGIN (sfield) = DECL_ABSTRACT_ORIGIN (t);
1143 insert_field_into_struct (ctx->srecord_type, sfield);
1144 splay_tree_insert (ctx->sfield_map,
1145 (splay_tree_key) DECL_ABSTRACT_ORIGIN (t),
1146 (splay_tree_value) sfield);
1147 }
1148 }
1149 sfield = field;
1150 insert_field_into_struct ((mask & 1) ? ctx->record_type
1151 : ctx->srecord_type, field);
1152 }
953ff289 1153
a68ab351
JJ
1154 if (mask & 1)
1155 splay_tree_insert (ctx->field_map, (splay_tree_key) var,
1156 (splay_tree_value) field);
1157 if ((mask & 2) && ctx->sfield_map)
1158 splay_tree_insert (ctx->sfield_map, (splay_tree_key) var,
1159 (splay_tree_value) sfield);
953ff289
DN
1160}
1161
1162static tree
1163install_var_local (tree var, omp_context *ctx)
1164{
1165 tree new_var = omp_copy_decl_1 (var, ctx);
1166 insert_decl_map (&ctx->cb, var, new_var);
1167 return new_var;
1168}
1169
1170/* Adjust the replacement for DECL in CTX for the new context. This means
1171 copying the DECL_VALUE_EXPR, and fixing up the type. */
1172
1173static void
1174fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
1175{
1176 tree new_decl, size;
1177
1178 new_decl = lookup_decl (decl, ctx);
1179
1180 TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
1181
1182 if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
1183 && DECL_HAS_VALUE_EXPR_P (decl))
1184 {
1185 tree ve = DECL_VALUE_EXPR (decl);
726a989a 1186 walk_tree (&ve, copy_tree_body_r, &ctx->cb, NULL);
953ff289
DN
1187 SET_DECL_VALUE_EXPR (new_decl, ve);
1188 DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
1189 }
1190
1191 if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
1192 {
1193 size = remap_decl (DECL_SIZE (decl), &ctx->cb);
1194 if (size == error_mark_node)
1195 size = TYPE_SIZE (TREE_TYPE (new_decl));
1196 DECL_SIZE (new_decl) = size;
1197
1198 size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
1199 if (size == error_mark_node)
1200 size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
1201 DECL_SIZE_UNIT (new_decl) = size;
1202 }
1203}
1204
1205/* The callback for remap_decl. Search all containing contexts for a
1206 mapping of the variable; this avoids having to duplicate the splay
1207 tree ahead of time. We know a mapping doesn't already exist in the
1208 given context. Create new mappings to implement default semantics. */
1209
1210static tree
1211omp_copy_decl (tree var, copy_body_data *cb)
1212{
1213 omp_context *ctx = (omp_context *) cb;
1214 tree new_var;
1215
953ff289
DN
1216 if (TREE_CODE (var) == LABEL_DECL)
1217 {
c2255bc4 1218 new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
50674e96 1219 DECL_CONTEXT (new_var) = current_function_decl;
953ff289
DN
1220 insert_decl_map (&ctx->cb, var, new_var);
1221 return new_var;
1222 }
1223
a68ab351 1224 while (!is_taskreg_ctx (ctx))
953ff289
DN
1225 {
1226 ctx = ctx->outer;
1227 if (ctx == NULL)
1228 return var;
1229 new_var = maybe_lookup_decl (var, ctx);
1230 if (new_var)
1231 return new_var;
1232 }
1233
8ca5b2a2
JJ
1234 if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
1235 return var;
1236
953ff289
DN
1237 return error_mark_node;
1238}
1239
50674e96 1240
50674e96
DN
1241/* Debugging dumps for parallel regions. */
1242void dump_omp_region (FILE *, struct omp_region *, int);
1243void debug_omp_region (struct omp_region *);
1244void debug_all_omp_regions (void);
1245
1246/* Dump the parallel region tree rooted at REGION. */
1247
1248void
1249dump_omp_region (FILE *file, struct omp_region *region, int indent)
1250{
777f7f9a 1251 fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
726a989a 1252 gimple_code_name[region->type]);
50674e96
DN
1253
1254 if (region->inner)
1255 dump_omp_region (file, region->inner, indent + 4);
1256
777f7f9a
RH
1257 if (region->cont)
1258 {
726a989a 1259 fprintf (file, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent, "",
777f7f9a
RH
1260 region->cont->index);
1261 }
b8698a0f 1262
50674e96 1263 if (region->exit)
726a989a 1264 fprintf (file, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent, "",
777f7f9a 1265 region->exit->index);
50674e96 1266 else
777f7f9a 1267 fprintf (file, "%*s[no exit marker]\n", indent, "");
50674e96
DN
1268
1269 if (region->next)
777f7f9a 1270 dump_omp_region (file, region->next, indent);
50674e96
DN
1271}
1272
24e47c76 1273DEBUG_FUNCTION void
50674e96
DN
1274debug_omp_region (struct omp_region *region)
1275{
1276 dump_omp_region (stderr, region, 0);
1277}
1278
24e47c76 1279DEBUG_FUNCTION void
50674e96
DN
1280debug_all_omp_regions (void)
1281{
1282 dump_omp_region (stderr, root_omp_region, 0);
1283}
1284
1285
1286/* Create a new parallel region starting at STMT inside region PARENT. */
1287
0645c1a2 1288static struct omp_region *
726a989a
RB
1289new_omp_region (basic_block bb, enum gimple_code type,
1290 struct omp_region *parent)
50674e96 1291{
d3bfe4de 1292 struct omp_region *region = XCNEW (struct omp_region);
50674e96
DN
1293
1294 region->outer = parent;
777f7f9a
RH
1295 region->entry = bb;
1296 region->type = type;
50674e96
DN
1297
1298 if (parent)
1299 {
1300 /* This is a nested region. Add it to the list of inner
1301 regions in PARENT. */
1302 region->next = parent->inner;
1303 parent->inner = region;
1304 }
777f7f9a 1305 else
50674e96
DN
1306 {
1307 /* This is a toplevel region. Add it to the list of toplevel
1308 regions in ROOT_OMP_REGION. */
1309 region->next = root_omp_region;
1310 root_omp_region = region;
1311 }
777f7f9a
RH
1312
1313 return region;
1314}
1315
1316/* Release the memory associated with the region tree rooted at REGION. */
1317
1318static void
1319free_omp_region_1 (struct omp_region *region)
1320{
1321 struct omp_region *i, *n;
1322
1323 for (i = region->inner; i ; i = n)
50674e96 1324 {
777f7f9a
RH
1325 n = i->next;
1326 free_omp_region_1 (i);
50674e96
DN
1327 }
1328
777f7f9a
RH
1329 free (region);
1330}
50674e96 1331
777f7f9a
RH
1332/* Release the memory for the entire omp region tree. */
1333
1334void
1335free_omp_regions (void)
1336{
1337 struct omp_region *r, *n;
1338 for (r = root_omp_region; r ; r = n)
1339 {
1340 n = r->next;
1341 free_omp_region_1 (r);
1342 }
1343 root_omp_region = NULL;
50674e96
DN
1344}
1345
1346
953ff289
DN
1347/* Create a new context, with OUTER_CTX being the surrounding context. */
1348
1349static omp_context *
726a989a 1350new_omp_context (gimple stmt, omp_context *outer_ctx)
953ff289
DN
1351{
1352 omp_context *ctx = XCNEW (omp_context);
1353
1354 splay_tree_insert (all_contexts, (splay_tree_key) stmt,
1355 (splay_tree_value) ctx);
1356 ctx->stmt = stmt;
1357
1358 if (outer_ctx)
1359 {
1360 ctx->outer = outer_ctx;
1361 ctx->cb = outer_ctx->cb;
1362 ctx->cb.block = NULL;
1363 ctx->depth = outer_ctx->depth + 1;
1364 }
1365 else
1366 {
1367 ctx->cb.src_fn = current_function_decl;
1368 ctx->cb.dst_fn = current_function_decl;
d52f5295 1369 ctx->cb.src_node = cgraph_node::get (current_function_decl);
fe660d7b 1370 gcc_checking_assert (ctx->cb.src_node);
953ff289
DN
1371 ctx->cb.dst_node = ctx->cb.src_node;
1372 ctx->cb.src_cfun = cfun;
1373 ctx->cb.copy_decl = omp_copy_decl;
1d65f45c 1374 ctx->cb.eh_lp_nr = 0;
953ff289
DN
1375 ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
1376 ctx->depth = 1;
1377 }
1378
b787e7a2 1379 ctx->cb.decl_map = new hash_map<tree, tree>;
953ff289
DN
1380
1381 return ctx;
1382}
1383
726a989a 1384static gimple_seq maybe_catch_exception (gimple_seq);
2368a460
JJ
1385
1386/* Finalize task copyfn. */
1387
1388static void
726a989a 1389finalize_task_copyfn (gimple task_stmt)
2368a460
JJ
1390{
1391 struct function *child_cfun;
af16bc76 1392 tree child_fn;
355a7673 1393 gimple_seq seq = NULL, new_seq;
726a989a 1394 gimple bind;
2368a460 1395
726a989a 1396 child_fn = gimple_omp_task_copy_fn (task_stmt);
2368a460
JJ
1397 if (child_fn == NULL_TREE)
1398 return;
1399
1400 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
d7ed20db 1401 DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
2368a460 1402
2368a460 1403 push_cfun (child_cfun);
3ad065ef 1404 bind = gimplify_body (child_fn, false);
726a989a
RB
1405 gimple_seq_add_stmt (&seq, bind);
1406 new_seq = maybe_catch_exception (seq);
1407 if (new_seq != seq)
1408 {
1409 bind = gimple_build_bind (NULL, new_seq, NULL);
355a7673 1410 seq = NULL;
726a989a
RB
1411 gimple_seq_add_stmt (&seq, bind);
1412 }
1413 gimple_set_body (child_fn, seq);
2368a460 1414 pop_cfun ();
2368a460 1415
d7ed20db 1416 /* Inform the callgraph about the new function. */
d52f5295 1417 cgraph_node::add_new_function (child_fn, false);
2368a460
JJ
1418}
1419
953ff289
DN
1420/* Destroy a omp_context data structures. Called through the splay tree
1421 value delete callback. */
1422
1423static void
1424delete_omp_context (splay_tree_value value)
1425{
1426 omp_context *ctx = (omp_context *) value;
1427
b787e7a2 1428 delete ctx->cb.decl_map;
953ff289
DN
1429
1430 if (ctx->field_map)
1431 splay_tree_delete (ctx->field_map);
a68ab351
JJ
1432 if (ctx->sfield_map)
1433 splay_tree_delete (ctx->sfield_map);
953ff289
DN
1434
1435 /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
1436 it produces corrupt debug information. */
1437 if (ctx->record_type)
1438 {
1439 tree t;
910ad8de 1440 for (t = TYPE_FIELDS (ctx->record_type); t ; t = DECL_CHAIN (t))
953ff289
DN
1441 DECL_ABSTRACT_ORIGIN (t) = NULL;
1442 }
a68ab351
JJ
1443 if (ctx->srecord_type)
1444 {
1445 tree t;
910ad8de 1446 for (t = TYPE_FIELDS (ctx->srecord_type); t ; t = DECL_CHAIN (t))
a68ab351
JJ
1447 DECL_ABSTRACT_ORIGIN (t) = NULL;
1448 }
953ff289 1449
2368a460
JJ
1450 if (is_task_ctx (ctx))
1451 finalize_task_copyfn (ctx->stmt);
1452
953ff289
DN
1453 XDELETE (ctx);
1454}
1455
1456/* Fix up RECEIVER_DECL with a type that has been remapped to the child
1457 context. */
1458
1459static void
1460fixup_child_record_type (omp_context *ctx)
1461{
1462 tree f, type = ctx->record_type;
1463
1464 /* ??? It isn't sufficient to just call remap_type here, because
1465 variably_modified_type_p doesn't work the way we expect for
1466 record types. Testing each field for whether it needs remapping
1467 and creating a new record by hand works, however. */
910ad8de 1468 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
953ff289
DN
1469 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
1470 break;
1471 if (f)
1472 {
1473 tree name, new_fields = NULL;
1474
1475 type = lang_hooks.types.make_type (RECORD_TYPE);
1476 name = DECL_NAME (TYPE_NAME (ctx->record_type));
c2255bc4
AH
1477 name = build_decl (DECL_SOURCE_LOCATION (ctx->receiver_decl),
1478 TYPE_DECL, name, type);
953ff289
DN
1479 TYPE_NAME (type) = name;
1480
910ad8de 1481 for (f = TYPE_FIELDS (ctx->record_type); f ; f = DECL_CHAIN (f))
953ff289
DN
1482 {
1483 tree new_f = copy_node (f);
1484 DECL_CONTEXT (new_f) = type;
1485 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
910ad8de 1486 DECL_CHAIN (new_f) = new_fields;
726a989a
RB
1487 walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &ctx->cb, NULL);
1488 walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r,
1489 &ctx->cb, NULL);
1490 walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
1491 &ctx->cb, NULL);
953ff289
DN
1492 new_fields = new_f;
1493
1494 /* Arrange to be able to look up the receiver field
1495 given the sender field. */
1496 splay_tree_insert (ctx->field_map, (splay_tree_key) f,
1497 (splay_tree_value) new_f);
1498 }
1499 TYPE_FIELDS (type) = nreverse (new_fields);
1500 layout_type (type);
1501 }
1502
1503 TREE_TYPE (ctx->receiver_decl) = build_pointer_type (type);
1504}
1505
1506/* Instantiate decls as necessary in CTX to satisfy the data sharing
1507 specified by CLAUSES. */
1508
1509static void
1510scan_sharing_clauses (tree clauses, omp_context *ctx)
1511{
1512 tree c, decl;
1513 bool scan_array_reductions = false;
1514
1515 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1516 {
1517 bool by_ref;
1518
aaf46ef9 1519 switch (OMP_CLAUSE_CODE (c))
953ff289
DN
1520 {
1521 case OMP_CLAUSE_PRIVATE:
1522 decl = OMP_CLAUSE_DECL (c);
a68ab351
JJ
1523 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
1524 goto do_private;
1525 else if (!is_variable_sized (decl))
953ff289
DN
1526 install_var_local (decl, ctx);
1527 break;
1528
1529 case OMP_CLAUSE_SHARED:
9cf32741 1530 decl = OMP_CLAUSE_DECL (c);
acf0174b
JJ
1531 /* Ignore shared directives in teams construct. */
1532 if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
9cf32741
JJ
1533 {
1534 /* Global variables don't need to be copied,
1535 the receiver side will use them directly. */
1536 tree odecl = maybe_lookup_decl_in_outer_ctx (decl, ctx);
1537 if (is_global_var (odecl))
1538 break;
1539 insert_decl_map (&ctx->cb, decl, odecl);
1540 break;
1541 }
a68ab351 1542 gcc_assert (is_taskreg_ctx (ctx));
5da250fc
JJ
1543 gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl))
1544 || !is_variable_sized (decl));
8ca5b2a2
JJ
1545 /* Global variables don't need to be copied,
1546 the receiver side will use them directly. */
1547 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1548 break;
a68ab351 1549 by_ref = use_pointer_for_field (decl, ctx);
953ff289
DN
1550 if (! TREE_READONLY (decl)
1551 || TREE_ADDRESSABLE (decl)
1552 || by_ref
1553 || is_reference (decl))
1554 {
a68ab351 1555 install_var_field (decl, by_ref, 3, ctx);
953ff289
DN
1556 install_var_local (decl, ctx);
1557 break;
1558 }
1559 /* We don't need to copy const scalar vars back. */
aaf46ef9 1560 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
953ff289
DN
1561 goto do_private;
1562
1563 case OMP_CLAUSE_LASTPRIVATE:
1564 /* Let the corresponding firstprivate clause create
1565 the variable. */
1566 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1567 break;
1568 /* FALLTHRU */
1569
1570 case OMP_CLAUSE_FIRSTPRIVATE:
1571 case OMP_CLAUSE_REDUCTION:
74bf76ed 1572 case OMP_CLAUSE_LINEAR:
953ff289
DN
1573 decl = OMP_CLAUSE_DECL (c);
1574 do_private:
1575 if (is_variable_sized (decl))
953ff289 1576 {
a68ab351
JJ
1577 if (is_task_ctx (ctx))
1578 install_var_field (decl, false, 1, ctx);
1579 break;
1580 }
1581 else if (is_taskreg_ctx (ctx))
1582 {
1583 bool global
1584 = is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx));
7c8f7639 1585 by_ref = use_pointer_for_field (decl, NULL);
a68ab351
JJ
1586
1587 if (is_task_ctx (ctx)
1588 && (global || by_ref || is_reference (decl)))
1589 {
1590 install_var_field (decl, false, 1, ctx);
1591 if (!global)
1592 install_var_field (decl, by_ref, 2, ctx);
1593 }
1594 else if (!global)
1595 install_var_field (decl, by_ref, 3, ctx);
953ff289
DN
1596 }
1597 install_var_local (decl, ctx);
1598 break;
1599
acf0174b
JJ
1600 case OMP_CLAUSE__LOOPTEMP_:
1601 gcc_assert (is_parallel_ctx (ctx));
1602 decl = OMP_CLAUSE_DECL (c);
1603 install_var_field (decl, false, 3, ctx);
1604 install_var_local (decl, ctx);
1605 break;
1606
953ff289 1607 case OMP_CLAUSE_COPYPRIVATE:
953ff289
DN
1608 case OMP_CLAUSE_COPYIN:
1609 decl = OMP_CLAUSE_DECL (c);
7c8f7639 1610 by_ref = use_pointer_for_field (decl, NULL);
a68ab351 1611 install_var_field (decl, by_ref, 3, ctx);
953ff289
DN
1612 break;
1613
1614 case OMP_CLAUSE_DEFAULT:
1615 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
1616 break;
1617
20906c66 1618 case OMP_CLAUSE_FINAL:
953ff289
DN
1619 case OMP_CLAUSE_IF:
1620 case OMP_CLAUSE_NUM_THREADS:
acf0174b
JJ
1621 case OMP_CLAUSE_NUM_TEAMS:
1622 case OMP_CLAUSE_THREAD_LIMIT:
1623 case OMP_CLAUSE_DEVICE:
953ff289 1624 case OMP_CLAUSE_SCHEDULE:
acf0174b
JJ
1625 case OMP_CLAUSE_DIST_SCHEDULE:
1626 case OMP_CLAUSE_DEPEND:
9a771876 1627 case OMP_CLAUSE__CILK_FOR_COUNT_:
953ff289 1628 if (ctx->outer)
726a989a 1629 scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
953ff289
DN
1630 break;
1631
acf0174b
JJ
1632 case OMP_CLAUSE_TO:
1633 case OMP_CLAUSE_FROM:
1634 case OMP_CLAUSE_MAP:
1635 if (ctx->outer)
1636 scan_omp_op (&OMP_CLAUSE_SIZE (c), ctx->outer);
1637 decl = OMP_CLAUSE_DECL (c);
1638 /* Global variables with "omp declare target" attribute
1639 don't need to be copied, the receiver side will use them
1640 directly. */
1641 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
1642 && DECL_P (decl)
1643 && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
1644 && lookup_attribute ("omp declare target",
1645 DECL_ATTRIBUTES (decl)))
1646 break;
1647 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
1648 && OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_POINTER)
1649 {
1650 /* Ignore OMP_CLAUSE_MAP_POINTER kind for arrays in
1651 #pragma omp target data, there is nothing to map for
1652 those. */
1653 if (gimple_omp_target_kind (ctx->stmt) == GF_OMP_TARGET_KIND_DATA
1654 && !POINTER_TYPE_P (TREE_TYPE (decl)))
1655 break;
1656 }
1657 if (DECL_P (decl))
1658 {
1659 if (DECL_SIZE (decl)
1660 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
1661 {
1662 tree decl2 = DECL_VALUE_EXPR (decl);
1663 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
1664 decl2 = TREE_OPERAND (decl2, 0);
1665 gcc_assert (DECL_P (decl2));
1666 install_var_field (decl2, true, 3, ctx);
1667 install_var_local (decl2, ctx);
1668 install_var_local (decl, ctx);
1669 }
1670 else
1671 {
1672 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
1673 && OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_POINTER
1674 && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
1675 && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
1676 install_var_field (decl, true, 7, ctx);
1677 else
1678 install_var_field (decl, true, 3, ctx);
1679 if (gimple_omp_target_kind (ctx->stmt)
1680 == GF_OMP_TARGET_KIND_REGION)
1681 install_var_local (decl, ctx);
1682 }
1683 }
1684 else
1685 {
1686 tree base = get_base_address (decl);
1687 tree nc = OMP_CLAUSE_CHAIN (c);
1688 if (DECL_P (base)
1689 && nc != NULL_TREE
1690 && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
1691 && OMP_CLAUSE_DECL (nc) == base
1692 && OMP_CLAUSE_MAP_KIND (nc) == OMP_CLAUSE_MAP_POINTER
1693 && integer_zerop (OMP_CLAUSE_SIZE (nc)))
1694 {
1695 OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c) = 1;
1696 OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (nc) = 1;
1697 }
1698 else
1699 {
f014c653
JJ
1700 if (ctx->outer)
1701 {
1702 scan_omp_op (&OMP_CLAUSE_DECL (c), ctx->outer);
1703 decl = OMP_CLAUSE_DECL (c);
1704 }
acf0174b
JJ
1705 gcc_assert (!splay_tree_lookup (ctx->field_map,
1706 (splay_tree_key) decl));
1707 tree field
1708 = build_decl (OMP_CLAUSE_LOCATION (c),
1709 FIELD_DECL, NULL_TREE, ptr_type_node);
1710 DECL_ALIGN (field) = TYPE_ALIGN (ptr_type_node);
1711 insert_field_into_struct (ctx->record_type, field);
1712 splay_tree_insert (ctx->field_map, (splay_tree_key) decl,
1713 (splay_tree_value) field);
1714 }
1715 }
1716 break;
1717
953ff289
DN
1718 case OMP_CLAUSE_NOWAIT:
1719 case OMP_CLAUSE_ORDERED:
a68ab351
JJ
1720 case OMP_CLAUSE_COLLAPSE:
1721 case OMP_CLAUSE_UNTIED:
20906c66 1722 case OMP_CLAUSE_MERGEABLE:
acf0174b 1723 case OMP_CLAUSE_PROC_BIND:
74bf76ed 1724 case OMP_CLAUSE_SAFELEN:
953ff289
DN
1725 break;
1726
acf0174b
JJ
1727 case OMP_CLAUSE_ALIGNED:
1728 decl = OMP_CLAUSE_DECL (c);
1729 if (is_global_var (decl)
1730 && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
1731 install_var_local (decl, ctx);
1732 break;
1733
953ff289
DN
1734 default:
1735 gcc_unreachable ();
1736 }
1737 }
1738
1739 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1740 {
aaf46ef9 1741 switch (OMP_CLAUSE_CODE (c))
953ff289
DN
1742 {
1743 case OMP_CLAUSE_LASTPRIVATE:
1744 /* Let the corresponding firstprivate clause create
1745 the variable. */
726a989a 1746 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
a68ab351 1747 scan_array_reductions = true;
953ff289
DN
1748 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1749 break;
1750 /* FALLTHRU */
1751
1752 case OMP_CLAUSE_PRIVATE:
1753 case OMP_CLAUSE_FIRSTPRIVATE:
1754 case OMP_CLAUSE_REDUCTION:
74bf76ed 1755 case OMP_CLAUSE_LINEAR:
953ff289
DN
1756 decl = OMP_CLAUSE_DECL (c);
1757 if (is_variable_sized (decl))
1758 install_var_local (decl, ctx);
1759 fixup_remapped_decl (decl, ctx,
aaf46ef9 1760 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
953ff289 1761 && OMP_CLAUSE_PRIVATE_DEBUG (c));
aaf46ef9 1762 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
953ff289
DN
1763 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1764 scan_array_reductions = true;
f7468577
JJ
1765 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
1766 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
1767 scan_array_reductions = true;
953ff289
DN
1768 break;
1769
1770 case OMP_CLAUSE_SHARED:
acf0174b
JJ
1771 /* Ignore shared directives in teams construct. */
1772 if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
1773 break;
953ff289 1774 decl = OMP_CLAUSE_DECL (c);
8ca5b2a2
JJ
1775 if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1776 fixup_remapped_decl (decl, ctx, false);
953ff289
DN
1777 break;
1778
acf0174b
JJ
1779 case OMP_CLAUSE_MAP:
1780 if (gimple_omp_target_kind (ctx->stmt) == GF_OMP_TARGET_KIND_DATA)
1781 break;
1782 decl = OMP_CLAUSE_DECL (c);
1783 if (DECL_P (decl)
1784 && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
1785 && lookup_attribute ("omp declare target",
1786 DECL_ATTRIBUTES (decl)))
1787 break;
1788 if (DECL_P (decl))
1789 {
1790 if (OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_POINTER
1791 && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
1792 && !COMPLETE_TYPE_P (TREE_TYPE (decl)))
1793 {
1794 tree new_decl = lookup_decl (decl, ctx);
1795 TREE_TYPE (new_decl)
1796 = remap_type (TREE_TYPE (decl), &ctx->cb);
1797 }
1798 else if (DECL_SIZE (decl)
1799 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
1800 {
1801 tree decl2 = DECL_VALUE_EXPR (decl);
1802 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
1803 decl2 = TREE_OPERAND (decl2, 0);
1804 gcc_assert (DECL_P (decl2));
1805 fixup_remapped_decl (decl2, ctx, false);
1806 fixup_remapped_decl (decl, ctx, true);
1807 }
1808 else
1809 fixup_remapped_decl (decl, ctx, false);
1810 }
1811 break;
1812
953ff289
DN
1813 case OMP_CLAUSE_COPYPRIVATE:
1814 case OMP_CLAUSE_COPYIN:
1815 case OMP_CLAUSE_DEFAULT:
1816 case OMP_CLAUSE_IF:
1817 case OMP_CLAUSE_NUM_THREADS:
acf0174b
JJ
1818 case OMP_CLAUSE_NUM_TEAMS:
1819 case OMP_CLAUSE_THREAD_LIMIT:
1820 case OMP_CLAUSE_DEVICE:
953ff289 1821 case OMP_CLAUSE_SCHEDULE:
acf0174b 1822 case OMP_CLAUSE_DIST_SCHEDULE:
953ff289
DN
1823 case OMP_CLAUSE_NOWAIT:
1824 case OMP_CLAUSE_ORDERED:
a68ab351
JJ
1825 case OMP_CLAUSE_COLLAPSE:
1826 case OMP_CLAUSE_UNTIED:
20906c66
JJ
1827 case OMP_CLAUSE_FINAL:
1828 case OMP_CLAUSE_MERGEABLE:
acf0174b 1829 case OMP_CLAUSE_PROC_BIND:
74bf76ed 1830 case OMP_CLAUSE_SAFELEN:
acf0174b
JJ
1831 case OMP_CLAUSE_ALIGNED:
1832 case OMP_CLAUSE_DEPEND:
1833 case OMP_CLAUSE__LOOPTEMP_:
1834 case OMP_CLAUSE_TO:
1835 case OMP_CLAUSE_FROM:
9a771876 1836 case OMP_CLAUSE__CILK_FOR_COUNT_:
953ff289
DN
1837 break;
1838
1839 default:
1840 gcc_unreachable ();
1841 }
1842 }
1843
1844 if (scan_array_reductions)
1845 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
aaf46ef9 1846 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
953ff289
DN
1847 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1848 {
26127932
JJ
1849 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
1850 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
953ff289 1851 }
a68ab351 1852 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
726a989a 1853 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
26127932 1854 scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
f7468577
JJ
1855 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
1856 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
1857 scan_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
953ff289
DN
1858}
1859
9a771876
JJ
1860/* Create a new name for omp child function. Returns an identifier. If
1861 IS_CILK_FOR is true then the suffix for the child function is
1862 "_cilk_for_fn." */
953ff289 1863
953ff289 1864static tree
9a771876 1865create_omp_child_function_name (bool task_copy, bool is_cilk_for)
953ff289 1866{
9a771876
JJ
1867 if (is_cilk_for)
1868 return clone_function_name (current_function_decl, "_cilk_for_fn");
1869 return clone_function_name (current_function_decl,
1870 task_copy ? "_omp_cpyfn" : "_omp_fn");
1871}
1872
1873/* Returns the type of the induction variable for the child function for
1874 _Cilk_for and the types for _high and _low variables based on TYPE. */
1875
1876static tree
1877cilk_for_check_loop_diff_type (tree type)
1878{
1879 if (TYPE_PRECISION (type) <= TYPE_PRECISION (uint32_type_node))
1880 {
1881 if (TYPE_UNSIGNED (type))
1882 return uint32_type_node;
1883 else
1884 return integer_type_node;
1885 }
1886 else
1887 {
1888 if (TYPE_UNSIGNED (type))
1889 return uint64_type_node;
1890 else
1891 return long_long_integer_type_node;
1892 }
953ff289
DN
1893}
1894
1895/* Build a decl for the omp child function. It'll not contain a body
1896 yet, just the bare decl. */
1897
1898static void
a68ab351 1899create_omp_child_function (omp_context *ctx, bool task_copy)
953ff289
DN
1900{
1901 tree decl, type, name, t;
1902
9a771876
JJ
1903 tree cilk_for_count
1904 = (flag_cilkplus && gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
1905 ? find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
1906 OMP_CLAUSE__CILK_FOR_COUNT_) : NULL_TREE;
1907 tree cilk_var_type = NULL_TREE;
1908
1909 name = create_omp_child_function_name (task_copy,
1910 cilk_for_count != NULL_TREE);
a68ab351
JJ
1911 if (task_copy)
1912 type = build_function_type_list (void_type_node, ptr_type_node,
1913 ptr_type_node, NULL_TREE);
9a771876
JJ
1914 else if (cilk_for_count)
1915 {
1916 type = TREE_TYPE (OMP_CLAUSE_OPERAND (cilk_for_count, 0));
1917 cilk_var_type = cilk_for_check_loop_diff_type (type);
1918 type = build_function_type_list (void_type_node, ptr_type_node,
1919 cilk_var_type, cilk_var_type, NULL_TREE);
1920 }
a68ab351
JJ
1921 else
1922 type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
953ff289 1923
9a771876 1924 decl = build_decl (gimple_location (ctx->stmt), FUNCTION_DECL, name, type);
953ff289 1925
a68ab351
JJ
1926 if (!task_copy)
1927 ctx->cb.dst_fn = decl;
1928 else
726a989a 1929 gimple_omp_task_set_copy_fn (ctx->stmt, decl);
953ff289
DN
1930
1931 TREE_STATIC (decl) = 1;
1932 TREE_USED (decl) = 1;
1933 DECL_ARTIFICIAL (decl) = 1;
1934 DECL_IGNORED_P (decl) = 0;
1935 TREE_PUBLIC (decl) = 0;
1936 DECL_UNINLINABLE (decl) = 1;
1937 DECL_EXTERNAL (decl) = 0;
1938 DECL_CONTEXT (decl) = NULL_TREE;
50674e96 1939 DECL_INITIAL (decl) = make_node (BLOCK);
acf0174b
JJ
1940 bool target_p = false;
1941 if (lookup_attribute ("omp declare target",
1942 DECL_ATTRIBUTES (current_function_decl)))
1943 target_p = true;
1944 else
1945 {
1946 omp_context *octx;
1947 for (octx = ctx; octx; octx = octx->outer)
1948 if (gimple_code (octx->stmt) == GIMPLE_OMP_TARGET
1949 && gimple_omp_target_kind (octx->stmt)
1950 == GF_OMP_TARGET_KIND_REGION)
1951 {
1952 target_p = true;
1953 break;
1954 }
1955 }
1956 if (target_p)
1957 DECL_ATTRIBUTES (decl)
1958 = tree_cons (get_identifier ("omp declare target"),
1959 NULL_TREE, DECL_ATTRIBUTES (decl));
953ff289 1960
c2255bc4
AH
1961 t = build_decl (DECL_SOURCE_LOCATION (decl),
1962 RESULT_DECL, NULL_TREE, void_type_node);
953ff289
DN
1963 DECL_ARTIFICIAL (t) = 1;
1964 DECL_IGNORED_P (t) = 1;
07485407 1965 DECL_CONTEXT (t) = decl;
953ff289
DN
1966 DECL_RESULT (decl) = t;
1967
9a771876
JJ
1968 /* _Cilk_for's child function requires two extra parameters called
1969 __low and __high that are set the by Cilk runtime when it calls this
1970 function. */
1971 if (cilk_for_count)
1972 {
1973 t = build_decl (DECL_SOURCE_LOCATION (decl),
1974 PARM_DECL, get_identifier ("__high"), cilk_var_type);
1975 DECL_ARTIFICIAL (t) = 1;
1976 DECL_NAMELESS (t) = 1;
1977 DECL_ARG_TYPE (t) = ptr_type_node;
1978 DECL_CONTEXT (t) = current_function_decl;
1979 TREE_USED (t) = 1;
1980 DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
1981 DECL_ARGUMENTS (decl) = t;
1982
1983 t = build_decl (DECL_SOURCE_LOCATION (decl),
1984 PARM_DECL, get_identifier ("__low"), cilk_var_type);
1985 DECL_ARTIFICIAL (t) = 1;
1986 DECL_NAMELESS (t) = 1;
1987 DECL_ARG_TYPE (t) = ptr_type_node;
1988 DECL_CONTEXT (t) = current_function_decl;
1989 TREE_USED (t) = 1;
1990 DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
1991 DECL_ARGUMENTS (decl) = t;
1992 }
1993
1994 tree data_name = get_identifier (".omp_data_i");
1995 t = build_decl (DECL_SOURCE_LOCATION (decl), PARM_DECL, data_name,
1996 ptr_type_node);
953ff289 1997 DECL_ARTIFICIAL (t) = 1;
cd3f04c8 1998 DECL_NAMELESS (t) = 1;
953ff289 1999 DECL_ARG_TYPE (t) = ptr_type_node;
50674e96 2000 DECL_CONTEXT (t) = current_function_decl;
953ff289 2001 TREE_USED (t) = 1;
9a771876
JJ
2002 if (cilk_for_count)
2003 DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
953ff289 2004 DECL_ARGUMENTS (decl) = t;
a68ab351
JJ
2005 if (!task_copy)
2006 ctx->receiver_decl = t;
2007 else
2008 {
c2255bc4
AH
2009 t = build_decl (DECL_SOURCE_LOCATION (decl),
2010 PARM_DECL, get_identifier (".omp_data_o"),
a68ab351
JJ
2011 ptr_type_node);
2012 DECL_ARTIFICIAL (t) = 1;
cd3f04c8 2013 DECL_NAMELESS (t) = 1;
a68ab351
JJ
2014 DECL_ARG_TYPE (t) = ptr_type_node;
2015 DECL_CONTEXT (t) = current_function_decl;
2016 TREE_USED (t) = 1;
628c189e 2017 TREE_ADDRESSABLE (t) = 1;
910ad8de 2018 DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
a68ab351
JJ
2019 DECL_ARGUMENTS (decl) = t;
2020 }
953ff289 2021
b8698a0f 2022 /* Allocate memory for the function structure. The call to
50674e96 2023 allocate_struct_function clobbers CFUN, so we need to restore
953ff289 2024 it afterward. */
db2960f4 2025 push_struct_function (decl);
726a989a 2026 cfun->function_end_locus = gimple_location (ctx->stmt);
db2960f4 2027 pop_cfun ();
953ff289
DN
2028}
2029
acf0174b
JJ
2030/* Callback for walk_gimple_seq. Check if combined parallel
2031 contains gimple_omp_for_combined_into_p OMP_FOR. */
2032
2033static tree
2034find_combined_for (gimple_stmt_iterator *gsi_p,
2035 bool *handled_ops_p,
2036 struct walk_stmt_info *wi)
2037{
2038 gimple stmt = gsi_stmt (*gsi_p);
2039
2040 *handled_ops_p = true;
2041 switch (gimple_code (stmt))
2042 {
2043 WALK_SUBSTMTS;
2044
2045 case GIMPLE_OMP_FOR:
2046 if (gimple_omp_for_combined_into_p (stmt)
2047 && gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR)
2048 {
2049 wi->info = stmt;
2050 return integer_zero_node;
2051 }
2052 break;
2053 default:
2054 break;
2055 }
2056 return NULL;
2057}
2058
953ff289
DN
2059/* Scan an OpenMP parallel directive. */
2060
2061static void
726a989a 2062scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
953ff289
DN
2063{
2064 omp_context *ctx;
2065 tree name;
726a989a 2066 gimple stmt = gsi_stmt (*gsi);
953ff289
DN
2067
2068 /* Ignore parallel directives with empty bodies, unless there
2069 are copyin clauses. */
2070 if (optimize > 0
726a989a
RB
2071 && empty_body_p (gimple_omp_body (stmt))
2072 && find_omp_clause (gimple_omp_parallel_clauses (stmt),
2073 OMP_CLAUSE_COPYIN) == NULL)
953ff289 2074 {
726a989a 2075 gsi_replace (gsi, gimple_build_nop (), false);
953ff289
DN
2076 return;
2077 }
2078
acf0174b
JJ
2079 if (gimple_omp_parallel_combined_p (stmt))
2080 {
2081 gimple for_stmt;
2082 struct walk_stmt_info wi;
2083
2084 memset (&wi, 0, sizeof (wi));
2085 wi.val_only = true;
2086 walk_gimple_seq (gimple_omp_body (stmt),
2087 find_combined_for, NULL, &wi);
2088 for_stmt = (gimple) wi.info;
2089 if (for_stmt)
2090 {
2091 struct omp_for_data fd;
2092 extract_omp_for_data (for_stmt, &fd, NULL);
2093 /* We need two temporaries with fd.loop.v type (istart/iend)
2094 and then (fd.collapse - 1) temporaries with the same
2095 type for count2 ... countN-1 vars if not constant. */
2096 size_t count = 2, i;
2097 tree type = fd.iter_type;
2098 if (fd.collapse > 1
2099 && TREE_CODE (fd.loop.n2) != INTEGER_CST)
2100 count += fd.collapse - 1;
2101 for (i = 0; i < count; i++)
2102 {
2103 tree temp = create_tmp_var (type, NULL);
2104 tree c = build_omp_clause (UNKNOWN_LOCATION,
2105 OMP_CLAUSE__LOOPTEMP_);
f014c653 2106 insert_decl_map (&outer_ctx->cb, temp, temp);
acf0174b
JJ
2107 OMP_CLAUSE_DECL (c) = temp;
2108 OMP_CLAUSE_CHAIN (c) = gimple_omp_parallel_clauses (stmt);
2109 gimple_omp_parallel_set_clauses (stmt, c);
2110 }
2111 }
2112 }
2113
726a989a 2114 ctx = new_omp_context (stmt, outer_ctx);
5771c391 2115 taskreg_contexts.safe_push (ctx);
a68ab351 2116 if (taskreg_nesting_level > 1)
50674e96 2117 ctx->is_nested = true;
953ff289 2118 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
953ff289
DN
2119 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
2120 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
953ff289 2121 name = create_tmp_var_name (".omp_data_s");
c2255bc4
AH
2122 name = build_decl (gimple_location (stmt),
2123 TYPE_DECL, name, ctx->record_type);
cd3f04c8
JJ
2124 DECL_ARTIFICIAL (name) = 1;
2125 DECL_NAMELESS (name) = 1;
953ff289 2126 TYPE_NAME (ctx->record_type) = name;
a68ab351 2127 create_omp_child_function (ctx, false);
726a989a 2128 gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
953ff289 2129
726a989a 2130 scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
26127932 2131 scan_omp (gimple_omp_body_ptr (stmt), ctx);
953ff289
DN
2132
2133 if (TYPE_FIELDS (ctx->record_type) == NULL)
2134 ctx->record_type = ctx->receiver_decl = NULL;
953ff289
DN
2135}
2136
a68ab351
JJ
2137/* Scan an OpenMP task directive. */
2138
2139static void
726a989a 2140scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
a68ab351
JJ
2141{
2142 omp_context *ctx;
726a989a
RB
2143 tree name, t;
2144 gimple stmt = gsi_stmt (*gsi);
a68ab351
JJ
2145
2146 /* Ignore task directives with empty bodies. */
2147 if (optimize > 0
726a989a 2148 && empty_body_p (gimple_omp_body (stmt)))
a68ab351 2149 {
726a989a 2150 gsi_replace (gsi, gimple_build_nop (), false);
a68ab351
JJ
2151 return;
2152 }
2153
726a989a 2154 ctx = new_omp_context (stmt, outer_ctx);
5771c391 2155 taskreg_contexts.safe_push (ctx);
a68ab351
JJ
2156 if (taskreg_nesting_level > 1)
2157 ctx->is_nested = true;
2158 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
2159 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
2160 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
2161 name = create_tmp_var_name (".omp_data_s");
c2255bc4
AH
2162 name = build_decl (gimple_location (stmt),
2163 TYPE_DECL, name, ctx->record_type);
cd3f04c8
JJ
2164 DECL_ARTIFICIAL (name) = 1;
2165 DECL_NAMELESS (name) = 1;
a68ab351
JJ
2166 TYPE_NAME (ctx->record_type) = name;
2167 create_omp_child_function (ctx, false);
726a989a 2168 gimple_omp_task_set_child_fn (stmt, ctx->cb.dst_fn);
a68ab351 2169
726a989a 2170 scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);
a68ab351
JJ
2171
2172 if (ctx->srecord_type)
2173 {
2174 name = create_tmp_var_name (".omp_data_a");
c2255bc4
AH
2175 name = build_decl (gimple_location (stmt),
2176 TYPE_DECL, name, ctx->srecord_type);
cd3f04c8
JJ
2177 DECL_ARTIFICIAL (name) = 1;
2178 DECL_NAMELESS (name) = 1;
a68ab351
JJ
2179 TYPE_NAME (ctx->srecord_type) = name;
2180 create_omp_child_function (ctx, true);
2181 }
2182
26127932 2183 scan_omp (gimple_omp_body_ptr (stmt), ctx);
a68ab351
JJ
2184
2185 if (TYPE_FIELDS (ctx->record_type) == NULL)
2186 {
2187 ctx->record_type = ctx->receiver_decl = NULL;
726a989a
RB
2188 t = build_int_cst (long_integer_type_node, 0);
2189 gimple_omp_task_set_arg_size (stmt, t);
2190 t = build_int_cst (long_integer_type_node, 1);
2191 gimple_omp_task_set_arg_align (stmt, t);
a68ab351 2192 }
5771c391
JJ
2193}
2194
2195
2196/* If any decls have been made addressable during scan_omp,
2197 adjust their fields if needed, and layout record types
2198 of parallel/task constructs. */
2199
2200static void
2201finish_taskreg_scan (omp_context *ctx)
2202{
2203 if (ctx->record_type == NULL_TREE)
2204 return;
2205
2206 /* If any task_shared_vars were needed, verify all
2207 OMP_CLAUSE_SHARED clauses on GIMPLE_OMP_{PARALLEL,TASK}
2208 statements if use_pointer_for_field hasn't changed
2209 because of that. If it did, update field types now. */
2210 if (task_shared_vars)
2211 {
2212 tree c;
2213
2214 for (c = gimple_omp_taskreg_clauses (ctx->stmt);
2215 c; c = OMP_CLAUSE_CHAIN (c))
2216 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED)
2217 {
2218 tree decl = OMP_CLAUSE_DECL (c);
2219
2220 /* Global variables don't need to be copied,
2221 the receiver side will use them directly. */
2222 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
2223 continue;
2224 if (!bitmap_bit_p (task_shared_vars, DECL_UID (decl))
2225 || !use_pointer_for_field (decl, ctx))
2226 continue;
2227 tree field = lookup_field (decl, ctx);
2228 if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE
2229 && TREE_TYPE (TREE_TYPE (field)) == TREE_TYPE (decl))
2230 continue;
2231 TREE_TYPE (field) = build_pointer_type (TREE_TYPE (decl));
2232 TREE_THIS_VOLATILE (field) = 0;
2233 DECL_USER_ALIGN (field) = 0;
2234 DECL_ALIGN (field) = TYPE_ALIGN (TREE_TYPE (field));
2235 if (TYPE_ALIGN (ctx->record_type) < DECL_ALIGN (field))
2236 TYPE_ALIGN (ctx->record_type) = DECL_ALIGN (field);
2237 if (ctx->srecord_type)
2238 {
2239 tree sfield = lookup_sfield (decl, ctx);
2240 TREE_TYPE (sfield) = TREE_TYPE (field);
2241 TREE_THIS_VOLATILE (sfield) = 0;
2242 DECL_USER_ALIGN (sfield) = 0;
2243 DECL_ALIGN (sfield) = DECL_ALIGN (field);
2244 if (TYPE_ALIGN (ctx->srecord_type) < DECL_ALIGN (sfield))
2245 TYPE_ALIGN (ctx->srecord_type) = DECL_ALIGN (sfield);
2246 }
2247 }
2248 }
2249
2250 if (gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
2251 {
2252 layout_type (ctx->record_type);
2253 fixup_child_record_type (ctx);
2254 }
a68ab351
JJ
2255 else
2256 {
5771c391 2257 location_t loc = gimple_location (ctx->stmt);
a68ab351
JJ
2258 tree *p, vla_fields = NULL_TREE, *q = &vla_fields;
2259 /* Move VLA fields to the end. */
2260 p = &TYPE_FIELDS (ctx->record_type);
2261 while (*p)
2262 if (!TYPE_SIZE_UNIT (TREE_TYPE (*p))
2263 || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p))))
2264 {
2265 *q = *p;
2266 *p = TREE_CHAIN (*p);
2267 TREE_CHAIN (*q) = NULL_TREE;
2268 q = &TREE_CHAIN (*q);
2269 }
2270 else
910ad8de 2271 p = &DECL_CHAIN (*p);
a68ab351
JJ
2272 *p = vla_fields;
2273 layout_type (ctx->record_type);
2274 fixup_child_record_type (ctx);
2275 if (ctx->srecord_type)
2276 layout_type (ctx->srecord_type);
5771c391
JJ
2277 tree t = fold_convert_loc (loc, long_integer_type_node,
2278 TYPE_SIZE_UNIT (ctx->record_type));
2279 gimple_omp_task_set_arg_size (ctx->stmt, t);
726a989a 2280 t = build_int_cst (long_integer_type_node,
a68ab351 2281 TYPE_ALIGN_UNIT (ctx->record_type));
5771c391 2282 gimple_omp_task_set_arg_align (ctx->stmt, t);
a68ab351
JJ
2283 }
2284}
2285
953ff289 2286
50674e96 2287/* Scan an OpenMP loop directive. */
953ff289
DN
2288
2289static void
726a989a 2290scan_omp_for (gimple stmt, omp_context *outer_ctx)
953ff289 2291{
50674e96 2292 omp_context *ctx;
726a989a 2293 size_t i;
953ff289 2294
50674e96 2295 ctx = new_omp_context (stmt, outer_ctx);
953ff289 2296
726a989a 2297 scan_sharing_clauses (gimple_omp_for_clauses (stmt), ctx);
953ff289 2298
26127932 2299 scan_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
726a989a 2300 for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
a68ab351 2301 {
726a989a
RB
2302 scan_omp_op (gimple_omp_for_index_ptr (stmt, i), ctx);
2303 scan_omp_op (gimple_omp_for_initial_ptr (stmt, i), ctx);
2304 scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
2305 scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
a68ab351 2306 }
26127932 2307 scan_omp (gimple_omp_body_ptr (stmt), ctx);
953ff289
DN
2308}
2309
2310/* Scan an OpenMP sections directive. */
2311
2312static void
726a989a 2313scan_omp_sections (gimple stmt, omp_context *outer_ctx)
953ff289 2314{
953ff289
DN
2315 omp_context *ctx;
2316
2317 ctx = new_omp_context (stmt, outer_ctx);
726a989a 2318 scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
26127932 2319 scan_omp (gimple_omp_body_ptr (stmt), ctx);
953ff289
DN
2320}
2321
2322/* Scan an OpenMP single directive. */
2323
2324static void
726a989a 2325scan_omp_single (gimple stmt, omp_context *outer_ctx)
953ff289 2326{
953ff289
DN
2327 omp_context *ctx;
2328 tree name;
2329
2330 ctx = new_omp_context (stmt, outer_ctx);
2331 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
2332 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
2333 name = create_tmp_var_name (".omp_copy_s");
c2255bc4
AH
2334 name = build_decl (gimple_location (stmt),
2335 TYPE_DECL, name, ctx->record_type);
953ff289
DN
2336 TYPE_NAME (ctx->record_type) = name;
2337
726a989a 2338 scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
26127932 2339 scan_omp (gimple_omp_body_ptr (stmt), ctx);
953ff289
DN
2340
2341 if (TYPE_FIELDS (ctx->record_type) == NULL)
2342 ctx->record_type = NULL;
2343 else
2344 layout_type (ctx->record_type);
2345}
2346
acf0174b
JJ
2347/* Scan an OpenMP target{, data, update} directive. */
2348
2349static void
2350scan_omp_target (gimple stmt, omp_context *outer_ctx)
2351{
2352 omp_context *ctx;
2353 tree name;
2354 int kind = gimple_omp_target_kind (stmt);
2355
2356 ctx = new_omp_context (stmt, outer_ctx);
2357 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
2358 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
2359 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
2360 name = create_tmp_var_name (".omp_data_t");
2361 name = build_decl (gimple_location (stmt),
2362 TYPE_DECL, name, ctx->record_type);
2363 DECL_ARTIFICIAL (name) = 1;
2364 DECL_NAMELESS (name) = 1;
2365 TYPE_NAME (ctx->record_type) = name;
2366 if (kind == GF_OMP_TARGET_KIND_REGION)
2367 {
2368 create_omp_child_function (ctx, false);
2369 gimple_omp_target_set_child_fn (stmt, ctx->cb.dst_fn);
2370 }
2371
2372 scan_sharing_clauses (gimple_omp_target_clauses (stmt), ctx);
2373 scan_omp (gimple_omp_body_ptr (stmt), ctx);
2374
2375 if (TYPE_FIELDS (ctx->record_type) == NULL)
2376 ctx->record_type = ctx->receiver_decl = NULL;
2377 else
2378 {
2379 TYPE_FIELDS (ctx->record_type)
2380 = nreverse (TYPE_FIELDS (ctx->record_type));
2381#ifdef ENABLE_CHECKING
2382 tree field;
2383 unsigned int align = DECL_ALIGN (TYPE_FIELDS (ctx->record_type));
2384 for (field = TYPE_FIELDS (ctx->record_type);
2385 field;
2386 field = DECL_CHAIN (field))
2387 gcc_assert (DECL_ALIGN (field) == align);
2388#endif
2389 layout_type (ctx->record_type);
2390 if (kind == GF_OMP_TARGET_KIND_REGION)
2391 fixup_child_record_type (ctx);
2392 }
2393}
2394
2395/* Scan an OpenMP teams directive. */
2396
2397static void
2398scan_omp_teams (gimple stmt, omp_context *outer_ctx)
2399{
2400 omp_context *ctx = new_omp_context (stmt, outer_ctx);
2401 scan_sharing_clauses (gimple_omp_teams_clauses (stmt), ctx);
2402 scan_omp (gimple_omp_body_ptr (stmt), ctx);
2403}
953ff289 2404
a6fc8e21 2405/* Check OpenMP nesting restrictions. */
26127932
JJ
2406static bool
2407check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
a6fc8e21 2408{
74bf76ed
JJ
2409 if (ctx != NULL)
2410 {
2411 if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
0aadce73 2412 && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
74bf76ed
JJ
2413 {
2414 error_at (gimple_location (stmt),
2415 "OpenMP constructs may not be nested inside simd region");
2416 return false;
2417 }
acf0174b
JJ
2418 else if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
2419 {
2420 if ((gimple_code (stmt) != GIMPLE_OMP_FOR
2421 || (gimple_omp_for_kind (stmt)
2422 != GF_OMP_FOR_KIND_DISTRIBUTE))
2423 && gimple_code (stmt) != GIMPLE_OMP_PARALLEL)
2424 {
2425 error_at (gimple_location (stmt),
2426 "only distribute or parallel constructs are allowed to "
2427 "be closely nested inside teams construct");
2428 return false;
2429 }
2430 }
74bf76ed 2431 }
726a989a 2432 switch (gimple_code (stmt))
a6fc8e21 2433 {
726a989a 2434 case GIMPLE_OMP_FOR:
0aadce73 2435 if (gimple_omp_for_kind (stmt) & GF_OMP_FOR_SIMD)
74bf76ed 2436 return true;
acf0174b
JJ
2437 if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_DISTRIBUTE)
2438 {
2439 if (ctx != NULL && gimple_code (ctx->stmt) != GIMPLE_OMP_TEAMS)
2440 {
2441 error_at (gimple_location (stmt),
2442 "distribute construct must be closely nested inside "
2443 "teams construct");
2444 return false;
2445 }
2446 return true;
2447 }
2448 /* FALLTHRU */
2449 case GIMPLE_CALL:
2450 if (is_gimple_call (stmt)
2451 && (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2452 == BUILT_IN_GOMP_CANCEL
2453 || DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2454 == BUILT_IN_GOMP_CANCELLATION_POINT))
2455 {
2456 const char *bad = NULL;
2457 const char *kind = NULL;
2458 if (ctx == NULL)
2459 {
2460 error_at (gimple_location (stmt), "orphaned %qs construct",
2461 DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2462 == BUILT_IN_GOMP_CANCEL
2463 ? "#pragma omp cancel"
2464 : "#pragma omp cancellation point");
2465 return false;
2466 }
9541ffee 2467 switch (tree_fits_shwi_p (gimple_call_arg (stmt, 0))
9439e9a1 2468 ? tree_to_shwi (gimple_call_arg (stmt, 0))
acf0174b
JJ
2469 : 0)
2470 {
2471 case 1:
2472 if (gimple_code (ctx->stmt) != GIMPLE_OMP_PARALLEL)
2473 bad = "#pragma omp parallel";
2474 else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2475 == BUILT_IN_GOMP_CANCEL
2476 && !integer_zerop (gimple_call_arg (stmt, 1)))
2477 ctx->cancellable = true;
2478 kind = "parallel";
2479 break;
2480 case 2:
2481 if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
2482 || gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR)
2483 bad = "#pragma omp for";
2484 else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2485 == BUILT_IN_GOMP_CANCEL
2486 && !integer_zerop (gimple_call_arg (stmt, 1)))
2487 {
2488 ctx->cancellable = true;
2489 if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
2490 OMP_CLAUSE_NOWAIT))
2491 warning_at (gimple_location (stmt), 0,
2492 "%<#pragma omp cancel for%> inside "
2493 "%<nowait%> for construct");
2494 if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
2495 OMP_CLAUSE_ORDERED))
2496 warning_at (gimple_location (stmt), 0,
2497 "%<#pragma omp cancel for%> inside "
2498 "%<ordered%> for construct");
2499 }
2500 kind = "for";
2501 break;
2502 case 4:
2503 if (gimple_code (ctx->stmt) != GIMPLE_OMP_SECTIONS
2504 && gimple_code (ctx->stmt) != GIMPLE_OMP_SECTION)
2505 bad = "#pragma omp sections";
2506 else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2507 == BUILT_IN_GOMP_CANCEL
2508 && !integer_zerop (gimple_call_arg (stmt, 1)))
2509 {
2510 if (gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS)
2511 {
2512 ctx->cancellable = true;
2513 if (find_omp_clause (gimple_omp_sections_clauses
2514 (ctx->stmt),
2515 OMP_CLAUSE_NOWAIT))
2516 warning_at (gimple_location (stmt), 0,
2517 "%<#pragma omp cancel sections%> inside "
2518 "%<nowait%> sections construct");
2519 }
2520 else
2521 {
2522 gcc_assert (ctx->outer
2523 && gimple_code (ctx->outer->stmt)
2524 == GIMPLE_OMP_SECTIONS);
2525 ctx->outer->cancellable = true;
2526 if (find_omp_clause (gimple_omp_sections_clauses
2527 (ctx->outer->stmt),
2528 OMP_CLAUSE_NOWAIT))
2529 warning_at (gimple_location (stmt), 0,
2530 "%<#pragma omp cancel sections%> inside "
2531 "%<nowait%> sections construct");
2532 }
2533 }
2534 kind = "sections";
2535 break;
2536 case 8:
2537 if (gimple_code (ctx->stmt) != GIMPLE_OMP_TASK)
2538 bad = "#pragma omp task";
2539 else
2540 ctx->cancellable = true;
2541 kind = "taskgroup";
2542 break;
2543 default:
2544 error_at (gimple_location (stmt), "invalid arguments");
2545 return false;
2546 }
2547 if (bad)
2548 {
2549 error_at (gimple_location (stmt),
2550 "%<%s %s%> construct not closely nested inside of %qs",
2551 DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2552 == BUILT_IN_GOMP_CANCEL
2553 ? "#pragma omp cancel"
2554 : "#pragma omp cancellation point", kind, bad);
2555 return false;
2556 }
2557 }
74bf76ed 2558 /* FALLTHRU */
726a989a
RB
2559 case GIMPLE_OMP_SECTIONS:
2560 case GIMPLE_OMP_SINGLE:
a6fc8e21 2561 for (; ctx != NULL; ctx = ctx->outer)
726a989a 2562 switch (gimple_code (ctx->stmt))
a6fc8e21 2563 {
726a989a
RB
2564 case GIMPLE_OMP_FOR:
2565 case GIMPLE_OMP_SECTIONS:
2566 case GIMPLE_OMP_SINGLE:
2567 case GIMPLE_OMP_ORDERED:
2568 case GIMPLE_OMP_MASTER:
2569 case GIMPLE_OMP_TASK:
acf0174b 2570 case GIMPLE_OMP_CRITICAL:
726a989a 2571 if (is_gimple_call (stmt))
a68ab351 2572 {
acf0174b
JJ
2573 if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2574 != BUILT_IN_GOMP_BARRIER)
2575 return true;
26127932
JJ
2576 error_at (gimple_location (stmt),
2577 "barrier region may not be closely nested inside "
2578 "of work-sharing, critical, ordered, master or "
2579 "explicit task region");
2580 return false;
a68ab351 2581 }
26127932
JJ
2582 error_at (gimple_location (stmt),
2583 "work-sharing region may not be closely nested inside "
2584 "of work-sharing, critical, ordered, master or explicit "
2585 "task region");
2586 return false;
726a989a 2587 case GIMPLE_OMP_PARALLEL:
26127932 2588 return true;
a6fc8e21
JJ
2589 default:
2590 break;
2591 }
2592 break;
726a989a 2593 case GIMPLE_OMP_MASTER:
a6fc8e21 2594 for (; ctx != NULL; ctx = ctx->outer)
726a989a 2595 switch (gimple_code (ctx->stmt))
a6fc8e21 2596 {
726a989a
RB
2597 case GIMPLE_OMP_FOR:
2598 case GIMPLE_OMP_SECTIONS:
2599 case GIMPLE_OMP_SINGLE:
2600 case GIMPLE_OMP_TASK:
26127932
JJ
2601 error_at (gimple_location (stmt),
2602 "master region may not be closely nested inside "
2603 "of work-sharing or explicit task region");
2604 return false;
726a989a 2605 case GIMPLE_OMP_PARALLEL:
26127932 2606 return true;
a6fc8e21
JJ
2607 default:
2608 break;
2609 }
2610 break;
726a989a 2611 case GIMPLE_OMP_ORDERED:
a6fc8e21 2612 for (; ctx != NULL; ctx = ctx->outer)
726a989a 2613 switch (gimple_code (ctx->stmt))
a6fc8e21 2614 {
726a989a
RB
2615 case GIMPLE_OMP_CRITICAL:
2616 case GIMPLE_OMP_TASK:
26127932
JJ
2617 error_at (gimple_location (stmt),
2618 "ordered region may not be closely nested inside "
2619 "of critical or explicit task region");
2620 return false;
726a989a
RB
2621 case GIMPLE_OMP_FOR:
2622 if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
a6fc8e21 2623 OMP_CLAUSE_ORDERED) == NULL)
26127932
JJ
2624 {
2625 error_at (gimple_location (stmt),
2626 "ordered region must be closely nested inside "
a6fc8e21 2627 "a loop region with an ordered clause");
26127932
JJ
2628 return false;
2629 }
2630 return true;
726a989a 2631 case GIMPLE_OMP_PARALLEL:
acf0174b
JJ
2632 error_at (gimple_location (stmt),
2633 "ordered region must be closely nested inside "
2634 "a loop region with an ordered clause");
2635 return false;
a6fc8e21
JJ
2636 default:
2637 break;
2638 }
2639 break;
726a989a 2640 case GIMPLE_OMP_CRITICAL:
a6fc8e21 2641 for (; ctx != NULL; ctx = ctx->outer)
726a989a
RB
2642 if (gimple_code (ctx->stmt) == GIMPLE_OMP_CRITICAL
2643 && (gimple_omp_critical_name (stmt)
2644 == gimple_omp_critical_name (ctx->stmt)))
a6fc8e21 2645 {
26127932
JJ
2646 error_at (gimple_location (stmt),
2647 "critical region may not be nested inside a critical "
2648 "region with the same name");
2649 return false;
a6fc8e21
JJ
2650 }
2651 break;
acf0174b
JJ
2652 case GIMPLE_OMP_TEAMS:
2653 if (ctx == NULL
2654 || gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET
2655 || gimple_omp_target_kind (ctx->stmt) != GF_OMP_TARGET_KIND_REGION)
2656 {
2657 error_at (gimple_location (stmt),
2658 "teams construct not closely nested inside of target "
2659 "region");
2660 return false;
2661 }
2662 break;
f014c653
JJ
2663 case GIMPLE_OMP_TARGET:
2664 for (; ctx != NULL; ctx = ctx->outer)
2665 if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
2666 && gimple_omp_target_kind (ctx->stmt) == GF_OMP_TARGET_KIND_REGION)
2667 {
2668 const char *name;
2669 switch (gimple_omp_target_kind (stmt))
2670 {
2671 case GF_OMP_TARGET_KIND_REGION: name = "target"; break;
2672 case GF_OMP_TARGET_KIND_DATA: name = "target data"; break;
2673 case GF_OMP_TARGET_KIND_UPDATE: name = "target update"; break;
2674 default: gcc_unreachable ();
2675 }
2676 warning_at (gimple_location (stmt), 0,
2677 "%s construct inside of target region", name);
2678 }
2679 break;
a6fc8e21
JJ
2680 default:
2681 break;
2682 }
26127932 2683 return true;
a6fc8e21
JJ
2684}
2685
2686
726a989a
RB
2687/* Helper function scan_omp.
2688
2689 Callback for walk_tree or operators in walk_gimple_stmt used to
2690 scan for OpenMP directives in TP. */
953ff289
DN
2691
2692static tree
726a989a 2693scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
953ff289 2694{
d3bfe4de
KG
2695 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
2696 omp_context *ctx = (omp_context *) wi->info;
953ff289
DN
2697 tree t = *tp;
2698
726a989a
RB
2699 switch (TREE_CODE (t))
2700 {
2701 case VAR_DECL:
2702 case PARM_DECL:
2703 case LABEL_DECL:
2704 case RESULT_DECL:
2705 if (ctx)
2706 *tp = remap_decl (t, &ctx->cb);
2707 break;
2708
2709 default:
2710 if (ctx && TYPE_P (t))
2711 *tp = remap_type (t, &ctx->cb);
2712 else if (!DECL_P (t))
a900ae6b
JJ
2713 {
2714 *walk_subtrees = 1;
2715 if (ctx)
70f34814
RG
2716 {
2717 tree tem = remap_type (TREE_TYPE (t), &ctx->cb);
2718 if (tem != TREE_TYPE (t))
2719 {
2720 if (TREE_CODE (t) == INTEGER_CST)
807e902e 2721 *tp = wide_int_to_tree (tem, t);
70f34814
RG
2722 else
2723 TREE_TYPE (t) = tem;
2724 }
2725 }
a900ae6b 2726 }
726a989a
RB
2727 break;
2728 }
2729
2730 return NULL_TREE;
2731}
2732
c02065fc
AH
2733/* Return true if FNDECL is a setjmp or a longjmp. */
2734
2735static bool
2736setjmp_or_longjmp_p (const_tree fndecl)
2737{
2738 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
2739 && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SETJMP
2740 || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LONGJMP))
2741 return true;
2742
2743 tree declname = DECL_NAME (fndecl);
2744 if (!declname)
2745 return false;
2746 const char *name = IDENTIFIER_POINTER (declname);
2747 return !strcmp (name, "setjmp") || !strcmp (name, "longjmp");
2748}
2749
726a989a
RB
2750
2751/* Helper function for scan_omp.
2752
2753 Callback for walk_gimple_stmt used to scan for OpenMP directives in
2754 the current statement in GSI. */
2755
2756static tree
2757scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
2758 struct walk_stmt_info *wi)
2759{
2760 gimple stmt = gsi_stmt (*gsi);
2761 omp_context *ctx = (omp_context *) wi->info;
2762
2763 if (gimple_has_location (stmt))
2764 input_location = gimple_location (stmt);
953ff289 2765
a6fc8e21 2766 /* Check the OpenMP nesting restrictions. */
acf0174b
JJ
2767 bool remove = false;
2768 if (is_gimple_omp (stmt))
2769 remove = !check_omp_nesting_restrictions (stmt, ctx);
2770 else if (is_gimple_call (stmt))
2771 {
2772 tree fndecl = gimple_call_fndecl (stmt);
c02065fc
AH
2773 if (fndecl)
2774 {
2775 if (setjmp_or_longjmp_p (fndecl)
2776 && ctx
2777 && gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
0aadce73 2778 && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
c02065fc
AH
2779 {
2780 remove = true;
2781 error_at (gimple_location (stmt),
2782 "setjmp/longjmp inside simd construct");
2783 }
2784 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
2785 switch (DECL_FUNCTION_CODE (fndecl))
2786 {
2787 case BUILT_IN_GOMP_BARRIER:
2788 case BUILT_IN_GOMP_CANCEL:
2789 case BUILT_IN_GOMP_CANCELLATION_POINT:
2790 case BUILT_IN_GOMP_TASKYIELD:
2791 case BUILT_IN_GOMP_TASKWAIT:
2792 case BUILT_IN_GOMP_TASKGROUP_START:
2793 case BUILT_IN_GOMP_TASKGROUP_END:
2794 remove = !check_omp_nesting_restrictions (stmt, ctx);
2795 break;
2796 default:
2797 break;
2798 }
2799 }
acf0174b
JJ
2800 }
2801 if (remove)
2802 {
2803 stmt = gimple_build_nop ();
2804 gsi_replace (gsi, stmt, false);
a68ab351 2805 }
a6fc8e21 2806
726a989a
RB
2807 *handled_ops_p = true;
2808
2809 switch (gimple_code (stmt))
953ff289 2810 {
726a989a 2811 case GIMPLE_OMP_PARALLEL:
a68ab351 2812 taskreg_nesting_level++;
726a989a 2813 scan_omp_parallel (gsi, ctx);
a68ab351
JJ
2814 taskreg_nesting_level--;
2815 break;
2816
726a989a 2817 case GIMPLE_OMP_TASK:
a68ab351 2818 taskreg_nesting_level++;
726a989a 2819 scan_omp_task (gsi, ctx);
a68ab351 2820 taskreg_nesting_level--;
953ff289
DN
2821 break;
2822
726a989a
RB
2823 case GIMPLE_OMP_FOR:
2824 scan_omp_for (stmt, ctx);
953ff289
DN
2825 break;
2826
726a989a
RB
2827 case GIMPLE_OMP_SECTIONS:
2828 scan_omp_sections (stmt, ctx);
953ff289
DN
2829 break;
2830
726a989a
RB
2831 case GIMPLE_OMP_SINGLE:
2832 scan_omp_single (stmt, ctx);
953ff289
DN
2833 break;
2834
726a989a
RB
2835 case GIMPLE_OMP_SECTION:
2836 case GIMPLE_OMP_MASTER:
acf0174b 2837 case GIMPLE_OMP_TASKGROUP:
726a989a
RB
2838 case GIMPLE_OMP_ORDERED:
2839 case GIMPLE_OMP_CRITICAL:
2840 ctx = new_omp_context (stmt, ctx);
26127932 2841 scan_omp (gimple_omp_body_ptr (stmt), ctx);
953ff289
DN
2842 break;
2843
acf0174b
JJ
2844 case GIMPLE_OMP_TARGET:
2845 scan_omp_target (stmt, ctx);
2846 break;
2847
2848 case GIMPLE_OMP_TEAMS:
2849 scan_omp_teams (stmt, ctx);
2850 break;
2851
726a989a 2852 case GIMPLE_BIND:
953ff289
DN
2853 {
2854 tree var;
953ff289 2855
726a989a
RB
2856 *handled_ops_p = false;
2857 if (ctx)
910ad8de 2858 for (var = gimple_bind_vars (stmt); var ; var = DECL_CHAIN (var))
726a989a 2859 insert_decl_map (&ctx->cb, var, var);
953ff289
DN
2860 }
2861 break;
953ff289 2862 default:
726a989a 2863 *handled_ops_p = false;
953ff289
DN
2864 break;
2865 }
2866
2867 return NULL_TREE;
2868}
2869
2870
726a989a
RB
2871/* Scan all the statements starting at the current statement. CTX
2872 contains context information about the OpenMP directives and
2873 clauses found during the scan. */
953ff289
DN
2874
2875static void
26127932 2876scan_omp (gimple_seq *body_p, omp_context *ctx)
953ff289
DN
2877{
2878 location_t saved_location;
2879 struct walk_stmt_info wi;
2880
2881 memset (&wi, 0, sizeof (wi));
953ff289 2882 wi.info = ctx;
953ff289
DN
2883 wi.want_locations = true;
2884
2885 saved_location = input_location;
26127932 2886 walk_gimple_seq_mod (body_p, scan_omp_1_stmt, scan_omp_1_op, &wi);
953ff289
DN
2887 input_location = saved_location;
2888}
2889\f
2890/* Re-gimplification and code generation routines. */
2891
2892/* Build a call to GOMP_barrier. */
2893
acf0174b
JJ
2894static gimple
2895build_omp_barrier (tree lhs)
2896{
2897 tree fndecl = builtin_decl_explicit (lhs ? BUILT_IN_GOMP_BARRIER_CANCEL
2898 : BUILT_IN_GOMP_BARRIER);
2899 gimple g = gimple_build_call (fndecl, 0);
2900 if (lhs)
2901 gimple_call_set_lhs (g, lhs);
2902 return g;
953ff289
DN
2903}
2904
2905/* If a context was created for STMT when it was scanned, return it. */
2906
2907static omp_context *
726a989a 2908maybe_lookup_ctx (gimple stmt)
953ff289
DN
2909{
2910 splay_tree_node n;
2911 n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
2912 return n ? (omp_context *) n->value : NULL;
2913}
2914
50674e96
DN
2915
2916/* Find the mapping for DECL in CTX or the immediately enclosing
2917 context that has a mapping for DECL.
2918
2919 If CTX is a nested parallel directive, we may have to use the decl
2920 mappings created in CTX's parent context. Suppose that we have the
2921 following parallel nesting (variable UIDs showed for clarity):
2922
2923 iD.1562 = 0;
2924 #omp parallel shared(iD.1562) -> outer parallel
2925 iD.1562 = iD.1562 + 1;
2926
2927 #omp parallel shared (iD.1562) -> inner parallel
2928 iD.1562 = iD.1562 - 1;
2929
2930 Each parallel structure will create a distinct .omp_data_s structure
2931 for copying iD.1562 in/out of the directive:
2932
2933 outer parallel .omp_data_s.1.i -> iD.1562
2934 inner parallel .omp_data_s.2.i -> iD.1562
2935
2936 A shared variable mapping will produce a copy-out operation before
2937 the parallel directive and a copy-in operation after it. So, in
2938 this case we would have:
2939
2940 iD.1562 = 0;
2941 .omp_data_o.1.i = iD.1562;
2942 #omp parallel shared(iD.1562) -> outer parallel
2943 .omp_data_i.1 = &.omp_data_o.1
2944 .omp_data_i.1->i = .omp_data_i.1->i + 1;
2945
2946 .omp_data_o.2.i = iD.1562; -> **
2947 #omp parallel shared(iD.1562) -> inner parallel
2948 .omp_data_i.2 = &.omp_data_o.2
2949 .omp_data_i.2->i = .omp_data_i.2->i - 1;
2950
2951
2952 ** This is a problem. The symbol iD.1562 cannot be referenced
2953 inside the body of the outer parallel region. But since we are
2954 emitting this copy operation while expanding the inner parallel
2955 directive, we need to access the CTX structure of the outer
2956 parallel directive to get the correct mapping:
2957
2958 .omp_data_o.2.i = .omp_data_i.1->i
2959
2960 Since there may be other workshare or parallel directives enclosing
2961 the parallel directive, it may be necessary to walk up the context
2962 parent chain. This is not a problem in general because nested
2963 parallelism happens only rarely. */
2964
2965static tree
2966lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
2967{
2968 tree t;
2969 omp_context *up;
2970
50674e96
DN
2971 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
2972 t = maybe_lookup_decl (decl, up);
2973
d2dda7fe 2974 gcc_assert (!ctx->is_nested || t || is_global_var (decl));
50674e96 2975
64964499 2976 return t ? t : decl;
50674e96
DN
2977}
2978
2979
8ca5b2a2
JJ
2980/* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
2981 in outer contexts. */
2982
2983static tree
2984maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
2985{
2986 tree t = NULL;
2987 omp_context *up;
2988
d2dda7fe
JJ
2989 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
2990 t = maybe_lookup_decl (decl, up);
8ca5b2a2
JJ
2991
2992 return t ? t : decl;
2993}
2994
2995
953ff289
DN
2996/* Construct the initialization value for reduction CLAUSE. */
2997
2998tree
2999omp_reduction_init (tree clause, tree type)
3000{
db3927fb 3001 location_t loc = OMP_CLAUSE_LOCATION (clause);
953ff289
DN
3002 switch (OMP_CLAUSE_REDUCTION_CODE (clause))
3003 {
3004 case PLUS_EXPR:
3005 case MINUS_EXPR:
3006 case BIT_IOR_EXPR:
3007 case BIT_XOR_EXPR:
3008 case TRUTH_OR_EXPR:
3009 case TRUTH_ORIF_EXPR:
3010 case TRUTH_XOR_EXPR:
3011 case NE_EXPR:
e8160c9a 3012 return build_zero_cst (type);
953ff289
DN
3013
3014 case MULT_EXPR:
3015 case TRUTH_AND_EXPR:
3016 case TRUTH_ANDIF_EXPR:
3017 case EQ_EXPR:
db3927fb 3018 return fold_convert_loc (loc, type, integer_one_node);
953ff289
DN
3019
3020 case BIT_AND_EXPR:
db3927fb 3021 return fold_convert_loc (loc, type, integer_minus_one_node);
953ff289
DN
3022
3023 case MAX_EXPR:
3024 if (SCALAR_FLOAT_TYPE_P (type))
3025 {
3026 REAL_VALUE_TYPE max, min;
3027 if (HONOR_INFINITIES (TYPE_MODE (type)))
3028 {
3029 real_inf (&max);
3030 real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
3031 }
3032 else
3033 real_maxval (&min, 1, TYPE_MODE (type));
3034 return build_real (type, min);
3035 }
3036 else
3037 {
3038 gcc_assert (INTEGRAL_TYPE_P (type));
3039 return TYPE_MIN_VALUE (type);
3040 }
3041
3042 case MIN_EXPR:
3043 if (SCALAR_FLOAT_TYPE_P (type))
3044 {
3045 REAL_VALUE_TYPE max;
3046 if (HONOR_INFINITIES (TYPE_MODE (type)))
3047 real_inf (&max);
3048 else
3049 real_maxval (&max, 0, TYPE_MODE (type));
3050 return build_real (type, max);
3051 }
3052 else
3053 {
3054 gcc_assert (INTEGRAL_TYPE_P (type));
3055 return TYPE_MAX_VALUE (type);
3056 }
3057
3058 default:
3059 gcc_unreachable ();
3060 }
3061}
3062
acf0174b
JJ
3063/* Return alignment to be assumed for var in CLAUSE, which should be
3064 OMP_CLAUSE_ALIGNED. */
3065
3066static tree
3067omp_clause_aligned_alignment (tree clause)
3068{
3069 if (OMP_CLAUSE_ALIGNED_ALIGNMENT (clause))
3070 return OMP_CLAUSE_ALIGNED_ALIGNMENT (clause);
3071
3072 /* Otherwise return implementation defined alignment. */
3073 unsigned int al = 1;
ef4bddc2 3074 machine_mode mode, vmode;
acf0174b
JJ
3075 int vs = targetm.vectorize.autovectorize_vector_sizes ();
3076 if (vs)
3077 vs = 1 << floor_log2 (vs);
3078 static enum mode_class classes[]
3079 = { MODE_INT, MODE_VECTOR_INT, MODE_FLOAT, MODE_VECTOR_FLOAT };
3080 for (int i = 0; i < 4; i += 2)
3081 for (mode = GET_CLASS_NARROWEST_MODE (classes[i]);
3082 mode != VOIDmode;
3083 mode = GET_MODE_WIDER_MODE (mode))
3084 {
3085 vmode = targetm.vectorize.preferred_simd_mode (mode);
3086 if (GET_MODE_CLASS (vmode) != classes[i + 1])
3087 continue;
3088 while (vs
3089 && GET_MODE_SIZE (vmode) < vs
3090 && GET_MODE_2XWIDER_MODE (vmode) != VOIDmode)
3091 vmode = GET_MODE_2XWIDER_MODE (vmode);
3092
3093 tree type = lang_hooks.types.type_for_mode (mode, 1);
3094 if (type == NULL_TREE || TYPE_MODE (type) != mode)
3095 continue;
3096 type = build_vector_type (type, GET_MODE_SIZE (vmode)
3097 / GET_MODE_SIZE (mode));
3098 if (TYPE_MODE (type) != vmode)
3099 continue;
3100 if (TYPE_ALIGN_UNIT (type) > al)
3101 al = TYPE_ALIGN_UNIT (type);
3102 }
3103 return build_int_cst (integer_type_node, al);
3104}
3105
74bf76ed
JJ
3106/* Return maximum possible vectorization factor for the target. */
3107
3108static int
3109omp_max_vf (void)
3110{
3111 if (!optimize
3112 || optimize_debug
ab2ffbeb 3113 || !flag_tree_loop_optimize
ea0f3e87
XDL
3114 || (!flag_tree_loop_vectorize
3115 && (global_options_set.x_flag_tree_loop_vectorize
3116 || global_options_set.x_flag_tree_vectorize)))
74bf76ed
JJ
3117 return 1;
3118
3119 int vs = targetm.vectorize.autovectorize_vector_sizes ();
3120 if (vs)
3121 {
3122 vs = 1 << floor_log2 (vs);
3123 return vs;
3124 }
ef4bddc2 3125 machine_mode vqimode = targetm.vectorize.preferred_simd_mode (QImode);
74bf76ed
JJ
3126 if (GET_MODE_CLASS (vqimode) == MODE_VECTOR_INT)
3127 return GET_MODE_NUNITS (vqimode);
3128 return 1;
3129}
3130
3131/* Helper function of lower_rec_input_clauses, used for #pragma omp simd
3132 privatization. */
3133
3134static bool
3135lower_rec_simd_input_clauses (tree new_var, omp_context *ctx, int &max_vf,
3136 tree &idx, tree &lane, tree &ivar, tree &lvar)
3137{
3138 if (max_vf == 0)
3139 {
3140 max_vf = omp_max_vf ();
3141 if (max_vf > 1)
3142 {
3143 tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
3144 OMP_CLAUSE_SAFELEN);
b46ebd6c
JJ
3145 if (c && TREE_CODE (OMP_CLAUSE_SAFELEN_EXPR (c)) != INTEGER_CST)
3146 max_vf = 1;
3147 else if (c && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c),
3148 max_vf) == -1)
9439e9a1 3149 max_vf = tree_to_shwi (OMP_CLAUSE_SAFELEN_EXPR (c));
74bf76ed
JJ
3150 }
3151 if (max_vf > 1)
3152 {
3153 idx = create_tmp_var (unsigned_type_node, NULL);
3154 lane = create_tmp_var (unsigned_type_node, NULL);
3155 }
3156 }
3157 if (max_vf == 1)
3158 return false;
3159
3160 tree atype = build_array_type_nelts (TREE_TYPE (new_var), max_vf);
3161 tree avar = create_tmp_var_raw (atype, NULL);
3162 if (TREE_ADDRESSABLE (new_var))
3163 TREE_ADDRESSABLE (avar) = 1;
3164 DECL_ATTRIBUTES (avar)
3165 = tree_cons (get_identifier ("omp simd array"), NULL,
3166 DECL_ATTRIBUTES (avar));
3167 gimple_add_tmp_var (avar);
3168 ivar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, idx,
3169 NULL_TREE, NULL_TREE);
3170 lvar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, lane,
3171 NULL_TREE, NULL_TREE);
acf0174b
JJ
3172 if (DECL_P (new_var))
3173 {
3174 SET_DECL_VALUE_EXPR (new_var, lvar);
3175 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
3176 }
74bf76ed
JJ
3177 return true;
3178}
3179
decaaec8
JJ
3180/* Helper function of lower_rec_input_clauses. For a reference
3181 in simd reduction, add an underlying variable it will reference. */
3182
3183static void
3184handle_simd_reference (location_t loc, tree new_vard, gimple_seq *ilist)
3185{
3186 tree z = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_vard)));
3187 if (TREE_CONSTANT (z))
3188 {
3189 const char *name = NULL;
3190 if (DECL_NAME (new_vard))
3191 name = IDENTIFIER_POINTER (DECL_NAME (new_vard));
3192
3193 z = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_vard)), name);
3194 gimple_add_tmp_var (z);
3195 TREE_ADDRESSABLE (z) = 1;
3196 z = build_fold_addr_expr_loc (loc, z);
3197 gimplify_assign (new_vard, z, ilist);
3198 }
3199}
3200
953ff289
DN
3201/* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
3202 from the receiver (aka child) side and initializers for REFERENCE_TYPE
3203 private variables. Initialization statements go in ILIST, while calls
3204 to destructors go in DLIST. */
3205
3206static void
726a989a 3207lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
acf0174b 3208 omp_context *ctx, struct omp_for_data *fd)
953ff289 3209{
5039610b 3210 tree c, dtor, copyin_seq, x, ptr;
953ff289 3211 bool copyin_by_ref = false;
8ca5b2a2 3212 bool lastprivate_firstprivate = false;
acf0174b 3213 bool reduction_omp_orig_ref = false;
953ff289 3214 int pass;
74bf76ed 3215 bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
0aadce73 3216 && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD);
74bf76ed
JJ
3217 int max_vf = 0;
3218 tree lane = NULL_TREE, idx = NULL_TREE;
3219 tree ivar = NULL_TREE, lvar = NULL_TREE;
3220 gimple_seq llist[2] = { NULL, NULL };
953ff289 3221
953ff289
DN
3222 copyin_seq = NULL;
3223
74bf76ed
JJ
3224 /* Set max_vf=1 (which will later enforce safelen=1) in simd loops
3225 with data sharing clauses referencing variable sized vars. That
3226 is unnecessarily hard to support and very unlikely to result in
3227 vectorized code anyway. */
3228 if (is_simd)
3229 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
3230 switch (OMP_CLAUSE_CODE (c))
3231 {
da6f124d
JJ
3232 case OMP_CLAUSE_LINEAR:
3233 if (OMP_CLAUSE_LINEAR_ARRAY (c))
3234 max_vf = 1;
3235 /* FALLTHRU */
74bf76ed 3236 case OMP_CLAUSE_REDUCTION:
74bf76ed
JJ
3237 case OMP_CLAUSE_PRIVATE:
3238 case OMP_CLAUSE_FIRSTPRIVATE:
3239 case OMP_CLAUSE_LASTPRIVATE:
74bf76ed
JJ
3240 if (is_variable_sized (OMP_CLAUSE_DECL (c)))
3241 max_vf = 1;
3242 break;
3243 default:
3244 continue;
3245 }
3246
953ff289
DN
3247 /* Do all the fixed sized types in the first pass, and the variable sized
3248 types in the second pass. This makes sure that the scalar arguments to
b8698a0f 3249 the variable sized types are processed before we use them in the
953ff289
DN
3250 variable sized operations. */
3251 for (pass = 0; pass < 2; ++pass)
3252 {
3253 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
3254 {
aaf46ef9 3255 enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
953ff289
DN
3256 tree var, new_var;
3257 bool by_ref;
db3927fb 3258 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
953ff289
DN
3259
3260 switch (c_kind)
3261 {
3262 case OMP_CLAUSE_PRIVATE:
3263 if (OMP_CLAUSE_PRIVATE_DEBUG (c))
3264 continue;
3265 break;
3266 case OMP_CLAUSE_SHARED:
acf0174b
JJ
3267 /* Ignore shared directives in teams construct. */
3268 if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
3269 continue;
8ca5b2a2
JJ
3270 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
3271 {
3272 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c)));
3273 continue;
3274 }
953ff289 3275 case OMP_CLAUSE_FIRSTPRIVATE:
953ff289 3276 case OMP_CLAUSE_COPYIN:
acf0174b
JJ
3277 case OMP_CLAUSE_LINEAR:
3278 break;
953ff289 3279 case OMP_CLAUSE_REDUCTION:
acf0174b
JJ
3280 if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
3281 reduction_omp_orig_ref = true;
953ff289 3282 break;
acf0174b
JJ
3283 case OMP_CLAUSE__LOOPTEMP_:
3284 /* Handle _looptemp_ clauses only on parallel. */
3285 if (fd)
3286 continue;
74bf76ed 3287 break;
077b0dfb 3288 case OMP_CLAUSE_LASTPRIVATE:
8ca5b2a2
JJ
3289 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
3290 {
3291 lastprivate_firstprivate = true;
3292 if (pass != 0)
3293 continue;
3294 }
92d28cbb
JJ
3295 /* Even without corresponding firstprivate, if
3296 decl is Fortran allocatable, it needs outer var
3297 reference. */
3298 else if (pass == 0
3299 && lang_hooks.decls.omp_private_outer_ref
3300 (OMP_CLAUSE_DECL (c)))
3301 lastprivate_firstprivate = true;
077b0dfb 3302 break;
acf0174b
JJ
3303 case OMP_CLAUSE_ALIGNED:
3304 if (pass == 0)
3305 continue;
3306 var = OMP_CLAUSE_DECL (c);
3307 if (TREE_CODE (TREE_TYPE (var)) == POINTER_TYPE
3308 && !is_global_var (var))
3309 {
3310 new_var = maybe_lookup_decl (var, ctx);
3311 if (new_var == NULL_TREE)
3312 new_var = maybe_lookup_decl_in_outer_ctx (var, ctx);
3313 x = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
3314 x = build_call_expr_loc (clause_loc, x, 2, new_var,
3315 omp_clause_aligned_alignment (c));
3316 x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
3317 x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
3318 gimplify_and_add (x, ilist);
3319 }
3320 else if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE
3321 && is_global_var (var))
3322 {
3323 tree ptype = build_pointer_type (TREE_TYPE (var)), t, t2;
3324 new_var = lookup_decl (var, ctx);
3325 t = maybe_lookup_decl_in_outer_ctx (var, ctx);
3326 t = build_fold_addr_expr_loc (clause_loc, t);
3327 t2 = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
3328 t = build_call_expr_loc (clause_loc, t2, 2, t,
3329 omp_clause_aligned_alignment (c));
3330 t = fold_convert_loc (clause_loc, ptype, t);
3331 x = create_tmp_var (ptype, NULL);
3332 t = build2 (MODIFY_EXPR, ptype, x, t);
3333 gimplify_and_add (t, ilist);
3334 t = build_simple_mem_ref_loc (clause_loc, x);
3335 SET_DECL_VALUE_EXPR (new_var, t);
3336 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
3337 }
3338 continue;
953ff289
DN
3339 default:
3340 continue;
3341 }
3342
3343 new_var = var = OMP_CLAUSE_DECL (c);
3344 if (c_kind != OMP_CLAUSE_COPYIN)
3345 new_var = lookup_decl (var, ctx);
3346
3347 if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
3348 {
3349 if (pass != 0)
3350 continue;
3351 }
953ff289
DN
3352 else if (is_variable_sized (var))
3353 {
50674e96
DN
3354 /* For variable sized types, we need to allocate the
3355 actual storage here. Call alloca and store the
3356 result in the pointer decl that we created elsewhere. */
953ff289
DN
3357 if (pass == 0)
3358 continue;
3359
a68ab351
JJ
3360 if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
3361 {
726a989a 3362 gimple stmt;
e79983f4 3363 tree tmp, atmp;
726a989a 3364
a68ab351
JJ
3365 ptr = DECL_VALUE_EXPR (new_var);
3366 gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
3367 ptr = TREE_OPERAND (ptr, 0);
3368 gcc_assert (DECL_P (ptr));
3369 x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
726a989a
RB
3370
3371 /* void *tmp = __builtin_alloca */
e79983f4
MM
3372 atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
3373 stmt = gimple_build_call (atmp, 1, x);
726a989a
RB
3374 tmp = create_tmp_var_raw (ptr_type_node, NULL);
3375 gimple_add_tmp_var (tmp);
3376 gimple_call_set_lhs (stmt, tmp);
3377
3378 gimple_seq_add_stmt (ilist, stmt);
3379
db3927fb 3380 x = fold_convert_loc (clause_loc, TREE_TYPE (ptr), tmp);
726a989a 3381 gimplify_assign (ptr, x, ilist);
a68ab351 3382 }
953ff289 3383 }
953ff289
DN
3384 else if (is_reference (var))
3385 {
50674e96
DN
3386 /* For references that are being privatized for Fortran,
3387 allocate new backing storage for the new pointer
3388 variable. This allows us to avoid changing all the
3389 code that expects a pointer to something that expects
acf0174b 3390 a direct variable. */
953ff289
DN
3391 if (pass == 0)
3392 continue;
3393
3394 x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
a68ab351
JJ
3395 if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
3396 {
3397 x = build_receiver_ref (var, false, ctx);
db3927fb 3398 x = build_fold_addr_expr_loc (clause_loc, x);
a68ab351
JJ
3399 }
3400 else if (TREE_CONSTANT (x))
953ff289 3401 {
decaaec8
JJ
3402 /* For reduction in SIMD loop, defer adding the
3403 initialization of the reference, because if we decide
3404 to use SIMD array for it, the initilization could cause
3405 expansion ICE. */
3406 if (c_kind == OMP_CLAUSE_REDUCTION && is_simd)
4ceffa27
JJ
3407 x = NULL_TREE;
3408 else
3409 {
3410 const char *name = NULL;
3411 if (DECL_NAME (var))
3412 name = IDENTIFIER_POINTER (DECL_NAME (new_var));
3413
3414 x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
3415 name);
3416 gimple_add_tmp_var (x);
3417 TREE_ADDRESSABLE (x) = 1;
3418 x = build_fold_addr_expr_loc (clause_loc, x);
3419 }
953ff289
DN
3420 }
3421 else
3422 {
e79983f4
MM
3423 tree atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
3424 x = build_call_expr_loc (clause_loc, atmp, 1, x);
953ff289
DN
3425 }
3426
4ceffa27
JJ
3427 if (x)
3428 {
3429 x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
3430 gimplify_assign (new_var, x, ilist);
3431 }
953ff289 3432
70f34814 3433 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
953ff289
DN
3434 }
3435 else if (c_kind == OMP_CLAUSE_REDUCTION
3436 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
3437 {
3438 if (pass == 0)
3439 continue;
3440 }
3441 else if (pass != 0)
3442 continue;
3443
aaf46ef9 3444 switch (OMP_CLAUSE_CODE (c))
953ff289
DN
3445 {
3446 case OMP_CLAUSE_SHARED:
acf0174b
JJ
3447 /* Ignore shared directives in teams construct. */
3448 if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
3449 continue;
8ca5b2a2
JJ
3450 /* Shared global vars are just accessed directly. */
3451 if (is_global_var (new_var))
3452 break;
953ff289
DN
3453 /* Set up the DECL_VALUE_EXPR for shared variables now. This
3454 needs to be delayed until after fixup_child_record_type so
3455 that we get the correct type during the dereference. */
7c8f7639 3456 by_ref = use_pointer_for_field (var, ctx);
953ff289
DN
3457 x = build_receiver_ref (var, by_ref, ctx);
3458 SET_DECL_VALUE_EXPR (new_var, x);
3459 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
3460
3461 /* ??? If VAR is not passed by reference, and the variable
3462 hasn't been initialized yet, then we'll get a warning for
3463 the store into the omp_data_s structure. Ideally, we'd be
b8698a0f 3464 able to notice this and not store anything at all, but
953ff289
DN
3465 we're generating code too early. Suppress the warning. */
3466 if (!by_ref)
3467 TREE_NO_WARNING (var) = 1;
3468 break;
3469
3470 case OMP_CLAUSE_LASTPRIVATE:
3471 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
3472 break;
3473 /* FALLTHRU */
3474
3475 case OMP_CLAUSE_PRIVATE:
a68ab351
JJ
3476 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE)
3477 x = build_outer_var_ref (var, ctx);
3478 else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
3479 {
3480 if (is_task_ctx (ctx))
3481 x = build_receiver_ref (var, false, ctx);
3482 else
3483 x = build_outer_var_ref (var, ctx);
3484 }
3485 else
3486 x = NULL;
74bf76ed 3487 do_private:
acf0174b
JJ
3488 tree nx;
3489 nx = lang_hooks.decls.omp_clause_default_ctor (c, new_var, x);
74bf76ed
JJ
3490 if (is_simd)
3491 {
3492 tree y = lang_hooks.decls.omp_clause_dtor (c, new_var);
acf0174b 3493 if ((TREE_ADDRESSABLE (new_var) || nx || y
74bf76ed
JJ
3494 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
3495 && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
3496 idx, lane, ivar, lvar))
3497 {
acf0174b 3498 if (nx)
74bf76ed
JJ
3499 x = lang_hooks.decls.omp_clause_default_ctor
3500 (c, unshare_expr (ivar), x);
acf0174b 3501 if (nx && x)
74bf76ed
JJ
3502 gimplify_and_add (x, &llist[0]);
3503 if (y)
3504 {
3505 y = lang_hooks.decls.omp_clause_dtor (c, ivar);
3506 if (y)
3507 {
3508 gimple_seq tseq = NULL;
3509
3510 dtor = y;
3511 gimplify_stmt (&dtor, &tseq);
3512 gimple_seq_add_seq (&llist[1], tseq);
3513 }
3514 }
3515 break;
3516 }
3517 }
acf0174b
JJ
3518 if (nx)
3519 gimplify_and_add (nx, ilist);
953ff289
DN
3520 /* FALLTHRU */
3521
3522 do_dtor:
3523 x = lang_hooks.decls.omp_clause_dtor (c, new_var);
3524 if (x)
3525 {
726a989a
RB
3526 gimple_seq tseq = NULL;
3527
953ff289 3528 dtor = x;
726a989a 3529 gimplify_stmt (&dtor, &tseq);
355a7673 3530 gimple_seq_add_seq (dlist, tseq);
953ff289
DN
3531 }
3532 break;
3533
74bf76ed
JJ
3534 case OMP_CLAUSE_LINEAR:
3535 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
3536 goto do_firstprivate;
3537 if (OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
3538 x = NULL;
3539 else
3540 x = build_outer_var_ref (var, ctx);
3541 goto do_private;
3542
953ff289 3543 case OMP_CLAUSE_FIRSTPRIVATE:
a68ab351
JJ
3544 if (is_task_ctx (ctx))
3545 {
3546 if (is_reference (var) || is_variable_sized (var))
3547 goto do_dtor;
3548 else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var,
3549 ctx))
3550 || use_pointer_for_field (var, NULL))
3551 {
3552 x = build_receiver_ref (var, false, ctx);
3553 SET_DECL_VALUE_EXPR (new_var, x);
3554 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
3555 goto do_dtor;
3556 }
3557 }
74bf76ed 3558 do_firstprivate:
953ff289 3559 x = build_outer_var_ref (var, ctx);
74bf76ed
JJ
3560 if (is_simd)
3561 {
acf0174b
JJ
3562 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
3563 && gimple_omp_for_combined_into_p (ctx->stmt))
3564 {
da6f124d
JJ
3565 tree t = OMP_CLAUSE_LINEAR_STEP (c);
3566 tree stept = TREE_TYPE (t);
3567 tree ct = find_omp_clause (clauses,
3568 OMP_CLAUSE__LOOPTEMP_);
3569 gcc_assert (ct);
3570 tree l = OMP_CLAUSE_DECL (ct);
56ad0e38
JJ
3571 tree n1 = fd->loop.n1;
3572 tree step = fd->loop.step;
3573 tree itype = TREE_TYPE (l);
3574 if (POINTER_TYPE_P (itype))
3575 itype = signed_type_for (itype);
3576 l = fold_build2 (MINUS_EXPR, itype, l, n1);
3577 if (TYPE_UNSIGNED (itype)
3578 && fd->loop.cond_code == GT_EXPR)
3579 l = fold_build2 (TRUNC_DIV_EXPR, itype,
3580 fold_build1 (NEGATE_EXPR, itype, l),
3581 fold_build1 (NEGATE_EXPR,
3582 itype, step));
3583 else
3584 l = fold_build2 (TRUNC_DIV_EXPR, itype, l, step);
acf0174b
JJ
3585 t = fold_build2 (MULT_EXPR, stept,
3586 fold_convert (stept, l), t);
da6f124d
JJ
3587
3588 if (OMP_CLAUSE_LINEAR_ARRAY (c))
3589 {
3590 x = lang_hooks.decls.omp_clause_linear_ctor
3591 (c, new_var, x, t);
3592 gimplify_and_add (x, ilist);
3593 goto do_dtor;
3594 }
3595
acf0174b
JJ
3596 if (POINTER_TYPE_P (TREE_TYPE (x)))
3597 x = fold_build2 (POINTER_PLUS_EXPR,
3598 TREE_TYPE (x), x, t);
3599 else
3600 x = fold_build2 (PLUS_EXPR, TREE_TYPE (x), x, t);
3601 }
3602
74bf76ed
JJ
3603 if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
3604 || TREE_ADDRESSABLE (new_var))
3605 && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
3606 idx, lane, ivar, lvar))
3607 {
3608 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
3609 {
3610 tree iv = create_tmp_var (TREE_TYPE (new_var), NULL);
3611 x = lang_hooks.decls.omp_clause_copy_ctor (c, iv, x);
3612 gimplify_and_add (x, ilist);
3613 gimple_stmt_iterator gsi
3614 = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt));
3615 gimple g
3616 = gimple_build_assign (unshare_expr (lvar), iv);
3617 gsi_insert_before_without_update (&gsi, g,
3618 GSI_SAME_STMT);
da6f124d 3619 tree t = OMP_CLAUSE_LINEAR_STEP (c);
74bf76ed
JJ
3620 enum tree_code code = PLUS_EXPR;
3621 if (POINTER_TYPE_P (TREE_TYPE (new_var)))
3622 code = POINTER_PLUS_EXPR;
3623 g = gimple_build_assign_with_ops (code, iv, iv, t);
3624 gsi_insert_before_without_update (&gsi, g,
3625 GSI_SAME_STMT);
3626 break;
3627 }
3628 x = lang_hooks.decls.omp_clause_copy_ctor
3629 (c, unshare_expr (ivar), x);
3630 gimplify_and_add (x, &llist[0]);
3631 x = lang_hooks.decls.omp_clause_dtor (c, ivar);
3632 if (x)
3633 {
3634 gimple_seq tseq = NULL;
3635
3636 dtor = x;
3637 gimplify_stmt (&dtor, &tseq);
3638 gimple_seq_add_seq (&llist[1], tseq);
3639 }
3640 break;
3641 }
3642 }
953ff289
DN
3643 x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
3644 gimplify_and_add (x, ilist);
3645 goto do_dtor;
953ff289 3646
acf0174b
JJ
3647 case OMP_CLAUSE__LOOPTEMP_:
3648 gcc_assert (is_parallel_ctx (ctx));
3649 x = build_outer_var_ref (var, ctx);
3650 x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
3651 gimplify_and_add (x, ilist);
3652 break;
3653
953ff289 3654 case OMP_CLAUSE_COPYIN:
7c8f7639 3655 by_ref = use_pointer_for_field (var, NULL);
953ff289
DN
3656 x = build_receiver_ref (var, by_ref, ctx);
3657 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
3658 append_to_statement_list (x, &copyin_seq);
3659 copyin_by_ref |= by_ref;
3660 break;
3661
3662 case OMP_CLAUSE_REDUCTION:
3663 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
3664 {
a68ab351 3665 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
acf0174b 3666 gimple tseq;
a68ab351
JJ
3667 x = build_outer_var_ref (var, ctx);
3668
acf0174b
JJ
3669 if (is_reference (var)
3670 && !useless_type_conversion_p (TREE_TYPE (placeholder),
3671 TREE_TYPE (x)))
db3927fb 3672 x = build_fold_addr_expr_loc (clause_loc, x);
a68ab351
JJ
3673 SET_DECL_VALUE_EXPR (placeholder, x);
3674 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
acf0174b
JJ
3675 tree new_vard = new_var;
3676 if (is_reference (var))
3677 {
3678 gcc_assert (TREE_CODE (new_var) == MEM_REF);
3679 new_vard = TREE_OPERAND (new_var, 0);
3680 gcc_assert (DECL_P (new_vard));
3681 }
74bf76ed
JJ
3682 if (is_simd
3683 && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
3684 idx, lane, ivar, lvar))
3685 {
acf0174b
JJ
3686 if (new_vard == new_var)
3687 {
3688 gcc_assert (DECL_VALUE_EXPR (new_var) == lvar);
3689 SET_DECL_VALUE_EXPR (new_var, ivar);
3690 }
3691 else
3692 {
3693 SET_DECL_VALUE_EXPR (new_vard,
3694 build_fold_addr_expr (ivar));
3695 DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
3696 }
3697 x = lang_hooks.decls.omp_clause_default_ctor
3698 (c, unshare_expr (ivar),
3699 build_outer_var_ref (var, ctx));
3700 if (x)
3701 gimplify_and_add (x, &llist[0]);
3702 if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
3703 {
3704 tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
3705 lower_omp (&tseq, ctx);
3706 gimple_seq_add_seq (&llist[0], tseq);
3707 }
3708 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
3709 tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
3710 lower_omp (&tseq, ctx);
3711 gimple_seq_add_seq (&llist[1], tseq);
3712 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
3713 DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
3714 if (new_vard == new_var)
3715 SET_DECL_VALUE_EXPR (new_var, lvar);
3716 else
3717 SET_DECL_VALUE_EXPR (new_vard,
3718 build_fold_addr_expr (lvar));
3719 x = lang_hooks.decls.omp_clause_dtor (c, ivar);
3720 if (x)
3721 {
3722 tseq = NULL;
3723 dtor = x;
3724 gimplify_stmt (&dtor, &tseq);
3725 gimple_seq_add_seq (&llist[1], tseq);
3726 }
3727 break;
3728 }
4ceffa27
JJ
3729 /* If this is a reference to constant size reduction var
3730 with placeholder, we haven't emitted the initializer
3731 for it because it is undesirable if SIMD arrays are used.
3732 But if they aren't used, we need to emit the deferred
3733 initialization now. */
3734 else if (is_reference (var) && is_simd)
decaaec8 3735 handle_simd_reference (clause_loc, new_vard, ilist);
acf0174b 3736 x = lang_hooks.decls.omp_clause_default_ctor
92d28cbb
JJ
3737 (c, unshare_expr (new_var),
3738 build_outer_var_ref (var, ctx));
acf0174b
JJ
3739 if (x)
3740 gimplify_and_add (x, ilist);
3741 if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
3742 {
3743 tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
3744 lower_omp (&tseq, ctx);
3745 gimple_seq_add_seq (ilist, tseq);
3746 }
3747 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
3748 if (is_simd)
3749 {
3750 tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
3751 lower_omp (&tseq, ctx);
3752 gimple_seq_add_seq (dlist, tseq);
3753 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
3754 }
3755 DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
3756 goto do_dtor;
3757 }
3758 else
3759 {
3760 x = omp_reduction_init (c, TREE_TYPE (new_var));
3761 gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
e9792e1d
JJ
3762 enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
3763
3764 /* reduction(-:var) sums up the partial results, so it
3765 acts identically to reduction(+:var). */
3766 if (code == MINUS_EXPR)
3767 code = PLUS_EXPR;
3768
decaaec8
JJ
3769 tree new_vard = new_var;
3770 if (is_simd && is_reference (var))
3771 {
3772 gcc_assert (TREE_CODE (new_var) == MEM_REF);
3773 new_vard = TREE_OPERAND (new_var, 0);
3774 gcc_assert (DECL_P (new_vard));
3775 }
acf0174b
JJ
3776 if (is_simd
3777 && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
3778 idx, lane, ivar, lvar))
3779 {
acf0174b
JJ
3780 tree ref = build_outer_var_ref (var, ctx);
3781
3782 gimplify_assign (unshare_expr (ivar), x, &llist[0]);
3783
acf0174b 3784 x = build2 (code, TREE_TYPE (ref), ref, ivar);
74bf76ed
JJ
3785 ref = build_outer_var_ref (var, ctx);
3786 gimplify_assign (ref, x, &llist[1]);
decaaec8
JJ
3787
3788 if (new_vard != new_var)
3789 {
3790 SET_DECL_VALUE_EXPR (new_vard,
3791 build_fold_addr_expr (lvar));
3792 DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
3793 }
74bf76ed
JJ
3794 }
3795 else
3796 {
decaaec8
JJ
3797 if (is_reference (var) && is_simd)
3798 handle_simd_reference (clause_loc, new_vard, ilist);
74bf76ed
JJ
3799 gimplify_assign (new_var, x, ilist);
3800 if (is_simd)
e9792e1d
JJ
3801 {
3802 tree ref = build_outer_var_ref (var, ctx);
3803
3804 x = build2 (code, TREE_TYPE (ref), ref, new_var);
3805 ref = build_outer_var_ref (var, ctx);
3806 gimplify_assign (ref, x, dlist);
3807 }
74bf76ed 3808 }
953ff289
DN
3809 }
3810 break;
3811
3812 default:
3813 gcc_unreachable ();
3814 }
3815 }
3816 }
3817
74bf76ed
JJ
3818 if (lane)
3819 {
3820 tree uid = create_tmp_var (ptr_type_node, "simduid");
8928eff3
JJ
3821 /* Don't want uninit warnings on simduid, it is always uninitialized,
3822 but we use it not for the value, but for the DECL_UID only. */
3823 TREE_NO_WARNING (uid) = 1;
74bf76ed
JJ
3824 gimple g
3825 = gimple_build_call_internal (IFN_GOMP_SIMD_LANE, 1, uid);
3826 gimple_call_set_lhs (g, lane);
3827 gimple_stmt_iterator gsi = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt));
3828 gsi_insert_before_without_update (&gsi, g, GSI_SAME_STMT);
3829 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SIMDUID_);
3830 OMP_CLAUSE__SIMDUID__DECL (c) = uid;
3831 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
3832 gimple_omp_for_set_clauses (ctx->stmt, c);
3833 g = gimple_build_assign_with_ops (INTEGER_CST, lane,
3834 build_int_cst (unsigned_type_node, 0),
3835 NULL_TREE);
3836 gimple_seq_add_stmt (ilist, g);
3837 for (int i = 0; i < 2; i++)
3838 if (llist[i])
3839 {
3840 tree vf = create_tmp_var (unsigned_type_node, NULL);
3841 g = gimple_build_call_internal (IFN_GOMP_SIMD_VF, 1, uid);
3842 gimple_call_set_lhs (g, vf);
3843 gimple_seq *seq = i == 0 ? ilist : dlist;
3844 gimple_seq_add_stmt (seq, g);
3845 tree t = build_int_cst (unsigned_type_node, 0);
3846 g = gimple_build_assign_with_ops (INTEGER_CST, idx, t, NULL_TREE);
3847 gimple_seq_add_stmt (seq, g);
3848 tree body = create_artificial_label (UNKNOWN_LOCATION);
3849 tree header = create_artificial_label (UNKNOWN_LOCATION);
3850 tree end = create_artificial_label (UNKNOWN_LOCATION);
3851 gimple_seq_add_stmt (seq, gimple_build_goto (header));
3852 gimple_seq_add_stmt (seq, gimple_build_label (body));
3853 gimple_seq_add_seq (seq, llist[i]);
3854 t = build_int_cst (unsigned_type_node, 1);
3855 g = gimple_build_assign_with_ops (PLUS_EXPR, idx, idx, t);
3856 gimple_seq_add_stmt (seq, g);
3857 gimple_seq_add_stmt (seq, gimple_build_label (header));
3858 g = gimple_build_cond (LT_EXPR, idx, vf, body, end);
3859 gimple_seq_add_stmt (seq, g);
3860 gimple_seq_add_stmt (seq, gimple_build_label (end));
3861 }
3862 }
3863
953ff289
DN
3864 /* The copyin sequence is not to be executed by the main thread, since
3865 that would result in self-copies. Perhaps not visible to scalars,
3866 but it certainly is to C++ operator=. */
3867 if (copyin_seq)
3868 {
e79983f4
MM
3869 x = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM),
3870 0);
953ff289
DN
3871 x = build2 (NE_EXPR, boolean_type_node, x,
3872 build_int_cst (TREE_TYPE (x), 0));
3873 x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
3874 gimplify_and_add (x, ilist);
3875 }
3876
3877 /* If any copyin variable is passed by reference, we must ensure the
3878 master thread doesn't modify it before it is copied over in all
8ca5b2a2
JJ
3879 threads. Similarly for variables in both firstprivate and
3880 lastprivate clauses we need to ensure the lastprivate copying
acf0174b
JJ
3881 happens after firstprivate copying in all threads. And similarly
3882 for UDRs if initializer expression refers to omp_orig. */
3883 if (copyin_by_ref || lastprivate_firstprivate || reduction_omp_orig_ref)
74bf76ed
JJ
3884 {
3885 /* Don't add any barrier for #pragma omp simd or
3886 #pragma omp distribute. */
3887 if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
e2110f8f 3888 || gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_FOR)
acf0174b 3889 gimple_seq_add_stmt (ilist, build_omp_barrier (NULL_TREE));
74bf76ed
JJ
3890 }
3891
3892 /* If max_vf is non-zero, then we can use only a vectorization factor
3893 up to the max_vf we chose. So stick it into the safelen clause. */
3894 if (max_vf)
3895 {
3896 tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
3897 OMP_CLAUSE_SAFELEN);
3898 if (c == NULL_TREE
b46ebd6c
JJ
3899 || (TREE_CODE (OMP_CLAUSE_SAFELEN_EXPR (c)) == INTEGER_CST
3900 && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c),
3901 max_vf) == 1))
74bf76ed
JJ
3902 {
3903 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
3904 OMP_CLAUSE_SAFELEN_EXPR (c) = build_int_cst (integer_type_node,
3905 max_vf);
3906 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
3907 gimple_omp_for_set_clauses (ctx->stmt, c);
3908 }
3909 }
953ff289
DN
3910}
3911
50674e96 3912
953ff289
DN
3913/* Generate code to implement the LASTPRIVATE clauses. This is used for
3914 both parallel and workshare constructs. PREDICATE may be NULL if it's
3915 always true. */
3916
3917static void
726a989a 3918lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
acf0174b 3919 omp_context *ctx)
953ff289 3920{
74bf76ed 3921 tree x, c, label = NULL, orig_clauses = clauses;
a68ab351 3922 bool par_clauses = false;
74bf76ed 3923 tree simduid = NULL, lastlane = NULL;
953ff289 3924
74bf76ed
JJ
3925 /* Early exit if there are no lastprivate or linear clauses. */
3926 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
3927 if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LASTPRIVATE
3928 || (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LINEAR
3929 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (clauses)))
3930 break;
953ff289
DN
3931 if (clauses == NULL)
3932 {
3933 /* If this was a workshare clause, see if it had been combined
3934 with its parallel. In that case, look for the clauses on the
3935 parallel statement itself. */
3936 if (is_parallel_ctx (ctx))
3937 return;
3938
3939 ctx = ctx->outer;
3940 if (ctx == NULL || !is_parallel_ctx (ctx))
3941 return;
3942
726a989a 3943 clauses = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
953ff289
DN
3944 OMP_CLAUSE_LASTPRIVATE);
3945 if (clauses == NULL)
3946 return;
a68ab351 3947 par_clauses = true;
953ff289
DN
3948 }
3949
726a989a
RB
3950 if (predicate)
3951 {
3952 gimple stmt;
3953 tree label_true, arm1, arm2;
3954
c2255bc4
AH
3955 label = create_artificial_label (UNKNOWN_LOCATION);
3956 label_true = create_artificial_label (UNKNOWN_LOCATION);
726a989a
RB
3957 arm1 = TREE_OPERAND (predicate, 0);
3958 arm2 = TREE_OPERAND (predicate, 1);
3959 gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
3960 gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
3961 stmt = gimple_build_cond (TREE_CODE (predicate), arm1, arm2,
3962 label_true, label);
3963 gimple_seq_add_stmt (stmt_list, stmt);
3964 gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
3965 }
953ff289 3966
74bf76ed 3967 if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
0aadce73 3968 && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
74bf76ed
JJ
3969 {
3970 simduid = find_omp_clause (orig_clauses, OMP_CLAUSE__SIMDUID_);
3971 if (simduid)
3972 simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
3973 }
3974
a68ab351 3975 for (c = clauses; c ;)
953ff289
DN
3976 {
3977 tree var, new_var;
db3927fb 3978 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
953ff289 3979
74bf76ed
JJ
3980 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
3981 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
3982 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
a68ab351
JJ
3983 {
3984 var = OMP_CLAUSE_DECL (c);
3985 new_var = lookup_decl (var, ctx);
953ff289 3986
74bf76ed
JJ
3987 if (simduid && DECL_HAS_VALUE_EXPR_P (new_var))
3988 {
3989 tree val = DECL_VALUE_EXPR (new_var);
3990 if (TREE_CODE (val) == ARRAY_REF
3991 && VAR_P (TREE_OPERAND (val, 0))
3992 && lookup_attribute ("omp simd array",
3993 DECL_ATTRIBUTES (TREE_OPERAND (val,
3994 0))))
3995 {
3996 if (lastlane == NULL)
3997 {
3998 lastlane = create_tmp_var (unsigned_type_node, NULL);
3999 gimple g
4000 = gimple_build_call_internal (IFN_GOMP_SIMD_LAST_LANE,
4001 2, simduid,
4002 TREE_OPERAND (val, 1));
4003 gimple_call_set_lhs (g, lastlane);
4004 gimple_seq_add_stmt (stmt_list, g);
4005 }
4006 new_var = build4 (ARRAY_REF, TREE_TYPE (val),
4007 TREE_OPERAND (val, 0), lastlane,
4008 NULL_TREE, NULL_TREE);
4009 }
4010 }
4011
4012 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
4013 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
726a989a 4014 {
355a7673 4015 lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
726a989a
RB
4016 gimple_seq_add_seq (stmt_list,
4017 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
74bf76ed 4018 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
726a989a 4019 }
f7468577
JJ
4020 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
4021 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
4022 {
4023 lower_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
4024 gimple_seq_add_seq (stmt_list,
4025 OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
4026 OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) = NULL;
4027 }
953ff289 4028
a68ab351
JJ
4029 x = build_outer_var_ref (var, ctx);
4030 if (is_reference (var))
70f34814 4031 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
a68ab351 4032 x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
726a989a 4033 gimplify_and_add (x, stmt_list);
a68ab351
JJ
4034 }
4035 c = OMP_CLAUSE_CHAIN (c);
4036 if (c == NULL && !par_clauses)
4037 {
4038 /* If this was a workshare clause, see if it had been combined
4039 with its parallel. In that case, continue looking for the
4040 clauses also on the parallel statement itself. */
4041 if (is_parallel_ctx (ctx))
4042 break;
4043
4044 ctx = ctx->outer;
4045 if (ctx == NULL || !is_parallel_ctx (ctx))
4046 break;
4047
726a989a 4048 c = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
a68ab351
JJ
4049 OMP_CLAUSE_LASTPRIVATE);
4050 par_clauses = true;
4051 }
953ff289
DN
4052 }
4053
726a989a
RB
4054 if (label)
4055 gimple_seq_add_stmt (stmt_list, gimple_build_label (label));
953ff289
DN
4056}
4057
50674e96 4058
953ff289
DN
4059/* Generate code to implement the REDUCTION clauses. */
4060
4061static void
726a989a 4062lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
953ff289 4063{
726a989a
RB
4064 gimple_seq sub_seq = NULL;
4065 gimple stmt;
4066 tree x, c;
953ff289
DN
4067 int count = 0;
4068
74bf76ed
JJ
4069 /* SIMD reductions are handled in lower_rec_input_clauses. */
4070 if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
0aadce73 4071 && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
74bf76ed
JJ
4072 return;
4073
953ff289
DN
4074 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
4075 update in that case, otherwise use a lock. */
4076 for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
aaf46ef9 4077 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
953ff289
DN
4078 {
4079 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
4080 {
acf0174b 4081 /* Never use OMP_ATOMIC for array reductions or UDRs. */
953ff289
DN
4082 count = -1;
4083 break;
4084 }
4085 count++;
4086 }
4087
4088 if (count == 0)
4089 return;
4090
4091 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
4092 {
4093 tree var, ref, new_var;
4094 enum tree_code code;
db3927fb 4095 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
953ff289 4096
aaf46ef9 4097 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
953ff289
DN
4098 continue;
4099
4100 var = OMP_CLAUSE_DECL (c);
4101 new_var = lookup_decl (var, ctx);
4102 if (is_reference (var))
70f34814 4103 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
953ff289
DN
4104 ref = build_outer_var_ref (var, ctx);
4105 code = OMP_CLAUSE_REDUCTION_CODE (c);
50674e96
DN
4106
4107 /* reduction(-:var) sums up the partial results, so it acts
4108 identically to reduction(+:var). */
953ff289
DN
4109 if (code == MINUS_EXPR)
4110 code = PLUS_EXPR;
4111
4112 if (count == 1)
4113 {
db3927fb 4114 tree addr = build_fold_addr_expr_loc (clause_loc, ref);
953ff289
DN
4115
4116 addr = save_expr (addr);
4117 ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
db3927fb 4118 x = fold_build2_loc (clause_loc, code, TREE_TYPE (ref), ref, new_var);
953ff289 4119 x = build2 (OMP_ATOMIC, void_type_node, addr, x);
726a989a 4120 gimplify_and_add (x, stmt_seqp);
953ff289
DN
4121 return;
4122 }
4123
4124 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
4125 {
4126 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
4127
acf0174b
JJ
4128 if (is_reference (var)
4129 && !useless_type_conversion_p (TREE_TYPE (placeholder),
4130 TREE_TYPE (ref)))
db3927fb 4131 ref = build_fold_addr_expr_loc (clause_loc, ref);
953ff289
DN
4132 SET_DECL_VALUE_EXPR (placeholder, ref);
4133 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
355a7673 4134 lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
726a989a
RB
4135 gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
4136 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
953ff289
DN
4137 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
4138 }
4139 else
4140 {
4141 x = build2 (code, TREE_TYPE (ref), ref, new_var);
4142 ref = build_outer_var_ref (var, ctx);
726a989a 4143 gimplify_assign (ref, x, &sub_seq);
953ff289
DN
4144 }
4145 }
4146
e79983f4
MM
4147 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START),
4148 0);
726a989a 4149 gimple_seq_add_stmt (stmt_seqp, stmt);
953ff289 4150
726a989a 4151 gimple_seq_add_seq (stmt_seqp, sub_seq);
953ff289 4152
e79983f4
MM
4153 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END),
4154 0);
726a989a 4155 gimple_seq_add_stmt (stmt_seqp, stmt);
953ff289
DN
4156}
4157
50674e96 4158
953ff289
DN
4159/* Generate code to implement the COPYPRIVATE clauses. */
4160
4161static void
726a989a 4162lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist,
953ff289
DN
4163 omp_context *ctx)
4164{
4165 tree c;
4166
4167 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
4168 {
78db7d92 4169 tree var, new_var, ref, x;
953ff289 4170 bool by_ref;
db3927fb 4171 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
953ff289 4172
aaf46ef9 4173 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
953ff289
DN
4174 continue;
4175
4176 var = OMP_CLAUSE_DECL (c);
7c8f7639 4177 by_ref = use_pointer_for_field (var, NULL);
953ff289
DN
4178
4179 ref = build_sender_ref (var, ctx);
78db7d92
JJ
4180 x = new_var = lookup_decl_in_outer_ctx (var, ctx);
4181 if (by_ref)
4182 {
4183 x = build_fold_addr_expr_loc (clause_loc, new_var);
4184 x = fold_convert_loc (clause_loc, TREE_TYPE (ref), x);
4185 }
726a989a 4186 gimplify_assign (ref, x, slist);
953ff289 4187
78db7d92
JJ
4188 ref = build_receiver_ref (var, false, ctx);
4189 if (by_ref)
4190 {
4191 ref = fold_convert_loc (clause_loc,
4192 build_pointer_type (TREE_TYPE (new_var)),
4193 ref);
4194 ref = build_fold_indirect_ref_loc (clause_loc, ref);
4195 }
953ff289
DN
4196 if (is_reference (var))
4197 {
78db7d92 4198 ref = fold_convert_loc (clause_loc, TREE_TYPE (new_var), ref);
70f34814
RG
4199 ref = build_simple_mem_ref_loc (clause_loc, ref);
4200 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
953ff289 4201 }
78db7d92 4202 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, ref);
953ff289
DN
4203 gimplify_and_add (x, rlist);
4204 }
4205}
4206
50674e96 4207
953ff289
DN
4208/* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
4209 and REDUCTION from the sender (aka parent) side. */
4210
4211static void
726a989a
RB
4212lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist,
4213 omp_context *ctx)
953ff289
DN
4214{
4215 tree c;
4216
4217 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
4218 {
50674e96 4219 tree val, ref, x, var;
953ff289 4220 bool by_ref, do_in = false, do_out = false;
db3927fb 4221 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
953ff289 4222
aaf46ef9 4223 switch (OMP_CLAUSE_CODE (c))
953ff289 4224 {
a68ab351
JJ
4225 case OMP_CLAUSE_PRIVATE:
4226 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
4227 break;
4228 continue;
953ff289
DN
4229 case OMP_CLAUSE_FIRSTPRIVATE:
4230 case OMP_CLAUSE_COPYIN:
4231 case OMP_CLAUSE_LASTPRIVATE:
4232 case OMP_CLAUSE_REDUCTION:
acf0174b 4233 case OMP_CLAUSE__LOOPTEMP_:
953ff289
DN
4234 break;
4235 default:
4236 continue;
4237 }
4238
d2dda7fe
JJ
4239 val = OMP_CLAUSE_DECL (c);
4240 var = lookup_decl_in_outer_ctx (val, ctx);
50674e96 4241
8ca5b2a2
JJ
4242 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
4243 && is_global_var (var))
4244 continue;
953ff289
DN
4245 if (is_variable_sized (val))
4246 continue;
7c8f7639 4247 by_ref = use_pointer_for_field (val, NULL);
953ff289 4248
aaf46ef9 4249 switch (OMP_CLAUSE_CODE (c))
953ff289 4250 {
a68ab351 4251 case OMP_CLAUSE_PRIVATE:
953ff289
DN
4252 case OMP_CLAUSE_FIRSTPRIVATE:
4253 case OMP_CLAUSE_COPYIN:
acf0174b 4254 case OMP_CLAUSE__LOOPTEMP_:
953ff289
DN
4255 do_in = true;
4256 break;
4257
4258 case OMP_CLAUSE_LASTPRIVATE:
4259 if (by_ref || is_reference (val))
4260 {
4261 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
4262 continue;
4263 do_in = true;
4264 }
4265 else
a68ab351
JJ
4266 {
4267 do_out = true;
4268 if (lang_hooks.decls.omp_private_outer_ref (val))
4269 do_in = true;
4270 }
953ff289
DN
4271 break;
4272
4273 case OMP_CLAUSE_REDUCTION:
4274 do_in = true;
4275 do_out = !(by_ref || is_reference (val));
4276 break;
4277
4278 default:
4279 gcc_unreachable ();
4280 }
4281
4282 if (do_in)
4283 {
4284 ref = build_sender_ref (val, ctx);
db3927fb 4285 x = by_ref ? build_fold_addr_expr_loc (clause_loc, var) : var;
726a989a 4286 gimplify_assign (ref, x, ilist);
a68ab351
JJ
4287 if (is_task_ctx (ctx))
4288 DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref, 1)) = NULL;
953ff289 4289 }
50674e96 4290
953ff289
DN
4291 if (do_out)
4292 {
4293 ref = build_sender_ref (val, ctx);
726a989a 4294 gimplify_assign (var, ref, olist);
953ff289
DN
4295 }
4296 }
4297}
4298
726a989a
RB
4299/* Generate code to implement SHARED from the sender (aka parent)
4300 side. This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
4301 list things that got automatically shared. */
953ff289
DN
4302
4303static void
726a989a 4304lower_send_shared_vars (gimple_seq *ilist, gimple_seq *olist, omp_context *ctx)
953ff289 4305{
a68ab351 4306 tree var, ovar, nvar, f, x, record_type;
953ff289
DN
4307
4308 if (ctx->record_type == NULL)
4309 return;
50674e96 4310
a68ab351 4311 record_type = ctx->srecord_type ? ctx->srecord_type : ctx->record_type;
910ad8de 4312 for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
953ff289
DN
4313 {
4314 ovar = DECL_ABSTRACT_ORIGIN (f);
4315 nvar = maybe_lookup_decl (ovar, ctx);
4316 if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
4317 continue;
4318
50674e96
DN
4319 /* If CTX is a nested parallel directive. Find the immediately
4320 enclosing parallel or workshare construct that contains a
4321 mapping for OVAR. */
d2dda7fe 4322 var = lookup_decl_in_outer_ctx (ovar, ctx);
50674e96 4323
7c8f7639 4324 if (use_pointer_for_field (ovar, ctx))
953ff289
DN
4325 {
4326 x = build_sender_ref (ovar, ctx);
50674e96 4327 var = build_fold_addr_expr (var);
726a989a 4328 gimplify_assign (x, var, ilist);
953ff289
DN
4329 }
4330 else
4331 {
4332 x = build_sender_ref (ovar, ctx);
726a989a 4333 gimplify_assign (x, var, ilist);
953ff289 4334
14e5b285
RG
4335 if (!TREE_READONLY (var)
4336 /* We don't need to receive a new reference to a result
4337 or parm decl. In fact we may not store to it as we will
4338 invalidate any pending RSO and generate wrong gimple
4339 during inlining. */
4340 && !((TREE_CODE (var) == RESULT_DECL
4341 || TREE_CODE (var) == PARM_DECL)
4342 && DECL_BY_REFERENCE (var)))
a68ab351
JJ
4343 {
4344 x = build_sender_ref (ovar, ctx);
726a989a 4345 gimplify_assign (var, x, olist);
a68ab351 4346 }
953ff289
DN
4347 }
4348 }
4349}
4350
726a989a
RB
4351
4352/* A convenience function to build an empty GIMPLE_COND with just the
4353 condition. */
4354
4355static gimple
4356gimple_build_cond_empty (tree cond)
4357{
4358 enum tree_code pred_code;
4359 tree lhs, rhs;
4360
4361 gimple_cond_get_ops_from_tree (cond, &pred_code, &lhs, &rhs);
4362 return gimple_build_cond (pred_code, lhs, rhs, NULL_TREE, NULL_TREE);
4363}
4364
4365
b8698a0f 4366/* Build the function calls to GOMP_parallel_start etc to actually
50674e96
DN
4367 generate the parallel operation. REGION is the parallel region
4368 being expanded. BB is the block where to insert the code. WS_ARGS
4369 will be set if this is a call to a combined parallel+workshare
4370 construct, it contains the list of additional arguments needed by
4371 the workshare construct. */
953ff289
DN
4372
4373static void
777f7f9a 4374expand_parallel_call (struct omp_region *region, basic_block bb,
9771b263 4375 gimple entry_stmt, vec<tree, va_gc> *ws_args)
953ff289 4376{
acf0174b 4377 tree t, t1, t2, val, cond, c, clauses, flags;
726a989a
RB
4378 gimple_stmt_iterator gsi;
4379 gimple stmt;
e79983f4
MM
4380 enum built_in_function start_ix;
4381 int start_ix2;
db3927fb 4382 location_t clause_loc;
9771b263 4383 vec<tree, va_gc> *args;
50674e96 4384
726a989a 4385 clauses = gimple_omp_parallel_clauses (entry_stmt);
50674e96 4386
acf0174b 4387 /* Determine what flavor of GOMP_parallel we will be
50674e96 4388 emitting. */
acf0174b 4389 start_ix = BUILT_IN_GOMP_PARALLEL;
50674e96
DN
4390 if (is_combined_parallel (region))
4391 {
777f7f9a 4392 switch (region->inner->type)
50674e96 4393 {
726a989a 4394 case GIMPLE_OMP_FOR:
a68ab351 4395 gcc_assert (region->inner->sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
acf0174b 4396 start_ix2 = ((int)BUILT_IN_GOMP_PARALLEL_LOOP_STATIC
e79983f4
MM
4397 + (region->inner->sched_kind
4398 == OMP_CLAUSE_SCHEDULE_RUNTIME
4399 ? 3 : region->inner->sched_kind));
4400 start_ix = (enum built_in_function)start_ix2;
777f7f9a 4401 break;
726a989a 4402 case GIMPLE_OMP_SECTIONS:
acf0174b 4403 start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS;
777f7f9a
RH
4404 break;
4405 default:
4406 gcc_unreachable ();
50674e96 4407 }
50674e96 4408 }
953ff289
DN
4409
4410 /* By default, the value of NUM_THREADS is zero (selected at run time)
4411 and there is no conditional. */
4412 cond = NULL_TREE;
4413 val = build_int_cst (unsigned_type_node, 0);
acf0174b 4414 flags = build_int_cst (unsigned_type_node, 0);
953ff289
DN
4415
4416 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
4417 if (c)
4418 cond = OMP_CLAUSE_IF_EXPR (c);
4419
4420 c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
4421 if (c)
db3927fb
AH
4422 {
4423 val = OMP_CLAUSE_NUM_THREADS_EXPR (c);
4424 clause_loc = OMP_CLAUSE_LOCATION (c);
4425 }
4426 else
4427 clause_loc = gimple_location (entry_stmt);
953ff289 4428
acf0174b
JJ
4429 c = find_omp_clause (clauses, OMP_CLAUSE_PROC_BIND);
4430 if (c)
4431 flags = build_int_cst (unsigned_type_node, OMP_CLAUSE_PROC_BIND_KIND (c));
4432
953ff289 4433 /* Ensure 'val' is of the correct type. */
db3927fb 4434 val = fold_convert_loc (clause_loc, unsigned_type_node, val);
953ff289
DN
4435
4436 /* If we found the clause 'if (cond)', build either
4437 (cond != 0) or (cond ? val : 1u). */
4438 if (cond)
4439 {
50674e96
DN
4440 cond = gimple_boolify (cond);
4441
953ff289 4442 if (integer_zerop (val))
db3927fb
AH
4443 val = fold_build2_loc (clause_loc,
4444 EQ_EXPR, unsigned_type_node, cond,
917948d3 4445 build_int_cst (TREE_TYPE (cond), 0));
953ff289 4446 else
50674e96
DN
4447 {
4448 basic_block cond_bb, then_bb, else_bb;
917948d3 4449 edge e, e_then, e_else;
726a989a 4450 tree tmp_then, tmp_else, tmp_join, tmp_var;
917948d3
ZD
4451
4452 tmp_var = create_tmp_var (TREE_TYPE (val), NULL);
4453 if (gimple_in_ssa_p (cfun))
4454 {
726a989a
RB
4455 tmp_then = make_ssa_name (tmp_var, NULL);
4456 tmp_else = make_ssa_name (tmp_var, NULL);
4457 tmp_join = make_ssa_name (tmp_var, NULL);
917948d3
ZD
4458 }
4459 else
4460 {
4461 tmp_then = tmp_var;
4462 tmp_else = tmp_var;
4463 tmp_join = tmp_var;
4464 }
50674e96 4465
50674e96
DN
4466 e = split_block (bb, NULL);
4467 cond_bb = e->src;
4468 bb = e->dest;
4469 remove_edge (e);
4470
4471 then_bb = create_empty_bb (cond_bb);
4472 else_bb = create_empty_bb (then_bb);
917948d3
ZD
4473 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
4474 set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
50674e96 4475
726a989a
RB
4476 stmt = gimple_build_cond_empty (cond);
4477 gsi = gsi_start_bb (cond_bb);
4478 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
50674e96 4479
726a989a
RB
4480 gsi = gsi_start_bb (then_bb);
4481 stmt = gimple_build_assign (tmp_then, val);
4482 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
50674e96 4483
726a989a
RB
4484 gsi = gsi_start_bb (else_bb);
4485 stmt = gimple_build_assign
4486 (tmp_else, build_int_cst (unsigned_type_node, 1));
4487 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
50674e96
DN
4488
4489 make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
4490 make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
726338f4
RB
4491 add_bb_to_loop (then_bb, cond_bb->loop_father);
4492 add_bb_to_loop (else_bb, cond_bb->loop_father);
917948d3
ZD
4493 e_then = make_edge (then_bb, bb, EDGE_FALLTHRU);
4494 e_else = make_edge (else_bb, bb, EDGE_FALLTHRU);
50674e96 4495
917948d3
ZD
4496 if (gimple_in_ssa_p (cfun))
4497 {
726a989a 4498 gimple phi = create_phi_node (tmp_join, bb);
9e227d60
DC
4499 add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION);
4500 add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION);
917948d3
ZD
4501 }
4502
4503 val = tmp_join;
50674e96
DN
4504 }
4505
726a989a
RB
4506 gsi = gsi_start_bb (bb);
4507 val = force_gimple_operand_gsi (&gsi, val, true, NULL_TREE,
4508 false, GSI_CONTINUE_LINKING);
953ff289
DN
4509 }
4510
726a989a
RB
4511 gsi = gsi_last_bb (bb);
4512 t = gimple_omp_parallel_data_arg (entry_stmt);
953ff289 4513 if (t == NULL)
5039610b 4514 t1 = null_pointer_node;
953ff289 4515 else
5039610b 4516 t1 = build_fold_addr_expr (t);
726a989a 4517 t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
50674e96 4518
acf0174b 4519 vec_alloc (args, 4 + vec_safe_length (ws_args));
9771b263
DN
4520 args->quick_push (t2);
4521 args->quick_push (t1);
4522 args->quick_push (val);
4523 if (ws_args)
4524 args->splice (*ws_args);
acf0174b 4525 args->quick_push (flags);
3bb06db4
NF
4526
4527 t = build_call_expr_loc_vec (UNKNOWN_LOCATION,
e79983f4 4528 builtin_decl_explicit (start_ix), args);
50674e96 4529
726a989a
RB
4530 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4531 false, GSI_CONTINUE_LINKING);
953ff289
DN
4532}
4533
9a771876
JJ
4534/* Insert a function call whose name is FUNC_NAME with the information from
4535 ENTRY_STMT into the basic_block BB. */
4536
4537static void
4538expand_cilk_for_call (basic_block bb, gimple entry_stmt,
4539 vec <tree, va_gc> *ws_args)
4540{
4541 tree t, t1, t2;
4542 gimple_stmt_iterator gsi;
4543 vec <tree, va_gc> *args;
4544
4545 gcc_assert (vec_safe_length (ws_args) == 2);
4546 tree func_name = (*ws_args)[0];
4547 tree grain = (*ws_args)[1];
4548
4549 tree clauses = gimple_omp_parallel_clauses (entry_stmt);
4550 tree count = find_omp_clause (clauses, OMP_CLAUSE__CILK_FOR_COUNT_);
4551 gcc_assert (count != NULL_TREE);
4552 count = OMP_CLAUSE_OPERAND (count, 0);
4553
4554 gsi = gsi_last_bb (bb);
4555 t = gimple_omp_parallel_data_arg (entry_stmt);
4556 if (t == NULL)
4557 t1 = null_pointer_node;
4558 else
4559 t1 = build_fold_addr_expr (t);
4560 t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
4561
4562 vec_alloc (args, 4);
4563 args->quick_push (t2);
4564 args->quick_push (t1);
4565 args->quick_push (count);
4566 args->quick_push (grain);
4567 t = build_call_expr_loc_vec (UNKNOWN_LOCATION, func_name, args);
4568
4569 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, false,
4570 GSI_CONTINUE_LINKING);
4571}
50674e96 4572
a68ab351
JJ
4573/* Build the function call to GOMP_task to actually
4574 generate the task operation. BB is the block where to insert the code. */
4575
4576static void
726a989a 4577expand_task_call (basic_block bb, gimple entry_stmt)
a68ab351 4578{
acf0174b 4579 tree t, t1, t2, t3, flags, cond, c, c2, clauses, depend;
726a989a 4580 gimple_stmt_iterator gsi;
db3927fb 4581 location_t loc = gimple_location (entry_stmt);
a68ab351 4582
726a989a 4583 clauses = gimple_omp_task_clauses (entry_stmt);
a68ab351 4584
a68ab351
JJ
4585 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
4586 if (c)
4587 cond = gimple_boolify (OMP_CLAUSE_IF_EXPR (c));
4588 else
4589 cond = boolean_true_node;
4590
4591 c = find_omp_clause (clauses, OMP_CLAUSE_UNTIED);
20906c66 4592 c2 = find_omp_clause (clauses, OMP_CLAUSE_MERGEABLE);
acf0174b 4593 depend = find_omp_clause (clauses, OMP_CLAUSE_DEPEND);
20906c66 4594 flags = build_int_cst (unsigned_type_node,
acf0174b 4595 (c ? 1 : 0) + (c2 ? 4 : 0) + (depend ? 8 : 0));
20906c66
JJ
4596
4597 c = find_omp_clause (clauses, OMP_CLAUSE_FINAL);
4598 if (c)
4599 {
4600 c = gimple_boolify (OMP_CLAUSE_FINAL_EXPR (c));
4601 c = fold_build3_loc (loc, COND_EXPR, unsigned_type_node, c,
4602 build_int_cst (unsigned_type_node, 2),
4603 build_int_cst (unsigned_type_node, 0));
4604 flags = fold_build2_loc (loc, PLUS_EXPR, unsigned_type_node, flags, c);
4605 }
acf0174b
JJ
4606 if (depend)
4607 depend = OMP_CLAUSE_DECL (depend);
4608 else
4609 depend = build_int_cst (ptr_type_node, 0);
a68ab351 4610
726a989a
RB
4611 gsi = gsi_last_bb (bb);
4612 t = gimple_omp_task_data_arg (entry_stmt);
a68ab351
JJ
4613 if (t == NULL)
4614 t2 = null_pointer_node;
4615 else
db3927fb
AH
4616 t2 = build_fold_addr_expr_loc (loc, t);
4617 t1 = build_fold_addr_expr_loc (loc, gimple_omp_task_child_fn (entry_stmt));
726a989a 4618 t = gimple_omp_task_copy_fn (entry_stmt);
a68ab351
JJ
4619 if (t == NULL)
4620 t3 = null_pointer_node;
4621 else
db3927fb 4622 t3 = build_fold_addr_expr_loc (loc, t);
a68ab351 4623
e79983f4 4624 t = build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_TASK),
acf0174b 4625 8, t1, t2, t3,
726a989a 4626 gimple_omp_task_arg_size (entry_stmt),
acf0174b
JJ
4627 gimple_omp_task_arg_align (entry_stmt), cond, flags,
4628 depend);
a68ab351 4629
726a989a
RB
4630 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4631 false, GSI_CONTINUE_LINKING);
a68ab351
JJ
4632}
4633
4634
726a989a
RB
4635/* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
4636 catch handler and return it. This prevents programs from violating the
4637 structured block semantics with throws. */
953ff289 4638
726a989a
RB
4639static gimple_seq
4640maybe_catch_exception (gimple_seq body)
953ff289 4641{
1d65f45c
RH
4642 gimple g;
4643 tree decl;
953ff289
DN
4644
4645 if (!flag_exceptions)
726a989a 4646 return body;
953ff289 4647
3b06d379
SB
4648 if (lang_hooks.eh_protect_cleanup_actions != NULL)
4649 decl = lang_hooks.eh_protect_cleanup_actions ();
953ff289 4650 else
e79983f4 4651 decl = builtin_decl_explicit (BUILT_IN_TRAP);
726a989a 4652
1d65f45c
RH
4653 g = gimple_build_eh_must_not_throw (decl);
4654 g = gimple_build_try (body, gimple_seq_alloc_with_stmt (g),
726a989a 4655 GIMPLE_TRY_CATCH);
953ff289 4656
1d65f45c 4657 return gimple_seq_alloc_with_stmt (g);
953ff289
DN
4658}
4659
50674e96 4660/* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
953ff289 4661
50674e96 4662static tree
9771b263 4663vec2chain (vec<tree, va_gc> *v)
953ff289 4664{
c021f10b
NF
4665 tree chain = NULL_TREE, t;
4666 unsigned ix;
953ff289 4667
9771b263 4668 FOR_EACH_VEC_SAFE_ELT_REVERSE (v, ix, t)
50674e96 4669 {
910ad8de 4670 DECL_CHAIN (t) = chain;
c021f10b 4671 chain = t;
50674e96 4672 }
953ff289 4673
c021f10b 4674 return chain;
50674e96 4675}
953ff289 4676
953ff289 4677
50674e96 4678/* Remove barriers in REGION->EXIT's block. Note that this is only
726a989a
RB
4679 valid for GIMPLE_OMP_PARALLEL regions. Since the end of a parallel region
4680 is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
4681 left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
50674e96 4682 removed. */
953ff289 4683
50674e96
DN
4684static void
4685remove_exit_barrier (struct omp_region *region)
4686{
726a989a 4687 gimple_stmt_iterator gsi;
50674e96 4688 basic_block exit_bb;
777f7f9a
RH
4689 edge_iterator ei;
4690 edge e;
726a989a 4691 gimple stmt;
03742a9b 4692 int any_addressable_vars = -1;
953ff289 4693
777f7f9a 4694 exit_bb = region->exit;
953ff289 4695
2aee3e57
JJ
4696 /* If the parallel region doesn't return, we don't have REGION->EXIT
4697 block at all. */
4698 if (! exit_bb)
4699 return;
4700
726a989a
RB
4701 /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN. The
4702 workshare's GIMPLE_OMP_RETURN will be in a preceding block. The kinds of
777f7f9a
RH
4703 statements that can appear in between are extremely limited -- no
4704 memory operations at all. Here, we allow nothing at all, so the
726a989a
RB
4705 only thing we allow to precede this GIMPLE_OMP_RETURN is a label. */
4706 gsi = gsi_last_bb (exit_bb);
4707 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
4708 gsi_prev (&gsi);
4709 if (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
50674e96 4710 return;
953ff289 4711
777f7f9a
RH
4712 FOR_EACH_EDGE (e, ei, exit_bb->preds)
4713 {
726a989a
RB
4714 gsi = gsi_last_bb (e->src);
4715 if (gsi_end_p (gsi))
777f7f9a 4716 continue;
726a989a 4717 stmt = gsi_stmt (gsi);
03742a9b
JJ
4718 if (gimple_code (stmt) == GIMPLE_OMP_RETURN
4719 && !gimple_omp_return_nowait_p (stmt))
4720 {
4721 /* OpenMP 3.0 tasks unfortunately prevent this optimization
4722 in many cases. If there could be tasks queued, the barrier
4723 might be needed to let the tasks run before some local
4724 variable of the parallel that the task uses as shared
4725 runs out of scope. The task can be spawned either
4726 from within current function (this would be easy to check)
4727 or from some function it calls and gets passed an address
4728 of such a variable. */
4729 if (any_addressable_vars < 0)
4730 {
4731 gimple parallel_stmt = last_stmt (region->entry);
4732 tree child_fun = gimple_omp_parallel_child_fn (parallel_stmt);
c021f10b
NF
4733 tree local_decls, block, decl;
4734 unsigned ix;
03742a9b
JJ
4735
4736 any_addressable_vars = 0;
c021f10b
NF
4737 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (child_fun), ix, decl)
4738 if (TREE_ADDRESSABLE (decl))
03742a9b
JJ
4739 {
4740 any_addressable_vars = 1;
4741 break;
4742 }
4743 for (block = gimple_block (stmt);
4744 !any_addressable_vars
4745 && block
4746 && TREE_CODE (block) == BLOCK;
4747 block = BLOCK_SUPERCONTEXT (block))
4748 {
4749 for (local_decls = BLOCK_VARS (block);
4750 local_decls;
910ad8de 4751 local_decls = DECL_CHAIN (local_decls))
03742a9b
JJ
4752 if (TREE_ADDRESSABLE (local_decls))
4753 {
4754 any_addressable_vars = 1;
4755 break;
4756 }
4757 if (block == gimple_block (parallel_stmt))
4758 break;
4759 }
4760 }
4761 if (!any_addressable_vars)
4762 gimple_omp_return_set_nowait (stmt);
4763 }
777f7f9a 4764 }
953ff289
DN
4765}
4766
777f7f9a
RH
4767static void
4768remove_exit_barriers (struct omp_region *region)
4769{
726a989a 4770 if (region->type == GIMPLE_OMP_PARALLEL)
777f7f9a
RH
4771 remove_exit_barrier (region);
4772
4773 if (region->inner)
4774 {
4775 region = region->inner;
4776 remove_exit_barriers (region);
4777 while (region->next)
4778 {
4779 region = region->next;
4780 remove_exit_barriers (region);
4781 }
4782 }
4783}
50674e96 4784
2b4cf991
JJ
4785/* Optimize omp_get_thread_num () and omp_get_num_threads ()
4786 calls. These can't be declared as const functions, but
4787 within one parallel body they are constant, so they can be
4788 transformed there into __builtin_omp_get_{thread_num,num_threads} ()
a68ab351
JJ
4789 which are declared const. Similarly for task body, except
4790 that in untied task omp_get_thread_num () can change at any task
4791 scheduling point. */
2b4cf991
JJ
4792
4793static void
726a989a 4794optimize_omp_library_calls (gimple entry_stmt)
2b4cf991
JJ
4795{
4796 basic_block bb;
726a989a 4797 gimple_stmt_iterator gsi;
e79983f4
MM
4798 tree thr_num_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
4799 tree thr_num_id = DECL_ASSEMBLER_NAME (thr_num_tree);
4800 tree num_thr_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
4801 tree num_thr_id = DECL_ASSEMBLER_NAME (num_thr_tree);
726a989a
RB
4802 bool untied_task = (gimple_code (entry_stmt) == GIMPLE_OMP_TASK
4803 && find_omp_clause (gimple_omp_task_clauses (entry_stmt),
a68ab351 4804 OMP_CLAUSE_UNTIED) != NULL);
2b4cf991 4805
11cd3bed 4806 FOR_EACH_BB_FN (bb, cfun)
726a989a 4807 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2b4cf991 4808 {
726a989a 4809 gimple call = gsi_stmt (gsi);
2b4cf991
JJ
4810 tree decl;
4811
726a989a
RB
4812 if (is_gimple_call (call)
4813 && (decl = gimple_call_fndecl (call))
2b4cf991
JJ
4814 && DECL_EXTERNAL (decl)
4815 && TREE_PUBLIC (decl)
4816 && DECL_INITIAL (decl) == NULL)
4817 {
4818 tree built_in;
4819
4820 if (DECL_NAME (decl) == thr_num_id)
a68ab351
JJ
4821 {
4822 /* In #pragma omp task untied omp_get_thread_num () can change
4823 during the execution of the task region. */
4824 if (untied_task)
4825 continue;
e79983f4 4826 built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
a68ab351 4827 }
2b4cf991 4828 else if (DECL_NAME (decl) == num_thr_id)
e79983f4 4829 built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
2b4cf991
JJ
4830 else
4831 continue;
4832
4833 if (DECL_ASSEMBLER_NAME (decl) != DECL_ASSEMBLER_NAME (built_in)
726a989a 4834 || gimple_call_num_args (call) != 0)
2b4cf991
JJ
4835 continue;
4836
4837 if (flag_exceptions && !TREE_NOTHROW (decl))
4838 continue;
4839
4840 if (TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE
9600efe1
MM
4841 || !types_compatible_p (TREE_TYPE (TREE_TYPE (decl)),
4842 TREE_TYPE (TREE_TYPE (built_in))))
2b4cf991
JJ
4843 continue;
4844
7c9577be 4845 gimple_call_set_fndecl (call, built_in);
2b4cf991
JJ
4846 }
4847 }
4848}
4849
5a0f4dd3
JJ
4850/* Callback for expand_omp_build_assign. Return non-NULL if *tp needs to be
4851 regimplified. */
4852
4853static tree
4854expand_omp_regimplify_p (tree *tp, int *walk_subtrees, void *)
4855{
4856 tree t = *tp;
4857
4858 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
4859 if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
4860 return t;
4861
4862 if (TREE_CODE (t) == ADDR_EXPR)
4863 recompute_tree_invariant_for_addr_expr (t);
4864
4865 *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
4866 return NULL_TREE;
4867}
4868
74bf76ed
JJ
4869/* Prepend TO = FROM assignment before *GSI_P. */
4870
4871static void
4872expand_omp_build_assign (gimple_stmt_iterator *gsi_p, tree to, tree from)
4873{
4874 bool simple_p = DECL_P (to) && TREE_ADDRESSABLE (to);
4875 from = force_gimple_operand_gsi (gsi_p, from, simple_p, NULL_TREE,
4876 true, GSI_SAME_STMT);
4877 gimple stmt = gimple_build_assign (to, from);
4878 gsi_insert_before (gsi_p, stmt, GSI_SAME_STMT);
4879 if (walk_tree (&from, expand_omp_regimplify_p, NULL, NULL)
4880 || walk_tree (&to, expand_omp_regimplify_p, NULL, NULL))
4881 {
4882 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
4883 gimple_regimplify_operands (stmt, &gsi);
4884 }
4885}
4886
a68ab351 4887/* Expand the OpenMP parallel or task directive starting at REGION. */
953ff289
DN
4888
4889static void
a68ab351 4890expand_omp_taskreg (struct omp_region *region)
953ff289 4891{
50674e96 4892 basic_block entry_bb, exit_bb, new_bb;
db2960f4 4893 struct function *child_cfun;
3bb06db4 4894 tree child_fn, block, t;
726a989a
RB
4895 gimple_stmt_iterator gsi;
4896 gimple entry_stmt, stmt;
50674e96 4897 edge e;
9771b263 4898 vec<tree, va_gc> *ws_args;
50674e96 4899
777f7f9a 4900 entry_stmt = last_stmt (region->entry);
726a989a 4901 child_fn = gimple_omp_taskreg_child_fn (entry_stmt);
50674e96 4902 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
50674e96 4903
777f7f9a
RH
4904 entry_bb = region->entry;
4905 exit_bb = region->exit;
50674e96 4906
9a771876
JJ
4907 bool is_cilk_for
4908 = (flag_cilkplus
4909 && gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL
4910 && find_omp_clause (gimple_omp_parallel_clauses (entry_stmt),
4911 OMP_CLAUSE__CILK_FOR_COUNT_) != NULL_TREE);
4912
4913 if (is_cilk_for)
4914 /* If it is a _Cilk_for statement, it is modelled *like* a parallel for,
4915 and the inner statement contains the name of the built-in function
4916 and grain. */
4917 ws_args = region->inner->ws_args;
4918 else if (is_combined_parallel (region))
777f7f9a 4919 ws_args = region->ws_args;
50674e96 4920 else
3bb06db4 4921 ws_args = NULL;
953ff289 4922
777f7f9a 4923 if (child_cfun->cfg)
953ff289 4924 {
50674e96
DN
4925 /* Due to inlining, it may happen that we have already outlined
4926 the region, in which case all we need to do is make the
4927 sub-graph unreachable and emit the parallel call. */
4928 edge entry_succ_e, exit_succ_e;
50674e96
DN
4929
4930 entry_succ_e = single_succ_edge (entry_bb);
50674e96 4931
726a989a
RB
4932 gsi = gsi_last_bb (entry_bb);
4933 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_PARALLEL
4934 || gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_TASK);
4935 gsi_remove (&gsi, true);
50674e96
DN
4936
4937 new_bb = entry_bb;
d3c673c7
JJ
4938 if (exit_bb)
4939 {
4940 exit_succ_e = single_succ_edge (exit_bb);
4941 make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
4942 }
917948d3 4943 remove_edge_and_dominated_blocks (entry_succ_e);
953ff289 4944 }
50674e96
DN
4945 else
4946 {
2fed2012 4947 unsigned srcidx, dstidx, num;
c021f10b 4948
50674e96 4949 /* If the parallel region needs data sent from the parent
b570947c
JJ
4950 function, then the very first statement (except possible
4951 tree profile counter updates) of the parallel body
50674e96
DN
4952 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
4953 &.OMP_DATA_O is passed as an argument to the child function,
4954 we need to replace it with the argument as seen by the child
4955 function.
4956
4957 In most cases, this will end up being the identity assignment
4958 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
4959 a function call that has been inlined, the original PARM_DECL
4960 .OMP_DATA_I may have been converted into a different local
4961 variable. In which case, we need to keep the assignment. */
726a989a 4962 if (gimple_omp_taskreg_data_arg (entry_stmt))
50674e96
DN
4963 {
4964 basic_block entry_succ_bb = single_succ (entry_bb);
726a989a
RB
4965 tree arg, narg;
4966 gimple parcopy_stmt = NULL;
953ff289 4967
726a989a 4968 for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
b570947c 4969 {
726a989a 4970 gimple stmt;
b570947c 4971
726a989a
RB
4972 gcc_assert (!gsi_end_p (gsi));
4973 stmt = gsi_stmt (gsi);
4974 if (gimple_code (stmt) != GIMPLE_ASSIGN)
018b899b
JJ
4975 continue;
4976
726a989a 4977 if (gimple_num_ops (stmt) == 2)
b570947c 4978 {
726a989a
RB
4979 tree arg = gimple_assign_rhs1 (stmt);
4980
4981 /* We're ignore the subcode because we're
4982 effectively doing a STRIP_NOPS. */
4983
4984 if (TREE_CODE (arg) == ADDR_EXPR
4985 && TREE_OPERAND (arg, 0)
4986 == gimple_omp_taskreg_data_arg (entry_stmt))
4987 {
4988 parcopy_stmt = stmt;
4989 break;
4990 }
b570947c
JJ
4991 }
4992 }
917948d3 4993
726a989a 4994 gcc_assert (parcopy_stmt != NULL);
917948d3
ZD
4995 arg = DECL_ARGUMENTS (child_fn);
4996
4997 if (!gimple_in_ssa_p (cfun))
4998 {
726a989a
RB
4999 if (gimple_assign_lhs (parcopy_stmt) == arg)
5000 gsi_remove (&gsi, true);
917948d3 5001 else
726a989a
RB
5002 {
5003 /* ?? Is setting the subcode really necessary ?? */
5004 gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (arg));
5005 gimple_assign_set_rhs1 (parcopy_stmt, arg);
5006 }
917948d3
ZD
5007 }
5008 else
5009 {
5010 /* If we are in ssa form, we must load the value from the default
5011 definition of the argument. That should not be defined now,
5012 since the argument is not used uninitialized. */
32244553 5013 gcc_assert (ssa_default_def (cfun, arg) == NULL);
726a989a 5014 narg = make_ssa_name (arg, gimple_build_nop ());
32244553 5015 set_ssa_default_def (cfun, arg, narg);
726a989a
RB
5016 /* ?? Is setting the subcode really necessary ?? */
5017 gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (narg));
5018 gimple_assign_set_rhs1 (parcopy_stmt, narg);
917948d3
ZD
5019 update_stmt (parcopy_stmt);
5020 }
50674e96
DN
5021 }
5022
5023 /* Declare local variables needed in CHILD_CFUN. */
5024 block = DECL_INITIAL (child_fn);
c021f10b 5025 BLOCK_VARS (block) = vec2chain (child_cfun->local_decls);
4f0ae266
JJ
5026 /* The gimplifier could record temporaries in parallel/task block
5027 rather than in containing function's local_decls chain,
5028 which would mean cgraph missed finalizing them. Do it now. */
910ad8de 5029 for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
4f0ae266
JJ
5030 if (TREE_CODE (t) == VAR_DECL
5031 && TREE_STATIC (t)
5032 && !DECL_EXTERNAL (t))
9041d2e6 5033 varpool_node::finalize_decl (t);
726a989a 5034 DECL_SAVED_TREE (child_fn) = NULL;
355a7673
MM
5035 /* We'll create a CFG for child_fn, so no gimple body is needed. */
5036 gimple_set_body (child_fn, NULL);
b357f682 5037 TREE_USED (block) = 1;
50674e96 5038
917948d3 5039 /* Reset DECL_CONTEXT on function arguments. */
910ad8de 5040 for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
50674e96
DN
5041 DECL_CONTEXT (t) = child_fn;
5042
726a989a
RB
5043 /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
5044 so that it can be moved to the child function. */
5045 gsi = gsi_last_bb (entry_bb);
5046 stmt = gsi_stmt (gsi);
5047 gcc_assert (stmt && (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
5048 || gimple_code (stmt) == GIMPLE_OMP_TASK));
5049 gsi_remove (&gsi, true);
5050 e = split_block (entry_bb, stmt);
50674e96
DN
5051 entry_bb = e->dest;
5052 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
5053
726a989a 5054 /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
2aee3e57
JJ
5055 if (exit_bb)
5056 {
726a989a
RB
5057 gsi = gsi_last_bb (exit_bb);
5058 gcc_assert (!gsi_end_p (gsi)
5059 && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
5060 stmt = gimple_build_return (NULL);
5061 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
5062 gsi_remove (&gsi, true);
2aee3e57 5063 }
917948d3
ZD
5064
5065 /* Move the parallel region into CHILD_CFUN. */
b8698a0f 5066
917948d3
ZD
5067 if (gimple_in_ssa_p (cfun))
5068 {
5db9ba0c 5069 init_tree_ssa (child_cfun);
3828719a
RG
5070 init_ssa_operands (child_cfun);
5071 child_cfun->gimple_df->in_ssa_p = true;
b357f682 5072 block = NULL_TREE;
917948d3 5073 }
b357f682 5074 else
726a989a 5075 block = gimple_block (entry_stmt);
b357f682
JJ
5076
5077 new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
917948d3
ZD
5078 if (exit_bb)
5079 single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
6093bc06
RB
5080 /* When the OMP expansion process cannot guarantee an up-to-date
5081 loop tree arrange for the child function to fixup loops. */
5082 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
5083 child_cfun->x_current_loops->state |= LOOPS_NEED_FIXUP;
917948d3 5084
b357f682 5085 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
9771b263 5086 num = vec_safe_length (child_cfun->local_decls);
2fed2012
JJ
5087 for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
5088 {
9771b263 5089 t = (*child_cfun->local_decls)[srcidx];
2fed2012
JJ
5090 if (DECL_CONTEXT (t) == cfun->decl)
5091 continue;
5092 if (srcidx != dstidx)
9771b263 5093 (*child_cfun->local_decls)[dstidx] = t;
2fed2012
JJ
5094 dstidx++;
5095 }
5096 if (dstidx != num)
9771b263 5097 vec_safe_truncate (child_cfun->local_decls, dstidx);
b357f682 5098
917948d3 5099 /* Inform the callgraph about the new function. */
d7ed20db 5100 DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
d52f5295 5101 cgraph_node::add_new_function (child_fn, true);
917948d3
ZD
5102
5103 /* Fix the callgraph edges for child_cfun. Those for cfun will be
5104 fixed in a following pass. */
5105 push_cfun (child_cfun);
2b4cf991 5106 if (optimize)
a68ab351 5107 optimize_omp_library_calls (entry_stmt);
3dafb85c 5108 cgraph_edge::rebuild_edges ();
99819c63
JJ
5109
5110 /* Some EH regions might become dead, see PR34608. If
5111 pass_cleanup_cfg isn't the first pass to happen with the
5112 new child, these dead EH edges might cause problems.
5113 Clean them up now. */
5114 if (flag_exceptions)
5115 {
5116 basic_block bb;
99819c63
JJ
5117 bool changed = false;
5118
11cd3bed 5119 FOR_EACH_BB_FN (bb, cfun)
726a989a 5120 changed |= gimple_purge_dead_eh_edges (bb);
99819c63
JJ
5121 if (changed)
5122 cleanup_tree_cfg ();
99819c63 5123 }
5006671f
RG
5124 if (gimple_in_ssa_p (cfun))
5125 update_ssa (TODO_update_ssa);
917948d3 5126 pop_cfun ();
50674e96 5127 }
b8698a0f 5128
50674e96 5129 /* Emit a library call to launch the children threads. */
9a771876
JJ
5130 if (is_cilk_for)
5131 expand_cilk_for_call (new_bb, entry_stmt, ws_args);
5132 else if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
a68ab351
JJ
5133 expand_parallel_call (region, new_bb, entry_stmt, ws_args);
5134 else
5135 expand_task_call (new_bb, entry_stmt);
a5efada7
RG
5136 if (gimple_in_ssa_p (cfun))
5137 update_ssa (TODO_update_ssa_only_virtuals);
953ff289
DN
5138}
5139
50674e96 5140
74bf76ed
JJ
5141/* Helper function for expand_omp_{for_*,simd}. If this is the outermost
5142 of the combined collapse > 1 loop constructs, generate code like:
5143 if (__builtin_expect (N32 cond3 N31, 0)) goto ZERO_ITER_BB;
5144 if (cond3 is <)
5145 adj = STEP3 - 1;
5146 else
5147 adj = STEP3 + 1;
5148 count3 = (adj + N32 - N31) / STEP3;
5149 if (__builtin_expect (N22 cond2 N21, 0)) goto ZERO_ITER_BB;
5150 if (cond2 is <)
5151 adj = STEP2 - 1;
5152 else
5153 adj = STEP2 + 1;
5154 count2 = (adj + N22 - N21) / STEP2;
5155 if (__builtin_expect (N12 cond1 N11, 0)) goto ZERO_ITER_BB;
5156 if (cond1 is <)
5157 adj = STEP1 - 1;
5158 else
5159 adj = STEP1 + 1;
5160 count1 = (adj + N12 - N11) / STEP1;
5161 count = count1 * count2 * count3;
5162 Furthermore, if ZERO_ITER_BB is NULL, create a BB which does:
5163 count = 0;
acf0174b
JJ
5164 and set ZERO_ITER_BB to that bb. If this isn't the outermost
5165 of the combined loop constructs, just initialize COUNTS array
5166 from the _looptemp_ clauses. */
74bf76ed
JJ
5167
5168/* NOTE: It *could* be better to moosh all of the BBs together,
5169 creating one larger BB with all the computation and the unexpected
5170 jump at the end. I.e.
5171
5172 bool zero3, zero2, zero1, zero;
5173
5174 zero3 = N32 c3 N31;
5175 count3 = (N32 - N31) /[cl] STEP3;
5176 zero2 = N22 c2 N21;
5177 count2 = (N22 - N21) /[cl] STEP2;
5178 zero1 = N12 c1 N11;
5179 count1 = (N12 - N11) /[cl] STEP1;
5180 zero = zero3 || zero2 || zero1;
5181 count = count1 * count2 * count3;
5182 if (__builtin_expect(zero, false)) goto zero_iter_bb;
5183
5184 After all, we expect the zero=false, and thus we expect to have to
5185 evaluate all of the comparison expressions, so short-circuiting
5186 oughtn't be a win. Since the condition isn't protecting a
5187 denominator, we're not concerned about divide-by-zero, so we can
5188 fully evaluate count even if a numerator turned out to be wrong.
5189
5190 It seems like putting this all together would create much better
5191 scheduling opportunities, and less pressure on the chip's branch
5192 predictor. */
5193
5194static void
5195expand_omp_for_init_counts (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
5196 basic_block &entry_bb, tree *counts,
5197 basic_block &zero_iter_bb, int &first_zero_iter,
5198 basic_block &l2_dom_bb)
5199{
5200 tree t, type = TREE_TYPE (fd->loop.v);
5201 gimple stmt;
5202 edge e, ne;
5203 int i;
5204
5205 /* Collapsed loops need work for expansion into SSA form. */
5206 gcc_assert (!gimple_in_ssa_p (cfun));
5207
acf0174b
JJ
5208 if (gimple_omp_for_combined_into_p (fd->for_stmt)
5209 && TREE_CODE (fd->loop.n2) != INTEGER_CST)
5210 {
5211 /* First two _looptemp_ clauses are for istart/iend, counts[0]
5212 isn't supposed to be handled, as the inner loop doesn't
5213 use it. */
5214 tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
5215 OMP_CLAUSE__LOOPTEMP_);
5216 gcc_assert (innerc);
5217 for (i = 0; i < fd->collapse; i++)
5218 {
5219 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
5220 OMP_CLAUSE__LOOPTEMP_);
5221 gcc_assert (innerc);
5222 if (i)
5223 counts[i] = OMP_CLAUSE_DECL (innerc);
5224 else
5225 counts[0] = NULL_TREE;
5226 }
5227 return;
5228 }
5229
74bf76ed
JJ
5230 for (i = 0; i < fd->collapse; i++)
5231 {
5232 tree itype = TREE_TYPE (fd->loops[i].v);
5233
5234 if (SSA_VAR_P (fd->loop.n2)
5235 && ((t = fold_binary (fd->loops[i].cond_code, boolean_type_node,
5236 fold_convert (itype, fd->loops[i].n1),
5237 fold_convert (itype, fd->loops[i].n2)))
5238 == NULL_TREE || !integer_onep (t)))
5239 {
5240 tree n1, n2;
5241 n1 = fold_convert (itype, unshare_expr (fd->loops[i].n1));
5242 n1 = force_gimple_operand_gsi (gsi, n1, true, NULL_TREE,
5243 true, GSI_SAME_STMT);
5244 n2 = fold_convert (itype, unshare_expr (fd->loops[i].n2));
5245 n2 = force_gimple_operand_gsi (gsi, n2, true, NULL_TREE,
5246 true, GSI_SAME_STMT);
5247 stmt = gimple_build_cond (fd->loops[i].cond_code, n1, n2,
5248 NULL_TREE, NULL_TREE);
5249 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
5250 if (walk_tree (gimple_cond_lhs_ptr (stmt),
5251 expand_omp_regimplify_p, NULL, NULL)
5252 || walk_tree (gimple_cond_rhs_ptr (stmt),
5253 expand_omp_regimplify_p, NULL, NULL))
5254 {
5255 *gsi = gsi_for_stmt (stmt);
5256 gimple_regimplify_operands (stmt, gsi);
5257 }
5258 e = split_block (entry_bb, stmt);
5259 if (zero_iter_bb == NULL)
5260 {
5261 first_zero_iter = i;
5262 zero_iter_bb = create_empty_bb (entry_bb);
726338f4 5263 add_bb_to_loop (zero_iter_bb, entry_bb->loop_father);
74bf76ed
JJ
5264 *gsi = gsi_after_labels (zero_iter_bb);
5265 stmt = gimple_build_assign (fd->loop.n2,
5266 build_zero_cst (type));
5267 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
5268 set_immediate_dominator (CDI_DOMINATORS, zero_iter_bb,
5269 entry_bb);
5270 }
5271 ne = make_edge (entry_bb, zero_iter_bb, EDGE_FALSE_VALUE);
5272 ne->probability = REG_BR_PROB_BASE / 2000 - 1;
5273 e->flags = EDGE_TRUE_VALUE;
5274 e->probability = REG_BR_PROB_BASE - ne->probability;
5275 if (l2_dom_bb == NULL)
5276 l2_dom_bb = entry_bb;
5277 entry_bb = e->dest;
5278 *gsi = gsi_last_bb (entry_bb);
5279 }
5280
5281 if (POINTER_TYPE_P (itype))
5282 itype = signed_type_for (itype);
5283 t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR
5284 ? -1 : 1));
5285 t = fold_build2 (PLUS_EXPR, itype,
5286 fold_convert (itype, fd->loops[i].step), t);
5287 t = fold_build2 (PLUS_EXPR, itype, t,
5288 fold_convert (itype, fd->loops[i].n2));
5289 t = fold_build2 (MINUS_EXPR, itype, t,
5290 fold_convert (itype, fd->loops[i].n1));
5291 /* ?? We could probably use CEIL_DIV_EXPR instead of
5292 TRUNC_DIV_EXPR and adjusting by hand. Unless we can't
5293 generate the same code in the end because generically we
5294 don't know that the values involved must be negative for
5295 GT?? */
5296 if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
5297 t = fold_build2 (TRUNC_DIV_EXPR, itype,
5298 fold_build1 (NEGATE_EXPR, itype, t),
5299 fold_build1 (NEGATE_EXPR, itype,
5300 fold_convert (itype,
5301 fd->loops[i].step)));
5302 else
5303 t = fold_build2 (TRUNC_DIV_EXPR, itype, t,
5304 fold_convert (itype, fd->loops[i].step));
5305 t = fold_convert (type, t);
5306 if (TREE_CODE (t) == INTEGER_CST)
5307 counts[i] = t;
5308 else
5309 {
5310 counts[i] = create_tmp_reg (type, ".count");
5311 expand_omp_build_assign (gsi, counts[i], t);
5312 }
5313 if (SSA_VAR_P (fd->loop.n2))
5314 {
5315 if (i == 0)
5316 t = counts[0];
5317 else
5318 t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
5319 expand_omp_build_assign (gsi, fd->loop.n2, t);
5320 }
5321 }
5322}
5323
5324
5325/* Helper function for expand_omp_{for_*,simd}. Generate code like:
5326 T = V;
5327 V3 = N31 + (T % count3) * STEP3;
5328 T = T / count3;
5329 V2 = N21 + (T % count2) * STEP2;
5330 T = T / count2;
5331 V1 = N11 + T * STEP1;
acf0174b
JJ
5332 if this loop doesn't have an inner loop construct combined with it.
5333 If it does have an inner loop construct combined with it and the
5334 iteration count isn't known constant, store values from counts array
5335 into its _looptemp_ temporaries instead. */
74bf76ed
JJ
5336
5337static void
5338expand_omp_for_init_vars (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
acf0174b 5339 tree *counts, gimple inner_stmt, tree startvar)
74bf76ed
JJ
5340{
5341 int i;
acf0174b
JJ
5342 if (gimple_omp_for_combined_p (fd->for_stmt))
5343 {
5344 /* If fd->loop.n2 is constant, then no propagation of the counts
5345 is needed, they are constant. */
5346 if (TREE_CODE (fd->loop.n2) == INTEGER_CST)
5347 return;
5348
5349 tree clauses = gimple_code (inner_stmt) == GIMPLE_OMP_PARALLEL
5350 ? gimple_omp_parallel_clauses (inner_stmt)
5351 : gimple_omp_for_clauses (inner_stmt);
5352 /* First two _looptemp_ clauses are for istart/iend, counts[0]
5353 isn't supposed to be handled, as the inner loop doesn't
5354 use it. */
5355 tree innerc = find_omp_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
5356 gcc_assert (innerc);
5357 for (i = 0; i < fd->collapse; i++)
5358 {
5359 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
5360 OMP_CLAUSE__LOOPTEMP_);
5361 gcc_assert (innerc);
5362 if (i)
5363 {
5364 tree tem = OMP_CLAUSE_DECL (innerc);
5365 tree t = fold_convert (TREE_TYPE (tem), counts[i]);
5366 t = force_gimple_operand_gsi (gsi, t, false, NULL_TREE,
5367 false, GSI_CONTINUE_LINKING);
5368 gimple stmt = gimple_build_assign (tem, t);
5369 gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
5370 }
5371 }
5372 return;
5373 }
5374
74bf76ed
JJ
5375 tree type = TREE_TYPE (fd->loop.v);
5376 tree tem = create_tmp_reg (type, ".tem");
5377 gimple stmt = gimple_build_assign (tem, startvar);
5378 gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
5379
5380 for (i = fd->collapse - 1; i >= 0; i--)
5381 {
5382 tree vtype = TREE_TYPE (fd->loops[i].v), itype, t;
5383 itype = vtype;
5384 if (POINTER_TYPE_P (vtype))
5385 itype = signed_type_for (vtype);
5386 if (i != 0)
5387 t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
5388 else
5389 t = tem;
5390 t = fold_convert (itype, t);
5391 t = fold_build2 (MULT_EXPR, itype, t,
5392 fold_convert (itype, fd->loops[i].step));
5393 if (POINTER_TYPE_P (vtype))
5394 t = fold_build_pointer_plus (fd->loops[i].n1, t);
5395 else
5396 t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
5397 t = force_gimple_operand_gsi (gsi, t,
5398 DECL_P (fd->loops[i].v)
5399 && TREE_ADDRESSABLE (fd->loops[i].v),
5400 NULL_TREE, false,
5401 GSI_CONTINUE_LINKING);
5402 stmt = gimple_build_assign (fd->loops[i].v, t);
5403 gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
5404 if (i != 0)
5405 {
5406 t = fold_build2 (TRUNC_DIV_EXPR, type, tem, counts[i]);
5407 t = force_gimple_operand_gsi (gsi, t, false, NULL_TREE,
5408 false, GSI_CONTINUE_LINKING);
5409 stmt = gimple_build_assign (tem, t);
5410 gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
5411 }
5412 }
5413}
5414
5415
5416/* Helper function for expand_omp_for_*. Generate code like:
5417 L10:
5418 V3 += STEP3;
5419 if (V3 cond3 N32) goto BODY_BB; else goto L11;
5420 L11:
5421 V3 = N31;
5422 V2 += STEP2;
5423 if (V2 cond2 N22) goto BODY_BB; else goto L12;
5424 L12:
5425 V2 = N21;
5426 V1 += STEP1;
5427 goto BODY_BB; */
5428
5429static basic_block
5430extract_omp_for_update_vars (struct omp_for_data *fd, basic_block cont_bb,
5431 basic_block body_bb)
5432{
5433 basic_block last_bb, bb, collapse_bb = NULL;
5434 int i;
5435 gimple_stmt_iterator gsi;
5436 edge e;
5437 tree t;
5438 gimple stmt;
5439
5440 last_bb = cont_bb;
5441 for (i = fd->collapse - 1; i >= 0; i--)
5442 {
5443 tree vtype = TREE_TYPE (fd->loops[i].v);
5444
5445 bb = create_empty_bb (last_bb);
726338f4 5446 add_bb_to_loop (bb, last_bb->loop_father);
74bf76ed
JJ
5447 gsi = gsi_start_bb (bb);
5448
5449 if (i < fd->collapse - 1)
5450 {
5451 e = make_edge (last_bb, bb, EDGE_FALSE_VALUE);
5452 e->probability = REG_BR_PROB_BASE / 8;
5453
5454 t = fd->loops[i + 1].n1;
5455 t = force_gimple_operand_gsi (&gsi, t,
5456 DECL_P (fd->loops[i + 1].v)
5457 && TREE_ADDRESSABLE (fd->loops[i
5458 + 1].v),
5459 NULL_TREE, false,
5460 GSI_CONTINUE_LINKING);
5461 stmt = gimple_build_assign (fd->loops[i + 1].v, t);
5462 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
5463 }
5464 else
5465 collapse_bb = bb;
5466
5467 set_immediate_dominator (CDI_DOMINATORS, bb, last_bb);
5468
5469 if (POINTER_TYPE_P (vtype))
5470 t = fold_build_pointer_plus (fd->loops[i].v, fd->loops[i].step);
5471 else
5472 t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v, fd->loops[i].step);
5473 t = force_gimple_operand_gsi (&gsi, t,
5474 DECL_P (fd->loops[i].v)
5475 && TREE_ADDRESSABLE (fd->loops[i].v),
5476 NULL_TREE, false, GSI_CONTINUE_LINKING);
5477 stmt = gimple_build_assign (fd->loops[i].v, t);
5478 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
5479
5480 if (i > 0)
5481 {
5482 t = fd->loops[i].n2;
5483 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
5484 false, GSI_CONTINUE_LINKING);
5485 tree v = fd->loops[i].v;
5486 if (DECL_P (v) && TREE_ADDRESSABLE (v))
5487 v = force_gimple_operand_gsi (&gsi, v, true, NULL_TREE,
5488 false, GSI_CONTINUE_LINKING);
5489 t = fold_build2 (fd->loops[i].cond_code, boolean_type_node, v, t);
5490 stmt = gimple_build_cond_empty (t);
5491 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
5492 e = make_edge (bb, body_bb, EDGE_TRUE_VALUE);
5493 e->probability = REG_BR_PROB_BASE * 7 / 8;
5494 }
5495 else
5496 make_edge (bb, body_bb, EDGE_FALLTHRU);
5497 last_bb = bb;
5498 }
5499
5500 return collapse_bb;
5501}
5502
5503
50674e96 5504/* A subroutine of expand_omp_for. Generate code for a parallel
953ff289
DN
5505 loop with any schedule. Given parameters:
5506
5507 for (V = N1; V cond N2; V += STEP) BODY;
5508
5509 where COND is "<" or ">", we generate pseudocode
5510
5511 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
50674e96 5512 if (more) goto L0; else goto L3;
953ff289
DN
5513 L0:
5514 V = istart0;
5515 iend = iend0;
5516 L1:
5517 BODY;
5518 V += STEP;
50674e96 5519 if (V cond iend) goto L1; else goto L2;
953ff289 5520 L2:
50674e96
DN
5521 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
5522 L3:
953ff289 5523
50674e96 5524 If this is a combined omp parallel loop, instead of the call to
a68ab351 5525 GOMP_loop_foo_start, we call GOMP_loop_foo_next.
acf0174b
JJ
5526 If this is gimple_omp_for_combined_p loop, then instead of assigning
5527 V and iend in L0 we assign the first two _looptemp_ clause decls of the
5528 inner GIMPLE_OMP_FOR and V += STEP; and
5529 if (V cond iend) goto L1; else goto L2; are removed.
a68ab351
JJ
5530
5531 For collapsed loops, given parameters:
5532 collapse(3)
5533 for (V1 = N11; V1 cond1 N12; V1 += STEP1)
5534 for (V2 = N21; V2 cond2 N22; V2 += STEP2)
5535 for (V3 = N31; V3 cond3 N32; V3 += STEP3)
5536 BODY;
5537
5538 we generate pseudocode
5539
5a0f4dd3 5540 if (__builtin_expect (N32 cond3 N31, 0)) goto Z0;
a68ab351
JJ
5541 if (cond3 is <)
5542 adj = STEP3 - 1;
5543 else
5544 adj = STEP3 + 1;
5545 count3 = (adj + N32 - N31) / STEP3;
5a0f4dd3 5546 if (__builtin_expect (N22 cond2 N21, 0)) goto Z0;
a68ab351
JJ
5547 if (cond2 is <)
5548 adj = STEP2 - 1;
5549 else
5550 adj = STEP2 + 1;
5551 count2 = (adj + N22 - N21) / STEP2;
5a0f4dd3 5552 if (__builtin_expect (N12 cond1 N11, 0)) goto Z0;
a68ab351
JJ
5553 if (cond1 is <)
5554 adj = STEP1 - 1;
5555 else
5556 adj = STEP1 + 1;
5557 count1 = (adj + N12 - N11) / STEP1;
5558 count = count1 * count2 * count3;
5a0f4dd3
JJ
5559 goto Z1;
5560 Z0:
5561 count = 0;
5562 Z1:
a68ab351
JJ
5563 more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
5564 if (more) goto L0; else goto L3;
5565 L0:
5566 V = istart0;
5567 T = V;
5568 V3 = N31 + (T % count3) * STEP3;
5569 T = T / count3;
5570 V2 = N21 + (T % count2) * STEP2;
5571 T = T / count2;
5572 V1 = N11 + T * STEP1;
5573 iend = iend0;
5574 L1:
5575 BODY;
5576 V += 1;
5577 if (V < iend) goto L10; else goto L2;
5578 L10:
5579 V3 += STEP3;
5580 if (V3 cond3 N32) goto L1; else goto L11;
5581 L11:
5582 V3 = N31;
5583 V2 += STEP2;
5584 if (V2 cond2 N22) goto L1; else goto L12;
5585 L12:
5586 V2 = N21;
5587 V1 += STEP1;
5588 goto L1;
5589 L2:
5590 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
5591 L3:
5592
5593 */
953ff289 5594
777f7f9a 5595static void
50674e96
DN
5596expand_omp_for_generic (struct omp_region *region,
5597 struct omp_for_data *fd,
953ff289 5598 enum built_in_function start_fn,
acf0174b
JJ
5599 enum built_in_function next_fn,
5600 gimple inner_stmt)
953ff289 5601{
726a989a 5602 tree type, istart0, iend0, iend;
a68ab351
JJ
5603 tree t, vmain, vback, bias = NULL_TREE;
5604 basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, collapse_bb;
d3c673c7 5605 basic_block l2_bb = NULL, l3_bb = NULL;
726a989a
RB
5606 gimple_stmt_iterator gsi;
5607 gimple stmt;
50674e96 5608 bool in_combined_parallel = is_combined_parallel (region);
e5c95afe 5609 bool broken_loop = region->cont == NULL;
917948d3 5610 edge e, ne;
a68ab351
JJ
5611 tree *counts = NULL;
5612 int i;
e5c95afe
ZD
5613
5614 gcc_assert (!broken_loop || !in_combined_parallel);
a68ab351
JJ
5615 gcc_assert (fd->iter_type == long_integer_type_node
5616 || !in_combined_parallel);
953ff289 5617
a68ab351
JJ
5618 type = TREE_TYPE (fd->loop.v);
5619 istart0 = create_tmp_var (fd->iter_type, ".istart0");
5620 iend0 = create_tmp_var (fd->iter_type, ".iend0");
5b4fc8fb
JJ
5621 TREE_ADDRESSABLE (istart0) = 1;
5622 TREE_ADDRESSABLE (iend0) = 1;
953ff289 5623
a68ab351
JJ
5624 /* See if we need to bias by LLONG_MIN. */
5625 if (fd->iter_type == long_long_unsigned_type_node
5626 && TREE_CODE (type) == INTEGER_TYPE
5627 && !TYPE_UNSIGNED (type))
5628 {
5629 tree n1, n2;
5630
5631 if (fd->loop.cond_code == LT_EXPR)
5632 {
5633 n1 = fd->loop.n1;
5634 n2 = fold_build2 (PLUS_EXPR, type, fd->loop.n2, fd->loop.step);
5635 }
5636 else
5637 {
5638 n1 = fold_build2 (MINUS_EXPR, type, fd->loop.n2, fd->loop.step);
5639 n2 = fd->loop.n1;
5640 }
5641 if (TREE_CODE (n1) != INTEGER_CST
5642 || TREE_CODE (n2) != INTEGER_CST
5643 || ((tree_int_cst_sgn (n1) < 0) ^ (tree_int_cst_sgn (n2) < 0)))
5644 bias = fold_convert (fd->iter_type, TYPE_MIN_VALUE (type));
5645 }
5646
777f7f9a 5647 entry_bb = region->entry;
d3c673c7 5648 cont_bb = region->cont;
a68ab351 5649 collapse_bb = NULL;
e5c95afe
ZD
5650 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
5651 gcc_assert (broken_loop
5652 || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
5653 l0_bb = split_edge (FALLTHRU_EDGE (entry_bb));
5654 l1_bb = single_succ (l0_bb);
5655 if (!broken_loop)
d3c673c7
JJ
5656 {
5657 l2_bb = create_empty_bb (cont_bb);
e5c95afe
ZD
5658 gcc_assert (BRANCH_EDGE (cont_bb)->dest == l1_bb);
5659 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
d3c673c7 5660 }
e5c95afe
ZD
5661 else
5662 l2_bb = NULL;
5663 l3_bb = BRANCH_EDGE (entry_bb)->dest;
5664 exit_bb = region->exit;
50674e96 5665
726a989a 5666 gsi = gsi_last_bb (entry_bb);
a68ab351 5667
726a989a 5668 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
a68ab351
JJ
5669 if (fd->collapse > 1)
5670 {
5a0f4dd3 5671 int first_zero_iter = -1;
74bf76ed 5672 basic_block zero_iter_bb = NULL, l2_dom_bb = NULL;
5a0f4dd3 5673
74bf76ed
JJ
5674 counts = XALLOCAVEC (tree, fd->collapse);
5675 expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
5676 zero_iter_bb, first_zero_iter,
5677 l2_dom_bb);
a68ab351 5678
5a0f4dd3
JJ
5679 if (zero_iter_bb)
5680 {
5681 /* Some counts[i] vars might be uninitialized if
5682 some loop has zero iterations. But the body shouldn't
5683 be executed in that case, so just avoid uninit warnings. */
5684 for (i = first_zero_iter; i < fd->collapse; i++)
5685 if (SSA_VAR_P (counts[i]))
5686 TREE_NO_WARNING (counts[i]) = 1;
5687 gsi_prev (&gsi);
5688 e = split_block (entry_bb, gsi_stmt (gsi));
5689 entry_bb = e->dest;
5690 make_edge (zero_iter_bb, entry_bb, EDGE_FALLTHRU);
5691 gsi = gsi_last_bb (entry_bb);
5692 set_immediate_dominator (CDI_DOMINATORS, entry_bb,
5693 get_immediate_dominator (CDI_DOMINATORS,
5694 zero_iter_bb));
5695 }
a68ab351 5696 }
917948d3
ZD
5697 if (in_combined_parallel)
5698 {
5699 /* In a combined parallel loop, emit a call to
5700 GOMP_loop_foo_next. */
e79983f4 5701 t = build_call_expr (builtin_decl_explicit (next_fn), 2,
917948d3
ZD
5702 build_fold_addr_expr (istart0),
5703 build_fold_addr_expr (iend0));
5704 }
5705 else
953ff289 5706 {
5039610b 5707 tree t0, t1, t2, t3, t4;
50674e96
DN
5708 /* If this is not a combined parallel loop, emit a call to
5709 GOMP_loop_foo_start in ENTRY_BB. */
5039610b
SL
5710 t4 = build_fold_addr_expr (iend0);
5711 t3 = build_fold_addr_expr (istart0);
a68ab351 5712 t2 = fold_convert (fd->iter_type, fd->loop.step);
74bf76ed
JJ
5713 t1 = fd->loop.n2;
5714 t0 = fd->loop.n1;
acf0174b
JJ
5715 if (gimple_omp_for_combined_into_p (fd->for_stmt))
5716 {
5717 tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
5718 OMP_CLAUSE__LOOPTEMP_);
5719 gcc_assert (innerc);
5720 t0 = OMP_CLAUSE_DECL (innerc);
5721 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
5722 OMP_CLAUSE__LOOPTEMP_);
5723 gcc_assert (innerc);
5724 t1 = OMP_CLAUSE_DECL (innerc);
5725 }
74bf76ed
JJ
5726 if (POINTER_TYPE_P (TREE_TYPE (t0))
5727 && TYPE_PRECISION (TREE_TYPE (t0))
5728 != TYPE_PRECISION (fd->iter_type))
c6ff4493
SE
5729 {
5730 /* Avoid casting pointers to integer of a different size. */
96f9265a 5731 tree itype = signed_type_for (type);
74bf76ed
JJ
5732 t1 = fold_convert (fd->iter_type, fold_convert (itype, t1));
5733 t0 = fold_convert (fd->iter_type, fold_convert (itype, t0));
c6ff4493
SE
5734 }
5735 else
5736 {
74bf76ed
JJ
5737 t1 = fold_convert (fd->iter_type, t1);
5738 t0 = fold_convert (fd->iter_type, t0);
c6ff4493 5739 }
a68ab351 5740 if (bias)
953ff289 5741 {
a68ab351
JJ
5742 t1 = fold_build2 (PLUS_EXPR, fd->iter_type, t1, bias);
5743 t0 = fold_build2 (PLUS_EXPR, fd->iter_type, t0, bias);
5744 }
5745 if (fd->iter_type == long_integer_type_node)
5746 {
5747 if (fd->chunk_size)
5748 {
5749 t = fold_convert (fd->iter_type, fd->chunk_size);
e79983f4
MM
5750 t = build_call_expr (builtin_decl_explicit (start_fn),
5751 6, t0, t1, t2, t, t3, t4);
a68ab351
JJ
5752 }
5753 else
e79983f4
MM
5754 t = build_call_expr (builtin_decl_explicit (start_fn),
5755 5, t0, t1, t2, t3, t4);
953ff289 5756 }
5039610b 5757 else
a68ab351
JJ
5758 {
5759 tree t5;
5760 tree c_bool_type;
e79983f4 5761 tree bfn_decl;
a68ab351
JJ
5762
5763 /* The GOMP_loop_ull_*start functions have additional boolean
5764 argument, true for < loops and false for > loops.
5765 In Fortran, the C bool type can be different from
5766 boolean_type_node. */
e79983f4
MM
5767 bfn_decl = builtin_decl_explicit (start_fn);
5768 c_bool_type = TREE_TYPE (TREE_TYPE (bfn_decl));
a68ab351
JJ
5769 t5 = build_int_cst (c_bool_type,
5770 fd->loop.cond_code == LT_EXPR ? 1 : 0);
5771 if (fd->chunk_size)
5772 {
e79983f4 5773 tree bfn_decl = builtin_decl_explicit (start_fn);
a68ab351 5774 t = fold_convert (fd->iter_type, fd->chunk_size);
e79983f4 5775 t = build_call_expr (bfn_decl, 7, t5, t0, t1, t2, t, t3, t4);
a68ab351
JJ
5776 }
5777 else
e79983f4
MM
5778 t = build_call_expr (builtin_decl_explicit (start_fn),
5779 6, t5, t0, t1, t2, t3, t4);
a68ab351 5780 }
953ff289 5781 }
a68ab351
JJ
5782 if (TREE_TYPE (t) != boolean_type_node)
5783 t = fold_build2 (NE_EXPR, boolean_type_node,
5784 t, build_int_cst (TREE_TYPE (t), 0));
726a989a
RB
5785 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
5786 true, GSI_SAME_STMT);
5787 gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
917948d3 5788
726a989a
RB
5789 /* Remove the GIMPLE_OMP_FOR statement. */
5790 gsi_remove (&gsi, true);
953ff289 5791
50674e96 5792 /* Iteration setup for sequential loop goes in L0_BB. */
74bf76ed
JJ
5793 tree startvar = fd->loop.v;
5794 tree endvar = NULL_TREE;
5795
acf0174b
JJ
5796 if (gimple_omp_for_combined_p (fd->for_stmt))
5797 {
5798 gcc_assert (gimple_code (inner_stmt) == GIMPLE_OMP_FOR
5799 && gimple_omp_for_kind (inner_stmt)
5800 == GF_OMP_FOR_KIND_SIMD);
5801 tree innerc = find_omp_clause (gimple_omp_for_clauses (inner_stmt),
5802 OMP_CLAUSE__LOOPTEMP_);
5803 gcc_assert (innerc);
5804 startvar = OMP_CLAUSE_DECL (innerc);
5805 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
5806 OMP_CLAUSE__LOOPTEMP_);
5807 gcc_assert (innerc);
5808 endvar = OMP_CLAUSE_DECL (innerc);
5809 }
5810
726a989a 5811 gsi = gsi_start_bb (l0_bb);
550918ca 5812 t = istart0;
a68ab351 5813 if (bias)
550918ca 5814 t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
74bf76ed
JJ
5815 if (POINTER_TYPE_P (TREE_TYPE (startvar)))
5816 t = fold_convert (signed_type_for (TREE_TYPE (startvar)), t);
5817 t = fold_convert (TREE_TYPE (startvar), t);
ea3a0fde 5818 t = force_gimple_operand_gsi (&gsi, t,
74bf76ed
JJ
5819 DECL_P (startvar)
5820 && TREE_ADDRESSABLE (startvar),
ea3a0fde 5821 NULL_TREE, false, GSI_CONTINUE_LINKING);
74bf76ed 5822 stmt = gimple_build_assign (startvar, t);
726a989a 5823 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
953ff289 5824
550918ca 5825 t = iend0;
a68ab351 5826 if (bias)
550918ca 5827 t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
74bf76ed
JJ
5828 if (POINTER_TYPE_P (TREE_TYPE (startvar)))
5829 t = fold_convert (signed_type_for (TREE_TYPE (startvar)), t);
5830 t = fold_convert (TREE_TYPE (startvar), t);
726a989a
RB
5831 iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
5832 false, GSI_CONTINUE_LINKING);
74bf76ed 5833 if (endvar)
a68ab351 5834 {
74bf76ed 5835 stmt = gimple_build_assign (endvar, iend);
726a989a 5836 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
95782571
JJ
5837 if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (iend)))
5838 stmt = gimple_build_assign (fd->loop.v, iend);
5839 else
5840 stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, iend,
5841 NULL_TREE);
5842 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
a68ab351 5843 }
74bf76ed 5844 if (fd->collapse > 1)
acf0174b 5845 expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
50674e96 5846
e5c95afe 5847 if (!broken_loop)
d3c673c7 5848 {
e5c95afe
ZD
5849 /* Code to control the increment and predicate for the sequential
5850 loop goes in the CONT_BB. */
726a989a
RB
5851 gsi = gsi_last_bb (cont_bb);
5852 stmt = gsi_stmt (gsi);
5853 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
5854 vmain = gimple_omp_continue_control_use (stmt);
5855 vback = gimple_omp_continue_control_def (stmt);
917948d3 5856
acf0174b 5857 if (!gimple_omp_for_combined_p (fd->for_stmt))
74bf76ed
JJ
5858 {
5859 if (POINTER_TYPE_P (type))
5860 t = fold_build_pointer_plus (vmain, fd->loop.step);
5861 else
5862 t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
5863 t = force_gimple_operand_gsi (&gsi, t,
5864 DECL_P (vback)
5865 && TREE_ADDRESSABLE (vback),
5866 NULL_TREE, true, GSI_SAME_STMT);
5867 stmt = gimple_build_assign (vback, t);
5868 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
5869
5870 t = build2 (fd->loop.cond_code, boolean_type_node,
5871 DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback,
5872 iend);
5873 stmt = gimple_build_cond_empty (t);
5874 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
5875 }
50674e96 5876
726a989a
RB
5877 /* Remove GIMPLE_OMP_CONTINUE. */
5878 gsi_remove (&gsi, true);
50674e96 5879
acf0174b 5880 if (fd->collapse > 1 && !gimple_omp_for_combined_p (fd->for_stmt))
74bf76ed 5881 collapse_bb = extract_omp_for_update_vars (fd, cont_bb, l1_bb);
a68ab351 5882
e5c95afe 5883 /* Emit code to get the next parallel iteration in L2_BB. */
726a989a 5884 gsi = gsi_start_bb (l2_bb);
50674e96 5885
e79983f4 5886 t = build_call_expr (builtin_decl_explicit (next_fn), 2,
e5c95afe
ZD
5887 build_fold_addr_expr (istart0),
5888 build_fold_addr_expr (iend0));
726a989a
RB
5889 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
5890 false, GSI_CONTINUE_LINKING);
a68ab351
JJ
5891 if (TREE_TYPE (t) != boolean_type_node)
5892 t = fold_build2 (NE_EXPR, boolean_type_node,
5893 t, build_int_cst (TREE_TYPE (t), 0));
726a989a
RB
5894 stmt = gimple_build_cond_empty (t);
5895 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
e5c95afe 5896 }
953ff289 5897
777f7f9a 5898 /* Add the loop cleanup function. */
726a989a
RB
5899 gsi = gsi_last_bb (exit_bb);
5900 if (gimple_omp_return_nowait_p (gsi_stmt (gsi)))
e79983f4 5901 t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_NOWAIT);
acf0174b
JJ
5902 else if (gimple_omp_return_lhs (gsi_stmt (gsi)))
5903 t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_CANCEL);
777f7f9a 5904 else
e79983f4 5905 t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END);
726a989a 5906 stmt = gimple_build_call (t, 0);
acf0174b
JJ
5907 if (gimple_omp_return_lhs (gsi_stmt (gsi)))
5908 gimple_call_set_lhs (stmt, gimple_omp_return_lhs (gsi_stmt (gsi)));
726a989a
RB
5909 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
5910 gsi_remove (&gsi, true);
50674e96
DN
5911
5912 /* Connect the new blocks. */
917948d3
ZD
5913 find_edge (entry_bb, l0_bb)->flags = EDGE_TRUE_VALUE;
5914 find_edge (entry_bb, l3_bb)->flags = EDGE_FALSE_VALUE;
953ff289 5915
e5c95afe
ZD
5916 if (!broken_loop)
5917 {
726a989a
RB
5918 gimple_seq phis;
5919
917948d3
ZD
5920 e = find_edge (cont_bb, l3_bb);
5921 ne = make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
5922
726a989a
RB
5923 phis = phi_nodes (l3_bb);
5924 for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
5925 {
5926 gimple phi = gsi_stmt (gsi);
5927 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, ne),
5928 PHI_ARG_DEF_FROM_EDGE (phi, e));
5929 }
917948d3
ZD
5930 remove_edge (e);
5931
e5c95afe 5932 make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
726338f4 5933 add_bb_to_loop (l2_bb, cont_bb->loop_father);
74bf76ed 5934 e = find_edge (cont_bb, l1_bb);
acf0174b
JJ
5935 if (gimple_omp_for_combined_p (fd->for_stmt))
5936 {
5937 remove_edge (e);
5938 e = NULL;
5939 }
74bf76ed 5940 else if (fd->collapse > 1)
a68ab351 5941 {
a68ab351
JJ
5942 remove_edge (e);
5943 e = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
5944 }
5945 else
74bf76ed
JJ
5946 e->flags = EDGE_TRUE_VALUE;
5947 if (e)
a68ab351 5948 {
74bf76ed
JJ
5949 e->probability = REG_BR_PROB_BASE * 7 / 8;
5950 find_edge (cont_bb, l2_bb)->probability = REG_BR_PROB_BASE / 8;
5951 }
5952 else
5953 {
5954 e = find_edge (cont_bb, l2_bb);
5955 e->flags = EDGE_FALLTHRU;
a68ab351 5956 }
e5c95afe 5957 make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
917948d3
ZD
5958
5959 set_immediate_dominator (CDI_DOMINATORS, l2_bb,
5960 recompute_dominator (CDI_DOMINATORS, l2_bb));
5961 set_immediate_dominator (CDI_DOMINATORS, l3_bb,
5962 recompute_dominator (CDI_DOMINATORS, l3_bb));
5963 set_immediate_dominator (CDI_DOMINATORS, l0_bb,
5964 recompute_dominator (CDI_DOMINATORS, l0_bb));
5965 set_immediate_dominator (CDI_DOMINATORS, l1_bb,
5966 recompute_dominator (CDI_DOMINATORS, l1_bb));
6093bc06
RB
5967
5968 struct loop *outer_loop = alloc_loop ();
5969 outer_loop->header = l0_bb;
5970 outer_loop->latch = l2_bb;
5971 add_loop (outer_loop, l0_bb->loop_father);
5972
acf0174b 5973 if (!gimple_omp_for_combined_p (fd->for_stmt))
74bf76ed
JJ
5974 {
5975 struct loop *loop = alloc_loop ();
5976 loop->header = l1_bb;
5977 /* The loop may have multiple latches. */
5978 add_loop (loop, outer_loop);
5979 }
e5c95afe 5980 }
953ff289
DN
5981}
5982
5983
50674e96
DN
5984/* A subroutine of expand_omp_for. Generate code for a parallel
5985 loop with static schedule and no specified chunk size. Given
5986 parameters:
953ff289
DN
5987
5988 for (V = N1; V cond N2; V += STEP) BODY;
5989
5990 where COND is "<" or ">", we generate pseudocode
5991
5a0f4dd3 5992 if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
953ff289
DN
5993 if (cond is <)
5994 adj = STEP - 1;
5995 else
5996 adj = STEP + 1;
a68ab351
JJ
5997 if ((__typeof (V)) -1 > 0 && cond is >)
5998 n = -(adj + N2 - N1) / -STEP;
5999 else
6000 n = (adj + N2 - N1) / STEP;
953ff289 6001 q = n / nthreads;
fb79f500
JJ
6002 tt = n % nthreads;
6003 if (threadid < tt) goto L3; else goto L4;
6004 L3:
6005 tt = 0;
6006 q = q + 1;
6007 L4:
6008 s0 = q * threadid + tt;
6009 e0 = s0 + q;
917948d3 6010 V = s0 * STEP + N1;
953ff289
DN
6011 if (s0 >= e0) goto L2; else goto L0;
6012 L0:
953ff289
DN
6013 e = e0 * STEP + N1;
6014 L1:
6015 BODY;
6016 V += STEP;
6017 if (V cond e) goto L1;
953ff289
DN
6018 L2:
6019*/
6020
777f7f9a 6021static void
50674e96 6022expand_omp_for_static_nochunk (struct omp_region *region,
acf0174b
JJ
6023 struct omp_for_data *fd,
6024 gimple inner_stmt)
953ff289 6025{
fb79f500 6026 tree n, q, s0, e0, e, t, tt, nthreads, threadid;
a68ab351 6027 tree type, itype, vmain, vback;
fb79f500 6028 basic_block entry_bb, second_bb, third_bb, exit_bb, seq_start_bb;
acf0174b 6029 basic_block body_bb, cont_bb, collapse_bb = NULL;
777f7f9a 6030 basic_block fin_bb;
726a989a
RB
6031 gimple_stmt_iterator gsi;
6032 gimple stmt;
fb79f500 6033 edge ep;
acf0174b
JJ
6034 enum built_in_function get_num_threads = BUILT_IN_OMP_GET_NUM_THREADS;
6035 enum built_in_function get_thread_num = BUILT_IN_OMP_GET_THREAD_NUM;
6036 bool broken_loop = region->cont == NULL;
6037 tree *counts = NULL;
6038 tree n1, n2, step;
953ff289 6039
a68ab351
JJ
6040 itype = type = TREE_TYPE (fd->loop.v);
6041 if (POINTER_TYPE_P (type))
96f9265a 6042 itype = signed_type_for (type);
953ff289 6043
777f7f9a 6044 entry_bb = region->entry;
777f7f9a 6045 cont_bb = region->cont;
e5c95afe 6046 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
acf0174b
JJ
6047 fin_bb = BRANCH_EDGE (entry_bb)->dest;
6048 gcc_assert (broken_loop
6049 || (fin_bb == FALLTHRU_EDGE (cont_bb)->dest));
e5c95afe
ZD
6050 seq_start_bb = split_edge (FALLTHRU_EDGE (entry_bb));
6051 body_bb = single_succ (seq_start_bb);
acf0174b
JJ
6052 if (!broken_loop)
6053 {
6054 gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
6055 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
6056 }
777f7f9a
RH
6057 exit_bb = region->exit;
6058
50674e96 6059 /* Iteration space partitioning goes in ENTRY_BB. */
726a989a
RB
6060 gsi = gsi_last_bb (entry_bb);
6061 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
777f7f9a 6062
acf0174b
JJ
6063 if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_DISTRIBUTE)
6064 {
6065 get_num_threads = BUILT_IN_OMP_GET_NUM_TEAMS;
6066 get_thread_num = BUILT_IN_OMP_GET_TEAM_NUM;
6067 }
6068
6069 if (fd->collapse > 1)
6070 {
6071 int first_zero_iter = -1;
6072 basic_block l2_dom_bb = NULL;
6073
6074 counts = XALLOCAVEC (tree, fd->collapse);
6075 expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
6076 fin_bb, first_zero_iter,
6077 l2_dom_bb);
6078 t = NULL_TREE;
6079 }
6080 else if (gimple_omp_for_combined_into_p (fd->for_stmt))
6081 t = integer_one_node;
6082 else
6083 t = fold_binary (fd->loop.cond_code, boolean_type_node,
6084 fold_convert (type, fd->loop.n1),
6085 fold_convert (type, fd->loop.n2));
6086 if (fd->collapse == 1
6087 && TYPE_UNSIGNED (type)
5a0f4dd3
JJ
6088 && (t == NULL_TREE || !integer_onep (t)))
6089 {
5a0f4dd3
JJ
6090 n1 = fold_convert (type, unshare_expr (fd->loop.n1));
6091 n1 = force_gimple_operand_gsi (&gsi, n1, true, NULL_TREE,
6092 true, GSI_SAME_STMT);
6093 n2 = fold_convert (type, unshare_expr (fd->loop.n2));
6094 n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE,
6095 true, GSI_SAME_STMT);
6096 stmt = gimple_build_cond (fd->loop.cond_code, n1, n2,
6097 NULL_TREE, NULL_TREE);
6098 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
6099 if (walk_tree (gimple_cond_lhs_ptr (stmt),
6100 expand_omp_regimplify_p, NULL, NULL)
6101 || walk_tree (gimple_cond_rhs_ptr (stmt),
6102 expand_omp_regimplify_p, NULL, NULL))
6103 {
6104 gsi = gsi_for_stmt (stmt);
6105 gimple_regimplify_operands (stmt, &gsi);
6106 }
6107 ep = split_block (entry_bb, stmt);
6108 ep->flags = EDGE_TRUE_VALUE;
6109 entry_bb = ep->dest;
6110 ep->probability = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1);
6111 ep = make_edge (ep->src, fin_bb, EDGE_FALSE_VALUE);
6112 ep->probability = REG_BR_PROB_BASE / 2000 - 1;
6113 if (gimple_in_ssa_p (cfun))
6114 {
6115 int dest_idx = find_edge (entry_bb, fin_bb)->dest_idx;
6116 for (gsi = gsi_start_phis (fin_bb);
6117 !gsi_end_p (gsi); gsi_next (&gsi))
6118 {
6119 gimple phi = gsi_stmt (gsi);
6120 add_phi_arg (phi, gimple_phi_arg_def (phi, dest_idx),
6121 ep, UNKNOWN_LOCATION);
6122 }
6123 }
6124 gsi = gsi_last_bb (entry_bb);
6125 }
6126
acf0174b 6127 t = build_call_expr (builtin_decl_explicit (get_num_threads), 0);
a68ab351 6128 t = fold_convert (itype, t);
726a989a
RB
6129 nthreads = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
6130 true, GSI_SAME_STMT);
b8698a0f 6131
acf0174b 6132 t = build_call_expr (builtin_decl_explicit (get_thread_num), 0);
a68ab351 6133 t = fold_convert (itype, t);
726a989a
RB
6134 threadid = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
6135 true, GSI_SAME_STMT);
953ff289 6136
acf0174b
JJ
6137 n1 = fd->loop.n1;
6138 n2 = fd->loop.n2;
6139 step = fd->loop.step;
6140 if (gimple_omp_for_combined_into_p (fd->for_stmt))
6141 {
6142 tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
6143 OMP_CLAUSE__LOOPTEMP_);
6144 gcc_assert (innerc);
6145 n1 = OMP_CLAUSE_DECL (innerc);
6146 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
6147 OMP_CLAUSE__LOOPTEMP_);
6148 gcc_assert (innerc);
6149 n2 = OMP_CLAUSE_DECL (innerc);
6150 }
6151 n1 = force_gimple_operand_gsi (&gsi, fold_convert (type, n1),
6152 true, NULL_TREE, true, GSI_SAME_STMT);
6153 n2 = force_gimple_operand_gsi (&gsi, fold_convert (itype, n2),
6154 true, NULL_TREE, true, GSI_SAME_STMT);
6155 step = force_gimple_operand_gsi (&gsi, fold_convert (itype, step),
6156 true, NULL_TREE, true, GSI_SAME_STMT);
a68ab351
JJ
6157
6158 t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
acf0174b
JJ
6159 t = fold_build2 (PLUS_EXPR, itype, step, t);
6160 t = fold_build2 (PLUS_EXPR, itype, t, n2);
6161 t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, n1));
a68ab351
JJ
6162 if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
6163 t = fold_build2 (TRUNC_DIV_EXPR, itype,
6164 fold_build1 (NEGATE_EXPR, itype, t),
acf0174b 6165 fold_build1 (NEGATE_EXPR, itype, step));
a68ab351 6166 else
acf0174b 6167 t = fold_build2 (TRUNC_DIV_EXPR, itype, t, step);
a68ab351 6168 t = fold_convert (itype, t);
726a989a 6169 n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
953ff289 6170
7cc434a3 6171 q = create_tmp_reg (itype, "q");
a68ab351 6172 t = fold_build2 (TRUNC_DIV_EXPR, itype, n, nthreads);
fb79f500
JJ
6173 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
6174 gsi_insert_before (&gsi, gimple_build_assign (q, t), GSI_SAME_STMT);
6175
7cc434a3 6176 tt = create_tmp_reg (itype, "tt");
fb79f500
JJ
6177 t = fold_build2 (TRUNC_MOD_EXPR, itype, n, nthreads);
6178 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
6179 gsi_insert_before (&gsi, gimple_build_assign (tt, t), GSI_SAME_STMT);
953ff289 6180
fb79f500
JJ
6181 t = build2 (LT_EXPR, boolean_type_node, threadid, tt);
6182 stmt = gimple_build_cond_empty (t);
6183 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
6184
6185 second_bb = split_block (entry_bb, stmt)->dest;
6186 gsi = gsi_last_bb (second_bb);
6187 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
6188
6189 gsi_insert_before (&gsi, gimple_build_assign (tt, build_int_cst (itype, 0)),
6190 GSI_SAME_STMT);
6191 stmt = gimple_build_assign_with_ops (PLUS_EXPR, q, q,
6192 build_int_cst (itype, 1));
6193 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
6194
6195 third_bb = split_block (second_bb, stmt)->dest;
6196 gsi = gsi_last_bb (third_bb);
6197 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
953ff289 6198
a68ab351 6199 t = build2 (MULT_EXPR, itype, q, threadid);
fb79f500 6200 t = build2 (PLUS_EXPR, itype, t, tt);
726a989a 6201 s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
953ff289 6202
a68ab351 6203 t = fold_build2 (PLUS_EXPR, itype, s0, q);
726a989a 6204 e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
917948d3 6205
953ff289 6206 t = build2 (GE_EXPR, boolean_type_node, s0, e0);
726a989a 6207 gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
50674e96 6208
726a989a
RB
6209 /* Remove the GIMPLE_OMP_FOR statement. */
6210 gsi_remove (&gsi, true);
50674e96
DN
6211
6212 /* Setup code for sequential iteration goes in SEQ_START_BB. */
726a989a 6213 gsi = gsi_start_bb (seq_start_bb);
953ff289 6214
acf0174b
JJ
6215 tree startvar = fd->loop.v;
6216 tree endvar = NULL_TREE;
6217
6218 if (gimple_omp_for_combined_p (fd->for_stmt))
6219 {
6220 tree clauses = gimple_code (inner_stmt) == GIMPLE_OMP_PARALLEL
6221 ? gimple_omp_parallel_clauses (inner_stmt)
6222 : gimple_omp_for_clauses (inner_stmt);
6223 tree innerc = find_omp_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
6224 gcc_assert (innerc);
6225 startvar = OMP_CLAUSE_DECL (innerc);
6226 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
6227 OMP_CLAUSE__LOOPTEMP_);
6228 gcc_assert (innerc);
6229 endvar = OMP_CLAUSE_DECL (innerc);
6230 }
a68ab351 6231 t = fold_convert (itype, s0);
acf0174b 6232 t = fold_build2 (MULT_EXPR, itype, t, step);
a68ab351 6233 if (POINTER_TYPE_P (type))
acf0174b 6234 t = fold_build_pointer_plus (n1, t);
a68ab351 6235 else
acf0174b
JJ
6236 t = fold_build2 (PLUS_EXPR, type, t, n1);
6237 t = fold_convert (TREE_TYPE (startvar), t);
ea3a0fde 6238 t = force_gimple_operand_gsi (&gsi, t,
acf0174b
JJ
6239 DECL_P (startvar)
6240 && TREE_ADDRESSABLE (startvar),
ea3a0fde 6241 NULL_TREE, false, GSI_CONTINUE_LINKING);
acf0174b 6242 stmt = gimple_build_assign (startvar, t);
726a989a 6243 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
b8698a0f 6244
a68ab351 6245 t = fold_convert (itype, e0);
acf0174b 6246 t = fold_build2 (MULT_EXPR, itype, t, step);
a68ab351 6247 if (POINTER_TYPE_P (type))
acf0174b 6248 t = fold_build_pointer_plus (n1, t);
a68ab351 6249 else
acf0174b
JJ
6250 t = fold_build2 (PLUS_EXPR, type, t, n1);
6251 t = fold_convert (TREE_TYPE (startvar), t);
726a989a
RB
6252 e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
6253 false, GSI_CONTINUE_LINKING);
acf0174b
JJ
6254 if (endvar)
6255 {
6256 stmt = gimple_build_assign (endvar, e);
6257 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
95782571
JJ
6258 if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
6259 stmt = gimple_build_assign (fd->loop.v, e);
6260 else
6261 stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, e,
6262 NULL_TREE);
6263 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
acf0174b
JJ
6264 }
6265 if (fd->collapse > 1)
6266 expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
953ff289 6267
acf0174b
JJ
6268 if (!broken_loop)
6269 {
6270 /* The code controlling the sequential loop replaces the
6271 GIMPLE_OMP_CONTINUE. */
6272 gsi = gsi_last_bb (cont_bb);
6273 stmt = gsi_stmt (gsi);
6274 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
6275 vmain = gimple_omp_continue_control_use (stmt);
6276 vback = gimple_omp_continue_control_def (stmt);
917948d3 6277
acf0174b
JJ
6278 if (!gimple_omp_for_combined_p (fd->for_stmt))
6279 {
6280 if (POINTER_TYPE_P (type))
6281 t = fold_build_pointer_plus (vmain, step);
6282 else
6283 t = fold_build2 (PLUS_EXPR, type, vmain, step);
6284 t = force_gimple_operand_gsi (&gsi, t,
6285 DECL_P (vback)
6286 && TREE_ADDRESSABLE (vback),
6287 NULL_TREE, true, GSI_SAME_STMT);
6288 stmt = gimple_build_assign (vback, t);
6289 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
917948d3 6290
acf0174b
JJ
6291 t = build2 (fd->loop.cond_code, boolean_type_node,
6292 DECL_P (vback) && TREE_ADDRESSABLE (vback)
6293 ? t : vback, e);
6294 gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
6295 }
953ff289 6296
acf0174b
JJ
6297 /* Remove the GIMPLE_OMP_CONTINUE statement. */
6298 gsi_remove (&gsi, true);
6299
6300 if (fd->collapse > 1 && !gimple_omp_for_combined_p (fd->for_stmt))
6301 collapse_bb = extract_omp_for_update_vars (fd, cont_bb, body_bb);
6302 }
50674e96 6303
726a989a
RB
6304 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
6305 gsi = gsi_last_bb (exit_bb);
6306 if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
acf0174b
JJ
6307 {
6308 t = gimple_omp_return_lhs (gsi_stmt (gsi));
6309 gsi_insert_after (&gsi, build_omp_barrier (t), GSI_SAME_STMT);
6310 }
726a989a 6311 gsi_remove (&gsi, true);
50674e96
DN
6312
6313 /* Connect all the blocks. */
fb79f500
JJ
6314 ep = make_edge (entry_bb, third_bb, EDGE_FALSE_VALUE);
6315 ep->probability = REG_BR_PROB_BASE / 4 * 3;
6316 ep = find_edge (entry_bb, second_bb);
6317 ep->flags = EDGE_TRUE_VALUE;
6318 ep->probability = REG_BR_PROB_BASE / 4;
6319 find_edge (third_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
6320 find_edge (third_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
917948d3 6321
acf0174b
JJ
6322 if (!broken_loop)
6323 {
6324 ep = find_edge (cont_bb, body_bb);
6325 if (gimple_omp_for_combined_p (fd->for_stmt))
6326 {
6327 remove_edge (ep);
6328 ep = NULL;
6329 }
6330 else if (fd->collapse > 1)
6331 {
6332 remove_edge (ep);
6333 ep = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
6334 }
6335 else
6336 ep->flags = EDGE_TRUE_VALUE;
6337 find_edge (cont_bb, fin_bb)->flags
6338 = ep ? EDGE_FALSE_VALUE : EDGE_FALLTHRU;
6339 }
b8698a0f 6340
fb79f500
JJ
6341 set_immediate_dominator (CDI_DOMINATORS, second_bb, entry_bb);
6342 set_immediate_dominator (CDI_DOMINATORS, third_bb, entry_bb);
6343 set_immediate_dominator (CDI_DOMINATORS, seq_start_bb, third_bb);
acf0174b 6344
917948d3
ZD
6345 set_immediate_dominator (CDI_DOMINATORS, body_bb,
6346 recompute_dominator (CDI_DOMINATORS, body_bb));
6347 set_immediate_dominator (CDI_DOMINATORS, fin_bb,
6348 recompute_dominator (CDI_DOMINATORS, fin_bb));
6093bc06 6349
acf0174b
JJ
6350 if (!broken_loop && !gimple_omp_for_combined_p (fd->for_stmt))
6351 {
6352 struct loop *loop = alloc_loop ();
6353 loop->header = body_bb;
6354 if (collapse_bb == NULL)
6355 loop->latch = cont_bb;
6356 add_loop (loop, body_bb->loop_father);
6357 }
953ff289
DN
6358}
6359
50674e96
DN
6360
6361/* A subroutine of expand_omp_for. Generate code for a parallel
6362 loop with static schedule and a specified chunk size. Given
6363 parameters:
953ff289
DN
6364
6365 for (V = N1; V cond N2; V += STEP) BODY;
6366
6367 where COND is "<" or ">", we generate pseudocode
6368
5a0f4dd3 6369 if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
953ff289
DN
6370 if (cond is <)
6371 adj = STEP - 1;
6372 else
6373 adj = STEP + 1;
a68ab351
JJ
6374 if ((__typeof (V)) -1 > 0 && cond is >)
6375 n = -(adj + N2 - N1) / -STEP;
6376 else
6377 n = (adj + N2 - N1) / STEP;
953ff289 6378 trip = 0;
917948d3
ZD
6379 V = threadid * CHUNK * STEP + N1; -- this extra definition of V is
6380 here so that V is defined
6381 if the loop is not entered
953ff289
DN
6382 L0:
6383 s0 = (trip * nthreads + threadid) * CHUNK;
6384 e0 = min(s0 + CHUNK, n);
6385 if (s0 < n) goto L1; else goto L4;
6386 L1:
6387 V = s0 * STEP + N1;
6388 e = e0 * STEP + N1;
6389 L2:
6390 BODY;
6391 V += STEP;
6392 if (V cond e) goto L2; else goto L3;
6393 L3:
6394 trip += 1;
6395 goto L0;
6396 L4:
953ff289
DN
6397*/
6398
777f7f9a 6399static void
acf0174b
JJ
6400expand_omp_for_static_chunk (struct omp_region *region,
6401 struct omp_for_data *fd, gimple inner_stmt)
953ff289 6402{
726a989a 6403 tree n, s0, e0, e, t;
917948d3 6404 tree trip_var, trip_init, trip_main, trip_back, nthreads, threadid;
ed20ae98 6405 tree type, itype, vmain, vback, vextra;
50674e96 6406 basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
acf0174b 6407 basic_block trip_update_bb = NULL, cont_bb, collapse_bb = NULL, fin_bb;
ed20ae98 6408 gimple_stmt_iterator gsi;
726a989a
RB
6409 gimple stmt;
6410 edge se;
acf0174b
JJ
6411 enum built_in_function get_num_threads = BUILT_IN_OMP_GET_NUM_THREADS;
6412 enum built_in_function get_thread_num = BUILT_IN_OMP_GET_THREAD_NUM;
6413 bool broken_loop = region->cont == NULL;
6414 tree *counts = NULL;
6415 tree n1, n2, step;
953ff289 6416
a68ab351
JJ
6417 itype = type = TREE_TYPE (fd->loop.v);
6418 if (POINTER_TYPE_P (type))
96f9265a 6419 itype = signed_type_for (type);
953ff289 6420
777f7f9a 6421 entry_bb = region->entry;
e5c95afe
ZD
6422 se = split_block (entry_bb, last_stmt (entry_bb));
6423 entry_bb = se->src;
6424 iter_part_bb = se->dest;
777f7f9a 6425 cont_bb = region->cont;
e5c95afe 6426 gcc_assert (EDGE_COUNT (iter_part_bb->succs) == 2);
acf0174b
JJ
6427 fin_bb = BRANCH_EDGE (iter_part_bb)->dest;
6428 gcc_assert (broken_loop
6429 || fin_bb == FALLTHRU_EDGE (cont_bb)->dest);
e5c95afe
ZD
6430 seq_start_bb = split_edge (FALLTHRU_EDGE (iter_part_bb));
6431 body_bb = single_succ (seq_start_bb);
acf0174b
JJ
6432 if (!broken_loop)
6433 {
6434 gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
6435 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
6436 trip_update_bb = split_edge (FALLTHRU_EDGE (cont_bb));
6437 }
777f7f9a 6438 exit_bb = region->exit;
50674e96 6439
50674e96 6440 /* Trip and adjustment setup goes in ENTRY_BB. */
ed20ae98
TS
6441 gsi = gsi_last_bb (entry_bb);
6442 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
50674e96 6443
acf0174b
JJ
6444 if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_DISTRIBUTE)
6445 {
6446 get_num_threads = BUILT_IN_OMP_GET_NUM_TEAMS;
6447 get_thread_num = BUILT_IN_OMP_GET_TEAM_NUM;
6448 }
6449
6450 if (fd->collapse > 1)
6451 {
6452 int first_zero_iter = -1;
6453 basic_block l2_dom_bb = NULL;
6454
6455 counts = XALLOCAVEC (tree, fd->collapse);
ed20ae98 6456 expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
acf0174b
JJ
6457 fin_bb, first_zero_iter,
6458 l2_dom_bb);
6459 t = NULL_TREE;
6460 }
6461 else if (gimple_omp_for_combined_into_p (fd->for_stmt))
6462 t = integer_one_node;
6463 else
6464 t = fold_binary (fd->loop.cond_code, boolean_type_node,
6465 fold_convert (type, fd->loop.n1),
6466 fold_convert (type, fd->loop.n2));
6467 if (fd->collapse == 1
6468 && TYPE_UNSIGNED (type)
5a0f4dd3
JJ
6469 && (t == NULL_TREE || !integer_onep (t)))
6470 {
5a0f4dd3 6471 n1 = fold_convert (type, unshare_expr (fd->loop.n1));
ed20ae98 6472 n1 = force_gimple_operand_gsi (&gsi, n1, true, NULL_TREE,
5a0f4dd3
JJ
6473 true, GSI_SAME_STMT);
6474 n2 = fold_convert (type, unshare_expr (fd->loop.n2));
ed20ae98 6475 n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE,
5a0f4dd3
JJ
6476 true, GSI_SAME_STMT);
6477 stmt = gimple_build_cond (fd->loop.cond_code, n1, n2,
6478 NULL_TREE, NULL_TREE);
ed20ae98 6479 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
5a0f4dd3
JJ
6480 if (walk_tree (gimple_cond_lhs_ptr (stmt),
6481 expand_omp_regimplify_p, NULL, NULL)
6482 || walk_tree (gimple_cond_rhs_ptr (stmt),
6483 expand_omp_regimplify_p, NULL, NULL))
6484 {
ed20ae98
TS
6485 gsi = gsi_for_stmt (stmt);
6486 gimple_regimplify_operands (stmt, &gsi);
5a0f4dd3
JJ
6487 }
6488 se = split_block (entry_bb, stmt);
6489 se->flags = EDGE_TRUE_VALUE;
6490 entry_bb = se->dest;
6491 se->probability = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1);
6492 se = make_edge (se->src, fin_bb, EDGE_FALSE_VALUE);
6493 se->probability = REG_BR_PROB_BASE / 2000 - 1;
6494 if (gimple_in_ssa_p (cfun))
6495 {
6496 int dest_idx = find_edge (entry_bb, fin_bb)->dest_idx;
ed20ae98
TS
6497 for (gsi = gsi_start_phis (fin_bb);
6498 !gsi_end_p (gsi); gsi_next (&gsi))
5a0f4dd3 6499 {
ed20ae98 6500 gimple phi = gsi_stmt (gsi);
5a0f4dd3
JJ
6501 add_phi_arg (phi, gimple_phi_arg_def (phi, dest_idx),
6502 se, UNKNOWN_LOCATION);
6503 }
6504 }
ed20ae98 6505 gsi = gsi_last_bb (entry_bb);
5a0f4dd3
JJ
6506 }
6507
acf0174b 6508 t = build_call_expr (builtin_decl_explicit (get_num_threads), 0);
a68ab351 6509 t = fold_convert (itype, t);
ed20ae98 6510 nthreads = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
726a989a 6511 true, GSI_SAME_STMT);
b8698a0f 6512
acf0174b 6513 t = build_call_expr (builtin_decl_explicit (get_thread_num), 0);
a68ab351 6514 t = fold_convert (itype, t);
ed20ae98 6515 threadid = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
726a989a 6516 true, GSI_SAME_STMT);
917948d3 6517
acf0174b
JJ
6518 n1 = fd->loop.n1;
6519 n2 = fd->loop.n2;
6520 step = fd->loop.step;
6521 if (gimple_omp_for_combined_into_p (fd->for_stmt))
6522 {
6523 tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
6524 OMP_CLAUSE__LOOPTEMP_);
6525 gcc_assert (innerc);
6526 n1 = OMP_CLAUSE_DECL (innerc);
6527 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
6528 OMP_CLAUSE__LOOPTEMP_);
6529 gcc_assert (innerc);
6530 n2 = OMP_CLAUSE_DECL (innerc);
6531 }
ed20ae98 6532 n1 = force_gimple_operand_gsi (&gsi, fold_convert (type, n1),
acf0174b 6533 true, NULL_TREE, true, GSI_SAME_STMT);
ed20ae98 6534 n2 = force_gimple_operand_gsi (&gsi, fold_convert (itype, n2),
acf0174b 6535 true, NULL_TREE, true, GSI_SAME_STMT);
ed20ae98 6536 step = force_gimple_operand_gsi (&gsi, fold_convert (itype, step),
acf0174b 6537 true, NULL_TREE, true, GSI_SAME_STMT);
917948d3 6538 fd->chunk_size
ed20ae98 6539 = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->chunk_size),
726a989a 6540 true, NULL_TREE, true, GSI_SAME_STMT);
a68ab351
JJ
6541
6542 t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
acf0174b
JJ
6543 t = fold_build2 (PLUS_EXPR, itype, step, t);
6544 t = fold_build2 (PLUS_EXPR, itype, t, n2);
6545 t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, n1));
a68ab351
JJ
6546 if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
6547 t = fold_build2 (TRUNC_DIV_EXPR, itype,
6548 fold_build1 (NEGATE_EXPR, itype, t),
acf0174b 6549 fold_build1 (NEGATE_EXPR, itype, step));
a68ab351 6550 else
acf0174b 6551 t = fold_build2 (TRUNC_DIV_EXPR, itype, t, step);
a68ab351 6552 t = fold_convert (itype, t);
ed20ae98 6553 n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
726a989a 6554 true, GSI_SAME_STMT);
917948d3 6555
a5efada7 6556 trip_var = create_tmp_reg (itype, ".trip");
917948d3
ZD
6557 if (gimple_in_ssa_p (cfun))
6558 {
726a989a
RB
6559 trip_init = make_ssa_name (trip_var, NULL);
6560 trip_main = make_ssa_name (trip_var, NULL);
6561 trip_back = make_ssa_name (trip_var, NULL);
917948d3 6562 }
953ff289 6563 else
917948d3
ZD
6564 {
6565 trip_init = trip_var;
6566 trip_main = trip_var;
6567 trip_back = trip_var;
6568 }
953ff289 6569
726a989a 6570 stmt = gimple_build_assign (trip_init, build_int_cst (itype, 0));
ed20ae98 6571 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
50674e96 6572
a68ab351 6573 t = fold_build2 (MULT_EXPR, itype, threadid, fd->chunk_size);
acf0174b 6574 t = fold_build2 (MULT_EXPR, itype, t, step);
a68ab351 6575 if (POINTER_TYPE_P (type))
acf0174b 6576 t = fold_build_pointer_plus (n1, t);
a68ab351 6577 else
acf0174b 6578 t = fold_build2 (PLUS_EXPR, type, t, n1);
ed20ae98
TS
6579 vextra = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
6580 true, GSI_SAME_STMT);
917948d3 6581
726a989a 6582 /* Remove the GIMPLE_OMP_FOR. */
ed20ae98 6583 gsi_remove (&gsi, true);
50674e96
DN
6584
6585 /* Iteration space partitioning goes in ITER_PART_BB. */
ed20ae98 6586 gsi = gsi_last_bb (iter_part_bb);
953ff289 6587
a68ab351
JJ
6588 t = fold_build2 (MULT_EXPR, itype, trip_main, nthreads);
6589 t = fold_build2 (PLUS_EXPR, itype, t, threadid);
6590 t = fold_build2 (MULT_EXPR, itype, t, fd->chunk_size);
ed20ae98 6591 s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
726a989a 6592 false, GSI_CONTINUE_LINKING);
953ff289 6593
a68ab351
JJ
6594 t = fold_build2 (PLUS_EXPR, itype, s0, fd->chunk_size);
6595 t = fold_build2 (MIN_EXPR, itype, t, n);
ed20ae98 6596 e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
726a989a 6597 false, GSI_CONTINUE_LINKING);
953ff289
DN
6598
6599 t = build2 (LT_EXPR, boolean_type_node, s0, n);
ed20ae98 6600 gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_CONTINUE_LINKING);
50674e96
DN
6601
6602 /* Setup code for sequential iteration goes in SEQ_START_BB. */
ed20ae98 6603 gsi = gsi_start_bb (seq_start_bb);
953ff289 6604
acf0174b
JJ
6605 tree startvar = fd->loop.v;
6606 tree endvar = NULL_TREE;
6607
6608 if (gimple_omp_for_combined_p (fd->for_stmt))
6609 {
6610 tree clauses = gimple_code (inner_stmt) == GIMPLE_OMP_PARALLEL
6611 ? gimple_omp_parallel_clauses (inner_stmt)
6612 : gimple_omp_for_clauses (inner_stmt);
6613 tree innerc = find_omp_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
6614 gcc_assert (innerc);
6615 startvar = OMP_CLAUSE_DECL (innerc);
6616 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
6617 OMP_CLAUSE__LOOPTEMP_);
6618 gcc_assert (innerc);
6619 endvar = OMP_CLAUSE_DECL (innerc);
6620 }
6621
a68ab351 6622 t = fold_convert (itype, s0);
acf0174b 6623 t = fold_build2 (MULT_EXPR, itype, t, step);
a68ab351 6624 if (POINTER_TYPE_P (type))
acf0174b 6625 t = fold_build_pointer_plus (n1, t);
a68ab351 6626 else
acf0174b
JJ
6627 t = fold_build2 (PLUS_EXPR, type, t, n1);
6628 t = fold_convert (TREE_TYPE (startvar), t);
ed20ae98 6629 t = force_gimple_operand_gsi (&gsi, t,
acf0174b
JJ
6630 DECL_P (startvar)
6631 && TREE_ADDRESSABLE (startvar),
ea3a0fde 6632 NULL_TREE, false, GSI_CONTINUE_LINKING);
acf0174b 6633 stmt = gimple_build_assign (startvar, t);
ed20ae98 6634 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
953ff289 6635
a68ab351 6636 t = fold_convert (itype, e0);
acf0174b 6637 t = fold_build2 (MULT_EXPR, itype, t, step);
a68ab351 6638 if (POINTER_TYPE_P (type))
acf0174b 6639 t = fold_build_pointer_plus (n1, t);
a68ab351 6640 else
acf0174b
JJ
6641 t = fold_build2 (PLUS_EXPR, type, t, n1);
6642 t = fold_convert (TREE_TYPE (startvar), t);
ed20ae98 6643 e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
726a989a 6644 false, GSI_CONTINUE_LINKING);
acf0174b
JJ
6645 if (endvar)
6646 {
6647 stmt = gimple_build_assign (endvar, e);
ed20ae98 6648 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
95782571
JJ
6649 if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
6650 stmt = gimple_build_assign (fd->loop.v, e);
6651 else
6652 stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, e,
6653 NULL_TREE);
ed20ae98 6654 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
acf0174b
JJ
6655 }
6656 if (fd->collapse > 1)
ed20ae98 6657 expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
acf0174b
JJ
6658
6659 if (!broken_loop)
6660 {
6661 /* The code controlling the sequential loop goes in CONT_BB,
6662 replacing the GIMPLE_OMP_CONTINUE. */
ed20ae98
TS
6663 gsi = gsi_last_bb (cont_bb);
6664 stmt = gsi_stmt (gsi);
acf0174b 6665 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
ed20ae98
TS
6666 vmain = gimple_omp_continue_control_use (stmt);
6667 vback = gimple_omp_continue_control_def (stmt);
953ff289 6668
acf0174b
JJ
6669 if (!gimple_omp_for_combined_p (fd->for_stmt))
6670 {
6671 if (POINTER_TYPE_P (type))
ed20ae98 6672 t = fold_build_pointer_plus (vmain, step);
acf0174b 6673 else
ed20ae98
TS
6674 t = fold_build2 (PLUS_EXPR, type, vmain, step);
6675 if (DECL_P (vback) && TREE_ADDRESSABLE (vback))
6676 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
acf0174b 6677 true, GSI_SAME_STMT);
ed20ae98
TS
6678 stmt = gimple_build_assign (vback, t);
6679 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
917948d3 6680
acf0174b 6681 t = build2 (fd->loop.cond_code, boolean_type_node,
ed20ae98
TS
6682 DECL_P (vback) && TREE_ADDRESSABLE (vback)
6683 ? t : vback, e);
6684 gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
acf0174b 6685 }
917948d3 6686
acf0174b 6687 /* Remove GIMPLE_OMP_CONTINUE. */
ed20ae98 6688 gsi_remove (&gsi, true);
b8698a0f 6689
acf0174b
JJ
6690 if (fd->collapse > 1 && !gimple_omp_for_combined_p (fd->for_stmt))
6691 collapse_bb = extract_omp_for_update_vars (fd, cont_bb, body_bb);
50674e96 6692
acf0174b 6693 /* Trip update code goes into TRIP_UPDATE_BB. */
ed20ae98 6694 gsi = gsi_start_bb (trip_update_bb);
953ff289 6695
acf0174b
JJ
6696 t = build_int_cst (itype, 1);
6697 t = build2 (PLUS_EXPR, itype, trip_main, t);
6698 stmt = gimple_build_assign (trip_back, t);
ed20ae98 6699 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
acf0174b 6700 }
953ff289 6701
726a989a 6702 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
ed20ae98
TS
6703 gsi = gsi_last_bb (exit_bb);
6704 if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
acf0174b 6705 {
ed20ae98
TS
6706 t = gimple_omp_return_lhs (gsi_stmt (gsi));
6707 gsi_insert_after (&gsi, build_omp_barrier (t), GSI_SAME_STMT);
acf0174b 6708 }
ed20ae98 6709 gsi_remove (&gsi, true);
953ff289 6710
50674e96 6711 /* Connect the new blocks. */
e5c95afe
ZD
6712 find_edge (iter_part_bb, seq_start_bb)->flags = EDGE_TRUE_VALUE;
6713 find_edge (iter_part_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
917948d3 6714
acf0174b
JJ
6715 if (!broken_loop)
6716 {
6717 se = find_edge (cont_bb, body_bb);
6718 if (gimple_omp_for_combined_p (fd->for_stmt))
6719 {
6720 remove_edge (se);
6721 se = NULL;
6722 }
6723 else if (fd->collapse > 1)
6724 {
6725 remove_edge (se);
6726 se = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
6727 }
6728 else
6729 se->flags = EDGE_TRUE_VALUE;
6730 find_edge (cont_bb, trip_update_bb)->flags
6731 = se ? EDGE_FALSE_VALUE : EDGE_FALLTHRU;
917948d3 6732
acf0174b
JJ
6733 redirect_edge_and_branch (single_succ_edge (trip_update_bb), iter_part_bb);
6734 }
917948d3
ZD
6735
6736 if (gimple_in_ssa_p (cfun))
6737 {
726a989a
RB
6738 gimple_stmt_iterator psi;
6739 gimple phi;
6740 edge re, ene;
726a989a
RB
6741 edge_var_map *vm;
6742 size_t i;
6743
acf0174b
JJ
6744 gcc_assert (fd->collapse == 1 && !broken_loop);
6745
917948d3
ZD
6746 /* When we redirect the edge from trip_update_bb to iter_part_bb, we
6747 remove arguments of the phi nodes in fin_bb. We need to create
6748 appropriate phi nodes in iter_part_bb instead. */
6749 se = single_pred_edge (fin_bb);
6750 re = single_succ_edge (trip_update_bb);
b787e7a2 6751 vec<edge_var_map> *head = redirect_edge_var_map_vector (re);
917948d3
ZD
6752 ene = single_succ_edge (entry_bb);
6753
726a989a 6754 psi = gsi_start_phis (fin_bb);
9771b263 6755 for (i = 0; !gsi_end_p (psi) && head->iterate (i, &vm);
726a989a 6756 gsi_next (&psi), ++i)
917948d3 6757 {
726a989a 6758 gimple nphi;
f5045c96 6759 source_location locus;
726a989a
RB
6760
6761 phi = gsi_stmt (psi);
6762 t = gimple_phi_result (phi);
6763 gcc_assert (t == redirect_edge_var_map_result (vm));
917948d3 6764 nphi = create_phi_node (t, iter_part_bb);
917948d3
ZD
6765
6766 t = PHI_ARG_DEF_FROM_EDGE (phi, se);
f5045c96
AM
6767 locus = gimple_phi_arg_location_from_edge (phi, se);
6768
a68ab351 6769 /* A special case -- fd->loop.v is not yet computed in
ed20ae98 6770 iter_part_bb, we need to use vextra instead. */
a68ab351 6771 if (t == fd->loop.v)
ed20ae98 6772 t = vextra;
9e227d60 6773 add_phi_arg (nphi, t, ene, locus);
f5045c96 6774 locus = redirect_edge_var_map_location (vm);
9e227d60 6775 add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus);
726a989a 6776 }
9771b263 6777 gcc_assert (!gsi_end_p (psi) && i == head->length ());
726a989a
RB
6778 redirect_edge_var_map_clear (re);
6779 while (1)
6780 {
6781 psi = gsi_start_phis (fin_bb);
6782 if (gsi_end_p (psi))
6783 break;
6784 remove_phi_node (&psi, false);
917948d3 6785 }
917948d3
ZD
6786
6787 /* Make phi node for trip. */
6788 phi = create_phi_node (trip_main, iter_part_bb);
f5045c96 6789 add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb),
9e227d60 6790 UNKNOWN_LOCATION);
f5045c96 6791 add_phi_arg (phi, trip_init, single_succ_edge (entry_bb),
9e227d60 6792 UNKNOWN_LOCATION);
917948d3
ZD
6793 }
6794
acf0174b
JJ
6795 if (!broken_loop)
6796 set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
917948d3
ZD
6797 set_immediate_dominator (CDI_DOMINATORS, iter_part_bb,
6798 recompute_dominator (CDI_DOMINATORS, iter_part_bb));
6799 set_immediate_dominator (CDI_DOMINATORS, fin_bb,
6800 recompute_dominator (CDI_DOMINATORS, fin_bb));
6801 set_immediate_dominator (CDI_DOMINATORS, seq_start_bb,
6802 recompute_dominator (CDI_DOMINATORS, seq_start_bb));
6803 set_immediate_dominator (CDI_DOMINATORS, body_bb,
6804 recompute_dominator (CDI_DOMINATORS, body_bb));
6093bc06 6805
acf0174b
JJ
6806 if (!broken_loop)
6807 {
6808 struct loop *trip_loop = alloc_loop ();
6809 trip_loop->header = iter_part_bb;
6810 trip_loop->latch = trip_update_bb;
6811 add_loop (trip_loop, iter_part_bb->loop_father);
6093bc06 6812
acf0174b
JJ
6813 if (!gimple_omp_for_combined_p (fd->for_stmt))
6814 {
6815 struct loop *loop = alloc_loop ();
6816 loop->header = body_bb;
01dde9b0
JJ
6817 if (collapse_bb == NULL)
6818 loop->latch = cont_bb;
acf0174b
JJ
6819 add_loop (loop, trip_loop);
6820 }
6821 }
953ff289
DN
6822}
6823
9a771876
JJ
6824/* A subroutine of expand_omp_for. Generate code for _Cilk_for loop.
6825 Given parameters:
6826 for (V = N1; V cond N2; V += STEP) BODY;
6827
6828 where COND is "<" or ">" or "!=", we generate pseudocode
6829
6830 for (ind_var = low; ind_var < high; ind_var++)
6831 {
6832 V = n1 + (ind_var * STEP)
6833
6834 <BODY>
6835 }
6836
6837 In the above pseudocode, low and high are function parameters of the
6838 child function. In the function below, we are inserting a temp.
6839 variable that will be making a call to two OMP functions that will not be
6840 found in the body of _Cilk_for (since OMP_FOR cannot be mixed
6841 with _Cilk_for). These functions are replaced with low and high
6842 by the function that handles taskreg. */
6843
6844
6845static void
6846expand_cilk_for (struct omp_region *region, struct omp_for_data *fd)
6847{
6848 bool broken_loop = region->cont == NULL;
6849 basic_block entry_bb = region->entry;
6850 basic_block cont_bb = region->cont;
6851
6852 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
6853 gcc_assert (broken_loop
6854 || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
6855 basic_block l0_bb = FALLTHRU_EDGE (entry_bb)->dest;
6856 basic_block l1_bb, l2_bb;
6857
6858 if (!broken_loop)
6859 {
6860 gcc_assert (BRANCH_EDGE (cont_bb)->dest == l0_bb);
6861 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
6862 l1_bb = split_block (cont_bb, last_stmt (cont_bb))->dest;
6863 l2_bb = BRANCH_EDGE (entry_bb)->dest;
6864 }
6865 else
6866 {
6867 BRANCH_EDGE (entry_bb)->flags &= ~EDGE_ABNORMAL;
6868 l1_bb = split_edge (BRANCH_EDGE (entry_bb));
6869 l2_bb = single_succ (l1_bb);
6870 }
6871 basic_block exit_bb = region->exit;
6872 basic_block l2_dom_bb = NULL;
6873
6874 gimple_stmt_iterator gsi = gsi_last_bb (entry_bb);
6875
6876 /* Below statements until the "tree high_val = ..." are pseudo statements
6877 used to pass information to be used by expand_omp_taskreg.
6878 low_val and high_val will be replaced by the __low and __high
6879 parameter from the child function.
6880
6881 The call_exprs part is a place-holder, it is mainly used
6882 to distinctly identify to the top-level part that this is
6883 where we should put low and high (reasoning given in header
6884 comment). */
6885
6886 tree child_fndecl
6887 = gimple_omp_parallel_child_fn (last_stmt (region->outer->entry));
6888 tree t, low_val = NULL_TREE, high_val = NULL_TREE;
6889 for (t = DECL_ARGUMENTS (child_fndecl); t; t = TREE_CHAIN (t))
6890 {
6891 if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__high"))
6892 high_val = t;
6893 else if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__low"))
6894 low_val = t;
6895 }
6896 gcc_assert (low_val && high_val);
6897
6898 tree type = TREE_TYPE (low_val);
6899 tree ind_var = create_tmp_reg (type, "__cilk_ind_var");
6900 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
6901
6902 /* Not needed in SSA form right now. */
6903 gcc_assert (!gimple_in_ssa_p (cfun));
6904 if (l2_dom_bb == NULL)
6905 l2_dom_bb = l1_bb;
6906
6907 tree n1 = low_val;
6908 tree n2 = high_val;
6909
6910 gimple stmt = gimple_build_assign (ind_var, n1);
6911
6912 /* Replace the GIMPLE_OMP_FOR statement. */
6913 gsi_replace (&gsi, stmt, true);
6914
6915 if (!broken_loop)
6916 {
6917 /* Code to control the increment goes in the CONT_BB. */
6918 gsi = gsi_last_bb (cont_bb);
6919 stmt = gsi_stmt (gsi);
6920 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
6921 stmt = gimple_build_assign_with_ops (PLUS_EXPR, ind_var, ind_var,
6922 build_one_cst (type));
6923
6924 /* Replace GIMPLE_OMP_CONTINUE. */
6925 gsi_replace (&gsi, stmt, true);
6926 }
6927
6928 /* Emit the condition in L1_BB. */
6929 gsi = gsi_after_labels (l1_bb);
6930 t = fold_build2 (MULT_EXPR, TREE_TYPE (fd->loop.step),
6931 fold_convert (TREE_TYPE (fd->loop.step), ind_var),
6932 fd->loop.step);
6933 if (POINTER_TYPE_P (TREE_TYPE (fd->loop.n1)))
6934 t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (fd->loop.n1),
6935 fd->loop.n1, fold_convert (sizetype, t));
6936 else
6937 t = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->loop.n1),
6938 fd->loop.n1, fold_convert (TREE_TYPE (fd->loop.n1), t));
6939 t = fold_convert (TREE_TYPE (fd->loop.v), t);
6940 expand_omp_build_assign (&gsi, fd->loop.v, t);
6941
6942 /* The condition is always '<' since the runtime will fill in the low
6943 and high values. */
6944 stmt = gimple_build_cond (LT_EXPR, ind_var, n2, NULL_TREE, NULL_TREE);
6945 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
6946
6947 /* Remove GIMPLE_OMP_RETURN. */
6948 gsi = gsi_last_bb (exit_bb);
6949 gsi_remove (&gsi, true);
6950
6951 /* Connect the new blocks. */
6952 remove_edge (FALLTHRU_EDGE (entry_bb));
6953
6954 edge e, ne;
6955 if (!broken_loop)
6956 {
6957 remove_edge (BRANCH_EDGE (entry_bb));
6958 make_edge (entry_bb, l1_bb, EDGE_FALLTHRU);
6959
6960 e = BRANCH_EDGE (l1_bb);
6961 ne = FALLTHRU_EDGE (l1_bb);
6962 e->flags = EDGE_TRUE_VALUE;
6963 }
6964 else
6965 {
6966 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
6967
6968 ne = single_succ_edge (l1_bb);
6969 e = make_edge (l1_bb, l0_bb, EDGE_TRUE_VALUE);
6970
6971 }
6972 ne->flags = EDGE_FALSE_VALUE;
6973 e->probability = REG_BR_PROB_BASE * 7 / 8;
6974 ne->probability = REG_BR_PROB_BASE / 8;
6975
6976 set_immediate_dominator (CDI_DOMINATORS, l1_bb, entry_bb);
6977 set_immediate_dominator (CDI_DOMINATORS, l2_bb, l2_dom_bb);
6978 set_immediate_dominator (CDI_DOMINATORS, l0_bb, l1_bb);
6979
6980 if (!broken_loop)
6981 {
6982 struct loop *loop = alloc_loop ();
6983 loop->header = l1_bb;
6984 loop->latch = cont_bb;
6985 add_loop (loop, l1_bb->loop_father);
6986 loop->safelen = INT_MAX;
6987 }
6988
6989 /* Pick the correct library function based on the precision of the
6990 induction variable type. */
6991 tree lib_fun = NULL_TREE;
6992 if (TYPE_PRECISION (type) == 32)
6993 lib_fun = cilk_for_32_fndecl;
6994 else if (TYPE_PRECISION (type) == 64)
6995 lib_fun = cilk_for_64_fndecl;
6996 else
6997 gcc_unreachable ();
6998
6999 gcc_assert (fd->sched_kind == OMP_CLAUSE_SCHEDULE_CILKFOR);
7000
7001 /* WS_ARGS contains the library function flavor to call:
7002 __libcilkrts_cilk_for_64 or __libcilkrts_cilk_for_32), and the
7003 user-defined grain value. If the user does not define one, then zero
7004 is passed in by the parser. */
7005 vec_alloc (region->ws_args, 2);
7006 region->ws_args->quick_push (lib_fun);
7007 region->ws_args->quick_push (fd->chunk_size);
7008}
acf0174b 7009
74bf76ed
JJ
7010/* A subroutine of expand_omp_for. Generate code for a simd non-worksharing
7011 loop. Given parameters:
7012
7013 for (V = N1; V cond N2; V += STEP) BODY;
7014
7015 where COND is "<" or ">", we generate pseudocode
7016
7017 V = N1;
7018 goto L1;
7019 L0:
7020 BODY;
7021 V += STEP;
7022 L1:
7023 if (V cond N2) goto L0; else goto L2;
7024 L2:
7025
7026 For collapsed loops, given parameters:
7027 collapse(3)
7028 for (V1 = N11; V1 cond1 N12; V1 += STEP1)
7029 for (V2 = N21; V2 cond2 N22; V2 += STEP2)
7030 for (V3 = N31; V3 cond3 N32; V3 += STEP3)
7031 BODY;
7032
7033 we generate pseudocode
7034
7035 if (cond3 is <)
7036 adj = STEP3 - 1;
7037 else
7038 adj = STEP3 + 1;
7039 count3 = (adj + N32 - N31) / STEP3;
7040 if (cond2 is <)
7041 adj = STEP2 - 1;
7042 else
7043 adj = STEP2 + 1;
7044 count2 = (adj + N22 - N21) / STEP2;
7045 if (cond1 is <)
7046 adj = STEP1 - 1;
7047 else
7048 adj = STEP1 + 1;
7049 count1 = (adj + N12 - N11) / STEP1;
7050 count = count1 * count2 * count3;
7051 V = 0;
7052 V1 = N11;
7053 V2 = N21;
7054 V3 = N31;
7055 goto L1;
7056 L0:
7057 BODY;
7058 V += 1;
7059 V3 += STEP3;
7060 V2 += (V3 cond3 N32) ? 0 : STEP2;
7061 V3 = (V3 cond3 N32) ? V3 : N31;
7062 V1 += (V2 cond2 N22) ? 0 : STEP1;
7063 V2 = (V2 cond2 N22) ? V2 : N21;
7064 L1:
7065 if (V < count) goto L0; else goto L2;
7066 L2:
7067
7068 */
7069
7070static void
7071expand_omp_simd (struct omp_region *region, struct omp_for_data *fd)
7072{
7073 tree type, t;
7074 basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, l2_bb, l2_dom_bb;
7075 gimple_stmt_iterator gsi;
7076 gimple stmt;
7077 bool broken_loop = region->cont == NULL;
7078 edge e, ne;
7079 tree *counts = NULL;
7080 int i;
7081 tree safelen = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
7082 OMP_CLAUSE_SAFELEN);
7083 tree simduid = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
7084 OMP_CLAUSE__SIMDUID_);
acf0174b 7085 tree n1, n2;
74bf76ed
JJ
7086
7087 type = TREE_TYPE (fd->loop.v);
7088 entry_bb = region->entry;
7089 cont_bb = region->cont;
7090 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
7091 gcc_assert (broken_loop
7092 || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
7093 l0_bb = FALLTHRU_EDGE (entry_bb)->dest;
7094 if (!broken_loop)
7095 {
7096 gcc_assert (BRANCH_EDGE (cont_bb)->dest == l0_bb);
7097 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
7098 l1_bb = split_block (cont_bb, last_stmt (cont_bb))->dest;
7099 l2_bb = BRANCH_EDGE (entry_bb)->dest;
7100 }
7101 else
7102 {
7103 BRANCH_EDGE (entry_bb)->flags &= ~EDGE_ABNORMAL;
7104 l1_bb = split_edge (BRANCH_EDGE (entry_bb));
7105 l2_bb = single_succ (l1_bb);
7106 }
7107 exit_bb = region->exit;
7108 l2_dom_bb = NULL;
7109
7110 gsi = gsi_last_bb (entry_bb);
7111
7112 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
7113 /* Not needed in SSA form right now. */
7114 gcc_assert (!gimple_in_ssa_p (cfun));
7115 if (fd->collapse > 1)
7116 {
7117 int first_zero_iter = -1;
7118 basic_block zero_iter_bb = l2_bb;
7119
7120 counts = XALLOCAVEC (tree, fd->collapse);
7121 expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
7122 zero_iter_bb, first_zero_iter,
7123 l2_dom_bb);
7124 }
7125 if (l2_dom_bb == NULL)
7126 l2_dom_bb = l1_bb;
7127
acf0174b 7128 n1 = fd->loop.n1;
74bf76ed 7129 n2 = fd->loop.n2;
acf0174b
JJ
7130 if (gimple_omp_for_combined_into_p (fd->for_stmt))
7131 {
7132 tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
7133 OMP_CLAUSE__LOOPTEMP_);
7134 gcc_assert (innerc);
7135 n1 = OMP_CLAUSE_DECL (innerc);
7136 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
7137 OMP_CLAUSE__LOOPTEMP_);
7138 gcc_assert (innerc);
7139 n2 = OMP_CLAUSE_DECL (innerc);
7140 expand_omp_build_assign (&gsi, fd->loop.v,
7141 fold_convert (type, n1));
7142 if (fd->collapse > 1)
7143 {
7144 gsi_prev (&gsi);
7145 expand_omp_for_init_vars (fd, &gsi, counts, NULL, n1);
7146 gsi_next (&gsi);
7147 }
7148 }
74bf76ed
JJ
7149 else
7150 {
7151 expand_omp_build_assign (&gsi, fd->loop.v,
7152 fold_convert (type, fd->loop.n1));
7153 if (fd->collapse > 1)
7154 for (i = 0; i < fd->collapse; i++)
7155 {
7156 tree itype = TREE_TYPE (fd->loops[i].v);
7157 if (POINTER_TYPE_P (itype))
7158 itype = signed_type_for (itype);
7159 t = fold_convert (TREE_TYPE (fd->loops[i].v), fd->loops[i].n1);
7160 expand_omp_build_assign (&gsi, fd->loops[i].v, t);
7161 }
7162 }
7163
7164 /* Remove the GIMPLE_OMP_FOR statement. */
7165 gsi_remove (&gsi, true);
7166
7167 if (!broken_loop)
7168 {
7169 /* Code to control the increment goes in the CONT_BB. */
7170 gsi = gsi_last_bb (cont_bb);
7171 stmt = gsi_stmt (gsi);
7172 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
7173
7174 if (POINTER_TYPE_P (type))
7175 t = fold_build_pointer_plus (fd->loop.v, fd->loop.step);
7176 else
7177 t = fold_build2 (PLUS_EXPR, type, fd->loop.v, fd->loop.step);
7178 expand_omp_build_assign (&gsi, fd->loop.v, t);
7179
7180 if (fd->collapse > 1)
7181 {
7182 i = fd->collapse - 1;
7183 if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i].v)))
7184 {
7185 t = fold_convert (sizetype, fd->loops[i].step);
7186 t = fold_build_pointer_plus (fd->loops[i].v, t);
7187 }
7188 else
7189 {
7190 t = fold_convert (TREE_TYPE (fd->loops[i].v),
7191 fd->loops[i].step);
7192 t = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->loops[i].v),
7193 fd->loops[i].v, t);
7194 }
7195 expand_omp_build_assign (&gsi, fd->loops[i].v, t);
7196
7197 for (i = fd->collapse - 1; i > 0; i--)
7198 {
7199 tree itype = TREE_TYPE (fd->loops[i].v);
7200 tree itype2 = TREE_TYPE (fd->loops[i - 1].v);
7201 if (POINTER_TYPE_P (itype2))
7202 itype2 = signed_type_for (itype2);
7203 t = build3 (COND_EXPR, itype2,
7204 build2 (fd->loops[i].cond_code, boolean_type_node,
7205 fd->loops[i].v,
7206 fold_convert (itype, fd->loops[i].n2)),
7207 build_int_cst (itype2, 0),
7208 fold_convert (itype2, fd->loops[i - 1].step));
7209 if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i - 1].v)))
7210 t = fold_build_pointer_plus (fd->loops[i - 1].v, t);
7211 else
7212 t = fold_build2 (PLUS_EXPR, itype2, fd->loops[i - 1].v, t);
7213 expand_omp_build_assign (&gsi, fd->loops[i - 1].v, t);
7214
7215 t = build3 (COND_EXPR, itype,
7216 build2 (fd->loops[i].cond_code, boolean_type_node,
7217 fd->loops[i].v,
7218 fold_convert (itype, fd->loops[i].n2)),
7219 fd->loops[i].v,
7220 fold_convert (itype, fd->loops[i].n1));
7221 expand_omp_build_assign (&gsi, fd->loops[i].v, t);
7222 }
7223 }
7224
7225 /* Remove GIMPLE_OMP_CONTINUE. */
7226 gsi_remove (&gsi, true);
7227 }
7228
7229 /* Emit the condition in L1_BB. */
7230 gsi = gsi_start_bb (l1_bb);
7231
7232 t = fold_convert (type, n2);
7233 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
7234 false, GSI_CONTINUE_LINKING);
7235 t = build2 (fd->loop.cond_code, boolean_type_node, fd->loop.v, t);
7236 stmt = gimple_build_cond_empty (t);
7237 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
7238 if (walk_tree (gimple_cond_lhs_ptr (stmt), expand_omp_regimplify_p,
7239 NULL, NULL)
7240 || walk_tree (gimple_cond_rhs_ptr (stmt), expand_omp_regimplify_p,
7241 NULL, NULL))
7242 {
7243 gsi = gsi_for_stmt (stmt);
7244 gimple_regimplify_operands (stmt, &gsi);
7245 }
7246
7247 /* Remove GIMPLE_OMP_RETURN. */
7248 gsi = gsi_last_bb (exit_bb);
7249 gsi_remove (&gsi, true);
7250
7251 /* Connect the new blocks. */
7252 remove_edge (FALLTHRU_EDGE (entry_bb));
7253
7254 if (!broken_loop)
7255 {
7256 remove_edge (BRANCH_EDGE (entry_bb));
7257 make_edge (entry_bb, l1_bb, EDGE_FALLTHRU);
7258
7259 e = BRANCH_EDGE (l1_bb);
7260 ne = FALLTHRU_EDGE (l1_bb);
7261 e->flags = EDGE_TRUE_VALUE;
7262 }
7263 else
7264 {
7265 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
7266
7267 ne = single_succ_edge (l1_bb);
7268 e = make_edge (l1_bb, l0_bb, EDGE_TRUE_VALUE);
7269
7270 }
7271 ne->flags = EDGE_FALSE_VALUE;
7272 e->probability = REG_BR_PROB_BASE * 7 / 8;
7273 ne->probability = REG_BR_PROB_BASE / 8;
7274
7275 set_immediate_dominator (CDI_DOMINATORS, l1_bb, entry_bb);
7276 set_immediate_dominator (CDI_DOMINATORS, l2_bb, l2_dom_bb);
7277 set_immediate_dominator (CDI_DOMINATORS, l0_bb, l1_bb);
7278
7279 if (!broken_loop)
7280 {
7281 struct loop *loop = alloc_loop ();
7282 loop->header = l1_bb;
01dde9b0 7283 loop->latch = cont_bb;
74bf76ed
JJ
7284 add_loop (loop, l1_bb->loop_father);
7285 if (safelen == NULL_TREE)
7286 loop->safelen = INT_MAX;
7287 else
7288 {
7289 safelen = OMP_CLAUSE_SAFELEN_EXPR (safelen);
b46ebd6c
JJ
7290 if (TREE_CODE (safelen) != INTEGER_CST)
7291 loop->safelen = 0;
7292 else if (!tree_fits_uhwi_p (safelen)
7293 || tree_to_uhwi (safelen) > INT_MAX)
74bf76ed
JJ
7294 loop->safelen = INT_MAX;
7295 else
ae7e9ddd 7296 loop->safelen = tree_to_uhwi (safelen);
74bf76ed
JJ
7297 if (loop->safelen == 1)
7298 loop->safelen = 0;
7299 }
7300 if (simduid)
7301 {
7302 loop->simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
7303 cfun->has_simduid_loops = true;
7304 }
ea0f3e87 7305 /* If not -fno-tree-loop-vectorize, hint that we want to vectorize
74bf76ed 7306 the loop. */
ea0f3e87
XDL
7307 if ((flag_tree_loop_vectorize
7308 || (!global_options_set.x_flag_tree_loop_vectorize
7309 && !global_options_set.x_flag_tree_vectorize))
ab2ffbeb 7310 && flag_tree_loop_optimize
74bf76ed
JJ
7311 && loop->safelen > 1)
7312 {
b15b5979
EB
7313 loop->force_vectorize = true;
7314 cfun->has_force_vectorize_loops = true;
74bf76ed
JJ
7315 }
7316 }
7317}
7318
953ff289 7319
50674e96 7320/* Expand the OpenMP loop defined by REGION. */
953ff289 7321
50674e96 7322static void
acf0174b 7323expand_omp_for (struct omp_region *region, gimple inner_stmt)
50674e96
DN
7324{
7325 struct omp_for_data fd;
a68ab351 7326 struct omp_for_data_loop *loops;
953ff289 7327
a68ab351
JJ
7328 loops
7329 = (struct omp_for_data_loop *)
726a989a 7330 alloca (gimple_omp_for_collapse (last_stmt (region->entry))
a68ab351 7331 * sizeof (struct omp_for_data_loop));
a68ab351 7332 extract_omp_for_data (last_stmt (region->entry), &fd, loops);
21a66e91 7333 region->sched_kind = fd.sched_kind;
953ff289 7334
135a171d
JJ
7335 gcc_assert (EDGE_COUNT (region->entry->succs) == 2);
7336 BRANCH_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
7337 FALLTHRU_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
7338 if (region->cont)
7339 {
7340 gcc_assert (EDGE_COUNT (region->cont->succs) == 2);
7341 BRANCH_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
7342 FALLTHRU_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
7343 }
6093bc06 7344 else
1aa95df7 7345 /* If there isn't a continue then this is a degerate case where
6093bc06
RB
7346 the introduction of abnormal edges during lowering will prevent
7347 original loops from being detected. Fix that up. */
7348 loops_state_set (LOOPS_NEED_FIXUP);
135a171d 7349
0aadce73 7350 if (gimple_omp_for_kind (fd.for_stmt) & GF_OMP_FOR_SIMD)
74bf76ed 7351 expand_omp_simd (region, &fd);
9a771876
JJ
7352 else if (gimple_omp_for_kind (fd.for_stmt) == GF_OMP_FOR_KIND_CILKFOR)
7353 expand_cilk_for (region, &fd);
74bf76ed 7354 else if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
acf0174b 7355 && !fd.have_ordered)
953ff289
DN
7356 {
7357 if (fd.chunk_size == NULL)
acf0174b 7358 expand_omp_for_static_nochunk (region, &fd, inner_stmt);
953ff289 7359 else
acf0174b 7360 expand_omp_for_static_chunk (region, &fd, inner_stmt);
953ff289
DN
7361 }
7362 else
7363 {
a68ab351
JJ
7364 int fn_index, start_ix, next_ix;
7365
74bf76ed
JJ
7366 gcc_assert (gimple_omp_for_kind (fd.for_stmt)
7367 == GF_OMP_FOR_KIND_FOR);
9abd5ed9
JJ
7368 if (fd.chunk_size == NULL
7369 && fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
7370 fd.chunk_size = integer_zero_node;
a68ab351
JJ
7371 gcc_assert (fd.sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
7372 fn_index = (fd.sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
726a989a 7373 ? 3 : fd.sched_kind;
a68ab351 7374 fn_index += fd.have_ordered * 4;
e79983f4
MM
7375 start_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_START) + fn_index;
7376 next_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_NEXT) + fn_index;
a68ab351
JJ
7377 if (fd.iter_type == long_long_unsigned_type_node)
7378 {
e79983f4
MM
7379 start_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_START
7380 - (int)BUILT_IN_GOMP_LOOP_STATIC_START);
7381 next_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT
7382 - (int)BUILT_IN_GOMP_LOOP_STATIC_NEXT);
a68ab351 7383 }
bbbbb16a 7384 expand_omp_for_generic (region, &fd, (enum built_in_function) start_ix,
acf0174b 7385 (enum built_in_function) next_ix, inner_stmt);
953ff289 7386 }
5f40b3cb 7387
a5efada7
RG
7388 if (gimple_in_ssa_p (cfun))
7389 update_ssa (TODO_update_ssa_only_virtuals);
953ff289
DN
7390}
7391
953ff289
DN
7392
7393/* Expand code for an OpenMP sections directive. In pseudo code, we generate
7394
953ff289
DN
7395 v = GOMP_sections_start (n);
7396 L0:
7397 switch (v)
7398 {
7399 case 0:
7400 goto L2;
7401 case 1:
7402 section 1;
7403 goto L1;
7404 case 2:
7405 ...
7406 case n:
7407 ...
953ff289
DN
7408 default:
7409 abort ();
7410 }
7411 L1:
7412 v = GOMP_sections_next ();
7413 goto L0;
7414 L2:
7415 reduction;
7416
50674e96 7417 If this is a combined parallel sections, replace the call to
917948d3 7418 GOMP_sections_start with call to GOMP_sections_next. */
953ff289
DN
7419
7420static void
50674e96 7421expand_omp_sections (struct omp_region *region)
953ff289 7422{
0f900dfa 7423 tree t, u, vin = NULL, vmain, vnext, l2;
726a989a 7424 unsigned len;
e5c95afe 7425 basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
726a989a
RB
7426 gimple_stmt_iterator si, switch_si;
7427 gimple sections_stmt, stmt, cont;
c34938a8
JJ
7428 edge_iterator ei;
7429 edge e;
777f7f9a 7430 struct omp_region *inner;
726a989a 7431 unsigned i, casei;
e5c95afe 7432 bool exit_reachable = region->cont != NULL;
953ff289 7433
65e7bfe3 7434 gcc_assert (region->exit != NULL);
777f7f9a 7435 entry_bb = region->entry;
e5c95afe 7436 l0_bb = single_succ (entry_bb);
777f7f9a 7437 l1_bb = region->cont;
e5c95afe 7438 l2_bb = region->exit;
65e7bfe3
JJ
7439 if (single_pred_p (l2_bb) && single_pred (l2_bb) == l0_bb)
7440 l2 = gimple_block_label (l2_bb);
7441 else
d3c673c7 7442 {
65e7bfe3
JJ
7443 /* This can happen if there are reductions. */
7444 len = EDGE_COUNT (l0_bb->succs);
7445 gcc_assert (len > 0);
7446 e = EDGE_SUCC (l0_bb, len - 1);
7447 si = gsi_last_bb (e->dest);
7448 l2 = NULL_TREE;
7449 if (gsi_end_p (si)
7450 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
7451 l2 = gimple_block_label (e->dest);
c34938a8 7452 else
65e7bfe3
JJ
7453 FOR_EACH_EDGE (e, ei, l0_bb->succs)
7454 {
7455 si = gsi_last_bb (e->dest);
7456 if (gsi_end_p (si)
7457 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
c34938a8 7458 {
65e7bfe3
JJ
7459 l2 = gimple_block_label (e->dest);
7460 break;
c34938a8 7461 }
65e7bfe3 7462 }
d3c673c7 7463 }
65e7bfe3
JJ
7464 if (exit_reachable)
7465 default_bb = create_empty_bb (l1_bb->prev_bb);
d3c673c7 7466 else
65e7bfe3 7467 default_bb = create_empty_bb (l0_bb);
50674e96
DN
7468
7469 /* We will build a switch() with enough cases for all the
726a989a 7470 GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
50674e96 7471 and a default case to abort if something goes wrong. */
e5c95afe 7472 len = EDGE_COUNT (l0_bb->succs);
726a989a 7473
9771b263 7474 /* Use vec::quick_push on label_vec throughout, since we know the size
726a989a 7475 in advance. */
ef062b13 7476 auto_vec<tree> label_vec (len);
953ff289 7477
777f7f9a 7478 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
726a989a
RB
7479 GIMPLE_OMP_SECTIONS statement. */
7480 si = gsi_last_bb (entry_bb);
7481 sections_stmt = gsi_stmt (si);
7482 gcc_assert (gimple_code (sections_stmt) == GIMPLE_OMP_SECTIONS);
7483 vin = gimple_omp_sections_control (sections_stmt);
50674e96 7484 if (!is_combined_parallel (region))
953ff289 7485 {
50674e96
DN
7486 /* If we are not inside a combined parallel+sections region,
7487 call GOMP_sections_start. */
4befd127 7488 t = build_int_cst (unsigned_type_node, len - 1);
e79983f4 7489 u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START);
726a989a 7490 stmt = gimple_build_call (u, 1, t);
953ff289 7491 }
917948d3
ZD
7492 else
7493 {
7494 /* Otherwise, call GOMP_sections_next. */
e79983f4 7495 u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
726a989a 7496 stmt = gimple_build_call (u, 0);
917948d3 7497 }
726a989a
RB
7498 gimple_call_set_lhs (stmt, vin);
7499 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
7500 gsi_remove (&si, true);
7501
7502 /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
7503 L0_BB. */
7504 switch_si = gsi_last_bb (l0_bb);
7505 gcc_assert (gimple_code (gsi_stmt (switch_si)) == GIMPLE_OMP_SECTIONS_SWITCH);
917948d3
ZD
7506 if (exit_reachable)
7507 {
7508 cont = last_stmt (l1_bb);
726a989a
RB
7509 gcc_assert (gimple_code (cont) == GIMPLE_OMP_CONTINUE);
7510 vmain = gimple_omp_continue_control_use (cont);
7511 vnext = gimple_omp_continue_control_def (cont);
917948d3
ZD
7512 }
7513 else
7514 {
7515 vmain = vin;
7516 vnext = NULL_TREE;
7517 }
953ff289 7518
65e7bfe3 7519 t = build_case_label (build_int_cst (unsigned_type_node, 0), NULL, l2);
9771b263 7520 label_vec.quick_push (t);
65e7bfe3 7521 i = 1;
d3c673c7 7522
726a989a 7523 /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR. */
e5c95afe
ZD
7524 for (inner = region->inner, casei = 1;
7525 inner;
7526 inner = inner->next, i++, casei++)
953ff289 7527 {
50674e96
DN
7528 basic_block s_entry_bb, s_exit_bb;
7529
c34938a8 7530 /* Skip optional reduction region. */
726a989a 7531 if (inner->type == GIMPLE_OMP_ATOMIC_LOAD)
c34938a8
JJ
7532 {
7533 --i;
7534 --casei;
7535 continue;
7536 }
7537
777f7f9a
RH
7538 s_entry_bb = inner->entry;
7539 s_exit_bb = inner->exit;
953ff289 7540
726a989a 7541 t = gimple_block_label (s_entry_bb);
e5c95afe 7542 u = build_int_cst (unsigned_type_node, casei);
3d528853 7543 u = build_case_label (u, NULL, t);
9771b263 7544 label_vec.quick_push (u);
777f7f9a 7545
726a989a
RB
7546 si = gsi_last_bb (s_entry_bb);
7547 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SECTION);
7548 gcc_assert (i < len || gimple_omp_section_last_p (gsi_stmt (si)));
7549 gsi_remove (&si, true);
777f7f9a 7550 single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
d3c673c7
JJ
7551
7552 if (s_exit_bb == NULL)
7553 continue;
7554
726a989a
RB
7555 si = gsi_last_bb (s_exit_bb);
7556 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
7557 gsi_remove (&si, true);
d3c673c7 7558
50674e96 7559 single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
953ff289
DN
7560 }
7561
50674e96 7562 /* Error handling code goes in DEFAULT_BB. */
726a989a 7563 t = gimple_block_label (default_bb);
3d528853 7564 u = build_case_label (NULL, NULL, t);
777f7f9a 7565 make_edge (l0_bb, default_bb, 0);
726338f4 7566 add_bb_to_loop (default_bb, current_loops->tree_root);
953ff289 7567
fd8d363e 7568 stmt = gimple_build_switch (vmain, u, label_vec);
726a989a
RB
7569 gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
7570 gsi_remove (&switch_si, true);
726a989a
RB
7571
7572 si = gsi_start_bb (default_bb);
e79983f4 7573 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
726a989a 7574 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
50674e96 7575
e5c95afe 7576 if (exit_reachable)
d3c673c7 7577 {
e79983f4
MM
7578 tree bfn_decl;
7579
e5c95afe 7580 /* Code to get the next section goes in L1_BB. */
726a989a
RB
7581 si = gsi_last_bb (l1_bb);
7582 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CONTINUE);
953ff289 7583
e79983f4
MM
7584 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
7585 stmt = gimple_build_call (bfn_decl, 0);
726a989a
RB
7586 gimple_call_set_lhs (stmt, vnext);
7587 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
7588 gsi_remove (&si, true);
50674e96 7589
e5c95afe 7590 single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
d3c673c7 7591 }
50674e96 7592
65e7bfe3
JJ
7593 /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB. */
7594 si = gsi_last_bb (l2_bb);
7595 if (gimple_omp_return_nowait_p (gsi_stmt (si)))
7596 t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT);
acf0174b
JJ
7597 else if (gimple_omp_return_lhs (gsi_stmt (si)))
7598 t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_CANCEL);
65e7bfe3
JJ
7599 else
7600 t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END);
7601 stmt = gimple_build_call (t, 0);
acf0174b
JJ
7602 if (gimple_omp_return_lhs (gsi_stmt (si)))
7603 gimple_call_set_lhs (stmt, gimple_omp_return_lhs (gsi_stmt (si)));
65e7bfe3
JJ
7604 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
7605 gsi_remove (&si, true);
7606
917948d3 7607 set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb);
50674e96 7608}
953ff289 7609
953ff289 7610
777f7f9a
RH
7611/* Expand code for an OpenMP single directive. We've already expanded
7612 much of the code, here we simply place the GOMP_barrier call. */
7613
7614static void
7615expand_omp_single (struct omp_region *region)
7616{
7617 basic_block entry_bb, exit_bb;
726a989a 7618 gimple_stmt_iterator si;
777f7f9a
RH
7619
7620 entry_bb = region->entry;
7621 exit_bb = region->exit;
7622
726a989a 7623 si = gsi_last_bb (entry_bb);
726a989a
RB
7624 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE);
7625 gsi_remove (&si, true);
777f7f9a
RH
7626 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
7627
726a989a 7628 si = gsi_last_bb (exit_bb);
acf0174b
JJ
7629 if (!gimple_omp_return_nowait_p (gsi_stmt (si)))
7630 {
7631 tree t = gimple_omp_return_lhs (gsi_stmt (si));
7632 gsi_insert_after (&si, build_omp_barrier (t), GSI_SAME_STMT);
7633 }
726a989a 7634 gsi_remove (&si, true);
777f7f9a
RH
7635 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
7636}
7637
7638
7639/* Generic expansion for OpenMP synchronization directives: master,
7640 ordered and critical. All we need to do here is remove the entry
7641 and exit markers for REGION. */
50674e96
DN
7642
7643static void
7644expand_omp_synch (struct omp_region *region)
7645{
7646 basic_block entry_bb, exit_bb;
726a989a 7647 gimple_stmt_iterator si;
50674e96 7648
777f7f9a
RH
7649 entry_bb = region->entry;
7650 exit_bb = region->exit;
50674e96 7651
726a989a
RB
7652 si = gsi_last_bb (entry_bb);
7653 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE
7654 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASTER
acf0174b 7655 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_TASKGROUP
726a989a 7656 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ORDERED
acf0174b
JJ
7657 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CRITICAL
7658 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_TEAMS);
726a989a 7659 gsi_remove (&si, true);
50674e96
DN
7660 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
7661
d3c673c7
JJ
7662 if (exit_bb)
7663 {
726a989a
RB
7664 si = gsi_last_bb (exit_bb);
7665 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
7666 gsi_remove (&si, true);
d3c673c7
JJ
7667 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
7668 }
50674e96 7669}
953ff289 7670
20906c66
JJ
7671/* A subroutine of expand_omp_atomic. Attempt to implement the atomic
7672 operation as a normal volatile load. */
7673
7674static bool
05409788
RH
7675expand_omp_atomic_load (basic_block load_bb, tree addr,
7676 tree loaded_val, int index)
20906c66 7677{
05409788
RH
7678 enum built_in_function tmpbase;
7679 gimple_stmt_iterator gsi;
7680 basic_block store_bb;
7681 location_t loc;
7682 gimple stmt;
7683 tree decl, call, type, itype;
7684
7685 gsi = gsi_last_bb (load_bb);
7686 stmt = gsi_stmt (gsi);
7687 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
7688 loc = gimple_location (stmt);
7689
7690 /* ??? If the target does not implement atomic_load_optab[mode], and mode
7691 is smaller than word size, then expand_atomic_load assumes that the load
7692 is atomic. We could avoid the builtin entirely in this case. */
7693
7694 tmpbase = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
7695 decl = builtin_decl_explicit (tmpbase);
7696 if (decl == NULL_TREE)
7697 return false;
7698
7699 type = TREE_TYPE (loaded_val);
7700 itype = TREE_TYPE (TREE_TYPE (decl));
7701
7702 call = build_call_expr_loc (loc, decl, 2, addr,
acf0174b
JJ
7703 build_int_cst (NULL,
7704 gimple_omp_atomic_seq_cst_p (stmt)
7705 ? MEMMODEL_SEQ_CST
7706 : MEMMODEL_RELAXED));
05409788
RH
7707 if (!useless_type_conversion_p (type, itype))
7708 call = fold_build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
7709 call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
7710
7711 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
7712 gsi_remove (&gsi, true);
7713
7714 store_bb = single_succ (load_bb);
7715 gsi = gsi_last_bb (store_bb);
7716 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
7717 gsi_remove (&gsi, true);
7718
7719 if (gimple_in_ssa_p (cfun))
7720 update_ssa (TODO_update_ssa_no_phi);
7721
7722 return true;
20906c66
JJ
7723}
7724
7725/* A subroutine of expand_omp_atomic. Attempt to implement the atomic
7726 operation as a normal volatile store. */
7727
7728static bool
05409788
RH
7729expand_omp_atomic_store (basic_block load_bb, tree addr,
7730 tree loaded_val, tree stored_val, int index)
20906c66 7731{
05409788
RH
7732 enum built_in_function tmpbase;
7733 gimple_stmt_iterator gsi;
7734 basic_block store_bb = single_succ (load_bb);
7735 location_t loc;
7736 gimple stmt;
7737 tree decl, call, type, itype;
ef4bddc2 7738 machine_mode imode;
05409788
RH
7739 bool exchange;
7740
7741 gsi = gsi_last_bb (load_bb);
7742 stmt = gsi_stmt (gsi);
7743 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
7744
7745 /* If the load value is needed, then this isn't a store but an exchange. */
7746 exchange = gimple_omp_atomic_need_value_p (stmt);
7747
7748 gsi = gsi_last_bb (store_bb);
7749 stmt = gsi_stmt (gsi);
7750 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE);
7751 loc = gimple_location (stmt);
7752
7753 /* ??? If the target does not implement atomic_store_optab[mode], and mode
7754 is smaller than word size, then expand_atomic_store assumes that the store
7755 is atomic. We could avoid the builtin entirely in this case. */
7756
7757 tmpbase = (exchange ? BUILT_IN_ATOMIC_EXCHANGE_N : BUILT_IN_ATOMIC_STORE_N);
7758 tmpbase = (enum built_in_function) ((int) tmpbase + index + 1);
7759 decl = builtin_decl_explicit (tmpbase);
7760 if (decl == NULL_TREE)
7761 return false;
7762
7763 type = TREE_TYPE (stored_val);
7764
7765 /* Dig out the type of the function's second argument. */
7766 itype = TREE_TYPE (decl);
7767 itype = TYPE_ARG_TYPES (itype);
7768 itype = TREE_CHAIN (itype);
7769 itype = TREE_VALUE (itype);
7770 imode = TYPE_MODE (itype);
7771
7772 if (exchange && !can_atomic_exchange_p (imode, true))
7773 return false;
7774
7775 if (!useless_type_conversion_p (itype, type))
7776 stored_val = fold_build1_loc (loc, VIEW_CONVERT_EXPR, itype, stored_val);
7777 call = build_call_expr_loc (loc, decl, 3, addr, stored_val,
acf0174b
JJ
7778 build_int_cst (NULL,
7779 gimple_omp_atomic_seq_cst_p (stmt)
7780 ? MEMMODEL_SEQ_CST
7781 : MEMMODEL_RELAXED));
05409788
RH
7782 if (exchange)
7783 {
7784 if (!useless_type_conversion_p (type, itype))
7785 call = build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
7786 call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
7787 }
7788
7789 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
7790 gsi_remove (&gsi, true);
7791
7792 /* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above. */
7793 gsi = gsi_last_bb (load_bb);
7794 gsi_remove (&gsi, true);
7795
7796 if (gimple_in_ssa_p (cfun))
7797 update_ssa (TODO_update_ssa_no_phi);
7798
7799 return true;
20906c66
JJ
7800}
7801
a509ebb5 7802/* A subroutine of expand_omp_atomic. Attempt to implement the atomic
86951993 7803 operation as a __atomic_fetch_op builtin. INDEX is log2 of the
a509ebb5
RL
7804 size of the data type, and thus usable to find the index of the builtin
7805 decl. Returns false if the expression is not of the proper form. */
7806
7807static bool
7808expand_omp_atomic_fetch_op (basic_block load_bb,
7809 tree addr, tree loaded_val,
7810 tree stored_val, int index)
7811{
e79983f4 7812 enum built_in_function oldbase, newbase, tmpbase;
a509ebb5 7813 tree decl, itype, call;
20906c66 7814 tree lhs, rhs;
a509ebb5 7815 basic_block store_bb = single_succ (load_bb);
726a989a
RB
7816 gimple_stmt_iterator gsi;
7817 gimple stmt;
db3927fb 7818 location_t loc;
86951993 7819 enum tree_code code;
20906c66 7820 bool need_old, need_new;
ef4bddc2 7821 machine_mode imode;
acf0174b 7822 bool seq_cst;
a509ebb5
RL
7823
7824 /* We expect to find the following sequences:
b8698a0f 7825
a509ebb5 7826 load_bb:
726a989a 7827 GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
a509ebb5
RL
7828
7829 store_bb:
7830 val = tmp OP something; (or: something OP tmp)
b8698a0f 7831 GIMPLE_OMP_STORE (val)
a509ebb5 7832
b8698a0f 7833 ???FIXME: Allow a more flexible sequence.
a509ebb5 7834 Perhaps use data flow to pick the statements.
b8698a0f 7835
a509ebb5
RL
7836 */
7837
726a989a
RB
7838 gsi = gsi_after_labels (store_bb);
7839 stmt = gsi_stmt (gsi);
db3927fb 7840 loc = gimple_location (stmt);
726a989a 7841 if (!is_gimple_assign (stmt))
a509ebb5 7842 return false;
726a989a
RB
7843 gsi_next (&gsi);
7844 if (gimple_code (gsi_stmt (gsi)) != GIMPLE_OMP_ATOMIC_STORE)
a509ebb5 7845 return false;
20906c66
JJ
7846 need_new = gimple_omp_atomic_need_value_p (gsi_stmt (gsi));
7847 need_old = gimple_omp_atomic_need_value_p (last_stmt (load_bb));
acf0174b 7848 seq_cst = gimple_omp_atomic_seq_cst_p (last_stmt (load_bb));
20906c66 7849 gcc_checking_assert (!need_old || !need_new);
a509ebb5 7850
726a989a 7851 if (!operand_equal_p (gimple_assign_lhs (stmt), stored_val, 0))
a509ebb5
RL
7852 return false;
7853
a509ebb5 7854 /* Check for one of the supported fetch-op operations. */
86951993
AM
7855 code = gimple_assign_rhs_code (stmt);
7856 switch (code)
a509ebb5
RL
7857 {
7858 case PLUS_EXPR:
7859 case POINTER_PLUS_EXPR:
86951993
AM
7860 oldbase = BUILT_IN_ATOMIC_FETCH_ADD_N;
7861 newbase = BUILT_IN_ATOMIC_ADD_FETCH_N;
a509ebb5
RL
7862 break;
7863 case MINUS_EXPR:
86951993
AM
7864 oldbase = BUILT_IN_ATOMIC_FETCH_SUB_N;
7865 newbase = BUILT_IN_ATOMIC_SUB_FETCH_N;
a509ebb5
RL
7866 break;
7867 case BIT_AND_EXPR:
86951993
AM
7868 oldbase = BUILT_IN_ATOMIC_FETCH_AND_N;
7869 newbase = BUILT_IN_ATOMIC_AND_FETCH_N;
a509ebb5
RL
7870 break;
7871 case BIT_IOR_EXPR:
86951993
AM
7872 oldbase = BUILT_IN_ATOMIC_FETCH_OR_N;
7873 newbase = BUILT_IN_ATOMIC_OR_FETCH_N;
a509ebb5
RL
7874 break;
7875 case BIT_XOR_EXPR:
86951993
AM
7876 oldbase = BUILT_IN_ATOMIC_FETCH_XOR_N;
7877 newbase = BUILT_IN_ATOMIC_XOR_FETCH_N;
a509ebb5
RL
7878 break;
7879 default:
7880 return false;
7881 }
86951993 7882
a509ebb5 7883 /* Make sure the expression is of the proper form. */
726a989a
RB
7884 if (operand_equal_p (gimple_assign_rhs1 (stmt), loaded_val, 0))
7885 rhs = gimple_assign_rhs2 (stmt);
7886 else if (commutative_tree_code (gimple_assign_rhs_code (stmt))
7887 && operand_equal_p (gimple_assign_rhs2 (stmt), loaded_val, 0))
7888 rhs = gimple_assign_rhs1 (stmt);
a509ebb5
RL
7889 else
7890 return false;
7891
e79983f4
MM
7892 tmpbase = ((enum built_in_function)
7893 ((need_new ? newbase : oldbase) + index + 1));
7894 decl = builtin_decl_explicit (tmpbase);
20790697
JJ
7895 if (decl == NULL_TREE)
7896 return false;
a509ebb5 7897 itype = TREE_TYPE (TREE_TYPE (decl));
86951993 7898 imode = TYPE_MODE (itype);
a509ebb5 7899
86951993
AM
7900 /* We could test all of the various optabs involved, but the fact of the
7901 matter is that (with the exception of i486 vs i586 and xadd) all targets
7902 that support any atomic operaton optab also implements compare-and-swap.
7903 Let optabs.c take care of expanding any compare-and-swap loop. */
cedb4a1a 7904 if (!can_compare_and_swap_p (imode, true))
a509ebb5
RL
7905 return false;
7906
726a989a
RB
7907 gsi = gsi_last_bb (load_bb);
7908 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_LOAD);
86951993
AM
7909
7910 /* OpenMP does not imply any barrier-like semantics on its atomic ops.
7911 It only requires that the operation happen atomically. Thus we can
7912 use the RELAXED memory model. */
7913 call = build_call_expr_loc (loc, decl, 3, addr,
7914 fold_convert_loc (loc, itype, rhs),
acf0174b
JJ
7915 build_int_cst (NULL,
7916 seq_cst ? MEMMODEL_SEQ_CST
7917 : MEMMODEL_RELAXED));
86951993 7918
20906c66
JJ
7919 if (need_old || need_new)
7920 {
7921 lhs = need_old ? loaded_val : stored_val;
7922 call = fold_convert_loc (loc, TREE_TYPE (lhs), call);
7923 call = build2_loc (loc, MODIFY_EXPR, void_type_node, lhs, call);
7924 }
7925 else
7926 call = fold_convert_loc (loc, void_type_node, call);
726a989a
RB
7927 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
7928 gsi_remove (&gsi, true);
a509ebb5 7929
726a989a
RB
7930 gsi = gsi_last_bb (store_bb);
7931 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
7932 gsi_remove (&gsi, true);
7933 gsi = gsi_last_bb (store_bb);
7934 gsi_remove (&gsi, true);
a509ebb5
RL
7935
7936 if (gimple_in_ssa_p (cfun))
7937 update_ssa (TODO_update_ssa_no_phi);
7938
7939 return true;
7940}
7941
7942/* A subroutine of expand_omp_atomic. Implement the atomic operation as:
7943
7944 oldval = *addr;
7945 repeat:
7946 newval = rhs; // with oldval replacing *addr in rhs
7947 oldval = __sync_val_compare_and_swap (addr, oldval, newval);
7948 if (oldval != newval)
7949 goto repeat;
7950
7951 INDEX is log2 of the size of the data type, and thus usable to find the
7952 index of the builtin decl. */
7953
7954static bool
7955expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
7956 tree addr, tree loaded_val, tree stored_val,
7957 int index)
7958{
c18c98c0 7959 tree loadedi, storedi, initial, new_storedi, old_vali;
a509ebb5 7960 tree type, itype, cmpxchg, iaddr;
726a989a 7961 gimple_stmt_iterator si;
a509ebb5 7962 basic_block loop_header = single_succ (load_bb);
726a989a 7963 gimple phi, stmt;
a509ebb5 7964 edge e;
e79983f4 7965 enum built_in_function fncode;
a509ebb5 7966
86951993
AM
7967 /* ??? We need a non-pointer interface to __atomic_compare_exchange in
7968 order to use the RELAXED memory model effectively. */
e79983f4
MM
7969 fncode = (enum built_in_function)((int)BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
7970 + index + 1);
7971 cmpxchg = builtin_decl_explicit (fncode);
20790697
JJ
7972 if (cmpxchg == NULL_TREE)
7973 return false;
a509ebb5
RL
7974 type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
7975 itype = TREE_TYPE (TREE_TYPE (cmpxchg));
7976
cedb4a1a 7977 if (!can_compare_and_swap_p (TYPE_MODE (itype), true))
a509ebb5
RL
7978 return false;
7979
726a989a
RB
7980 /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */
7981 si = gsi_last_bb (load_bb);
7982 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
7983
c18c98c0
JJ
7984 /* For floating-point values, we'll need to view-convert them to integers
7985 so that we can perform the atomic compare and swap. Simplify the
7986 following code by always setting up the "i"ntegral variables. */
7987 if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
7988 {
726a989a
RB
7989 tree iaddr_val;
7990
7cc434a3
RG
7991 iaddr = create_tmp_reg (build_pointer_type_for_mode (itype, ptr_mode,
7992 true), NULL);
726a989a
RB
7993 iaddr_val
7994 = force_gimple_operand_gsi (&si,
7995 fold_convert (TREE_TYPE (iaddr), addr),
7996 false, NULL_TREE, true, GSI_SAME_STMT);
7997 stmt = gimple_build_assign (iaddr, iaddr_val);
7998 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
c18c98c0
JJ
7999 loadedi = create_tmp_var (itype, NULL);
8000 if (gimple_in_ssa_p (cfun))
46eb666a 8001 loadedi = make_ssa_name (loadedi, NULL);
c18c98c0
JJ
8002 }
8003 else
8004 {
8005 iaddr = addr;
8006 loadedi = loaded_val;
8007 }
726a989a 8008
8175be9a
JJ
8009 fncode = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
8010 tree loaddecl = builtin_decl_explicit (fncode);
8011 if (loaddecl)
8012 initial
8013 = fold_convert (TREE_TYPE (TREE_TYPE (iaddr)),
8014 build_call_expr (loaddecl, 2, iaddr,
8015 build_int_cst (NULL_TREE,
8016 MEMMODEL_RELAXED)));
8017 else
8018 initial = build2 (MEM_REF, TREE_TYPE (TREE_TYPE (iaddr)), iaddr,
8019 build_int_cst (TREE_TYPE (iaddr), 0));
8020
70f34814 8021 initial
8175be9a
JJ
8022 = force_gimple_operand_gsi (&si, initial, true, NULL_TREE, true,
8023 GSI_SAME_STMT);
c18c98c0
JJ
8024
8025 /* Move the value to the LOADEDI temporary. */
a509ebb5
RL
8026 if (gimple_in_ssa_p (cfun))
8027 {
726a989a 8028 gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header)));
c18c98c0 8029 phi = create_phi_node (loadedi, loop_header);
a509ebb5
RL
8030 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (load_bb)),
8031 initial);
8032 }
8033 else
726a989a
RB
8034 gsi_insert_before (&si,
8035 gimple_build_assign (loadedi, initial),
8036 GSI_SAME_STMT);
c18c98c0
JJ
8037 if (loadedi != loaded_val)
8038 {
726a989a
RB
8039 gimple_stmt_iterator gsi2;
8040 tree x;
c18c98c0
JJ
8041
8042 x = build1 (VIEW_CONVERT_EXPR, type, loadedi);
726a989a 8043 gsi2 = gsi_start_bb (loop_header);
c18c98c0
JJ
8044 if (gimple_in_ssa_p (cfun))
8045 {
726a989a
RB
8046 gimple stmt;
8047 x = force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
8048 true, GSI_SAME_STMT);
8049 stmt = gimple_build_assign (loaded_val, x);
8050 gsi_insert_before (&gsi2, stmt, GSI_SAME_STMT);
c18c98c0
JJ
8051 }
8052 else
8053 {
726a989a
RB
8054 x = build2 (MODIFY_EXPR, TREE_TYPE (loaded_val), loaded_val, x);
8055 force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
8056 true, GSI_SAME_STMT);
c18c98c0
JJ
8057 }
8058 }
726a989a 8059 gsi_remove (&si, true);
a509ebb5 8060
726a989a
RB
8061 si = gsi_last_bb (store_bb);
8062 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
a509ebb5 8063
c18c98c0
JJ
8064 if (iaddr == addr)
8065 storedi = stored_val;
a509ebb5 8066 else
c18c98c0 8067 storedi =
726a989a 8068 force_gimple_operand_gsi (&si,
c18c98c0
JJ
8069 build1 (VIEW_CONVERT_EXPR, itype,
8070 stored_val), true, NULL_TREE, true,
726a989a 8071 GSI_SAME_STMT);
a509ebb5
RL
8072
8073 /* Build the compare&swap statement. */
8074 new_storedi = build_call_expr (cmpxchg, 3, iaddr, loadedi, storedi);
726a989a 8075 new_storedi = force_gimple_operand_gsi (&si,
587aa063
RG
8076 fold_convert (TREE_TYPE (loadedi),
8077 new_storedi),
a509ebb5 8078 true, NULL_TREE,
726a989a 8079 true, GSI_SAME_STMT);
a509ebb5
RL
8080
8081 if (gimple_in_ssa_p (cfun))
8082 old_vali = loadedi;
8083 else
8084 {
587aa063 8085 old_vali = create_tmp_var (TREE_TYPE (loadedi), NULL);
726a989a
RB
8086 stmt = gimple_build_assign (old_vali, loadedi);
8087 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
a509ebb5 8088
726a989a
RB
8089 stmt = gimple_build_assign (loadedi, new_storedi);
8090 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
a509ebb5
RL
8091 }
8092
8093 /* Note that we always perform the comparison as an integer, even for
b8698a0f 8094 floating point. This allows the atomic operation to properly
a509ebb5 8095 succeed even with NaNs and -0.0. */
726a989a
RB
8096 stmt = gimple_build_cond_empty
8097 (build2 (NE_EXPR, boolean_type_node,
8098 new_storedi, old_vali));
8099 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
a509ebb5
RL
8100
8101 /* Update cfg. */
8102 e = single_succ_edge (store_bb);
8103 e->flags &= ~EDGE_FALLTHRU;
8104 e->flags |= EDGE_FALSE_VALUE;
8105
8106 e = make_edge (store_bb, loop_header, EDGE_TRUE_VALUE);
8107
c18c98c0 8108 /* Copy the new value to loadedi (we already did that before the condition
a509ebb5
RL
8109 if we are not in SSA). */
8110 if (gimple_in_ssa_p (cfun))
8111 {
726a989a 8112 phi = gimple_seq_first_stmt (phi_nodes (loop_header));
c18c98c0 8113 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), new_storedi);
a509ebb5
RL
8114 }
8115
726a989a
RB
8116 /* Remove GIMPLE_OMP_ATOMIC_STORE. */
8117 gsi_remove (&si, true);
a509ebb5 8118
6093bc06
RB
8119 struct loop *loop = alloc_loop ();
8120 loop->header = loop_header;
a1756c0a 8121 loop->latch = store_bb;
6093bc06
RB
8122 add_loop (loop, loop_header->loop_father);
8123
a509ebb5
RL
8124 if (gimple_in_ssa_p (cfun))
8125 update_ssa (TODO_update_ssa_no_phi);
8126
8127 return true;
8128}
8129
8130/* A subroutine of expand_omp_atomic. Implement the atomic operation as:
8131
8132 GOMP_atomic_start ();
8133 *addr = rhs;
8134 GOMP_atomic_end ();
8135
8136 The result is not globally atomic, but works so long as all parallel
8137 references are within #pragma omp atomic directives. According to
8138 responses received from omp@openmp.org, appears to be within spec.
8139 Which makes sense, since that's how several other compilers handle
b8698a0f 8140 this situation as well.
726a989a
RB
8141 LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
8142 expanding. STORED_VAL is the operand of the matching
8143 GIMPLE_OMP_ATOMIC_STORE.
a509ebb5 8144
b8698a0f
L
8145 We replace
8146 GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
a509ebb5
RL
8147 loaded_val = *addr;
8148
8149 and replace
05409788 8150 GIMPLE_OMP_ATOMIC_STORE (stored_val) with
b8698a0f 8151 *addr = stored_val;
a509ebb5
RL
8152*/
8153
8154static bool
8155expand_omp_atomic_mutex (basic_block load_bb, basic_block store_bb,
8156 tree addr, tree loaded_val, tree stored_val)
8157{
726a989a
RB
8158 gimple_stmt_iterator si;
8159 gimple stmt;
a509ebb5
RL
8160 tree t;
8161
726a989a
RB
8162 si = gsi_last_bb (load_bb);
8163 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
a509ebb5 8164
e79983f4 8165 t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
3bb06db4 8166 t = build_call_expr (t, 0);
726a989a 8167 force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
a509ebb5 8168
70f34814 8169 stmt = gimple_build_assign (loaded_val, build_simple_mem_ref (addr));
726a989a
RB
8170 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
8171 gsi_remove (&si, true);
a509ebb5 8172
726a989a
RB
8173 si = gsi_last_bb (store_bb);
8174 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
a509ebb5 8175
70f34814
RG
8176 stmt = gimple_build_assign (build_simple_mem_ref (unshare_expr (addr)),
8177 stored_val);
726a989a 8178 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
a509ebb5 8179
e79983f4 8180 t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
3bb06db4 8181 t = build_call_expr (t, 0);
726a989a
RB
8182 force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
8183 gsi_remove (&si, true);
a509ebb5
RL
8184
8185 if (gimple_in_ssa_p (cfun))
8186 update_ssa (TODO_update_ssa_no_phi);
8187 return true;
8188}
8189
b8698a0f
L
8190/* Expand an GIMPLE_OMP_ATOMIC statement. We try to expand
8191 using expand_omp_atomic_fetch_op. If it failed, we try to
a509ebb5
RL
8192 call expand_omp_atomic_pipeline, and if it fails too, the
8193 ultimate fallback is wrapping the operation in a mutex
b8698a0f
L
8194 (expand_omp_atomic_mutex). REGION is the atomic region built
8195 by build_omp_regions_1(). */
a509ebb5
RL
8196
8197static void
8198expand_omp_atomic (struct omp_region *region)
8199{
8200 basic_block load_bb = region->entry, store_bb = region->exit;
726a989a
RB
8201 gimple load = last_stmt (load_bb), store = last_stmt (store_bb);
8202 tree loaded_val = gimple_omp_atomic_load_lhs (load);
8203 tree addr = gimple_omp_atomic_load_rhs (load);
8204 tree stored_val = gimple_omp_atomic_store_val (store);
a509ebb5
RL
8205 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
8206 HOST_WIDE_INT index;
8207
8208 /* Make sure the type is one of the supported sizes. */
ae7e9ddd 8209 index = tree_to_uhwi (TYPE_SIZE_UNIT (type));
a509ebb5
RL
8210 index = exact_log2 (index);
8211 if (index >= 0 && index <= 4)
8212 {
8213 unsigned int align = TYPE_ALIGN_UNIT (type);
8214
8215 /* __sync builtins require strict data alignment. */
4999c62c 8216 if (exact_log2 (align) >= index)
a509ebb5 8217 {
05409788 8218 /* Atomic load. */
20906c66
JJ
8219 if (loaded_val == stored_val
8220 && (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
8221 || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
8222 && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
05409788 8223 && expand_omp_atomic_load (load_bb, addr, loaded_val, index))
20906c66
JJ
8224 return;
8225
05409788 8226 /* Atomic store. */
20906c66
JJ
8227 if ((GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
8228 || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
8229 && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
8230 && store_bb == single_succ (load_bb)
8231 && first_stmt (store_bb) == store
05409788
RH
8232 && expand_omp_atomic_store (load_bb, addr, loaded_val,
8233 stored_val, index))
20906c66
JJ
8234 return;
8235
a509ebb5
RL
8236 /* When possible, use specialized atomic update functions. */
8237 if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
05409788
RH
8238 && store_bb == single_succ (load_bb)
8239 && expand_omp_atomic_fetch_op (load_bb, addr,
8240 loaded_val, stored_val, index))
8241 return;
a509ebb5
RL
8242
8243 /* If we don't have specialized __sync builtins, try and implement
8244 as a compare and swap loop. */
8245 if (expand_omp_atomic_pipeline (load_bb, store_bb, addr,
8246 loaded_val, stored_val, index))
8247 return;
8248 }
8249 }
8250
8251 /* The ultimate fallback is wrapping the operation in a mutex. */
8252 expand_omp_atomic_mutex (load_bb, store_bb, addr, loaded_val, stored_val);
8253}
8254
953ff289 8255
acf0174b
JJ
8256/* Expand the OpenMP target{, data, update} directive starting at REGION. */
8257
8258static void
8259expand_omp_target (struct omp_region *region)
8260{
8261 basic_block entry_bb, exit_bb, new_bb;
8262 struct function *child_cfun = NULL;
8263 tree child_fn = NULL_TREE, block, t;
8264 gimple_stmt_iterator gsi;
8265 gimple entry_stmt, stmt;
8266 edge e;
8267
8268 entry_stmt = last_stmt (region->entry);
8269 new_bb = region->entry;
8270 int kind = gimple_omp_target_kind (entry_stmt);
8271 if (kind == GF_OMP_TARGET_KIND_REGION)
8272 {
8273 child_fn = gimple_omp_target_child_fn (entry_stmt);
8274 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
8275 }
8276
8277 entry_bb = region->entry;
8278 exit_bb = region->exit;
8279
8280 if (kind == GF_OMP_TARGET_KIND_REGION)
8281 {
8282 unsigned srcidx, dstidx, num;
8283
8284 /* If the target region needs data sent from the parent
8285 function, then the very first statement (except possible
8286 tree profile counter updates) of the parallel body
8287 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
8288 &.OMP_DATA_O is passed as an argument to the child function,
8289 we need to replace it with the argument as seen by the child
8290 function.
8291
8292 In most cases, this will end up being the identity assignment
8293 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
8294 a function call that has been inlined, the original PARM_DECL
8295 .OMP_DATA_I may have been converted into a different local
8296 variable. In which case, we need to keep the assignment. */
8297 if (gimple_omp_target_data_arg (entry_stmt))
8298 {
8299 basic_block entry_succ_bb = single_succ (entry_bb);
8300 gimple_stmt_iterator gsi;
8301 tree arg;
8302 gimple tgtcopy_stmt = NULL;
8303 tree sender
8304 = TREE_VEC_ELT (gimple_omp_target_data_arg (entry_stmt), 0);
8305
8306 for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
8307 {
8308 gcc_assert (!gsi_end_p (gsi));
8309 stmt = gsi_stmt (gsi);
8310 if (gimple_code (stmt) != GIMPLE_ASSIGN)
8311 continue;
8312
8313 if (gimple_num_ops (stmt) == 2)
8314 {
8315 tree arg = gimple_assign_rhs1 (stmt);
8316
8317 /* We're ignoring the subcode because we're
8318 effectively doing a STRIP_NOPS. */
8319
8320 if (TREE_CODE (arg) == ADDR_EXPR
8321 && TREE_OPERAND (arg, 0) == sender)
8322 {
8323 tgtcopy_stmt = stmt;
8324 break;
8325 }
8326 }
8327 }
8328
8329 gcc_assert (tgtcopy_stmt != NULL);
8330 arg = DECL_ARGUMENTS (child_fn);
8331
8332 gcc_assert (gimple_assign_lhs (tgtcopy_stmt) == arg);
8333 gsi_remove (&gsi, true);
8334 }
8335
8336 /* Declare local variables needed in CHILD_CFUN. */
8337 block = DECL_INITIAL (child_fn);
8338 BLOCK_VARS (block) = vec2chain (child_cfun->local_decls);
8339 /* The gimplifier could record temporaries in target block
8340 rather than in containing function's local_decls chain,
8341 which would mean cgraph missed finalizing them. Do it now. */
8342 for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
8343 if (TREE_CODE (t) == VAR_DECL
8344 && TREE_STATIC (t)
8345 && !DECL_EXTERNAL (t))
9041d2e6 8346 varpool_node::finalize_decl (t);
acf0174b
JJ
8347 DECL_SAVED_TREE (child_fn) = NULL;
8348 /* We'll create a CFG for child_fn, so no gimple body is needed. */
8349 gimple_set_body (child_fn, NULL);
8350 TREE_USED (block) = 1;
8351
8352 /* Reset DECL_CONTEXT on function arguments. */
8353 for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
8354 DECL_CONTEXT (t) = child_fn;
8355
8356 /* Split ENTRY_BB at GIMPLE_OMP_TARGET,
8357 so that it can be moved to the child function. */
8358 gsi = gsi_last_bb (entry_bb);
8359 stmt = gsi_stmt (gsi);
8360 gcc_assert (stmt && gimple_code (stmt) == GIMPLE_OMP_TARGET
8361 && gimple_omp_target_kind (stmt)
8362 == GF_OMP_TARGET_KIND_REGION);
8363 gsi_remove (&gsi, true);
8364 e = split_block (entry_bb, stmt);
8365 entry_bb = e->dest;
8366 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
8367
8368 /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
8369 if (exit_bb)
8370 {
8371 gsi = gsi_last_bb (exit_bb);
8372 gcc_assert (!gsi_end_p (gsi)
8373 && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
8374 stmt = gimple_build_return (NULL);
8375 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
8376 gsi_remove (&gsi, true);
8377 }
8378
8379 /* Move the target region into CHILD_CFUN. */
8380
8381 block = gimple_block (entry_stmt);
8382
8383 new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
8384 if (exit_bb)
8385 single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
8386 /* When the OMP expansion process cannot guarantee an up-to-date
8387 loop tree arrange for the child function to fixup loops. */
8388 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
8389 child_cfun->x_current_loops->state |= LOOPS_NEED_FIXUP;
8390
8391 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
8392 num = vec_safe_length (child_cfun->local_decls);
8393 for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
8394 {
8395 t = (*child_cfun->local_decls)[srcidx];
8396 if (DECL_CONTEXT (t) == cfun->decl)
8397 continue;
8398 if (srcidx != dstidx)
8399 (*child_cfun->local_decls)[dstidx] = t;
8400 dstidx++;
8401 }
8402 if (dstidx != num)
8403 vec_safe_truncate (child_cfun->local_decls, dstidx);
8404
8405 /* Inform the callgraph about the new function. */
8406 DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
d52f5295 8407 cgraph_node::add_new_function (child_fn, true);
acf0174b
JJ
8408
8409 /* Fix the callgraph edges for child_cfun. Those for cfun will be
8410 fixed in a following pass. */
8411 push_cfun (child_cfun);
3dafb85c 8412 cgraph_edge::rebuild_edges ();
acf0174b
JJ
8413
8414 /* Some EH regions might become dead, see PR34608. If
8415 pass_cleanup_cfg isn't the first pass to happen with the
8416 new child, these dead EH edges might cause problems.
8417 Clean them up now. */
8418 if (flag_exceptions)
8419 {
8420 basic_block bb;
8421 bool changed = false;
8422
11cd3bed 8423 FOR_EACH_BB_FN (bb, cfun)
acf0174b
JJ
8424 changed |= gimple_purge_dead_eh_edges (bb);
8425 if (changed)
8426 cleanup_tree_cfg ();
8427 }
8428 pop_cfun ();
8429 }
8430
8431 /* Emit a library call to launch the target region, or do data
8432 transfers. */
8433 tree t1, t2, t3, t4, device, cond, c, clauses;
8434 enum built_in_function start_ix;
8435 location_t clause_loc;
8436
8437 clauses = gimple_omp_target_clauses (entry_stmt);
8438
8439 if (kind == GF_OMP_TARGET_KIND_REGION)
8440 start_ix = BUILT_IN_GOMP_TARGET;
8441 else if (kind == GF_OMP_TARGET_KIND_DATA)
8442 start_ix = BUILT_IN_GOMP_TARGET_DATA;
8443 else
8444 start_ix = BUILT_IN_GOMP_TARGET_UPDATE;
8445
8446 /* By default, the value of DEVICE is -1 (let runtime library choose)
8447 and there is no conditional. */
8448 cond = NULL_TREE;
8449 device = build_int_cst (integer_type_node, -1);
8450
8451 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
8452 if (c)
8453 cond = OMP_CLAUSE_IF_EXPR (c);
8454
8455 c = find_omp_clause (clauses, OMP_CLAUSE_DEVICE);
8456 if (c)
8457 {
8458 device = OMP_CLAUSE_DEVICE_ID (c);
8459 clause_loc = OMP_CLAUSE_LOCATION (c);
8460 }
8461 else
8462 clause_loc = gimple_location (entry_stmt);
8463
8464 /* Ensure 'device' is of the correct type. */
8465 device = fold_convert_loc (clause_loc, integer_type_node, device);
8466
8467 /* If we found the clause 'if (cond)', build
8468 (cond ? device : -2). */
8469 if (cond)
8470 {
8471 cond = gimple_boolify (cond);
8472
8473 basic_block cond_bb, then_bb, else_bb;
8474 edge e;
8475 tree tmp_var;
8476
8477 tmp_var = create_tmp_var (TREE_TYPE (device), NULL);
8478 if (kind != GF_OMP_TARGET_KIND_REGION)
8479 {
8480 gsi = gsi_last_bb (new_bb);
8481 gsi_prev (&gsi);
8482 e = split_block (new_bb, gsi_stmt (gsi));
8483 }
8484 else
8485 e = split_block (new_bb, NULL);
8486 cond_bb = e->src;
8487 new_bb = e->dest;
8488 remove_edge (e);
8489
8490 then_bb = create_empty_bb (cond_bb);
8491 else_bb = create_empty_bb (then_bb);
8492 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
8493 set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
8494
8495 stmt = gimple_build_cond_empty (cond);
8496 gsi = gsi_last_bb (cond_bb);
8497 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
8498
8499 gsi = gsi_start_bb (then_bb);
8500 stmt = gimple_build_assign (tmp_var, device);
8501 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
8502
8503 gsi = gsi_start_bb (else_bb);
8504 stmt = gimple_build_assign (tmp_var,
8505 build_int_cst (integer_type_node, -2));
8506 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
8507
8508 make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
8509 make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
726338f4
RB
8510 add_bb_to_loop (then_bb, cond_bb->loop_father);
8511 add_bb_to_loop (else_bb, cond_bb->loop_father);
acf0174b
JJ
8512 make_edge (then_bb, new_bb, EDGE_FALLTHRU);
8513 make_edge (else_bb, new_bb, EDGE_FALLTHRU);
8514
8515 device = tmp_var;
8516 }
8517
8518 gsi = gsi_last_bb (new_bb);
8519 t = gimple_omp_target_data_arg (entry_stmt);
8520 if (t == NULL)
8521 {
8522 t1 = size_zero_node;
8523 t2 = build_zero_cst (ptr_type_node);
8524 t3 = t2;
8525 t4 = t2;
8526 }
8527 else
8528 {
8529 t1 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (TREE_VEC_ELT (t, 1))));
8530 t1 = size_binop (PLUS_EXPR, t1, size_int (1));
8531 t2 = build_fold_addr_expr (TREE_VEC_ELT (t, 0));
8532 t3 = build_fold_addr_expr (TREE_VEC_ELT (t, 1));
8533 t4 = build_fold_addr_expr (TREE_VEC_ELT (t, 2));
8534 }
8535
8536 gimple g;
8537 /* FIXME: This will be address of
8538 extern char __OPENMP_TARGET__[] __attribute__((visibility ("hidden")))
8539 symbol, as soon as the linker plugin is able to create it for us. */
8540 tree openmp_target = build_zero_cst (ptr_type_node);
8541 if (kind == GF_OMP_TARGET_KIND_REGION)
8542 {
8543 tree fnaddr = build_fold_addr_expr (child_fn);
8544 g = gimple_build_call (builtin_decl_explicit (start_ix), 7,
8545 device, fnaddr, openmp_target, t1, t2, t3, t4);
8546 }
8547 else
8548 g = gimple_build_call (builtin_decl_explicit (start_ix), 6,
8549 device, openmp_target, t1, t2, t3, t4);
8550 gimple_set_location (g, gimple_location (entry_stmt));
8551 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
8552 if (kind != GF_OMP_TARGET_KIND_REGION)
8553 {
8554 g = gsi_stmt (gsi);
8555 gcc_assert (g && gimple_code (g) == GIMPLE_OMP_TARGET);
8556 gsi_remove (&gsi, true);
8557 }
8558 if (kind == GF_OMP_TARGET_KIND_DATA && region->exit)
8559 {
8560 gsi = gsi_last_bb (region->exit);
8561 g = gsi_stmt (gsi);
8562 gcc_assert (g && gimple_code (g) == GIMPLE_OMP_RETURN);
8563 gsi_remove (&gsi, true);
8564 }
8565}
8566
8567
8568/* Expand the parallel region tree rooted at REGION. Expansion
8569 proceeds in depth-first order. Innermost regions are expanded
8570 first. This way, parallel regions that require a new function to
726a989a 8571 be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
50674e96
DN
8572 internal dependencies in their body. */
8573
8574static void
8575expand_omp (struct omp_region *region)
8576{
8577 while (region)
8578 {
b357f682 8579 location_t saved_location;
acf0174b 8580 gimple inner_stmt = NULL;
b357f682 8581
068e1875
ZD
8582 /* First, determine whether this is a combined parallel+workshare
8583 region. */
726a989a 8584 if (region->type == GIMPLE_OMP_PARALLEL)
068e1875
ZD
8585 determine_parallel_type (region);
8586
acf0174b
JJ
8587 if (region->type == GIMPLE_OMP_FOR
8588 && gimple_omp_for_combined_p (last_stmt (region->entry)))
8589 inner_stmt = last_stmt (region->inner->entry);
8590
50674e96
DN
8591 if (region->inner)
8592 expand_omp (region->inner);
8593
b357f682 8594 saved_location = input_location;
726a989a
RB
8595 if (gimple_has_location (last_stmt (region->entry)))
8596 input_location = gimple_location (last_stmt (region->entry));
b357f682 8597
777f7f9a 8598 switch (region->type)
50674e96 8599 {
726a989a
RB
8600 case GIMPLE_OMP_PARALLEL:
8601 case GIMPLE_OMP_TASK:
a68ab351
JJ
8602 expand_omp_taskreg (region);
8603 break;
8604
726a989a 8605 case GIMPLE_OMP_FOR:
acf0174b 8606 expand_omp_for (region, inner_stmt);
777f7f9a 8607 break;
50674e96 8608
726a989a 8609 case GIMPLE_OMP_SECTIONS:
777f7f9a
RH
8610 expand_omp_sections (region);
8611 break;
50674e96 8612
726a989a 8613 case GIMPLE_OMP_SECTION:
777f7f9a 8614 /* Individual omp sections are handled together with their
726a989a 8615 parent GIMPLE_OMP_SECTIONS region. */
777f7f9a 8616 break;
50674e96 8617
726a989a 8618 case GIMPLE_OMP_SINGLE:
777f7f9a
RH
8619 expand_omp_single (region);
8620 break;
50674e96 8621
726a989a 8622 case GIMPLE_OMP_MASTER:
acf0174b 8623 case GIMPLE_OMP_TASKGROUP:
726a989a
RB
8624 case GIMPLE_OMP_ORDERED:
8625 case GIMPLE_OMP_CRITICAL:
acf0174b 8626 case GIMPLE_OMP_TEAMS:
777f7f9a
RH
8627 expand_omp_synch (region);
8628 break;
50674e96 8629
726a989a 8630 case GIMPLE_OMP_ATOMIC_LOAD:
a509ebb5
RL
8631 expand_omp_atomic (region);
8632 break;
8633
acf0174b
JJ
8634 case GIMPLE_OMP_TARGET:
8635 expand_omp_target (region);
8636 break;
8637
777f7f9a
RH
8638 default:
8639 gcc_unreachable ();
8640 }
8d9c1aec 8641
b357f682 8642 input_location = saved_location;
50674e96
DN
8643 region = region->next;
8644 }
8645}
8646
8647
8648/* Helper for build_omp_regions. Scan the dominator tree starting at
5f40b3cb
ZD
8649 block BB. PARENT is the region that contains BB. If SINGLE_TREE is
8650 true, the function ends once a single tree is built (otherwise, whole
8651 forest of OMP constructs may be built). */
50674e96
DN
8652
8653static void
5f40b3cb
ZD
8654build_omp_regions_1 (basic_block bb, struct omp_region *parent,
8655 bool single_tree)
50674e96 8656{
726a989a
RB
8657 gimple_stmt_iterator gsi;
8658 gimple stmt;
50674e96
DN
8659 basic_block son;
8660
726a989a
RB
8661 gsi = gsi_last_bb (bb);
8662 if (!gsi_end_p (gsi) && is_gimple_omp (gsi_stmt (gsi)))
50674e96
DN
8663 {
8664 struct omp_region *region;
726a989a 8665 enum gimple_code code;
50674e96 8666
726a989a
RB
8667 stmt = gsi_stmt (gsi);
8668 code = gimple_code (stmt);
8669 if (code == GIMPLE_OMP_RETURN)
50674e96
DN
8670 {
8671 /* STMT is the return point out of region PARENT. Mark it
8672 as the exit point and make PARENT the immediately
8673 enclosing region. */
8674 gcc_assert (parent);
8675 region = parent;
777f7f9a 8676 region->exit = bb;
50674e96 8677 parent = parent->outer;
50674e96 8678 }
726a989a 8679 else if (code == GIMPLE_OMP_ATOMIC_STORE)
a509ebb5 8680 {
726a989a
RB
8681 /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
8682 GIMPLE_OMP_RETURN, but matches with
8683 GIMPLE_OMP_ATOMIC_LOAD. */
a509ebb5 8684 gcc_assert (parent);
726a989a 8685 gcc_assert (parent->type == GIMPLE_OMP_ATOMIC_LOAD);
a509ebb5
RL
8686 region = parent;
8687 region->exit = bb;
8688 parent = parent->outer;
8689 }
8690
726a989a 8691 else if (code == GIMPLE_OMP_CONTINUE)
777f7f9a
RH
8692 {
8693 gcc_assert (parent);
8694 parent->cont = bb;
8695 }
726a989a 8696 else if (code == GIMPLE_OMP_SECTIONS_SWITCH)
e5c95afe 8697 {
726a989a
RB
8698 /* GIMPLE_OMP_SECTIONS_SWITCH is part of
8699 GIMPLE_OMP_SECTIONS, and we do nothing for it. */
8700 ;
e5c95afe 8701 }
acf0174b
JJ
8702 else if (code == GIMPLE_OMP_TARGET
8703 && gimple_omp_target_kind (stmt) == GF_OMP_TARGET_KIND_UPDATE)
8704 new_omp_region (bb, code, parent);
50674e96
DN
8705 else
8706 {
8707 /* Otherwise, this directive becomes the parent for a new
8708 region. */
777f7f9a 8709 region = new_omp_region (bb, code, parent);
50674e96
DN
8710 parent = region;
8711 }
50674e96
DN
8712 }
8713
5f40b3cb
ZD
8714 if (single_tree && !parent)
8715 return;
8716
50674e96
DN
8717 for (son = first_dom_son (CDI_DOMINATORS, bb);
8718 son;
8719 son = next_dom_son (CDI_DOMINATORS, son))
5f40b3cb
ZD
8720 build_omp_regions_1 (son, parent, single_tree);
8721}
8722
8723/* Builds the tree of OMP regions rooted at ROOT, storing it to
8724 root_omp_region. */
8725
8726static void
8727build_omp_regions_root (basic_block root)
8728{
8729 gcc_assert (root_omp_region == NULL);
8730 build_omp_regions_1 (root, NULL, true);
8731 gcc_assert (root_omp_region != NULL);
50674e96
DN
8732}
8733
5f40b3cb
ZD
8734/* Expands omp construct (and its subconstructs) starting in HEAD. */
8735
8736void
8737omp_expand_local (basic_block head)
8738{
8739 build_omp_regions_root (head);
8740 if (dump_file && (dump_flags & TDF_DETAILS))
8741 {
8742 fprintf (dump_file, "\nOMP region tree\n\n");
8743 dump_omp_region (dump_file, root_omp_region, 0);
8744 fprintf (dump_file, "\n");
8745 }
8746
8747 remove_exit_barriers (root_omp_region);
8748 expand_omp (root_omp_region);
8749
8750 free_omp_regions ();
8751}
50674e96
DN
8752
8753/* Scan the CFG and build a tree of OMP regions. Return the root of
8754 the OMP region tree. */
8755
8756static void
8757build_omp_regions (void)
8758{
777f7f9a 8759 gcc_assert (root_omp_region == NULL);
50674e96 8760 calculate_dominance_info (CDI_DOMINATORS);
fefa31b5 8761 build_omp_regions_1 (ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, false);
50674e96
DN
8762}
8763
50674e96
DN
8764/* Main entry point for expanding OMP-GIMPLE into runtime calls. */
8765
c2924966 8766static unsigned int
50674e96
DN
8767execute_expand_omp (void)
8768{
8769 build_omp_regions ();
8770
777f7f9a
RH
8771 if (!root_omp_region)
8772 return 0;
50674e96 8773
777f7f9a
RH
8774 if (dump_file)
8775 {
8776 fprintf (dump_file, "\nOMP region tree\n\n");
8777 dump_omp_region (dump_file, root_omp_region, 0);
8778 fprintf (dump_file, "\n");
50674e96 8779 }
777f7f9a
RH
8780
8781 remove_exit_barriers (root_omp_region);
8782
8783 expand_omp (root_omp_region);
8784
777f7f9a
RH
8785 cleanup_tree_cfg ();
8786
8787 free_omp_regions ();
8788
c2924966 8789 return 0;
50674e96
DN
8790}
8791
917948d3
ZD
8792/* OMP expansion -- the default pass, run before creation of SSA form. */
8793
27a4cd48
DM
8794namespace {
8795
8796const pass_data pass_data_expand_omp =
8797{
8798 GIMPLE_PASS, /* type */
8799 "ompexp", /* name */
8800 OPTGROUP_NONE, /* optinfo_flags */
27a4cd48
DM
8801 TV_NONE, /* tv_id */
8802 PROP_gimple_any, /* properties_required */
8803 0, /* properties_provided */
8804 0, /* properties_destroyed */
8805 0, /* todo_flags_start */
8806 0, /* todo_flags_finish */
50674e96 8807};
27a4cd48
DM
8808
8809class pass_expand_omp : public gimple_opt_pass
8810{
8811public:
c3284718
RS
8812 pass_expand_omp (gcc::context *ctxt)
8813 : gimple_opt_pass (pass_data_expand_omp, ctxt)
27a4cd48
DM
8814 {}
8815
8816 /* opt_pass methods: */
1a3d085c
TS
8817 virtual bool gate (function *)
8818 {
8819 return ((flag_openmp != 0 || flag_openmp_simd != 0
8820 || flag_cilkplus != 0) && !seen_error ());
8821 }
8822
be55bfe6 8823 virtual unsigned int execute (function *) { return execute_expand_omp (); }
27a4cd48
DM
8824
8825}; // class pass_expand_omp
8826
8827} // anon namespace
8828
8829gimple_opt_pass *
8830make_pass_expand_omp (gcc::context *ctxt)
8831{
8832 return new pass_expand_omp (ctxt);
8833}
50674e96
DN
8834\f
8835/* Routines to lower OpenMP directives into OMP-GIMPLE. */
8836
acf0174b
JJ
8837/* If ctx is a worksharing context inside of a cancellable parallel
8838 region and it isn't nowait, add lhs to its GIMPLE_OMP_RETURN
8839 and conditional branch to parallel's cancel_label to handle
8840 cancellation in the implicit barrier. */
8841
8842static void
8843maybe_add_implicit_barrier_cancel (omp_context *ctx, gimple_seq *body)
8844{
8845 gimple omp_return = gimple_seq_last_stmt (*body);
8846 gcc_assert (gimple_code (omp_return) == GIMPLE_OMP_RETURN);
8847 if (gimple_omp_return_nowait_p (omp_return))
8848 return;
8849 if (ctx->outer
8850 && gimple_code (ctx->outer->stmt) == GIMPLE_OMP_PARALLEL
8851 && ctx->outer->cancellable)
8852 {
dd2fc525
JJ
8853 tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
8854 tree c_bool_type = TREE_TYPE (TREE_TYPE (fndecl));
8855 tree lhs = create_tmp_var (c_bool_type, NULL);
acf0174b
JJ
8856 gimple_omp_return_set_lhs (omp_return, lhs);
8857 tree fallthru_label = create_artificial_label (UNKNOWN_LOCATION);
dd2fc525
JJ
8858 gimple g = gimple_build_cond (NE_EXPR, lhs,
8859 fold_convert (c_bool_type,
8860 boolean_false_node),
acf0174b
JJ
8861 ctx->outer->cancel_label, fallthru_label);
8862 gimple_seq_add_stmt (body, g);
8863 gimple_seq_add_stmt (body, gimple_build_label (fallthru_label));
8864 }
8865}
8866
726a989a
RB
8867/* Lower the OpenMP sections directive in the current statement in GSI_P.
8868 CTX is the enclosing OMP context for the current statement. */
50674e96
DN
8869
8870static void
726a989a 8871lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
50674e96 8872{
726a989a
RB
8873 tree block, control;
8874 gimple_stmt_iterator tgsi;
726a989a 8875 gimple stmt, new_stmt, bind, t;
355a7673 8876 gimple_seq ilist, dlist, olist, new_body;
50674e96 8877
726a989a 8878 stmt = gsi_stmt (*gsi_p);
50674e96 8879
45852dcc 8880 push_gimplify_context ();
50674e96
DN
8881
8882 dlist = NULL;
8883 ilist = NULL;
726a989a 8884 lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
acf0174b 8885 &ilist, &dlist, ctx, NULL);
50674e96 8886
355a7673
MM
8887 new_body = gimple_omp_body (stmt);
8888 gimple_omp_set_body (stmt, NULL);
8889 tgsi = gsi_start (new_body);
8890 for (; !gsi_end_p (tgsi); gsi_next (&tgsi))
50674e96
DN
8891 {
8892 omp_context *sctx;
726a989a 8893 gimple sec_start;
50674e96 8894
726a989a 8895 sec_start = gsi_stmt (tgsi);
50674e96
DN
8896 sctx = maybe_lookup_ctx (sec_start);
8897 gcc_assert (sctx);
8898
355a7673
MM
8899 lower_omp (gimple_omp_body_ptr (sec_start), sctx);
8900 gsi_insert_seq_after (&tgsi, gimple_omp_body (sec_start),
8901 GSI_CONTINUE_LINKING);
726a989a 8902 gimple_omp_set_body (sec_start, NULL);
50674e96 8903
355a7673 8904 if (gsi_one_before_end_p (tgsi))
50674e96 8905 {
726a989a
RB
8906 gimple_seq l = NULL;
8907 lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
50674e96 8908 &l, ctx);
355a7673 8909 gsi_insert_seq_after (&tgsi, l, GSI_CONTINUE_LINKING);
726a989a 8910 gimple_omp_section_set_last (sec_start);
50674e96 8911 }
b8698a0f 8912
355a7673
MM
8913 gsi_insert_after (&tgsi, gimple_build_omp_return (false),
8914 GSI_CONTINUE_LINKING);
50674e96 8915 }
953ff289
DN
8916
8917 block = make_node (BLOCK);
355a7673 8918 bind = gimple_build_bind (NULL, new_body, block);
953ff289 8919
726a989a
RB
8920 olist = NULL;
8921 lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
50674e96 8922
b357f682 8923 block = make_node (BLOCK);
726a989a 8924 new_stmt = gimple_build_bind (NULL, NULL, block);
355a7673 8925 gsi_replace (gsi_p, new_stmt, true);
50674e96 8926
b357f682 8927 pop_gimplify_context (new_stmt);
726a989a
RB
8928 gimple_bind_append_vars (new_stmt, ctx->block_vars);
8929 BLOCK_VARS (block) = gimple_bind_vars (bind);
b357f682
JJ
8930 if (BLOCK_VARS (block))
8931 TREE_USED (block) = 1;
8932
726a989a
RB
8933 new_body = NULL;
8934 gimple_seq_add_seq (&new_body, ilist);
8935 gimple_seq_add_stmt (&new_body, stmt);
8936 gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
8937 gimple_seq_add_stmt (&new_body, bind);
777f7f9a 8938
e5c95afe 8939 control = create_tmp_var (unsigned_type_node, ".section");
726a989a
RB
8940 t = gimple_build_omp_continue (control, control);
8941 gimple_omp_sections_set_control (stmt, control);
8942 gimple_seq_add_stmt (&new_body, t);
777f7f9a 8943
726a989a 8944 gimple_seq_add_seq (&new_body, olist);
acf0174b
JJ
8945 if (ctx->cancellable)
8946 gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
726a989a 8947 gimple_seq_add_seq (&new_body, dlist);
50674e96 8948
726a989a 8949 new_body = maybe_catch_exception (new_body);
4a31b7ee 8950
726a989a
RB
8951 t = gimple_build_omp_return
8952 (!!find_omp_clause (gimple_omp_sections_clauses (stmt),
8953 OMP_CLAUSE_NOWAIT));
8954 gimple_seq_add_stmt (&new_body, t);
acf0174b 8955 maybe_add_implicit_barrier_cancel (ctx, &new_body);
777f7f9a 8956
726a989a 8957 gimple_bind_set_body (new_stmt, new_body);
953ff289
DN
8958}
8959
8960
50674e96 8961/* A subroutine of lower_omp_single. Expand the simple form of
726a989a 8962 a GIMPLE_OMP_SINGLE, without a copyprivate clause:
953ff289
DN
8963
8964 if (GOMP_single_start ())
8965 BODY;
8966 [ GOMP_barrier (); ] -> unless 'nowait' is present.
50674e96
DN
8967
8968 FIXME. It may be better to delay expanding the logic of this until
8969 pass_expand_omp. The expanded logic may make the job more difficult
8970 to a synchronization analysis pass. */
953ff289
DN
8971
8972static void
726a989a 8973lower_omp_single_simple (gimple single_stmt, gimple_seq *pre_p)
953ff289 8974{
c2255bc4
AH
8975 location_t loc = gimple_location (single_stmt);
8976 tree tlabel = create_artificial_label (loc);
8977 tree flabel = create_artificial_label (loc);
726a989a
RB
8978 gimple call, cond;
8979 tree lhs, decl;
8980
e79983f4 8981 decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START);
726a989a
RB
8982 lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)), NULL);
8983 call = gimple_build_call (decl, 0);
8984 gimple_call_set_lhs (call, lhs);
8985 gimple_seq_add_stmt (pre_p, call);
8986
8987 cond = gimple_build_cond (EQ_EXPR, lhs,
db3927fb
AH
8988 fold_convert_loc (loc, TREE_TYPE (lhs),
8989 boolean_true_node),
726a989a
RB
8990 tlabel, flabel);
8991 gimple_seq_add_stmt (pre_p, cond);
8992 gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
8993 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
8994 gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
953ff289
DN
8995}
8996
50674e96
DN
8997
8998/* A subroutine of lower_omp_single. Expand the simple form of
726a989a 8999 a GIMPLE_OMP_SINGLE, with a copyprivate clause:
953ff289
DN
9000
9001 #pragma omp single copyprivate (a, b, c)
9002
9003 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
9004
9005 {
9006 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
9007 {
9008 BODY;
9009 copyout.a = a;
9010 copyout.b = b;
9011 copyout.c = c;
9012 GOMP_single_copy_end (&copyout);
9013 }
9014 else
9015 {
9016 a = copyout_p->a;
9017 b = copyout_p->b;
9018 c = copyout_p->c;
9019 }
9020 GOMP_barrier ();
9021 }
50674e96
DN
9022
9023 FIXME. It may be better to delay expanding the logic of this until
9024 pass_expand_omp. The expanded logic may make the job more difficult
9025 to a synchronization analysis pass. */
953ff289
DN
9026
9027static void
726a989a 9028lower_omp_single_copy (gimple single_stmt, gimple_seq *pre_p, omp_context *ctx)
953ff289 9029{
e79983f4 9030 tree ptr_type, t, l0, l1, l2, bfn_decl;
726a989a 9031 gimple_seq copyin_seq;
c2255bc4 9032 location_t loc = gimple_location (single_stmt);
953ff289
DN
9033
9034 ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
9035
9036 ptr_type = build_pointer_type (ctx->record_type);
9037 ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
9038
c2255bc4
AH
9039 l0 = create_artificial_label (loc);
9040 l1 = create_artificial_label (loc);
9041 l2 = create_artificial_label (loc);
953ff289 9042
e79983f4
MM
9043 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START);
9044 t = build_call_expr_loc (loc, bfn_decl, 0);
db3927fb 9045 t = fold_convert_loc (loc, ptr_type, t);
726a989a 9046 gimplify_assign (ctx->receiver_decl, t, pre_p);
953ff289
DN
9047
9048 t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
9049 build_int_cst (ptr_type, 0));
9050 t = build3 (COND_EXPR, void_type_node, t,
9051 build_and_jump (&l0), build_and_jump (&l1));
9052 gimplify_and_add (t, pre_p);
9053
726a989a 9054 gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
953ff289 9055
726a989a 9056 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
953ff289
DN
9057
9058 copyin_seq = NULL;
726a989a 9059 lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
953ff289
DN
9060 &copyin_seq, ctx);
9061
db3927fb 9062 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
e79983f4
MM
9063 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END);
9064 t = build_call_expr_loc (loc, bfn_decl, 1, t);
953ff289
DN
9065 gimplify_and_add (t, pre_p);
9066
9067 t = build_and_jump (&l2);
9068 gimplify_and_add (t, pre_p);
9069
726a989a 9070 gimple_seq_add_stmt (pre_p, gimple_build_label (l1));
953ff289 9071
726a989a 9072 gimple_seq_add_seq (pre_p, copyin_seq);
953ff289 9073
726a989a 9074 gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
953ff289
DN
9075}
9076
50674e96 9077
953ff289
DN
9078/* Expand code for an OpenMP single directive. */
9079
9080static void
726a989a 9081lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
953ff289 9082{
726a989a
RB
9083 tree block;
9084 gimple t, bind, single_stmt = gsi_stmt (*gsi_p);
acf0174b 9085 gimple_seq bind_body, bind_body_tail = NULL, dlist;
953ff289 9086
45852dcc 9087 push_gimplify_context ();
953ff289 9088
355a7673
MM
9089 block = make_node (BLOCK);
9090 bind = gimple_build_bind (NULL, NULL, block);
9091 gsi_replace (gsi_p, bind, true);
726a989a 9092 bind_body = NULL;
355a7673 9093 dlist = NULL;
726a989a 9094 lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
acf0174b 9095 &bind_body, &dlist, ctx, NULL);
355a7673 9096 lower_omp (gimple_omp_body_ptr (single_stmt), ctx);
953ff289 9097
726a989a 9098 gimple_seq_add_stmt (&bind_body, single_stmt);
953ff289
DN
9099
9100 if (ctx->record_type)
726a989a 9101 lower_omp_single_copy (single_stmt, &bind_body, ctx);
953ff289 9102 else
726a989a
RB
9103 lower_omp_single_simple (single_stmt, &bind_body);
9104
9105 gimple_omp_set_body (single_stmt, NULL);
953ff289 9106
726a989a 9107 gimple_seq_add_seq (&bind_body, dlist);
777f7f9a 9108
726a989a 9109 bind_body = maybe_catch_exception (bind_body);
777f7f9a 9110
b8698a0f 9111 t = gimple_build_omp_return
726a989a
RB
9112 (!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
9113 OMP_CLAUSE_NOWAIT));
acf0174b
JJ
9114 gimple_seq_add_stmt (&bind_body_tail, t);
9115 maybe_add_implicit_barrier_cancel (ctx, &bind_body_tail);
9116 if (ctx->record_type)
9117 {
9118 gimple_stmt_iterator gsi = gsi_start (bind_body_tail);
9119 tree clobber = build_constructor (ctx->record_type, NULL);
9120 TREE_THIS_VOLATILE (clobber) = 1;
9121 gsi_insert_after (&gsi, gimple_build_assign (ctx->sender_decl,
9122 clobber), GSI_SAME_STMT);
9123 }
9124 gimple_seq_add_seq (&bind_body, bind_body_tail);
355a7673 9125 gimple_bind_set_body (bind, bind_body);
777f7f9a 9126
953ff289 9127 pop_gimplify_context (bind);
50674e96 9128
726a989a
RB
9129 gimple_bind_append_vars (bind, ctx->block_vars);
9130 BLOCK_VARS (block) = ctx->block_vars;
b357f682
JJ
9131 if (BLOCK_VARS (block))
9132 TREE_USED (block) = 1;
953ff289
DN
9133}
9134
50674e96 9135
953ff289
DN
9136/* Expand code for an OpenMP master directive. */
9137
9138static void
726a989a 9139lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
953ff289 9140{
e79983f4 9141 tree block, lab = NULL, x, bfn_decl;
726a989a 9142 gimple stmt = gsi_stmt (*gsi_p), bind;
db3927fb 9143 location_t loc = gimple_location (stmt);
726a989a 9144 gimple_seq tseq;
953ff289 9145
45852dcc 9146 push_gimplify_context ();
953ff289
DN
9147
9148 block = make_node (BLOCK);
355a7673
MM
9149 bind = gimple_build_bind (NULL, NULL, block);
9150 gsi_replace (gsi_p, bind, true);
9151 gimple_bind_add_stmt (bind, stmt);
777f7f9a 9152
e79983f4
MM
9153 bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
9154 x = build_call_expr_loc (loc, bfn_decl, 0);
953ff289
DN
9155 x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
9156 x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
726a989a
RB
9157 tseq = NULL;
9158 gimplify_and_add (x, &tseq);
9159 gimple_bind_add_seq (bind, tseq);
953ff289 9160
355a7673 9161 lower_omp (gimple_omp_body_ptr (stmt), ctx);
726a989a
RB
9162 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
9163 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
9164 gimple_omp_set_body (stmt, NULL);
953ff289 9165
726a989a 9166 gimple_bind_add_stmt (bind, gimple_build_label (lab));
777f7f9a 9167
726a989a 9168 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
777f7f9a 9169
953ff289 9170 pop_gimplify_context (bind);
50674e96 9171
726a989a
RB
9172 gimple_bind_append_vars (bind, ctx->block_vars);
9173 BLOCK_VARS (block) = ctx->block_vars;
953ff289
DN
9174}
9175
50674e96 9176
acf0174b
JJ
9177/* Expand code for an OpenMP taskgroup directive. */
9178
9179static void
9180lower_omp_taskgroup (gimple_stmt_iterator *gsi_p, omp_context *ctx)
9181{
9182 gimple stmt = gsi_stmt (*gsi_p), bind, x;
9183 tree block = make_node (BLOCK);
9184
9185 bind = gimple_build_bind (NULL, NULL, block);
9186 gsi_replace (gsi_p, bind, true);
9187 gimple_bind_add_stmt (bind, stmt);
9188
9189 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_START),
9190 0);
9191 gimple_bind_add_stmt (bind, x);
9192
9193 lower_omp (gimple_omp_body_ptr (stmt), ctx);
9194 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
9195 gimple_omp_set_body (stmt, NULL);
9196
9197 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
9198
9199 gimple_bind_append_vars (bind, ctx->block_vars);
9200 BLOCK_VARS (block) = ctx->block_vars;
9201}
9202
9203
953ff289
DN
9204/* Expand code for an OpenMP ordered directive. */
9205
9206static void
726a989a 9207lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
953ff289 9208{
726a989a
RB
9209 tree block;
9210 gimple stmt = gsi_stmt (*gsi_p), bind, x;
953ff289 9211
45852dcc 9212 push_gimplify_context ();
953ff289
DN
9213
9214 block = make_node (BLOCK);
355a7673
MM
9215 bind = gimple_build_bind (NULL, NULL, block);
9216 gsi_replace (gsi_p, bind, true);
9217 gimple_bind_add_stmt (bind, stmt);
777f7f9a 9218
e79983f4
MM
9219 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
9220 0);
726a989a 9221 gimple_bind_add_stmt (bind, x);
953ff289 9222
355a7673 9223 lower_omp (gimple_omp_body_ptr (stmt), ctx);
726a989a
RB
9224 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
9225 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
9226 gimple_omp_set_body (stmt, NULL);
953ff289 9227
e79983f4 9228 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END), 0);
726a989a 9229 gimple_bind_add_stmt (bind, x);
777f7f9a 9230
726a989a 9231 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
777f7f9a 9232
953ff289 9233 pop_gimplify_context (bind);
50674e96 9234
726a989a
RB
9235 gimple_bind_append_vars (bind, ctx->block_vars);
9236 BLOCK_VARS (block) = gimple_bind_vars (bind);
953ff289
DN
9237}
9238
953ff289 9239
726a989a 9240/* Gimplify a GIMPLE_OMP_CRITICAL statement. This is a relatively simple
953ff289
DN
9241 substitution of a couple of function calls. But in the NAMED case,
9242 requires that languages coordinate a symbol name. It is therefore
9243 best put here in common code. */
9244
9245static GTY((param1_is (tree), param2_is (tree)))
9246 splay_tree critical_name_mutexes;
9247
9248static void
726a989a 9249lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
953ff289 9250{
726a989a
RB
9251 tree block;
9252 tree name, lock, unlock;
9253 gimple stmt = gsi_stmt (*gsi_p), bind;
db3927fb 9254 location_t loc = gimple_location (stmt);
726a989a 9255 gimple_seq tbody;
953ff289 9256
726a989a 9257 name = gimple_omp_critical_name (stmt);
953ff289
DN
9258 if (name)
9259 {
5039610b 9260 tree decl;
953ff289
DN
9261 splay_tree_node n;
9262
9263 if (!critical_name_mutexes)
9264 critical_name_mutexes
a9429e29
LB
9265 = splay_tree_new_ggc (splay_tree_compare_pointers,
9266 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_s,
9267 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_node_s);
953ff289
DN
9268
9269 n = splay_tree_lookup (critical_name_mutexes, (splay_tree_key) name);
9270 if (n == NULL)
9271 {
9272 char *new_str;
9273
9274 decl = create_tmp_var_raw (ptr_type_node, NULL);
9275
9276 new_str = ACONCAT ((".gomp_critical_user_",
9277 IDENTIFIER_POINTER (name), NULL));
9278 DECL_NAME (decl) = get_identifier (new_str);
9279 TREE_PUBLIC (decl) = 1;
9280 TREE_STATIC (decl) = 1;
9281 DECL_COMMON (decl) = 1;
9282 DECL_ARTIFICIAL (decl) = 1;
9283 DECL_IGNORED_P (decl) = 1;
9041d2e6 9284 varpool_node::finalize_decl (decl);
953ff289
DN
9285
9286 splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
9287 (splay_tree_value) decl);
9288 }
9289 else
9290 decl = (tree) n->value;
9291
e79983f4 9292 lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START);
db3927fb 9293 lock = build_call_expr_loc (loc, lock, 1, build_fold_addr_expr_loc (loc, decl));
953ff289 9294
e79983f4 9295 unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END);
db3927fb
AH
9296 unlock = build_call_expr_loc (loc, unlock, 1,
9297 build_fold_addr_expr_loc (loc, decl));
953ff289
DN
9298 }
9299 else
9300 {
e79983f4 9301 lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START);
db3927fb 9302 lock = build_call_expr_loc (loc, lock, 0);
953ff289 9303
e79983f4 9304 unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END);
db3927fb 9305 unlock = build_call_expr_loc (loc, unlock, 0);
953ff289
DN
9306 }
9307
45852dcc 9308 push_gimplify_context ();
953ff289
DN
9309
9310 block = make_node (BLOCK);
355a7673
MM
9311 bind = gimple_build_bind (NULL, NULL, block);
9312 gsi_replace (gsi_p, bind, true);
9313 gimple_bind_add_stmt (bind, stmt);
777f7f9a 9314
726a989a
RB
9315 tbody = gimple_bind_body (bind);
9316 gimplify_and_add (lock, &tbody);
9317 gimple_bind_set_body (bind, tbody);
953ff289 9318
355a7673 9319 lower_omp (gimple_omp_body_ptr (stmt), ctx);
726a989a
RB
9320 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
9321 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
9322 gimple_omp_set_body (stmt, NULL);
953ff289 9323
726a989a
RB
9324 tbody = gimple_bind_body (bind);
9325 gimplify_and_add (unlock, &tbody);
9326 gimple_bind_set_body (bind, tbody);
777f7f9a 9327
726a989a 9328 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
953ff289
DN
9329
9330 pop_gimplify_context (bind);
726a989a
RB
9331 gimple_bind_append_vars (bind, ctx->block_vars);
9332 BLOCK_VARS (block) = gimple_bind_vars (bind);
50674e96
DN
9333}
9334
9335
9336/* A subroutine of lower_omp_for. Generate code to emit the predicate
9337 for a lastprivate clause. Given a loop control predicate of (V
9338 cond N2), we gate the clause on (!(V cond N2)). The lowered form
3d55c64b
JJ
9339 is appended to *DLIST, iterator initialization is appended to
9340 *BODY_P. */
50674e96
DN
9341
9342static void
726a989a
RB
9343lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
9344 gimple_seq *dlist, struct omp_context *ctx)
50674e96 9345{
726a989a 9346 tree clauses, cond, vinit;
50674e96 9347 enum tree_code cond_code;
726a989a 9348 gimple_seq stmts;
b8698a0f 9349
a68ab351 9350 cond_code = fd->loop.cond_code;
50674e96
DN
9351 cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
9352
9353 /* When possible, use a strict equality expression. This can let VRP
9354 type optimizations deduce the value and remove a copy. */
9541ffee 9355 if (tree_fits_shwi_p (fd->loop.step))
50674e96 9356 {
eb1ce453 9357 HOST_WIDE_INT step = tree_to_shwi (fd->loop.step);
50674e96
DN
9358 if (step == 1 || step == -1)
9359 cond_code = EQ_EXPR;
9360 }
9361
a68ab351 9362 cond = build2 (cond_code, boolean_type_node, fd->loop.v, fd->loop.n2);
50674e96 9363
726a989a 9364 clauses = gimple_omp_for_clauses (fd->for_stmt);
3d55c64b
JJ
9365 stmts = NULL;
9366 lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
726a989a 9367 if (!gimple_seq_empty_p (stmts))
3d55c64b 9368 {
726a989a 9369 gimple_seq_add_seq (&stmts, *dlist);
a68ab351 9370 *dlist = stmts;
3d55c64b
JJ
9371
9372 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
a68ab351 9373 vinit = fd->loop.n1;
3d55c64b 9374 if (cond_code == EQ_EXPR
9541ffee 9375 && tree_fits_shwi_p (fd->loop.n2)
a68ab351
JJ
9376 && ! integer_zerop (fd->loop.n2))
9377 vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
74bf76ed
JJ
9378 else
9379 vinit = unshare_expr (vinit);
3d55c64b
JJ
9380
9381 /* Initialize the iterator variable, so that threads that don't execute
9382 any iterations don't execute the lastprivate clauses by accident. */
726a989a 9383 gimplify_assign (fd->loop.v, vinit, body_p);
3d55c64b 9384 }
50674e96
DN
9385}
9386
9387
9388/* Lower code for an OpenMP loop directive. */
9389
9390static void
726a989a 9391lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
50674e96 9392{
726a989a 9393 tree *rhs_p, block;
acf0174b 9394 struct omp_for_data fd, *fdp = NULL;
726a989a 9395 gimple stmt = gsi_stmt (*gsi_p), new_stmt;
0f900dfa 9396 gimple_seq omp_for_body, body, dlist;
726a989a 9397 size_t i;
50674e96 9398
45852dcc 9399 push_gimplify_context ();
50674e96 9400
355a7673 9401 lower_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
50674e96 9402
b357f682 9403 block = make_node (BLOCK);
726a989a 9404 new_stmt = gimple_build_bind (NULL, NULL, block);
355a7673
MM
9405 /* Replace at gsi right away, so that 'stmt' is no member
9406 of a sequence anymore as we're going to add to to a different
9407 one below. */
9408 gsi_replace (gsi_p, new_stmt, true);
b357f682 9409
50674e96
DN
9410 /* Move declaration of temporaries in the loop body before we make
9411 it go away. */
726a989a
RB
9412 omp_for_body = gimple_omp_body (stmt);
9413 if (!gimple_seq_empty_p (omp_for_body)
9414 && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
9415 {
c74559df
JJ
9416 gimple inner_bind = gimple_seq_first_stmt (omp_for_body);
9417 tree vars = gimple_bind_vars (inner_bind);
726a989a 9418 gimple_bind_append_vars (new_stmt, vars);
c74559df
JJ
9419 /* bind_vars/BLOCK_VARS are being moved to new_stmt/block, don't
9420 keep them on the inner_bind and it's block. */
9421 gimple_bind_set_vars (inner_bind, NULL_TREE);
9422 if (gimple_bind_block (inner_bind))
9423 BLOCK_VARS (gimple_bind_block (inner_bind)) = NULL_TREE;
726a989a 9424 }
50674e96 9425
acf0174b
JJ
9426 if (gimple_omp_for_combined_into_p (stmt))
9427 {
9428 extract_omp_for_data (stmt, &fd, NULL);
9429 fdp = &fd;
9430
9431 /* We need two temporaries with fd.loop.v type (istart/iend)
9432 and then (fd.collapse - 1) temporaries with the same
9433 type for count2 ... countN-1 vars if not constant. */
9434 size_t count = 2;
9435 tree type = fd.iter_type;
9436 if (fd.collapse > 1
9437 && TREE_CODE (fd.loop.n2) != INTEGER_CST)
9438 count += fd.collapse - 1;
9439 bool parallel_for = gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR;
9440 tree outerc = NULL, *pc = gimple_omp_for_clauses_ptr (stmt);
9441 tree clauses = *pc;
9442 if (parallel_for)
9443 outerc
9444 = find_omp_clause (gimple_omp_parallel_clauses (ctx->outer->stmt),
9445 OMP_CLAUSE__LOOPTEMP_);
9446 for (i = 0; i < count; i++)
9447 {
9448 tree temp;
9449 if (parallel_for)
9450 {
9451 gcc_assert (outerc);
9452 temp = lookup_decl (OMP_CLAUSE_DECL (outerc), ctx->outer);
9453 outerc = find_omp_clause (OMP_CLAUSE_CHAIN (outerc),
9454 OMP_CLAUSE__LOOPTEMP_);
9455 }
9456 else
f014c653
JJ
9457 {
9458 temp = create_tmp_var (type, NULL);
9459 insert_decl_map (&ctx->outer->cb, temp, temp);
9460 }
acf0174b
JJ
9461 *pc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__LOOPTEMP_);
9462 OMP_CLAUSE_DECL (*pc) = temp;
9463 pc = &OMP_CLAUSE_CHAIN (*pc);
9464 }
9465 *pc = clauses;
9466 }
9467
726a989a 9468 /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR. */
50674e96 9469 dlist = NULL;
726a989a 9470 body = NULL;
acf0174b
JJ
9471 lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx,
9472 fdp);
726a989a 9473 gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
50674e96 9474
74bf76ed
JJ
9475 lower_omp (gimple_omp_body_ptr (stmt), ctx);
9476
50674e96
DN
9477 /* Lower the header expressions. At this point, we can assume that
9478 the header is of the form:
9479
9480 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
9481
9482 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
9483 using the .omp_data_s mapping, if needed. */
726a989a 9484 for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
a68ab351 9485 {
726a989a 9486 rhs_p = gimple_omp_for_initial_ptr (stmt, i);
a68ab351 9487 if (!is_gimple_min_invariant (*rhs_p))
726a989a 9488 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
a68ab351 9489
726a989a 9490 rhs_p = gimple_omp_for_final_ptr (stmt, i);
a68ab351 9491 if (!is_gimple_min_invariant (*rhs_p))
726a989a 9492 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
a68ab351 9493
726a989a 9494 rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
a68ab351 9495 if (!is_gimple_min_invariant (*rhs_p))
726a989a 9496 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
a68ab351 9497 }
50674e96
DN
9498
9499 /* Once lowered, extract the bounds and clauses. */
a68ab351 9500 extract_omp_for_data (stmt, &fd, NULL);
50674e96 9501
726a989a 9502 lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
50674e96 9503
726a989a
RB
9504 gimple_seq_add_stmt (&body, stmt);
9505 gimple_seq_add_seq (&body, gimple_omp_body (stmt));
777f7f9a 9506
726a989a
RB
9507 gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
9508 fd.loop.v));
777f7f9a 9509
50674e96 9510 /* After the loop, add exit clauses. */
726a989a 9511 lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, ctx);
acf0174b
JJ
9512
9513 if (ctx->cancellable)
9514 gimple_seq_add_stmt (&body, gimple_build_label (ctx->cancel_label));
9515
726a989a 9516 gimple_seq_add_seq (&body, dlist);
50674e96 9517
726a989a 9518 body = maybe_catch_exception (body);
4a31b7ee 9519
777f7f9a 9520 /* Region exit marker goes at the end of the loop body. */
726a989a 9521 gimple_seq_add_stmt (&body, gimple_build_omp_return (fd.have_nowait));
acf0174b 9522 maybe_add_implicit_barrier_cancel (ctx, &body);
b357f682 9523 pop_gimplify_context (new_stmt);
726a989a
RB
9524
9525 gimple_bind_append_vars (new_stmt, ctx->block_vars);
9526 BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
b357f682
JJ
9527 if (BLOCK_VARS (block))
9528 TREE_USED (block) = 1;
50674e96 9529
726a989a
RB
9530 gimple_bind_set_body (new_stmt, body);
9531 gimple_omp_set_body (stmt, NULL);
9532 gimple_omp_for_set_pre_body (stmt, NULL);
953ff289
DN
9533}
9534
b8698a0f 9535/* Callback for walk_stmts. Check if the current statement only contains
e0246869 9536 GIMPLE_OMP_FOR or GIMPLE_OMP_SECTIONS. */
69f1837b
JJ
9537
9538static tree
726a989a
RB
9539check_combined_parallel (gimple_stmt_iterator *gsi_p,
9540 bool *handled_ops_p,
9541 struct walk_stmt_info *wi)
69f1837b 9542{
d3bfe4de 9543 int *info = (int *) wi->info;
726a989a 9544 gimple stmt = gsi_stmt (*gsi_p);
69f1837b 9545
726a989a
RB
9546 *handled_ops_p = true;
9547 switch (gimple_code (stmt))
69f1837b 9548 {
726a989a
RB
9549 WALK_SUBSTMTS;
9550
9551 case GIMPLE_OMP_FOR:
9552 case GIMPLE_OMP_SECTIONS:
69f1837b
JJ
9553 *info = *info == 0 ? 1 : -1;
9554 break;
9555 default:
9556 *info = -1;
9557 break;
9558 }
9559 return NULL;
9560}
50674e96 9561
a68ab351
JJ
9562struct omp_taskcopy_context
9563{
9564 /* This field must be at the beginning, as we do "inheritance": Some
9565 callback functions for tree-inline.c (e.g., omp_copy_decl)
9566 receive a copy_body_data pointer that is up-casted to an
9567 omp_context pointer. */
9568 copy_body_data cb;
9569 omp_context *ctx;
9570};
9571
9572static tree
9573task_copyfn_copy_decl (tree var, copy_body_data *cb)
9574{
9575 struct omp_taskcopy_context *tcctx = (struct omp_taskcopy_context *) cb;
9576
9577 if (splay_tree_lookup (tcctx->ctx->sfield_map, (splay_tree_key) var))
9578 return create_tmp_var (TREE_TYPE (var), NULL);
9579
9580 return var;
9581}
9582
9583static tree
9584task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
9585{
9586 tree name, new_fields = NULL, type, f;
9587
9588 type = lang_hooks.types.make_type (RECORD_TYPE);
9589 name = DECL_NAME (TYPE_NAME (orig_type));
c2255bc4
AH
9590 name = build_decl (gimple_location (tcctx->ctx->stmt),
9591 TYPE_DECL, name, type);
a68ab351
JJ
9592 TYPE_NAME (type) = name;
9593
9594 for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
9595 {
9596 tree new_f = copy_node (f);
9597 DECL_CONTEXT (new_f) = type;
9598 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
9599 TREE_CHAIN (new_f) = new_fields;
726a989a
RB
9600 walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
9601 walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
9602 walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
9603 &tcctx->cb, NULL);
a68ab351 9604 new_fields = new_f;
b787e7a2 9605 tcctx->cb.decl_map->put (f, new_f);
a68ab351
JJ
9606 }
9607 TYPE_FIELDS (type) = nreverse (new_fields);
9608 layout_type (type);
9609 return type;
9610}
9611
9612/* Create task copyfn. */
9613
9614static void
726a989a 9615create_task_copyfn (gimple task_stmt, omp_context *ctx)
a68ab351
JJ
9616{
9617 struct function *child_cfun;
9618 tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
9619 tree record_type, srecord_type, bind, list;
9620 bool record_needs_remap = false, srecord_needs_remap = false;
9621 splay_tree_node n;
9622 struct omp_taskcopy_context tcctx;
db3927fb 9623 location_t loc = gimple_location (task_stmt);
a68ab351 9624
726a989a 9625 child_fn = gimple_omp_task_copy_fn (task_stmt);
a68ab351
JJ
9626 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
9627 gcc_assert (child_cfun->cfg == NULL);
a68ab351
JJ
9628 DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();
9629
9630 /* Reset DECL_CONTEXT on function arguments. */
910ad8de 9631 for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
a68ab351
JJ
9632 DECL_CONTEXT (t) = child_fn;
9633
9634 /* Populate the function. */
45852dcc 9635 push_gimplify_context ();
af16bc76 9636 push_cfun (child_cfun);
a68ab351
JJ
9637
9638 bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
9639 TREE_SIDE_EFFECTS (bind) = 1;
9640 list = NULL;
9641 DECL_SAVED_TREE (child_fn) = bind;
726a989a 9642 DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);
a68ab351
JJ
9643
9644 /* Remap src and dst argument types if needed. */
9645 record_type = ctx->record_type;
9646 srecord_type = ctx->srecord_type;
910ad8de 9647 for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
a68ab351
JJ
9648 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
9649 {
9650 record_needs_remap = true;
9651 break;
9652 }
910ad8de 9653 for (f = TYPE_FIELDS (srecord_type); f ; f = DECL_CHAIN (f))
a68ab351
JJ
9654 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
9655 {
9656 srecord_needs_remap = true;
9657 break;
9658 }
9659
9660 if (record_needs_remap || srecord_needs_remap)
9661 {
9662 memset (&tcctx, '\0', sizeof (tcctx));
9663 tcctx.cb.src_fn = ctx->cb.src_fn;
9664 tcctx.cb.dst_fn = child_fn;
d52f5295 9665 tcctx.cb.src_node = cgraph_node::get (tcctx.cb.src_fn);
fe660d7b 9666 gcc_checking_assert (tcctx.cb.src_node);
a68ab351
JJ
9667 tcctx.cb.dst_node = tcctx.cb.src_node;
9668 tcctx.cb.src_cfun = ctx->cb.src_cfun;
9669 tcctx.cb.copy_decl = task_copyfn_copy_decl;
1d65f45c 9670 tcctx.cb.eh_lp_nr = 0;
a68ab351 9671 tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
b787e7a2 9672 tcctx.cb.decl_map = new hash_map<tree, tree>;
a68ab351
JJ
9673 tcctx.ctx = ctx;
9674
9675 if (record_needs_remap)
9676 record_type = task_copyfn_remap_type (&tcctx, record_type);
9677 if (srecord_needs_remap)
9678 srecord_type = task_copyfn_remap_type (&tcctx, srecord_type);
9679 }
9680 else
9681 tcctx.cb.decl_map = NULL;
9682
a68ab351
JJ
9683 arg = DECL_ARGUMENTS (child_fn);
9684 TREE_TYPE (arg) = build_pointer_type (record_type);
910ad8de 9685 sarg = DECL_CHAIN (arg);
a68ab351
JJ
9686 TREE_TYPE (sarg) = build_pointer_type (srecord_type);
9687
9688 /* First pass: initialize temporaries used in record_type and srecord_type
9689 sizes and field offsets. */
9690 if (tcctx.cb.decl_map)
726a989a 9691 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
a68ab351
JJ
9692 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
9693 {
9694 tree *p;
9695
9696 decl = OMP_CLAUSE_DECL (c);
b787e7a2 9697 p = tcctx.cb.decl_map->get (decl);
a68ab351
JJ
9698 if (p == NULL)
9699 continue;
9700 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
9701 sf = (tree) n->value;
b787e7a2 9702 sf = *tcctx.cb.decl_map->get (sf);
70f34814 9703 src = build_simple_mem_ref_loc (loc, sarg);
a9a58711 9704 src = omp_build_component_ref (src, sf);
726a989a 9705 t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
a68ab351
JJ
9706 append_to_statement_list (t, &list);
9707 }
9708
9709 /* Second pass: copy shared var pointers and copy construct non-VLA
9710 firstprivate vars. */
726a989a 9711 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
a68ab351
JJ
9712 switch (OMP_CLAUSE_CODE (c))
9713 {
9714 case OMP_CLAUSE_SHARED:
9715 decl = OMP_CLAUSE_DECL (c);
9716 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
9717 if (n == NULL)
9718 break;
9719 f = (tree) n->value;
9720 if (tcctx.cb.decl_map)
b787e7a2 9721 f = *tcctx.cb.decl_map->get (f);
a68ab351
JJ
9722 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
9723 sf = (tree) n->value;
9724 if (tcctx.cb.decl_map)
b787e7a2 9725 sf = *tcctx.cb.decl_map->get (sf);
70f34814 9726 src = build_simple_mem_ref_loc (loc, sarg);
a9a58711 9727 src = omp_build_component_ref (src, sf);
70f34814 9728 dst = build_simple_mem_ref_loc (loc, arg);
a9a58711 9729 dst = omp_build_component_ref (dst, f);
726a989a 9730 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
a68ab351
JJ
9731 append_to_statement_list (t, &list);
9732 break;
9733 case OMP_CLAUSE_FIRSTPRIVATE:
9734 decl = OMP_CLAUSE_DECL (c);
9735 if (is_variable_sized (decl))
9736 break;
9737 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
9738 if (n == NULL)
9739 break;
9740 f = (tree) n->value;
9741 if (tcctx.cb.decl_map)
b787e7a2 9742 f = *tcctx.cb.decl_map->get (f);
a68ab351
JJ
9743 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
9744 if (n != NULL)
9745 {
9746 sf = (tree) n->value;
9747 if (tcctx.cb.decl_map)
b787e7a2 9748 sf = *tcctx.cb.decl_map->get (sf);
70f34814 9749 src = build_simple_mem_ref_loc (loc, sarg);
a9a58711 9750 src = omp_build_component_ref (src, sf);
a68ab351 9751 if (use_pointer_for_field (decl, NULL) || is_reference (decl))
70f34814 9752 src = build_simple_mem_ref_loc (loc, src);
a68ab351
JJ
9753 }
9754 else
9755 src = decl;
70f34814 9756 dst = build_simple_mem_ref_loc (loc, arg);
a9a58711 9757 dst = omp_build_component_ref (dst, f);
a68ab351
JJ
9758 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
9759 append_to_statement_list (t, &list);
9760 break;
9761 case OMP_CLAUSE_PRIVATE:
9762 if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c))
9763 break;
9764 decl = OMP_CLAUSE_DECL (c);
9765 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
9766 f = (tree) n->value;
9767 if (tcctx.cb.decl_map)
b787e7a2 9768 f = *tcctx.cb.decl_map->get (f);
a68ab351
JJ
9769 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
9770 if (n != NULL)
9771 {
9772 sf = (tree) n->value;
9773 if (tcctx.cb.decl_map)
b787e7a2 9774 sf = *tcctx.cb.decl_map->get (sf);
70f34814 9775 src = build_simple_mem_ref_loc (loc, sarg);
a9a58711 9776 src = omp_build_component_ref (src, sf);
a68ab351 9777 if (use_pointer_for_field (decl, NULL))
70f34814 9778 src = build_simple_mem_ref_loc (loc, src);
a68ab351
JJ
9779 }
9780 else
9781 src = decl;
70f34814 9782 dst = build_simple_mem_ref_loc (loc, arg);
a9a58711 9783 dst = omp_build_component_ref (dst, f);
726a989a 9784 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
a68ab351
JJ
9785 append_to_statement_list (t, &list);
9786 break;
9787 default:
9788 break;
9789 }
9790
9791 /* Last pass: handle VLA firstprivates. */
9792 if (tcctx.cb.decl_map)
726a989a 9793 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
a68ab351
JJ
9794 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
9795 {
9796 tree ind, ptr, df;
9797
9798 decl = OMP_CLAUSE_DECL (c);
9799 if (!is_variable_sized (decl))
9800 continue;
9801 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
9802 if (n == NULL)
9803 continue;
9804 f = (tree) n->value;
b787e7a2 9805 f = *tcctx.cb.decl_map->get (f);
a68ab351
JJ
9806 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
9807 ind = DECL_VALUE_EXPR (decl);
9808 gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
9809 gcc_assert (DECL_P (TREE_OPERAND (ind, 0)));
9810 n = splay_tree_lookup (ctx->sfield_map,
9811 (splay_tree_key) TREE_OPERAND (ind, 0));
9812 sf = (tree) n->value;
b787e7a2 9813 sf = *tcctx.cb.decl_map->get (sf);
70f34814 9814 src = build_simple_mem_ref_loc (loc, sarg);
a9a58711 9815 src = omp_build_component_ref (src, sf);
70f34814
RG
9816 src = build_simple_mem_ref_loc (loc, src);
9817 dst = build_simple_mem_ref_loc (loc, arg);
a9a58711 9818 dst = omp_build_component_ref (dst, f);
a68ab351
JJ
9819 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
9820 append_to_statement_list (t, &list);
9821 n = splay_tree_lookup (ctx->field_map,
9822 (splay_tree_key) TREE_OPERAND (ind, 0));
9823 df = (tree) n->value;
b787e7a2 9824 df = *tcctx.cb.decl_map->get (df);
70f34814 9825 ptr = build_simple_mem_ref_loc (loc, arg);
a9a58711 9826 ptr = omp_build_component_ref (ptr, df);
726a989a 9827 t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
db3927fb 9828 build_fold_addr_expr_loc (loc, dst));
a68ab351
JJ
9829 append_to_statement_list (t, &list);
9830 }
9831
9832 t = build1 (RETURN_EXPR, void_type_node, NULL);
9833 append_to_statement_list (t, &list);
9834
9835 if (tcctx.cb.decl_map)
b787e7a2 9836 delete tcctx.cb.decl_map;
a68ab351
JJ
9837 pop_gimplify_context (NULL);
9838 BIND_EXPR_BODY (bind) = list;
9839 pop_cfun ();
a68ab351
JJ
9840}
9841
acf0174b
JJ
9842static void
9843lower_depend_clauses (gimple stmt, gimple_seq *iseq, gimple_seq *oseq)
9844{
9845 tree c, clauses;
9846 gimple g;
9847 size_t n_in = 0, n_out = 0, idx = 2, i;
9848
9849 clauses = find_omp_clause (gimple_omp_task_clauses (stmt),
9850 OMP_CLAUSE_DEPEND);
9851 gcc_assert (clauses);
9852 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
9853 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
9854 switch (OMP_CLAUSE_DEPEND_KIND (c))
9855 {
9856 case OMP_CLAUSE_DEPEND_IN:
9857 n_in++;
9858 break;
9859 case OMP_CLAUSE_DEPEND_OUT:
9860 case OMP_CLAUSE_DEPEND_INOUT:
9861 n_out++;
9862 break;
9863 default:
9864 gcc_unreachable ();
9865 }
9866 tree type = build_array_type_nelts (ptr_type_node, n_in + n_out + 2);
9867 tree array = create_tmp_var (type, NULL);
9868 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
9869 NULL_TREE);
9870 g = gimple_build_assign (r, build_int_cst (ptr_type_node, n_in + n_out));
9871 gimple_seq_add_stmt (iseq, g);
9872 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
9873 NULL_TREE);
9874 g = gimple_build_assign (r, build_int_cst (ptr_type_node, n_out));
9875 gimple_seq_add_stmt (iseq, g);
9876 for (i = 0; i < 2; i++)
9877 {
9878 if ((i ? n_in : n_out) == 0)
9879 continue;
9880 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
9881 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
9882 && ((OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_IN) ^ i))
9883 {
9884 tree t = OMP_CLAUSE_DECL (c);
9885 t = fold_convert (ptr_type_node, t);
9886 gimplify_expr (&t, iseq, NULL, is_gimple_val, fb_rvalue);
9887 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (idx++),
9888 NULL_TREE, NULL_TREE);
9889 g = gimple_build_assign (r, t);
9890 gimple_seq_add_stmt (iseq, g);
9891 }
9892 }
9893 tree *p = gimple_omp_task_clauses_ptr (stmt);
9894 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
9895 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
9896 OMP_CLAUSE_CHAIN (c) = *p;
9897 *p = c;
9898 tree clobber = build_constructor (type, NULL);
9899 TREE_THIS_VOLATILE (clobber) = 1;
9900 g = gimple_build_assign (array, clobber);
9901 gimple_seq_add_stmt (oseq, g);
9902}
9903
726a989a
RB
9904/* Lower the OpenMP parallel or task directive in the current statement
9905 in GSI_P. CTX holds context information for the directive. */
50674e96
DN
9906
9907static void
726a989a 9908lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
50674e96 9909{
726a989a
RB
9910 tree clauses;
9911 tree child_fn, t;
9912 gimple stmt = gsi_stmt (*gsi_p);
acf0174b
JJ
9913 gimple par_bind, bind, dep_bind = NULL;
9914 gimple_seq par_body, olist, ilist, par_olist, par_rlist, par_ilist, new_body;
db3927fb 9915 location_t loc = gimple_location (stmt);
50674e96 9916
726a989a
RB
9917 clauses = gimple_omp_taskreg_clauses (stmt);
9918 par_bind = gimple_seq_first_stmt (gimple_omp_body (stmt));
9919 par_body = gimple_bind_body (par_bind);
50674e96 9920 child_fn = ctx->cb.dst_fn;
726a989a
RB
9921 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
9922 && !gimple_omp_parallel_combined_p (stmt))
69f1837b
JJ
9923 {
9924 struct walk_stmt_info wi;
9925 int ws_num = 0;
9926
9927 memset (&wi, 0, sizeof (wi));
69f1837b
JJ
9928 wi.info = &ws_num;
9929 wi.val_only = true;
726a989a 9930 walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
69f1837b 9931 if (ws_num == 1)
726a989a 9932 gimple_omp_parallel_set_combined_p (stmt, true);
69f1837b 9933 }
acf0174b
JJ
9934 gimple_seq dep_ilist = NULL;
9935 gimple_seq dep_olist = NULL;
9936 if (gimple_code (stmt) == GIMPLE_OMP_TASK
9937 && find_omp_clause (clauses, OMP_CLAUSE_DEPEND))
9938 {
45852dcc 9939 push_gimplify_context ();
acf0174b
JJ
9940 dep_bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
9941 lower_depend_clauses (stmt, &dep_ilist, &dep_olist);
9942 }
9943
a68ab351
JJ
9944 if (ctx->srecord_type)
9945 create_task_copyfn (stmt, ctx);
50674e96 9946
45852dcc 9947 push_gimplify_context ();
50674e96 9948
726a989a
RB
9949 par_olist = NULL;
9950 par_ilist = NULL;
acf0174b
JJ
9951 par_rlist = NULL;
9952 lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx, NULL);
355a7673 9953 lower_omp (&par_body, ctx);
726a989a 9954 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
acf0174b 9955 lower_reduction_clauses (clauses, &par_rlist, ctx);
50674e96
DN
9956
9957 /* Declare all the variables created by mapping and the variables
9958 declared in the scope of the parallel body. */
9959 record_vars_into (ctx->block_vars, child_fn);
726a989a 9960 record_vars_into (gimple_bind_vars (par_bind), child_fn);
50674e96
DN
9961
9962 if (ctx->record_type)
9963 {
a68ab351
JJ
9964 ctx->sender_decl
9965 = create_tmp_var (ctx->srecord_type ? ctx->srecord_type
9966 : ctx->record_type, ".omp_data_o");
cd3f04c8 9967 DECL_NAMELESS (ctx->sender_decl) = 1;
628c189e 9968 TREE_ADDRESSABLE (ctx->sender_decl) = 1;
726a989a 9969 gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
50674e96
DN
9970 }
9971
726a989a
RB
9972 olist = NULL;
9973 ilist = NULL;
50674e96
DN
9974 lower_send_clauses (clauses, &ilist, &olist, ctx);
9975 lower_send_shared_vars (&ilist, &olist, ctx);
9976
acf0174b
JJ
9977 if (ctx->record_type)
9978 {
9979 tree clobber = build_constructor (TREE_TYPE (ctx->sender_decl), NULL);
9980 TREE_THIS_VOLATILE (clobber) = 1;
9981 gimple_seq_add_stmt (&olist, gimple_build_assign (ctx->sender_decl,
9982 clobber));
9983 }
9984
50674e96 9985 /* Once all the expansions are done, sequence all the different
726a989a 9986 fragments inside gimple_omp_body. */
50674e96 9987
726a989a 9988 new_body = NULL;
50674e96
DN
9989
9990 if (ctx->record_type)
9991 {
db3927fb 9992 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
018b899b 9993 /* fixup_child_record_type might have changed receiver_decl's type. */
db3927fb 9994 t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
726a989a
RB
9995 gimple_seq_add_stmt (&new_body,
9996 gimple_build_assign (ctx->receiver_decl, t));
50674e96
DN
9997 }
9998
726a989a
RB
9999 gimple_seq_add_seq (&new_body, par_ilist);
10000 gimple_seq_add_seq (&new_body, par_body);
acf0174b
JJ
10001 gimple_seq_add_seq (&new_body, par_rlist);
10002 if (ctx->cancellable)
10003 gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
726a989a
RB
10004 gimple_seq_add_seq (&new_body, par_olist);
10005 new_body = maybe_catch_exception (new_body);
10006 gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
10007 gimple_omp_set_body (stmt, new_body);
50674e96 10008
726a989a 10009 bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
acf0174b
JJ
10010 gsi_replace (gsi_p, dep_bind ? dep_bind : bind, true);
10011 gimple_bind_add_seq (bind, ilist);
10012 gimple_bind_add_stmt (bind, stmt);
10013 gimple_bind_add_seq (bind, olist);
10014
10015 pop_gimplify_context (NULL);
10016
10017 if (dep_bind)
10018 {
10019 gimple_bind_add_seq (dep_bind, dep_ilist);
10020 gimple_bind_add_stmt (dep_bind, bind);
10021 gimple_bind_add_seq (dep_bind, dep_olist);
10022 pop_gimplify_context (dep_bind);
10023 }
10024}
10025
10026/* Lower the OpenMP target directive in the current statement
10027 in GSI_P. CTX holds context information for the directive. */
10028
10029static void
10030lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
10031{
10032 tree clauses;
10033 tree child_fn, t, c;
10034 gimple stmt = gsi_stmt (*gsi_p);
10035 gimple tgt_bind = NULL, bind;
10036 gimple_seq tgt_body = NULL, olist, ilist, new_body;
acf0174b
JJ
10037 location_t loc = gimple_location (stmt);
10038 int kind = gimple_omp_target_kind (stmt);
10039 unsigned int map_cnt = 0;
10040
10041 clauses = gimple_omp_target_clauses (stmt);
10042 if (kind == GF_OMP_TARGET_KIND_REGION)
10043 {
10044 tgt_bind = gimple_seq_first_stmt (gimple_omp_body (stmt));
10045 tgt_body = gimple_bind_body (tgt_bind);
10046 }
10047 else if (kind == GF_OMP_TARGET_KIND_DATA)
10048 tgt_body = gimple_omp_body (stmt);
10049 child_fn = ctx->cb.dst_fn;
10050
45852dcc 10051 push_gimplify_context ();
acf0174b
JJ
10052
10053 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
10054 switch (OMP_CLAUSE_CODE (c))
10055 {
10056 tree var, x;
10057
10058 default:
10059 break;
10060 case OMP_CLAUSE_MAP:
10061 case OMP_CLAUSE_TO:
10062 case OMP_CLAUSE_FROM:
10063 var = OMP_CLAUSE_DECL (c);
10064 if (!DECL_P (var))
10065 {
10066 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
10067 || !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
10068 map_cnt++;
10069 continue;
10070 }
10071
10072 if (DECL_SIZE (var)
10073 && TREE_CODE (DECL_SIZE (var)) != INTEGER_CST)
10074 {
10075 tree var2 = DECL_VALUE_EXPR (var);
10076 gcc_assert (TREE_CODE (var2) == INDIRECT_REF);
10077 var2 = TREE_OPERAND (var2, 0);
10078 gcc_assert (DECL_P (var2));
10079 var = var2;
10080 }
10081
10082 if (!maybe_lookup_field (var, ctx))
10083 continue;
10084
10085 if (kind == GF_OMP_TARGET_KIND_REGION)
10086 {
10087 x = build_receiver_ref (var, true, ctx);
10088 tree new_var = lookup_decl (var, ctx);
10089 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10090 && OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_POINTER
10091 && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
10092 && TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
10093 x = build_simple_mem_ref (x);
10094 SET_DECL_VALUE_EXPR (new_var, x);
10095 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
10096 }
10097 map_cnt++;
10098 }
10099
10100 if (kind == GF_OMP_TARGET_KIND_REGION)
10101 {
10102 target_nesting_level++;
10103 lower_omp (&tgt_body, ctx);
10104 target_nesting_level--;
10105 }
10106 else if (kind == GF_OMP_TARGET_KIND_DATA)
10107 lower_omp (&tgt_body, ctx);
10108
10109 if (kind == GF_OMP_TARGET_KIND_REGION)
10110 {
10111 /* Declare all the variables created by mapping and the variables
10112 declared in the scope of the target body. */
10113 record_vars_into (ctx->block_vars, child_fn);
10114 record_vars_into (gimple_bind_vars (tgt_bind), child_fn);
10115 }
10116
10117 olist = NULL;
10118 ilist = NULL;
10119 if (ctx->record_type)
10120 {
10121 ctx->sender_decl
10122 = create_tmp_var (ctx->record_type, ".omp_data_arr");
10123 DECL_NAMELESS (ctx->sender_decl) = 1;
10124 TREE_ADDRESSABLE (ctx->sender_decl) = 1;
10125 t = make_tree_vec (3);
10126 TREE_VEC_ELT (t, 0) = ctx->sender_decl;
10127 TREE_VEC_ELT (t, 1)
10128 = create_tmp_var (build_array_type_nelts (size_type_node, map_cnt),
10129 ".omp_data_sizes");
10130 DECL_NAMELESS (TREE_VEC_ELT (t, 1)) = 1;
10131 TREE_ADDRESSABLE (TREE_VEC_ELT (t, 1)) = 1;
10132 TREE_STATIC (TREE_VEC_ELT (t, 1)) = 1;
10133 TREE_VEC_ELT (t, 2)
10134 = create_tmp_var (build_array_type_nelts (unsigned_char_type_node,
10135 map_cnt),
10136 ".omp_data_kinds");
10137 DECL_NAMELESS (TREE_VEC_ELT (t, 2)) = 1;
10138 TREE_ADDRESSABLE (TREE_VEC_ELT (t, 2)) = 1;
10139 TREE_STATIC (TREE_VEC_ELT (t, 2)) = 1;
10140 gimple_omp_target_set_data_arg (stmt, t);
10141
10142 vec<constructor_elt, va_gc> *vsize;
10143 vec<constructor_elt, va_gc> *vkind;
10144 vec_alloc (vsize, map_cnt);
10145 vec_alloc (vkind, map_cnt);
10146 unsigned int map_idx = 0;
10147
10148 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
10149 switch (OMP_CLAUSE_CODE (c))
10150 {
10151 tree ovar, nc;
10152
10153 default:
10154 break;
10155 case OMP_CLAUSE_MAP:
10156 case OMP_CLAUSE_TO:
10157 case OMP_CLAUSE_FROM:
10158 nc = c;
10159 ovar = OMP_CLAUSE_DECL (c);
10160 if (!DECL_P (ovar))
10161 {
10162 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10163 && OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
10164 {
10165 gcc_checking_assert (OMP_CLAUSE_DECL (OMP_CLAUSE_CHAIN (c))
10166 == get_base_address (ovar));
10167 nc = OMP_CLAUSE_CHAIN (c);
10168 ovar = OMP_CLAUSE_DECL (nc);
10169 }
10170 else
10171 {
10172 tree x = build_sender_ref (ovar, ctx);
10173 tree v
10174 = build_fold_addr_expr_with_type (ovar, ptr_type_node);
10175 gimplify_assign (x, v, &ilist);
10176 nc = NULL_TREE;
10177 }
10178 }
10179 else
10180 {
10181 if (DECL_SIZE (ovar)
10182 && TREE_CODE (DECL_SIZE (ovar)) != INTEGER_CST)
10183 {
10184 tree ovar2 = DECL_VALUE_EXPR (ovar);
10185 gcc_assert (TREE_CODE (ovar2) == INDIRECT_REF);
10186 ovar2 = TREE_OPERAND (ovar2, 0);
10187 gcc_assert (DECL_P (ovar2));
10188 ovar = ovar2;
10189 }
10190 if (!maybe_lookup_field (ovar, ctx))
10191 continue;
10192 }
10193
0fe81a0f
JJ
10194 unsigned int talign = TYPE_ALIGN_UNIT (TREE_TYPE (ovar));
10195 if (DECL_P (ovar) && DECL_ALIGN_UNIT (ovar) > talign)
10196 talign = DECL_ALIGN_UNIT (ovar);
acf0174b
JJ
10197 if (nc)
10198 {
10199 tree var = lookup_decl_in_outer_ctx (ovar, ctx);
10200 tree x = build_sender_ref (ovar, ctx);
10201 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10202 && OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_POINTER
10203 && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
10204 && TREE_CODE (TREE_TYPE (ovar)) == ARRAY_TYPE)
10205 {
10206 gcc_assert (kind == GF_OMP_TARGET_KIND_REGION);
10207 tree avar
10208 = create_tmp_var (TREE_TYPE (TREE_TYPE (x)), NULL);
10209 mark_addressable (avar);
10210 gimplify_assign (avar, build_fold_addr_expr (var), &ilist);
0fe81a0f 10211 talign = DECL_ALIGN_UNIT (avar);
acf0174b
JJ
10212 avar = build_fold_addr_expr (avar);
10213 gimplify_assign (x, avar, &ilist);
10214 }
10215 else if (is_gimple_reg (var))
10216 {
10217 gcc_assert (kind == GF_OMP_TARGET_KIND_REGION);
10218 tree avar = create_tmp_var (TREE_TYPE (var), NULL);
10219 mark_addressable (avar);
10220 if (OMP_CLAUSE_MAP_KIND (c) != OMP_CLAUSE_MAP_ALLOC
10221 && OMP_CLAUSE_MAP_KIND (c) != OMP_CLAUSE_MAP_FROM)
10222 gimplify_assign (avar, var, &ilist);
10223 avar = build_fold_addr_expr (avar);
10224 gimplify_assign (x, avar, &ilist);
10225 if ((OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_FROM
10226 || OMP_CLAUSE_MAP_KIND (c) == OMP_CLAUSE_MAP_TOFROM)
10227 && !TYPE_READONLY (TREE_TYPE (var)))
10228 {
10229 x = build_sender_ref (ovar, ctx);
10230 x = build_simple_mem_ref (x);
10231 gimplify_assign (var, x, &olist);
10232 }
10233 }
10234 else
10235 {
10236 var = build_fold_addr_expr (var);
10237 gimplify_assign (x, var, &ilist);
10238 }
10239 }
10240 tree s = OMP_CLAUSE_SIZE (c);
10241 if (s == NULL_TREE)
10242 s = TYPE_SIZE_UNIT (TREE_TYPE (ovar));
10243 s = fold_convert (size_type_node, s);
10244 tree purpose = size_int (map_idx++);
10245 CONSTRUCTOR_APPEND_ELT (vsize, purpose, s);
10246 if (TREE_CODE (s) != INTEGER_CST)
10247 TREE_STATIC (TREE_VEC_ELT (t, 1)) = 0;
10248
10249 unsigned char tkind = 0;
10250 switch (OMP_CLAUSE_CODE (c))
10251 {
10252 case OMP_CLAUSE_MAP:
10253 tkind = OMP_CLAUSE_MAP_KIND (c);
10254 break;
10255 case OMP_CLAUSE_TO:
10256 tkind = OMP_CLAUSE_MAP_TO;
10257 break;
10258 case OMP_CLAUSE_FROM:
10259 tkind = OMP_CLAUSE_MAP_FROM;
10260 break;
10261 default:
10262 gcc_unreachable ();
10263 }
acf0174b
JJ
10264 talign = ceil_log2 (talign);
10265 tkind |= talign << 3;
10266 CONSTRUCTOR_APPEND_ELT (vkind, purpose,
10267 build_int_cst (unsigned_char_type_node,
10268 tkind));
10269 if (nc && nc != c)
10270 c = nc;
10271 }
10272
10273 gcc_assert (map_idx == map_cnt);
10274
10275 DECL_INITIAL (TREE_VEC_ELT (t, 1))
10276 = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 1)), vsize);
10277 DECL_INITIAL (TREE_VEC_ELT (t, 2))
10278 = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 2)), vkind);
10279 if (!TREE_STATIC (TREE_VEC_ELT (t, 1)))
10280 {
10281 gimple_seq initlist = NULL;
10282 force_gimple_operand (build1 (DECL_EXPR, void_type_node,
10283 TREE_VEC_ELT (t, 1)),
10284 &initlist, true, NULL_TREE);
10285 gimple_seq_add_seq (&ilist, initlist);
bae729a2
TS
10286
10287 tree clobber = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 1)),
10288 NULL);
10289 TREE_THIS_VOLATILE (clobber) = 1;
10290 gimple_seq_add_stmt (&olist,
10291 gimple_build_assign (TREE_VEC_ELT (t, 1),
10292 clobber));
acf0174b
JJ
10293 }
10294
10295 tree clobber = build_constructor (ctx->record_type, NULL);
10296 TREE_THIS_VOLATILE (clobber) = 1;
10297 gimple_seq_add_stmt (&olist, gimple_build_assign (ctx->sender_decl,
10298 clobber));
10299 }
10300
10301 /* Once all the expansions are done, sequence all the different
10302 fragments inside gimple_omp_body. */
10303
10304 new_body = NULL;
10305
10306 if (ctx->record_type && kind == GF_OMP_TARGET_KIND_REGION)
10307 {
10308 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
10309 /* fixup_child_record_type might have changed receiver_decl's type. */
10310 t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
10311 gimple_seq_add_stmt (&new_body,
10312 gimple_build_assign (ctx->receiver_decl, t));
10313 }
10314
10315 if (kind == GF_OMP_TARGET_KIND_REGION)
10316 {
10317 gimple_seq_add_seq (&new_body, tgt_body);
10318 new_body = maybe_catch_exception (new_body);
10319 }
10320 else if (kind == GF_OMP_TARGET_KIND_DATA)
10321 new_body = tgt_body;
10322 if (kind != GF_OMP_TARGET_KIND_UPDATE)
10323 {
10324 gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
10325 gimple_omp_set_body (stmt, new_body);
10326 }
10327
10328 bind = gimple_build_bind (NULL, NULL,
10329 tgt_bind ? gimple_bind_block (tgt_bind)
10330 : NULL_TREE);
726a989a 10331 gsi_replace (gsi_p, bind, true);
355a7673
MM
10332 gimple_bind_add_seq (bind, ilist);
10333 gimple_bind_add_stmt (bind, stmt);
10334 gimple_bind_add_seq (bind, olist);
50674e96 10335
726a989a 10336 pop_gimplify_context (NULL);
50674e96
DN
10337}
10338
acf0174b
JJ
10339/* Expand code for an OpenMP teams directive. */
10340
10341static void
10342lower_omp_teams (gimple_stmt_iterator *gsi_p, omp_context *ctx)
10343{
10344 gimple teams_stmt = gsi_stmt (*gsi_p);
45852dcc 10345 push_gimplify_context ();
acf0174b
JJ
10346
10347 tree block = make_node (BLOCK);
10348 gimple bind = gimple_build_bind (NULL, NULL, block);
10349 gsi_replace (gsi_p, bind, true);
10350 gimple_seq bind_body = NULL;
10351 gimple_seq dlist = NULL;
10352 gimple_seq olist = NULL;
10353
10354 tree num_teams = find_omp_clause (gimple_omp_teams_clauses (teams_stmt),
10355 OMP_CLAUSE_NUM_TEAMS);
10356 if (num_teams == NULL_TREE)
10357 num_teams = build_int_cst (unsigned_type_node, 0);
10358 else
10359 {
10360 num_teams = OMP_CLAUSE_NUM_TEAMS_EXPR (num_teams);
10361 num_teams = fold_convert (unsigned_type_node, num_teams);
10362 gimplify_expr (&num_teams, &bind_body, NULL, is_gimple_val, fb_rvalue);
10363 }
10364 tree thread_limit = find_omp_clause (gimple_omp_teams_clauses (teams_stmt),
10365 OMP_CLAUSE_THREAD_LIMIT);
10366 if (thread_limit == NULL_TREE)
10367 thread_limit = build_int_cst (unsigned_type_node, 0);
10368 else
10369 {
10370 thread_limit = OMP_CLAUSE_THREAD_LIMIT_EXPR (thread_limit);
10371 thread_limit = fold_convert (unsigned_type_node, thread_limit);
10372 gimplify_expr (&thread_limit, &bind_body, NULL, is_gimple_val,
10373 fb_rvalue);
10374 }
10375
10376 lower_rec_input_clauses (gimple_omp_teams_clauses (teams_stmt),
10377 &bind_body, &dlist, ctx, NULL);
10378 lower_omp (gimple_omp_body_ptr (teams_stmt), ctx);
10379 lower_reduction_clauses (gimple_omp_teams_clauses (teams_stmt), &olist, ctx);
10380 gimple_seq_add_stmt (&bind_body, teams_stmt);
10381
10382 location_t loc = gimple_location (teams_stmt);
10383 tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TEAMS);
10384 gimple call = gimple_build_call (decl, 2, num_teams, thread_limit);
10385 gimple_set_location (call, loc);
10386 gimple_seq_add_stmt (&bind_body, call);
10387
10388 gimple_seq_add_seq (&bind_body, gimple_omp_body (teams_stmt));
10389 gimple_omp_set_body (teams_stmt, NULL);
10390 gimple_seq_add_seq (&bind_body, olist);
10391 gimple_seq_add_seq (&bind_body, dlist);
10392 gimple_seq_add_stmt (&bind_body, gimple_build_omp_return (true));
10393 gimple_bind_set_body (bind, bind_body);
10394
10395 pop_gimplify_context (bind);
10396
10397 gimple_bind_append_vars (bind, ctx->block_vars);
10398 BLOCK_VARS (block) = ctx->block_vars;
10399 if (BLOCK_VARS (block))
10400 TREE_USED (block) = 1;
10401}
10402
10403
d0fb20be 10404/* Callback for lower_omp_1. Return non-NULL if *tp needs to be
726a989a
RB
10405 regimplified. If DATA is non-NULL, lower_omp_1 is outside
10406 of OpenMP context, but with task_shared_vars set. */
75a4c3c1
AP
10407
10408static tree
726a989a
RB
10409lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
10410 void *data)
75a4c3c1 10411{
d0fb20be 10412 tree t = *tp;
75a4c3c1 10413
d0fb20be 10414 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
726a989a 10415 if (TREE_CODE (t) == VAR_DECL && data == NULL && DECL_HAS_VALUE_EXPR_P (t))
b826efd9
JJ
10416 return t;
10417
10418 if (task_shared_vars
10419 && DECL_P (t)
10420 && bitmap_bit_p (task_shared_vars, DECL_UID (t)))
d0fb20be 10421 return t;
75a4c3c1 10422
d0fb20be
JJ
10423 /* If a global variable has been privatized, TREE_CONSTANT on
10424 ADDR_EXPR might be wrong. */
726a989a 10425 if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
d0fb20be 10426 recompute_tree_invariant_for_addr_expr (t);
75a4c3c1 10427
d0fb20be
JJ
10428 *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
10429 return NULL_TREE;
75a4c3c1 10430}
50674e96 10431
d0fb20be 10432static void
726a989a 10433lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
953ff289 10434{
726a989a
RB
10435 gimple stmt = gsi_stmt (*gsi_p);
10436 struct walk_stmt_info wi;
953ff289 10437
726a989a
RB
10438 if (gimple_has_location (stmt))
10439 input_location = gimple_location (stmt);
d0fb20be 10440
726a989a
RB
10441 if (task_shared_vars)
10442 memset (&wi, '\0', sizeof (wi));
d0fb20be 10443
50674e96
DN
10444 /* If we have issued syntax errors, avoid doing any heavy lifting.
10445 Just replace the OpenMP directives with a NOP to avoid
10446 confusing RTL expansion. */
1da2ed5f 10447 if (seen_error () && is_gimple_omp (stmt))
50674e96 10448 {
726a989a 10449 gsi_replace (gsi_p, gimple_build_nop (), true);
d0fb20be 10450 return;
50674e96
DN
10451 }
10452
726a989a 10453 switch (gimple_code (stmt))
953ff289 10454 {
726a989a 10455 case GIMPLE_COND:
a68ab351 10456 if ((ctx || task_shared_vars)
726a989a
RB
10457 && (walk_tree (gimple_cond_lhs_ptr (stmt), lower_omp_regimplify_p,
10458 ctx ? NULL : &wi, NULL)
10459 || walk_tree (gimple_cond_rhs_ptr (stmt), lower_omp_regimplify_p,
10460 ctx ? NULL : &wi, NULL)))
10461 gimple_regimplify_operands (stmt, gsi_p);
d0fb20be 10462 break;
726a989a 10463 case GIMPLE_CATCH:
355a7673 10464 lower_omp (gimple_catch_handler_ptr (stmt), ctx);
d0fb20be 10465 break;
726a989a 10466 case GIMPLE_EH_FILTER:
355a7673 10467 lower_omp (gimple_eh_filter_failure_ptr (stmt), ctx);
d0fb20be 10468 break;
726a989a 10469 case GIMPLE_TRY:
355a7673
MM
10470 lower_omp (gimple_try_eval_ptr (stmt), ctx);
10471 lower_omp (gimple_try_cleanup_ptr (stmt), ctx);
d0fb20be 10472 break;
d88513ea
PM
10473 case GIMPLE_TRANSACTION:
10474 lower_omp (gimple_transaction_body_ptr (stmt), ctx);
10475 break;
726a989a 10476 case GIMPLE_BIND:
355a7673 10477 lower_omp (gimple_bind_body_ptr (stmt), ctx);
d0fb20be 10478 break;
726a989a
RB
10479 case GIMPLE_OMP_PARALLEL:
10480 case GIMPLE_OMP_TASK:
10481 ctx = maybe_lookup_ctx (stmt);
acf0174b
JJ
10482 gcc_assert (ctx);
10483 if (ctx->cancellable)
10484 ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
726a989a 10485 lower_omp_taskreg (gsi_p, ctx);
d0fb20be 10486 break;
726a989a
RB
10487 case GIMPLE_OMP_FOR:
10488 ctx = maybe_lookup_ctx (stmt);
953ff289 10489 gcc_assert (ctx);
acf0174b
JJ
10490 if (ctx->cancellable)
10491 ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
726a989a 10492 lower_omp_for (gsi_p, ctx);
953ff289 10493 break;
726a989a
RB
10494 case GIMPLE_OMP_SECTIONS:
10495 ctx = maybe_lookup_ctx (stmt);
953ff289 10496 gcc_assert (ctx);
acf0174b
JJ
10497 if (ctx->cancellable)
10498 ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
726a989a 10499 lower_omp_sections (gsi_p, ctx);
953ff289 10500 break;
726a989a
RB
10501 case GIMPLE_OMP_SINGLE:
10502 ctx = maybe_lookup_ctx (stmt);
953ff289 10503 gcc_assert (ctx);
726a989a 10504 lower_omp_single (gsi_p, ctx);
953ff289 10505 break;
726a989a
RB
10506 case GIMPLE_OMP_MASTER:
10507 ctx = maybe_lookup_ctx (stmt);
953ff289 10508 gcc_assert (ctx);
726a989a 10509 lower_omp_master (gsi_p, ctx);
953ff289 10510 break;
acf0174b
JJ
10511 case GIMPLE_OMP_TASKGROUP:
10512 ctx = maybe_lookup_ctx (stmt);
10513 gcc_assert (ctx);
10514 lower_omp_taskgroup (gsi_p, ctx);
10515 break;
726a989a
RB
10516 case GIMPLE_OMP_ORDERED:
10517 ctx = maybe_lookup_ctx (stmt);
953ff289 10518 gcc_assert (ctx);
726a989a 10519 lower_omp_ordered (gsi_p, ctx);
953ff289 10520 break;
726a989a
RB
10521 case GIMPLE_OMP_CRITICAL:
10522 ctx = maybe_lookup_ctx (stmt);
953ff289 10523 gcc_assert (ctx);
726a989a
RB
10524 lower_omp_critical (gsi_p, ctx);
10525 break;
10526 case GIMPLE_OMP_ATOMIC_LOAD:
10527 if ((ctx || task_shared_vars)
10528 && walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt),
10529 lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
10530 gimple_regimplify_operands (stmt, gsi_p);
953ff289 10531 break;
acf0174b
JJ
10532 case GIMPLE_OMP_TARGET:
10533 ctx = maybe_lookup_ctx (stmt);
10534 gcc_assert (ctx);
10535 lower_omp_target (gsi_p, ctx);
10536 break;
10537 case GIMPLE_OMP_TEAMS:
10538 ctx = maybe_lookup_ctx (stmt);
10539 gcc_assert (ctx);
10540 lower_omp_teams (gsi_p, ctx);
10541 break;
10542 case GIMPLE_CALL:
10543 tree fndecl;
10544 fndecl = gimple_call_fndecl (stmt);
10545 if (fndecl
10546 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
10547 switch (DECL_FUNCTION_CODE (fndecl))
10548 {
10549 case BUILT_IN_GOMP_BARRIER:
10550 if (ctx == NULL)
10551 break;
10552 /* FALLTHRU */
10553 case BUILT_IN_GOMP_CANCEL:
10554 case BUILT_IN_GOMP_CANCELLATION_POINT:
10555 omp_context *cctx;
10556 cctx = ctx;
10557 if (gimple_code (cctx->stmt) == GIMPLE_OMP_SECTION)
10558 cctx = cctx->outer;
10559 gcc_assert (gimple_call_lhs (stmt) == NULL_TREE);
10560 if (!cctx->cancellable)
10561 {
10562 if (DECL_FUNCTION_CODE (fndecl)
10563 == BUILT_IN_GOMP_CANCELLATION_POINT)
10564 {
10565 stmt = gimple_build_nop ();
10566 gsi_replace (gsi_p, stmt, false);
10567 }
10568 break;
10569 }
acf0174b
JJ
10570 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER)
10571 {
10572 fndecl = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER_CANCEL);
10573 gimple_call_set_fndecl (stmt, fndecl);
10574 gimple_call_set_fntype (stmt, TREE_TYPE (fndecl));
10575 }
dd2fc525
JJ
10576 tree lhs;
10577 lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (fndecl)), NULL);
acf0174b
JJ
10578 gimple_call_set_lhs (stmt, lhs);
10579 tree fallthru_label;
10580 fallthru_label = create_artificial_label (UNKNOWN_LOCATION);
10581 gimple g;
10582 g = gimple_build_label (fallthru_label);
10583 gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
dd2fc525
JJ
10584 g = gimple_build_cond (NE_EXPR, lhs,
10585 fold_convert (TREE_TYPE (lhs),
10586 boolean_false_node),
acf0174b
JJ
10587 cctx->cancel_label, fallthru_label);
10588 gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
10589 break;
10590 default:
10591 break;
10592 }
10593 /* FALLTHRU */
d0fb20be 10594 default:
a68ab351 10595 if ((ctx || task_shared_vars)
726a989a
RB
10596 && walk_gimple_op (stmt, lower_omp_regimplify_p,
10597 ctx ? NULL : &wi))
47519a14
JJ
10598 {
10599 /* Just remove clobbers, this should happen only if we have
10600 "privatized" local addressable variables in SIMD regions,
10601 the clobber isn't needed in that case and gimplifying address
10602 of the ARRAY_REF into a pointer and creating MEM_REF based
10603 clobber would create worse code than we get with the clobber
10604 dropped. */
10605 if (gimple_clobber_p (stmt))
10606 {
10607 gsi_replace (gsi_p, gimple_build_nop (), true);
10608 break;
10609 }
10610 gimple_regimplify_operands (stmt, gsi_p);
10611 }
953ff289 10612 break;
953ff289 10613 }
953ff289
DN
10614}
10615
10616static void
355a7673 10617lower_omp (gimple_seq *body, omp_context *ctx)
953ff289 10618{
b357f682 10619 location_t saved_location = input_location;
355a7673
MM
10620 gimple_stmt_iterator gsi;
10621 for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
726a989a 10622 lower_omp_1 (&gsi, ctx);
88ac13da
TS
10623 /* During gimplification, we have not always invoked fold_stmt
10624 (gimplify.c:maybe_fold_stmt); call it now. */
acf0174b
JJ
10625 if (target_nesting_level)
10626 for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
10627 fold_stmt (&gsi);
b357f682 10628 input_location = saved_location;
953ff289
DN
10629}
10630\f
10631/* Main entry point. */
10632
c2924966 10633static unsigned int
953ff289
DN
10634execute_lower_omp (void)
10635{
726a989a 10636 gimple_seq body;
5771c391
JJ
10637 int i;
10638 omp_context *ctx;
726a989a 10639
535b544a
SB
10640 /* This pass always runs, to provide PROP_gimple_lomp.
10641 But there is nothing to do unless -fopenmp is given. */
b72271b9 10642 if (flag_openmp == 0 && flag_openmp_simd == 0 && flag_cilkplus == 0)
535b544a
SB
10643 return 0;
10644
953ff289
DN
10645 all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
10646 delete_omp_context);
10647
726a989a 10648 body = gimple_body (current_function_decl);
26127932 10649 scan_omp (&body, NULL);
a68ab351 10650 gcc_assert (taskreg_nesting_level == 0);
5771c391
JJ
10651 FOR_EACH_VEC_ELT (taskreg_contexts, i, ctx)
10652 finish_taskreg_scan (ctx);
10653 taskreg_contexts.release ();
953ff289
DN
10654
10655 if (all_contexts->root)
a68ab351
JJ
10656 {
10657 if (task_shared_vars)
45852dcc 10658 push_gimplify_context ();
355a7673 10659 lower_omp (&body, NULL);
a68ab351
JJ
10660 if (task_shared_vars)
10661 pop_gimplify_context (NULL);
10662 }
953ff289 10663
50674e96
DN
10664 if (all_contexts)
10665 {
10666 splay_tree_delete (all_contexts);
10667 all_contexts = NULL;
10668 }
a68ab351 10669 BITMAP_FREE (task_shared_vars);
c2924966 10670 return 0;
953ff289
DN
10671}
10672
27a4cd48
DM
10673namespace {
10674
10675const pass_data pass_data_lower_omp =
10676{
10677 GIMPLE_PASS, /* type */
10678 "omplower", /* name */
10679 OPTGROUP_NONE, /* optinfo_flags */
27a4cd48
DM
10680 TV_NONE, /* tv_id */
10681 PROP_gimple_any, /* properties_required */
10682 PROP_gimple_lomp, /* properties_provided */
10683 0, /* properties_destroyed */
10684 0, /* todo_flags_start */
10685 0, /* todo_flags_finish */
953ff289 10686};
27a4cd48
DM
10687
10688class pass_lower_omp : public gimple_opt_pass
10689{
10690public:
c3284718
RS
10691 pass_lower_omp (gcc::context *ctxt)
10692 : gimple_opt_pass (pass_data_lower_omp, ctxt)
27a4cd48
DM
10693 {}
10694
10695 /* opt_pass methods: */
be55bfe6 10696 virtual unsigned int execute (function *) { return execute_lower_omp (); }
27a4cd48
DM
10697
10698}; // class pass_lower_omp
10699
10700} // anon namespace
10701
10702gimple_opt_pass *
10703make_pass_lower_omp (gcc::context *ctxt)
10704{
10705 return new pass_lower_omp (ctxt);
10706}
953ff289
DN
10707\f
10708/* The following is a utility to diagnose OpenMP structured block violations.
777f7f9a
RH
10709 It is not part of the "omplower" pass, as that's invoked too late. It
10710 should be invoked by the respective front ends after gimplification. */
953ff289
DN
10711
10712static splay_tree all_labels;
10713
10714/* Check for mismatched contexts and generate an error if needed. Return
10715 true if an error is detected. */
10716
10717static bool
726a989a
RB
10718diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
10719 gimple branch_ctx, gimple label_ctx)
953ff289 10720{
726a989a 10721 if (label_ctx == branch_ctx)
953ff289
DN
10722 return false;
10723
b8698a0f 10724
726a989a
RB
10725 /*
10726 Previously we kept track of the label's entire context in diagnose_sb_[12]
10727 so we could traverse it and issue a correct "exit" or "enter" error
10728 message upon a structured block violation.
10729
10730 We built the context by building a list with tree_cons'ing, but there is
10731 no easy counterpart in gimple tuples. It seems like far too much work
10732 for issuing exit/enter error messages. If someone really misses the
10733 distinct error message... patches welcome.
10734 */
b8698a0f 10735
726a989a 10736#if 0
953ff289 10737 /* Try to avoid confusing the user by producing and error message
fa10beec 10738 with correct "exit" or "enter" verbiage. We prefer "exit"
953ff289
DN
10739 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
10740 if (branch_ctx == NULL)
10741 exit_p = false;
10742 else
10743 {
10744 while (label_ctx)
10745 {
10746 if (TREE_VALUE (label_ctx) == branch_ctx)
10747 {
10748 exit_p = false;
10749 break;
10750 }
10751 label_ctx = TREE_CHAIN (label_ctx);
10752 }
10753 }
10754
10755 if (exit_p)
10756 error ("invalid exit from OpenMP structured block");
10757 else
10758 error ("invalid entry to OpenMP structured block");
726a989a 10759#endif
953ff289 10760
c02065fc 10761 bool cilkplus_block = false;
b72271b9 10762 if (flag_cilkplus)
c02065fc
AH
10763 {
10764 if ((branch_ctx
10765 && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
10766 && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
64e5ace5
TS
10767 || (label_ctx
10768 && gimple_code (label_ctx) == GIMPLE_OMP_FOR
c02065fc
AH
10769 && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
10770 cilkplus_block = true;
10771 }
10772
726a989a
RB
10773 /* If it's obvious we have an invalid entry, be specific about the error. */
10774 if (branch_ctx == NULL)
c02065fc
AH
10775 {
10776 if (cilkplus_block)
10777 error ("invalid entry to Cilk Plus structured block");
10778 else
10779 error ("invalid entry to OpenMP structured block");
10780 }
726a989a 10781 else
c02065fc
AH
10782 {
10783 /* Otherwise, be vague and lazy, but efficient. */
10784 if (cilkplus_block)
10785 error ("invalid branch to/from a Cilk Plus structured block");
10786 else
10787 error ("invalid branch to/from an OpenMP structured block");
10788 }
726a989a
RB
10789
10790 gsi_replace (gsi_p, gimple_build_nop (), false);
953ff289
DN
10791 return true;
10792}
10793
10794/* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
726a989a 10795 where each label is found. */
953ff289
DN
10796
10797static tree
726a989a
RB
10798diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
10799 struct walk_stmt_info *wi)
953ff289 10800{
726a989a
RB
10801 gimple context = (gimple) wi->info;
10802 gimple inner_context;
10803 gimple stmt = gsi_stmt (*gsi_p);
953ff289 10804
726a989a
RB
10805 *handled_ops_p = true;
10806
10807 switch (gimple_code (stmt))
953ff289 10808 {
726a989a 10809 WALK_SUBSTMTS;
b8698a0f 10810
726a989a
RB
10811 case GIMPLE_OMP_PARALLEL:
10812 case GIMPLE_OMP_TASK:
10813 case GIMPLE_OMP_SECTIONS:
10814 case GIMPLE_OMP_SINGLE:
10815 case GIMPLE_OMP_SECTION:
10816 case GIMPLE_OMP_MASTER:
10817 case GIMPLE_OMP_ORDERED:
10818 case GIMPLE_OMP_CRITICAL:
acf0174b
JJ
10819 case GIMPLE_OMP_TARGET:
10820 case GIMPLE_OMP_TEAMS:
10821 case GIMPLE_OMP_TASKGROUP:
726a989a
RB
10822 /* The minimal context here is just the current OMP construct. */
10823 inner_context = stmt;
953ff289 10824 wi->info = inner_context;
726a989a 10825 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
953ff289
DN
10826 wi->info = context;
10827 break;
10828
726a989a
RB
10829 case GIMPLE_OMP_FOR:
10830 inner_context = stmt;
953ff289 10831 wi->info = inner_context;
726a989a
RB
10832 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
10833 walk them. */
10834 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
10835 diagnose_sb_1, NULL, wi);
10836 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
953ff289
DN
10837 wi->info = context;
10838 break;
10839
726a989a
RB
10840 case GIMPLE_LABEL:
10841 splay_tree_insert (all_labels, (splay_tree_key) gimple_label_label (stmt),
953ff289
DN
10842 (splay_tree_value) context);
10843 break;
10844
10845 default:
10846 break;
10847 }
10848
10849 return NULL_TREE;
10850}
10851
10852/* Pass 2: Check each branch and see if its context differs from that of
10853 the destination label's context. */
10854
10855static tree
726a989a
RB
10856diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
10857 struct walk_stmt_info *wi)
953ff289 10858{
726a989a 10859 gimple context = (gimple) wi->info;
953ff289 10860 splay_tree_node n;
726a989a 10861 gimple stmt = gsi_stmt (*gsi_p);
953ff289 10862
726a989a
RB
10863 *handled_ops_p = true;
10864
10865 switch (gimple_code (stmt))
953ff289 10866 {
726a989a
RB
10867 WALK_SUBSTMTS;
10868
10869 case GIMPLE_OMP_PARALLEL:
10870 case GIMPLE_OMP_TASK:
10871 case GIMPLE_OMP_SECTIONS:
10872 case GIMPLE_OMP_SINGLE:
10873 case GIMPLE_OMP_SECTION:
10874 case GIMPLE_OMP_MASTER:
10875 case GIMPLE_OMP_ORDERED:
10876 case GIMPLE_OMP_CRITICAL:
acf0174b
JJ
10877 case GIMPLE_OMP_TARGET:
10878 case GIMPLE_OMP_TEAMS:
10879 case GIMPLE_OMP_TASKGROUP:
726a989a 10880 wi->info = stmt;
355a7673 10881 walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
953ff289
DN
10882 wi->info = context;
10883 break;
10884
726a989a
RB
10885 case GIMPLE_OMP_FOR:
10886 wi->info = stmt;
10887 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
10888 walk them. */
355a7673
MM
10889 walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt),
10890 diagnose_sb_2, NULL, wi);
10891 walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
953ff289
DN
10892 wi->info = context;
10893 break;
10894
ca50f84a
L
10895 case GIMPLE_COND:
10896 {
10897 tree lab = gimple_cond_true_label (stmt);
10898 if (lab)
10899 {
10900 n = splay_tree_lookup (all_labels,
10901 (splay_tree_key) lab);
10902 diagnose_sb_0 (gsi_p, context,
10903 n ? (gimple) n->value : NULL);
10904 }
10905 lab = gimple_cond_false_label (stmt);
10906 if (lab)
10907 {
10908 n = splay_tree_lookup (all_labels,
10909 (splay_tree_key) lab);
10910 diagnose_sb_0 (gsi_p, context,
10911 n ? (gimple) n->value : NULL);
10912 }
10913 }
10914 break;
10915
726a989a 10916 case GIMPLE_GOTO:
953ff289 10917 {
726a989a 10918 tree lab = gimple_goto_dest (stmt);
953ff289
DN
10919 if (TREE_CODE (lab) != LABEL_DECL)
10920 break;
10921
10922 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
726a989a 10923 diagnose_sb_0 (gsi_p, context, n ? (gimple) n->value : NULL);
953ff289
DN
10924 }
10925 break;
10926
726a989a 10927 case GIMPLE_SWITCH:
953ff289 10928 {
726a989a
RB
10929 unsigned int i;
10930 for (i = 0; i < gimple_switch_num_labels (stmt); ++i)
953ff289 10931 {
726a989a 10932 tree lab = CASE_LABEL (gimple_switch_label (stmt, i));
953ff289 10933 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
726a989a 10934 if (n && diagnose_sb_0 (gsi_p, context, (gimple) n->value))
953ff289
DN
10935 break;
10936 }
10937 }
10938 break;
10939
726a989a
RB
10940 case GIMPLE_RETURN:
10941 diagnose_sb_0 (gsi_p, context, NULL);
953ff289
DN
10942 break;
10943
10944 default:
10945 break;
10946 }
10947
10948 return NULL_TREE;
10949}
10950
0645c1a2
AM
10951/* Called from tree-cfg.c::make_edges to create cfg edges for all GIMPLE_OMP
10952 codes. */
10953bool
09b22f48
JJ
10954make_gimple_omp_edges (basic_block bb, struct omp_region **region,
10955 int *region_idx)
0645c1a2
AM
10956{
10957 gimple last = last_stmt (bb);
10958 enum gimple_code code = gimple_code (last);
10959 struct omp_region *cur_region = *region;
10960 bool fallthru = false;
10961
10962 switch (code)
10963 {
10964 case GIMPLE_OMP_PARALLEL:
10965 case GIMPLE_OMP_TASK:
10966 case GIMPLE_OMP_FOR:
10967 case GIMPLE_OMP_SINGLE:
10968 case GIMPLE_OMP_TEAMS:
10969 case GIMPLE_OMP_MASTER:
10970 case GIMPLE_OMP_TASKGROUP:
10971 case GIMPLE_OMP_ORDERED:
10972 case GIMPLE_OMP_CRITICAL:
10973 case GIMPLE_OMP_SECTION:
10974 cur_region = new_omp_region (bb, code, cur_region);
10975 fallthru = true;
10976 break;
10977
10978 case GIMPLE_OMP_TARGET:
10979 cur_region = new_omp_region (bb, code, cur_region);
10980 fallthru = true;
10981 if (gimple_omp_target_kind (last) == GF_OMP_TARGET_KIND_UPDATE)
10982 cur_region = cur_region->outer;
10983 break;
10984
10985 case GIMPLE_OMP_SECTIONS:
10986 cur_region = new_omp_region (bb, code, cur_region);
10987 fallthru = true;
10988 break;
10989
10990 case GIMPLE_OMP_SECTIONS_SWITCH:
10991 fallthru = false;
10992 break;
10993
10994 case GIMPLE_OMP_ATOMIC_LOAD:
10995 case GIMPLE_OMP_ATOMIC_STORE:
10996 fallthru = true;
10997 break;
10998
10999 case GIMPLE_OMP_RETURN:
11000 /* In the case of a GIMPLE_OMP_SECTION, the edge will go
11001 somewhere other than the next block. This will be
11002 created later. */
11003 cur_region->exit = bb;
11004 fallthru = cur_region->type != GIMPLE_OMP_SECTION;
11005 cur_region = cur_region->outer;
11006 break;
11007
11008 case GIMPLE_OMP_CONTINUE:
11009 cur_region->cont = bb;
11010 switch (cur_region->type)
11011 {
11012 case GIMPLE_OMP_FOR:
11013 /* Mark all GIMPLE_OMP_FOR and GIMPLE_OMP_CONTINUE
11014 succs edges as abnormal to prevent splitting
11015 them. */
11016 single_succ_edge (cur_region->entry)->flags |= EDGE_ABNORMAL;
11017 /* Make the loopback edge. */
11018 make_edge (bb, single_succ (cur_region->entry),
11019 EDGE_ABNORMAL);
11020
11021 /* Create an edge from GIMPLE_OMP_FOR to exit, which
11022 corresponds to the case that the body of the loop
11023 is not executed at all. */
11024 make_edge (cur_region->entry, bb->next_bb, EDGE_ABNORMAL);
11025 make_edge (bb, bb->next_bb, EDGE_FALLTHRU | EDGE_ABNORMAL);
11026 fallthru = false;
11027 break;
11028
11029 case GIMPLE_OMP_SECTIONS:
11030 /* Wire up the edges into and out of the nested sections. */
11031 {
11032 basic_block switch_bb = single_succ (cur_region->entry);
11033
11034 struct omp_region *i;
11035 for (i = cur_region->inner; i ; i = i->next)
11036 {
11037 gcc_assert (i->type == GIMPLE_OMP_SECTION);
11038 make_edge (switch_bb, i->entry, 0);
11039 make_edge (i->exit, bb, EDGE_FALLTHRU);
11040 }
11041
11042 /* Make the loopback edge to the block with
11043 GIMPLE_OMP_SECTIONS_SWITCH. */
11044 make_edge (bb, switch_bb, 0);
11045
11046 /* Make the edge from the switch to exit. */
11047 make_edge (switch_bb, bb->next_bb, 0);
11048 fallthru = false;
11049 }
11050 break;
11051
11052 default:
11053 gcc_unreachable ();
11054 }
11055 break;
11056
11057 default:
11058 gcc_unreachable ();
11059 }
11060
11061 if (*region != cur_region)
09b22f48
JJ
11062 {
11063 *region = cur_region;
11064 if (cur_region)
11065 *region_idx = cur_region->entry->index;
11066 else
11067 *region_idx = 0;
11068 }
0645c1a2
AM
11069
11070 return fallthru;
11071}
11072
a406865a
RG
11073static unsigned int
11074diagnose_omp_structured_block_errors (void)
953ff289 11075{
953ff289 11076 struct walk_stmt_info wi;
a406865a 11077 gimple_seq body = gimple_body (current_function_decl);
953ff289
DN
11078
11079 all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
11080
11081 memset (&wi, 0, sizeof (wi));
726a989a 11082 walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);
953ff289
DN
11083
11084 memset (&wi, 0, sizeof (wi));
953ff289 11085 wi.want_locations = true;
355a7673
MM
11086 walk_gimple_seq_mod (&body, diagnose_sb_2, NULL, &wi);
11087
11088 gimple_set_body (current_function_decl, body);
953ff289
DN
11089
11090 splay_tree_delete (all_labels);
11091 all_labels = NULL;
11092
a406865a 11093 return 0;
953ff289
DN
11094}
11095
27a4cd48
DM
11096namespace {
11097
11098const pass_data pass_data_diagnose_omp_blocks =
11099{
11100 GIMPLE_PASS, /* type */
11101 "*diagnose_omp_blocks", /* name */
11102 OPTGROUP_NONE, /* optinfo_flags */
27a4cd48
DM
11103 TV_NONE, /* tv_id */
11104 PROP_gimple_any, /* properties_required */
11105 0, /* properties_provided */
11106 0, /* properties_destroyed */
11107 0, /* todo_flags_start */
11108 0, /* todo_flags_finish */
a406865a
RG
11109};
11110
27a4cd48
DM
11111class pass_diagnose_omp_blocks : public gimple_opt_pass
11112{
11113public:
c3284718
RS
11114 pass_diagnose_omp_blocks (gcc::context *ctxt)
11115 : gimple_opt_pass (pass_data_diagnose_omp_blocks, ctxt)
27a4cd48
DM
11116 {}
11117
11118 /* opt_pass methods: */
1a3d085c 11119 virtual bool gate (function *) { return flag_openmp || flag_cilkplus; }
be55bfe6
TS
11120 virtual unsigned int execute (function *)
11121 {
11122 return diagnose_omp_structured_block_errors ();
11123 }
27a4cd48
DM
11124
11125}; // class pass_diagnose_omp_blocks
11126
11127} // anon namespace
11128
11129gimple_opt_pass *
11130make_pass_diagnose_omp_blocks (gcc::context *ctxt)
11131{
11132 return new pass_diagnose_omp_blocks (ctxt);
11133}
0136f8f0
AH
11134\f
11135/* SIMD clone supporting code. */
11136
11137/* Allocate a fresh `simd_clone' and return it. NARGS is the number
11138 of arguments to reserve space for. */
11139
11140static struct cgraph_simd_clone *
11141simd_clone_struct_alloc (int nargs)
11142{
11143 struct cgraph_simd_clone *clone_info;
11144 size_t len = (sizeof (struct cgraph_simd_clone)
11145 + nargs * sizeof (struct cgraph_simd_clone_arg));
11146 clone_info = (struct cgraph_simd_clone *)
b3bb0eb9 11147 ggc_internal_cleared_alloc (len);
0136f8f0
AH
11148 return clone_info;
11149}
11150
11151/* Make a copy of the `struct cgraph_simd_clone' in FROM to TO. */
11152
11153static inline void
11154simd_clone_struct_copy (struct cgraph_simd_clone *to,
11155 struct cgraph_simd_clone *from)
11156{
11157 memcpy (to, from, (sizeof (struct cgraph_simd_clone)
92d05580
JJ
11158 + ((from->nargs - from->inbranch)
11159 * sizeof (struct cgraph_simd_clone_arg))));
0136f8f0
AH
11160}
11161
11162/* Return vector of parameter types of function FNDECL. This uses
11163 TYPE_ARG_TYPES if available, otherwise falls back to types of
11164 DECL_ARGUMENTS types. */
11165
11166vec<tree>
11167simd_clone_vector_of_formal_parm_types (tree fndecl)
11168{
11169 if (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
11170 return ipa_get_vector_of_formal_parm_types (TREE_TYPE (fndecl));
11171 vec<tree> args = ipa_get_vector_of_formal_parms (fndecl);
11172 unsigned int i;
11173 tree arg;
11174 FOR_EACH_VEC_ELT (args, i, arg)
11175 args[i] = TREE_TYPE (args[i]);
11176 return args;
11177}
11178
11179/* Given a simd function in NODE, extract the simd specific
11180 information from the OMP clauses passed in CLAUSES, and return
11181 the struct cgraph_simd_clone * if it should be cloned. *INBRANCH_SPECIFIED
11182 is set to TRUE if the `inbranch' or `notinbranch' clause specified,
11183 otherwise set to FALSE. */
11184
11185static struct cgraph_simd_clone *
11186simd_clone_clauses_extract (struct cgraph_node *node, tree clauses,
11187 bool *inbranch_specified)
11188{
11189 vec<tree> args = simd_clone_vector_of_formal_parm_types (node->decl);
11190 tree t;
11191 int n;
11192 *inbranch_specified = false;
11193
11194 n = args.length ();
11195 if (n > 0 && args.last () == void_type_node)
11196 n--;
11197
11198 /* To distinguish from an OpenMP simd clone, Cilk Plus functions to
11199 be cloned have a distinctive artificial label in addition to "omp
11200 declare simd". */
11201 bool cilk_clone
b72271b9 11202 = (flag_cilkplus
41958c28 11203 && lookup_attribute ("cilk simd function",
0136f8f0
AH
11204 DECL_ATTRIBUTES (node->decl)));
11205
11206 /* Allocate one more than needed just in case this is an in-branch
11207 clone which will require a mask argument. */
11208 struct cgraph_simd_clone *clone_info = simd_clone_struct_alloc (n + 1);
11209 clone_info->nargs = n;
11210 clone_info->cilk_elemental = cilk_clone;
11211
11212 if (!clauses)
11213 {
11214 args.release ();
11215 return clone_info;
11216 }
11217 clauses = TREE_VALUE (clauses);
11218 if (!clauses || TREE_CODE (clauses) != OMP_CLAUSE)
11219 return clone_info;
11220
11221 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
11222 {
11223 switch (OMP_CLAUSE_CODE (t))
11224 {
11225 case OMP_CLAUSE_INBRANCH:
11226 clone_info->inbranch = 1;
11227 *inbranch_specified = true;
11228 break;
11229 case OMP_CLAUSE_NOTINBRANCH:
11230 clone_info->inbranch = 0;
11231 *inbranch_specified = true;
11232 break;
11233 case OMP_CLAUSE_SIMDLEN:
11234 clone_info->simdlen
11235 = TREE_INT_CST_LOW (OMP_CLAUSE_SIMDLEN_EXPR (t));
11236 break;
11237 case OMP_CLAUSE_LINEAR:
11238 {
11239 tree decl = OMP_CLAUSE_DECL (t);
11240 tree step = OMP_CLAUSE_LINEAR_STEP (t);
11241 int argno = TREE_INT_CST_LOW (decl);
11242 if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (t))
11243 {
11244 clone_info->args[argno].arg_type
11245 = SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP;
11246 clone_info->args[argno].linear_step = tree_to_shwi (step);
11247 gcc_assert (clone_info->args[argno].linear_step >= 0
11248 && clone_info->args[argno].linear_step < n);
11249 }
11250 else
11251 {
11252 if (POINTER_TYPE_P (args[argno]))
11253 step = fold_convert (ssizetype, step);
11254 if (!tree_fits_shwi_p (step))
11255 {
11256 warning_at (OMP_CLAUSE_LOCATION (t), 0,
11257 "ignoring large linear step");
11258 args.release ();
11259 return NULL;
11260 }
11261 else if (integer_zerop (step))
11262 {
11263 warning_at (OMP_CLAUSE_LOCATION (t), 0,
11264 "ignoring zero linear step");
11265 args.release ();
11266 return NULL;
11267 }
11268 else
11269 {
11270 clone_info->args[argno].arg_type
11271 = SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP;
11272 clone_info->args[argno].linear_step = tree_to_shwi (step);
11273 }
11274 }
11275 break;
11276 }
11277 case OMP_CLAUSE_UNIFORM:
11278 {
11279 tree decl = OMP_CLAUSE_DECL (t);
11280 int argno = tree_to_uhwi (decl);
11281 clone_info->args[argno].arg_type
11282 = SIMD_CLONE_ARG_TYPE_UNIFORM;
11283 break;
11284 }
11285 case OMP_CLAUSE_ALIGNED:
11286 {
11287 tree decl = OMP_CLAUSE_DECL (t);
11288 int argno = tree_to_uhwi (decl);
11289 clone_info->args[argno].alignment
11290 = TREE_INT_CST_LOW (OMP_CLAUSE_ALIGNED_ALIGNMENT (t));
11291 break;
11292 }
11293 default:
11294 break;
11295 }
11296 }
11297 args.release ();
11298 return clone_info;
11299}
11300
11301/* Given a SIMD clone in NODE, calculate the characteristic data
11302 type and return the coresponding type. The characteristic data
11303 type is computed as described in the Intel Vector ABI. */
11304
11305static tree
11306simd_clone_compute_base_data_type (struct cgraph_node *node,
11307 struct cgraph_simd_clone *clone_info)
11308{
11309 tree type = integer_type_node;
11310 tree fndecl = node->decl;
11311
11312 /* a) For non-void function, the characteristic data type is the
11313 return type. */
11314 if (TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE)
11315 type = TREE_TYPE (TREE_TYPE (fndecl));
11316
11317 /* b) If the function has any non-uniform, non-linear parameters,
11318 then the characteristic data type is the type of the first
11319 such parameter. */
11320 else
11321 {
11322 vec<tree> map = simd_clone_vector_of_formal_parm_types (fndecl);
11323 for (unsigned int i = 0; i < clone_info->nargs; ++i)
11324 if (clone_info->args[i].arg_type == SIMD_CLONE_ARG_TYPE_VECTOR)
11325 {
11326 type = map[i];
11327 break;
11328 }
11329 map.release ();
11330 }
11331
11332 /* c) If the characteristic data type determined by a) or b) above
11333 is struct, union, or class type which is pass-by-value (except
11334 for the type that maps to the built-in complex data type), the
11335 characteristic data type is int. */
11336 if (RECORD_OR_UNION_TYPE_P (type)
11337 && !aggregate_value_p (type, NULL)
11338 && TREE_CODE (type) != COMPLEX_TYPE)
11339 return integer_type_node;
11340
11341 /* d) If none of the above three classes is applicable, the
11342 characteristic data type is int. */
11343
11344 return type;
11345
11346 /* e) For Intel Xeon Phi native and offload compilation, if the
11347 resulting characteristic data type is 8-bit or 16-bit integer
11348 data type, the characteristic data type is int. */
11349 /* Well, we don't handle Xeon Phi yet. */
11350}
11351
11352static tree
11353simd_clone_mangle (struct cgraph_node *node,
11354 struct cgraph_simd_clone *clone_info)
11355{
11356 char vecsize_mangle = clone_info->vecsize_mangle;
11357 char mask = clone_info->inbranch ? 'M' : 'N';
11358 unsigned int simdlen = clone_info->simdlen;
11359 unsigned int n;
11360 pretty_printer pp;
11361
11362 gcc_assert (vecsize_mangle && simdlen);
11363
11364 pp_string (&pp, "_ZGV");
11365 pp_character (&pp, vecsize_mangle);
11366 pp_character (&pp, mask);
11367 pp_decimal_int (&pp, simdlen);
11368
11369 for (n = 0; n < clone_info->nargs; ++n)
11370 {
11371 struct cgraph_simd_clone_arg arg = clone_info->args[n];
11372
11373 if (arg.arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM)
11374 pp_character (&pp, 'u');
11375 else if (arg.arg_type == SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP)
11376 {
11377 gcc_assert (arg.linear_step != 0);
11378 pp_character (&pp, 'l');
11379 if (arg.linear_step > 1)
11380 pp_unsigned_wide_integer (&pp, arg.linear_step);
11381 else if (arg.linear_step < 0)
11382 {
11383 pp_character (&pp, 'n');
11384 pp_unsigned_wide_integer (&pp, (-(unsigned HOST_WIDE_INT)
11385 arg.linear_step));
11386 }
11387 }
11388 else if (arg.arg_type == SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP)
11389 {
11390 pp_character (&pp, 's');
11391 pp_unsigned_wide_integer (&pp, arg.linear_step);
11392 }
11393 else
11394 pp_character (&pp, 'v');
11395 if (arg.alignment)
11396 {
11397 pp_character (&pp, 'a');
11398 pp_decimal_int (&pp, arg.alignment);
11399 }
11400 }
11401
11402 pp_underscore (&pp);
11403 pp_string (&pp,
11404 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl)));
11405 const char *str = pp_formatted_text (&pp);
11406
11407 /* If there already is a SIMD clone with the same mangled name, don't
11408 add another one. This can happen e.g. for
11409 #pragma omp declare simd
11410 #pragma omp declare simd simdlen(8)
11411 int foo (int, int);
11412 if the simdlen is assumed to be 8 for the first one, etc. */
11413 for (struct cgraph_node *clone = node->simd_clones; clone;
11414 clone = clone->simdclone->next_clone)
11415 if (strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (clone->decl)),
11416 str) == 0)
11417 return NULL_TREE;
11418
11419 return get_identifier (str);
11420}
11421
11422/* Create a simd clone of OLD_NODE and return it. */
11423
11424static struct cgraph_node *
11425simd_clone_create (struct cgraph_node *old_node)
11426{
11427 struct cgraph_node *new_node;
11428 if (old_node->definition)
e06f9964 11429 {
d52f5295 11430 if (!old_node->has_gimple_body_p ())
e06f9964 11431 return NULL;
d52f5295
ML
11432 old_node->get_body ();
11433 new_node = old_node->create_version_clone_with_body (vNULL, NULL, NULL,
11434 false, NULL, NULL,
11435 "simdclone");
e06f9964 11436 }
0136f8f0
AH
11437 else
11438 {
11439 tree old_decl = old_node->decl;
11440 tree new_decl = copy_node (old_node->decl);
11441 DECL_NAME (new_decl) = clone_function_name (old_decl, "simdclone");
11442 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
11443 SET_DECL_RTL (new_decl, NULL);
11444 DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
11445 DECL_STATIC_DESTRUCTOR (new_decl) = 0;
d52f5295 11446 new_node = old_node->create_version_clone (new_decl, vNULL, NULL);
3dafb85c 11447 symtab->call_cgraph_insertion_hooks (new_node);
0136f8f0
AH
11448 }
11449 if (new_node == NULL)
11450 return new_node;
11451
11452 TREE_PUBLIC (new_node->decl) = TREE_PUBLIC (old_node->decl);
11453
11454 /* The function cgraph_function_versioning () will force the new
11455 symbol local. Undo this, and inherit external visability from
11456 the old node. */
11457 new_node->local.local = old_node->local.local;
11458 new_node->externally_visible = old_node->externally_visible;
11459
11460 return new_node;
11461}
11462
11463/* Adjust the return type of the given function to its appropriate
11464 vector counterpart. Returns a simd array to be used throughout the
11465 function as a return value. */
11466
11467static tree
11468simd_clone_adjust_return_type (struct cgraph_node *node)
11469{
11470 tree fndecl = node->decl;
11471 tree orig_rettype = TREE_TYPE (TREE_TYPE (fndecl));
11472 unsigned int veclen;
11473 tree t;
11474
11475 /* Adjust the function return type. */
11476 if (orig_rettype == void_type_node)
11477 return NULL_TREE;
11478 TREE_TYPE (fndecl) = build_distinct_type_copy (TREE_TYPE (fndecl));
11479 if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
11480 || POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl))))
11481 veclen = node->simdclone->vecsize_int;
11482 else
11483 veclen = node->simdclone->vecsize_float;
11484 veclen /= GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl))));
11485 if (veclen > node->simdclone->simdlen)
11486 veclen = node->simdclone->simdlen;
11487 if (veclen == node->simdclone->simdlen)
11488 TREE_TYPE (TREE_TYPE (fndecl))
11489 = build_vector_type (TREE_TYPE (TREE_TYPE (fndecl)),
11490 node->simdclone->simdlen);
11491 else
11492 {
11493 t = build_vector_type (TREE_TYPE (TREE_TYPE (fndecl)), veclen);
11494 t = build_array_type_nelts (t, node->simdclone->simdlen / veclen);
11495 TREE_TYPE (TREE_TYPE (fndecl)) = t;
11496 }
11497 if (!node->definition)
11498 return NULL_TREE;
11499
11500 t = DECL_RESULT (fndecl);
11501 /* Adjust the DECL_RESULT. */
11502 gcc_assert (TREE_TYPE (t) != void_type_node);
11503 TREE_TYPE (t) = TREE_TYPE (TREE_TYPE (fndecl));
11504 relayout_decl (t);
11505
11506 tree atype = build_array_type_nelts (orig_rettype,
11507 node->simdclone->simdlen);
11508 if (veclen != node->simdclone->simdlen)
11509 return build1 (VIEW_CONVERT_EXPR, atype, t);
11510
11511 /* Set up a SIMD array to use as the return value. */
11512 tree retval = create_tmp_var_raw (atype, "retval");
11513 gimple_add_tmp_var (retval);
11514 return retval;
11515}
11516
11517/* Each vector argument has a corresponding array to be used locally
11518 as part of the eventual loop. Create such temporary array and
11519 return it.
11520
11521 PREFIX is the prefix to be used for the temporary.
11522
11523 TYPE is the inner element type.
11524
11525 SIMDLEN is the number of elements. */
11526
11527static tree
11528create_tmp_simd_array (const char *prefix, tree type, int simdlen)
11529{
11530 tree atype = build_array_type_nelts (type, simdlen);
11531 tree avar = create_tmp_var_raw (atype, prefix);
11532 gimple_add_tmp_var (avar);
11533 return avar;
11534}
11535
11536/* Modify the function argument types to their corresponding vector
11537 counterparts if appropriate. Also, create one array for each simd
11538 argument to be used locally when using the function arguments as
11539 part of the loop.
11540
11541 NODE is the function whose arguments are to be adjusted.
11542
11543 Returns an adjustment vector that will be filled describing how the
11544 argument types will be adjusted. */
11545
11546static ipa_parm_adjustment_vec
11547simd_clone_adjust_argument_types (struct cgraph_node *node)
11548{
11549 vec<tree> args;
11550 ipa_parm_adjustment_vec adjustments;
11551
11552 if (node->definition)
11553 args = ipa_get_vector_of_formal_parms (node->decl);
11554 else
11555 args = simd_clone_vector_of_formal_parm_types (node->decl);
11556 adjustments.create (args.length ());
11557 unsigned i, j, veclen;
11558 struct ipa_parm_adjustment adj;
11559 for (i = 0; i < node->simdclone->nargs; ++i)
11560 {
11561 memset (&adj, 0, sizeof (adj));
11562 tree parm = args[i];
11563 tree parm_type = node->definition ? TREE_TYPE (parm) : parm;
11564 adj.base_index = i;
11565 adj.base = parm;
11566
11567 node->simdclone->args[i].orig_arg = node->definition ? parm : NULL_TREE;
11568 node->simdclone->args[i].orig_type = parm_type;
11569
11570 if (node->simdclone->args[i].arg_type != SIMD_CLONE_ARG_TYPE_VECTOR)
11571 {
11572 /* No adjustment necessary for scalar arguments. */
11573 adj.op = IPA_PARM_OP_COPY;
11574 }
11575 else
11576 {
11577 if (INTEGRAL_TYPE_P (parm_type) || POINTER_TYPE_P (parm_type))
11578 veclen = node->simdclone->vecsize_int;
11579 else
11580 veclen = node->simdclone->vecsize_float;
11581 veclen /= GET_MODE_BITSIZE (TYPE_MODE (parm_type));
11582 if (veclen > node->simdclone->simdlen)
11583 veclen = node->simdclone->simdlen;
11584 adj.arg_prefix = "simd";
11585 adj.type = build_vector_type (parm_type, veclen);
11586 node->simdclone->args[i].vector_type = adj.type;
11587 for (j = veclen; j < node->simdclone->simdlen; j += veclen)
11588 {
11589 adjustments.safe_push (adj);
11590 if (j == veclen)
11591 {
11592 memset (&adj, 0, sizeof (adj));
11593 adj.op = IPA_PARM_OP_NEW;
11594 adj.arg_prefix = "simd";
11595 adj.base_index = i;
11596 adj.type = node->simdclone->args[i].vector_type;
11597 }
11598 }
11599
11600 if (node->definition)
11601 node->simdclone->args[i].simd_array
11602 = create_tmp_simd_array (IDENTIFIER_POINTER (DECL_NAME (parm)),
11603 parm_type, node->simdclone->simdlen);
11604 }
11605 adjustments.safe_push (adj);
11606 }
11607
11608 if (node->simdclone->inbranch)
11609 {
11610 tree base_type
11611 = simd_clone_compute_base_data_type (node->simdclone->origin,
11612 node->simdclone);
11613
11614 memset (&adj, 0, sizeof (adj));
11615 adj.op = IPA_PARM_OP_NEW;
11616 adj.arg_prefix = "mask";
11617
11618 adj.base_index = i;
11619 if (INTEGRAL_TYPE_P (base_type) || POINTER_TYPE_P (base_type))
11620 veclen = node->simdclone->vecsize_int;
11621 else
11622 veclen = node->simdclone->vecsize_float;
11623 veclen /= GET_MODE_BITSIZE (TYPE_MODE (base_type));
11624 if (veclen > node->simdclone->simdlen)
11625 veclen = node->simdclone->simdlen;
11626 adj.type = build_vector_type (base_type, veclen);
11627 adjustments.safe_push (adj);
11628
11629 for (j = veclen; j < node->simdclone->simdlen; j += veclen)
11630 adjustments.safe_push (adj);
11631
11632 /* We have previously allocated one extra entry for the mask. Use
11633 it and fill it. */
11634 struct cgraph_simd_clone *sc = node->simdclone;
11635 sc->nargs++;
11636 if (node->definition)
11637 {
11638 sc->args[i].orig_arg
11639 = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL, base_type);
11640 sc->args[i].simd_array
11641 = create_tmp_simd_array ("mask", base_type, sc->simdlen);
11642 }
11643 sc->args[i].orig_type = base_type;
11644 sc->args[i].arg_type = SIMD_CLONE_ARG_TYPE_MASK;
11645 }
11646
11647 if (node->definition)
11648 ipa_modify_formal_parameters (node->decl, adjustments);
11649 else
11650 {
11651 tree new_arg_types = NULL_TREE, new_reversed;
11652 bool last_parm_void = false;
11653 if (args.length () > 0 && args.last () == void_type_node)
11654 last_parm_void = true;
11655
11656 gcc_assert (TYPE_ARG_TYPES (TREE_TYPE (node->decl)));
11657 j = adjustments.length ();
11658 for (i = 0; i < j; i++)
11659 {
11660 struct ipa_parm_adjustment *adj = &adjustments[i];
11661 tree ptype;
11662 if (adj->op == IPA_PARM_OP_COPY)
11663 ptype = args[adj->base_index];
11664 else
11665 ptype = adj->type;
11666 new_arg_types = tree_cons (NULL_TREE, ptype, new_arg_types);
11667 }
11668 new_reversed = nreverse (new_arg_types);
11669 if (last_parm_void)
11670 {
11671 if (new_reversed)
11672 TREE_CHAIN (new_arg_types) = void_list_node;
11673 else
11674 new_reversed = void_list_node;
11675 }
11676
11677 tree new_type = build_distinct_type_copy (TREE_TYPE (node->decl));
11678 TYPE_ARG_TYPES (new_type) = new_reversed;
11679 TREE_TYPE (node->decl) = new_type;
11680
11681 adjustments.release ();
11682 }
11683 args.release ();
11684 return adjustments;
11685}
11686
11687/* Initialize and copy the function arguments in NODE to their
11688 corresponding local simd arrays. Returns a fresh gimple_seq with
11689 the instruction sequence generated. */
11690
11691static gimple_seq
11692simd_clone_init_simd_arrays (struct cgraph_node *node,
11693 ipa_parm_adjustment_vec adjustments)
11694{
11695 gimple_seq seq = NULL;
11696 unsigned i = 0, j = 0, k;
11697
11698 for (tree arg = DECL_ARGUMENTS (node->decl);
11699 arg;
11700 arg = DECL_CHAIN (arg), i++, j++)
11701 {
11702 if (adjustments[j].op == IPA_PARM_OP_COPY)
11703 continue;
11704
11705 node->simdclone->args[i].vector_arg = arg;
11706
11707 tree array = node->simdclone->args[i].simd_array;
11708 if (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg)) == node->simdclone->simdlen)
11709 {
11710 tree ptype = build_pointer_type (TREE_TYPE (TREE_TYPE (array)));
11711 tree ptr = build_fold_addr_expr (array);
11712 tree t = build2 (MEM_REF, TREE_TYPE (arg), ptr,
11713 build_int_cst (ptype, 0));
11714 t = build2 (MODIFY_EXPR, TREE_TYPE (t), t, arg);
11715 gimplify_and_add (t, &seq);
11716 }
11717 else
11718 {
11719 unsigned int simdlen = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg));
11720 tree ptype = build_pointer_type (TREE_TYPE (TREE_TYPE (array)));
11721 for (k = 0; k < node->simdclone->simdlen; k += simdlen)
11722 {
11723 tree ptr = build_fold_addr_expr (array);
11724 int elemsize;
11725 if (k)
11726 {
11727 arg = DECL_CHAIN (arg);
11728 j++;
11729 }
11730 elemsize
11731 = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))));
11732 tree t = build2 (MEM_REF, TREE_TYPE (arg), ptr,
11733 build_int_cst (ptype, k * elemsize));
11734 t = build2 (MODIFY_EXPR, TREE_TYPE (t), t, arg);
11735 gimplify_and_add (t, &seq);
11736 }
11737 }
11738 }
11739 return seq;
11740}
11741
11742/* Callback info for ipa_simd_modify_stmt_ops below. */
11743
11744struct modify_stmt_info {
11745 ipa_parm_adjustment_vec adjustments;
11746 gimple stmt;
11747 /* True if the parent statement was modified by
11748 ipa_simd_modify_stmt_ops. */
11749 bool modified;
11750};
11751
11752/* Callback for walk_gimple_op.
11753
11754 Adjust operands from a given statement as specified in the
11755 adjustments vector in the callback data. */
11756
11757static tree
11758ipa_simd_modify_stmt_ops (tree *tp, int *walk_subtrees, void *data)
11759{
11760 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
2044a4c3
JJ
11761 struct modify_stmt_info *info = (struct modify_stmt_info *) wi->info;
11762 tree *orig_tp = tp;
11763 if (TREE_CODE (*tp) == ADDR_EXPR)
11764 tp = &TREE_OPERAND (*tp, 0);
11765 struct ipa_parm_adjustment *cand = NULL;
11766 if (TREE_CODE (*tp) == PARM_DECL)
11767 cand = ipa_get_adjustment_candidate (&tp, NULL, info->adjustments, true);
11768 else
0136f8f0 11769 {
0136f8f0
AH
11770 if (TYPE_P (*tp))
11771 *walk_subtrees = 0;
0136f8f0 11772 }
0136f8f0 11773
2044a4c3
JJ
11774 tree repl = NULL_TREE;
11775 if (cand)
11776 repl = unshare_expr (cand->new_decl);
11777 else
0136f8f0 11778 {
2044a4c3
JJ
11779 if (tp != orig_tp)
11780 {
11781 *walk_subtrees = 0;
11782 bool modified = info->modified;
11783 info->modified = false;
11784 walk_tree (tp, ipa_simd_modify_stmt_ops, wi, wi->pset);
11785 if (!info->modified)
11786 {
11787 info->modified = modified;
11788 return NULL_TREE;
11789 }
11790 info->modified = modified;
11791 repl = *tp;
11792 }
11793 else
11794 return NULL_TREE;
0136f8f0 11795 }
2044a4c3
JJ
11796
11797 if (tp != orig_tp)
0136f8f0 11798 {
2044a4c3 11799 repl = build_fold_addr_expr (repl);
932b6d61
JJ
11800 gimple stmt;
11801 if (is_gimple_debug (info->stmt))
11802 {
11803 tree vexpr = make_node (DEBUG_EXPR_DECL);
11804 stmt = gimple_build_debug_source_bind (vexpr, repl, NULL);
11805 DECL_ARTIFICIAL (vexpr) = 1;
11806 TREE_TYPE (vexpr) = TREE_TYPE (repl);
11807 DECL_MODE (vexpr) = TYPE_MODE (TREE_TYPE (repl));
11808 repl = vexpr;
11809 }
11810 else
11811 {
11812 stmt = gimple_build_assign (make_ssa_name (TREE_TYPE (repl),
11813 NULL), repl);
11814 repl = gimple_assign_lhs (stmt);
11815 }
2044a4c3 11816 gimple_stmt_iterator gsi = gsi_for_stmt (info->stmt);
0136f8f0 11817 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
2044a4c3 11818 *orig_tp = repl;
0136f8f0 11819 }
2044a4c3 11820 else if (!useless_type_conversion_p (TREE_TYPE (*tp), TREE_TYPE (repl)))
0136f8f0
AH
11821 {
11822 tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*tp), repl);
11823 *tp = vce;
11824 }
11825 else
11826 *tp = repl;
11827
11828 info->modified = true;
0136f8f0
AH
11829 return NULL_TREE;
11830}
11831
11832/* Traverse the function body and perform all modifications as
11833 described in ADJUSTMENTS. At function return, ADJUSTMENTS will be
11834 modified such that the replacement/reduction value will now be an
11835 offset into the corresponding simd_array.
11836
11837 This function will replace all function argument uses with their
11838 corresponding simd array elements, and ajust the return values
11839 accordingly. */
11840
11841static void
11842ipa_simd_modify_function_body (struct cgraph_node *node,
11843 ipa_parm_adjustment_vec adjustments,
11844 tree retval_array, tree iter)
11845{
11846 basic_block bb;
2044a4c3 11847 unsigned int i, j, l;
0136f8f0
AH
11848
11849 /* Re-use the adjustments array, but this time use it to replace
11850 every function argument use to an offset into the corresponding
11851 simd_array. */
11852 for (i = 0, j = 0; i < node->simdclone->nargs; ++i, ++j)
11853 {
11854 if (!node->simdclone->args[i].vector_arg)
11855 continue;
11856
11857 tree basetype = TREE_TYPE (node->simdclone->args[i].orig_arg);
11858 tree vectype = TREE_TYPE (node->simdclone->args[i].vector_arg);
11859 adjustments[j].new_decl
11860 = build4 (ARRAY_REF,
11861 basetype,
11862 node->simdclone->args[i].simd_array,
11863 iter,
11864 NULL_TREE, NULL_TREE);
11865 if (adjustments[j].op == IPA_PARM_OP_NONE
11866 && TYPE_VECTOR_SUBPARTS (vectype) < node->simdclone->simdlen)
11867 j += node->simdclone->simdlen / TYPE_VECTOR_SUBPARTS (vectype) - 1;
11868 }
11869
2044a4c3
JJ
11870 l = adjustments.length ();
11871 for (i = 1; i < num_ssa_names; i++)
11872 {
11873 tree name = ssa_name (i);
11874 if (name
11875 && SSA_NAME_VAR (name)
11876 && TREE_CODE (SSA_NAME_VAR (name)) == PARM_DECL)
11877 {
11878 for (j = 0; j < l; j++)
11879 if (SSA_NAME_VAR (name) == adjustments[j].base
11880 && adjustments[j].new_decl)
11881 {
11882 tree base_var;
11883 if (adjustments[j].new_ssa_base == NULL_TREE)
11884 {
11885 base_var
11886 = copy_var_decl (adjustments[j].base,
11887 DECL_NAME (adjustments[j].base),
11888 TREE_TYPE (adjustments[j].base));
11889 adjustments[j].new_ssa_base = base_var;
11890 }
11891 else
11892 base_var = adjustments[j].new_ssa_base;
11893 if (SSA_NAME_IS_DEFAULT_DEF (name))
11894 {
11895 bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
11896 gimple_stmt_iterator gsi = gsi_after_labels (bb);
11897 tree new_decl = unshare_expr (adjustments[j].new_decl);
11898 set_ssa_default_def (cfun, adjustments[j].base, NULL_TREE);
11899 SET_SSA_NAME_VAR_OR_IDENTIFIER (name, base_var);
11900 SSA_NAME_IS_DEFAULT_DEF (name) = 0;
11901 gimple stmt = gimple_build_assign (name, new_decl);
11902 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
11903 }
11904 else
11905 SET_SSA_NAME_VAR_OR_IDENTIFIER (name, base_var);
11906 }
11907 }
11908 }
11909
0136f8f0
AH
11910 struct modify_stmt_info info;
11911 info.adjustments = adjustments;
11912
11913 FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
11914 {
11915 gimple_stmt_iterator gsi;
11916
11917 gsi = gsi_start_bb (bb);
11918 while (!gsi_end_p (gsi))
11919 {
11920 gimple stmt = gsi_stmt (gsi);
11921 info.stmt = stmt;
11922 struct walk_stmt_info wi;
11923
11924 memset (&wi, 0, sizeof (wi));
11925 info.modified = false;
11926 wi.info = &info;
11927 walk_gimple_op (stmt, ipa_simd_modify_stmt_ops, &wi);
11928
11929 if (gimple_code (stmt) == GIMPLE_RETURN)
11930 {
11931 tree retval = gimple_return_retval (stmt);
11932 if (!retval)
11933 {
11934 gsi_remove (&gsi, true);
11935 continue;
11936 }
11937
11938 /* Replace `return foo' with `retval_array[iter] = foo'. */
11939 tree ref = build4 (ARRAY_REF, TREE_TYPE (retval),
11940 retval_array, iter, NULL, NULL);
11941 stmt = gimple_build_assign (ref, retval);
11942 gsi_replace (&gsi, stmt, true);
11943 info.modified = true;
11944 }
11945
11946 if (info.modified)
11947 {
11948 update_stmt (stmt);
11949 if (maybe_clean_eh_stmt (stmt))
11950 gimple_purge_dead_eh_edges (gimple_bb (stmt));
11951 }
11952 gsi_next (&gsi);
11953 }
11954 }
11955}
11956
11957/* Adjust the argument types in NODE to their appropriate vector
11958 counterparts. */
11959
11960static void
11961simd_clone_adjust (struct cgraph_node *node)
11962{
11963 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
11964
11965 targetm.simd_clone.adjust (node);
11966
11967 tree retval = simd_clone_adjust_return_type (node);
11968 ipa_parm_adjustment_vec adjustments
11969 = simd_clone_adjust_argument_types (node);
11970
11971 push_gimplify_context ();
11972
11973 gimple_seq seq = simd_clone_init_simd_arrays (node, adjustments);
11974
11975 /* Adjust all uses of vector arguments accordingly. Adjust all
11976 return values accordingly. */
11977 tree iter = create_tmp_var (unsigned_type_node, "iter");
11978 tree iter1 = make_ssa_name (iter, NULL);
11979 tree iter2 = make_ssa_name (iter, NULL);
11980 ipa_simd_modify_function_body (node, adjustments, retval, iter1);
11981
11982 /* Initialize the iteration variable. */
11983 basic_block entry_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
11984 basic_block body_bb = split_block_after_labels (entry_bb)->dest;
11985 gimple_stmt_iterator gsi = gsi_after_labels (entry_bb);
11986 /* Insert the SIMD array and iv initialization at function
11987 entry. */
11988 gsi_insert_seq_before (&gsi, seq, GSI_NEW_STMT);
11989
11990 pop_gimplify_context (NULL);
11991
11992 /* Create a new BB right before the original exit BB, to hold the
11993 iteration increment and the condition/branch. */
11994 basic_block orig_exit = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), 0)->src;
11995 basic_block incr_bb = create_empty_bb (orig_exit);
33d9078a 11996 add_bb_to_loop (incr_bb, body_bb->loop_father);
0136f8f0
AH
11997 /* The succ of orig_exit was EXIT_BLOCK_PTR_FOR_FN (cfun), with an empty
11998 flag. Set it now to be a FALLTHRU_EDGE. */
11999 gcc_assert (EDGE_COUNT (orig_exit->succs) == 1);
12000 EDGE_SUCC (orig_exit, 0)->flags |= EDGE_FALLTHRU;
12001 for (unsigned i = 0;
12002 i < EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds); ++i)
12003 {
12004 edge e = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), i);
12005 redirect_edge_succ (e, incr_bb);
12006 }
12007 edge e = make_edge (incr_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
12008 e->probability = REG_BR_PROB_BASE;
12009 gsi = gsi_last_bb (incr_bb);
12010 gimple g = gimple_build_assign_with_ops (PLUS_EXPR, iter2, iter1,
12011 build_int_cst (unsigned_type_node,
12012 1));
12013 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
12014
12015 /* Mostly annotate the loop for the vectorizer (the rest is done below). */
12016 struct loop *loop = alloc_loop ();
b15b5979 12017 cfun->has_force_vectorize_loops = true;
0136f8f0 12018 loop->safelen = node->simdclone->simdlen;
b15b5979 12019 loop->force_vectorize = true;
0136f8f0 12020 loop->header = body_bb;
0136f8f0
AH
12021
12022 /* Branch around the body if the mask applies. */
12023 if (node->simdclone->inbranch)
12024 {
12025 gimple_stmt_iterator gsi = gsi_last_bb (loop->header);
12026 tree mask_array
12027 = node->simdclone->args[node->simdclone->nargs - 1].simd_array;
12028 tree mask = make_ssa_name (TREE_TYPE (TREE_TYPE (mask_array)), NULL);
12029 tree aref = build4 (ARRAY_REF,
12030 TREE_TYPE (TREE_TYPE (mask_array)),
12031 mask_array, iter1,
12032 NULL, NULL);
12033 g = gimple_build_assign (mask, aref);
12034 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
12035 int bitsize = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (aref)));
12036 if (!INTEGRAL_TYPE_P (TREE_TYPE (aref)))
12037 {
12038 aref = build1 (VIEW_CONVERT_EXPR,
12039 build_nonstandard_integer_type (bitsize, 0), mask);
12040 mask = make_ssa_name (TREE_TYPE (aref), NULL);
12041 g = gimple_build_assign (mask, aref);
12042 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
12043 }
12044
12045 g = gimple_build_cond (EQ_EXPR, mask, build_zero_cst (TREE_TYPE (mask)),
12046 NULL, NULL);
12047 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
12048 make_edge (loop->header, incr_bb, EDGE_TRUE_VALUE);
12049 FALLTHRU_EDGE (loop->header)->flags = EDGE_FALSE_VALUE;
12050 }
12051
12052 /* Generate the condition. */
12053 g = gimple_build_cond (LT_EXPR,
12054 iter2,
12055 build_int_cst (unsigned_type_node,
12056 node->simdclone->simdlen),
12057 NULL, NULL);
12058 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
12059 e = split_block (incr_bb, gsi_stmt (gsi));
12060 basic_block latch_bb = e->dest;
33d9078a 12061 basic_block new_exit_bb;
0136f8f0
AH
12062 new_exit_bb = split_block (latch_bb, NULL)->dest;
12063 loop->latch = latch_bb;
12064
12065 redirect_edge_succ (FALLTHRU_EDGE (latch_bb), body_bb);
12066
12067 make_edge (incr_bb, new_exit_bb, EDGE_FALSE_VALUE);
12068 /* The successor of incr_bb is already pointing to latch_bb; just
12069 change the flags.
12070 make_edge (incr_bb, latch_bb, EDGE_TRUE_VALUE); */
12071 FALLTHRU_EDGE (incr_bb)->flags = EDGE_TRUE_VALUE;
12072
12073 gimple phi = create_phi_node (iter1, body_bb);
12074 edge preheader_edge = find_edge (entry_bb, body_bb);
12075 edge latch_edge = single_succ_edge (latch_bb);
12076 add_phi_arg (phi, build_zero_cst (unsigned_type_node), preheader_edge,
12077 UNKNOWN_LOCATION);
12078 add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
12079
12080 /* Generate the new return. */
12081 gsi = gsi_last_bb (new_exit_bb);
12082 if (retval
12083 && TREE_CODE (retval) == VIEW_CONVERT_EXPR
12084 && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
12085 retval = TREE_OPERAND (retval, 0);
12086 else if (retval)
12087 {
12088 retval = build1 (VIEW_CONVERT_EXPR,
12089 TREE_TYPE (TREE_TYPE (node->decl)),
12090 retval);
12091 retval = force_gimple_operand_gsi (&gsi, retval, true, NULL,
12092 false, GSI_CONTINUE_LINKING);
12093 }
12094 g = gimple_build_return (retval);
12095 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
12096
12097 /* Handle aligned clauses by replacing default defs of the aligned
12098 uniform args with __builtin_assume_aligned (arg_N(D), alignment)
12099 lhs. Handle linear by adding PHIs. */
12100 for (unsigned i = 0; i < node->simdclone->nargs; i++)
12101 if (node->simdclone->args[i].alignment
12102 && node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM
12103 && (node->simdclone->args[i].alignment
12104 & (node->simdclone->args[i].alignment - 1)) == 0
12105 && TREE_CODE (TREE_TYPE (node->simdclone->args[i].orig_arg))
12106 == POINTER_TYPE)
12107 {
12108 unsigned int alignment = node->simdclone->args[i].alignment;
12109 tree orig_arg = node->simdclone->args[i].orig_arg;
12110 tree def = ssa_default_def (cfun, orig_arg);
ab04b46e 12111 if (def && !has_zero_uses (def))
0136f8f0
AH
12112 {
12113 tree fn = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
12114 gimple_seq seq = NULL;
12115 bool need_cvt = false;
12116 gimple call
12117 = gimple_build_call (fn, 2, def, size_int (alignment));
12118 g = call;
12119 if (!useless_type_conversion_p (TREE_TYPE (orig_arg),
12120 ptr_type_node))
12121 need_cvt = true;
12122 tree t = make_ssa_name (need_cvt ? ptr_type_node : orig_arg, NULL);
12123 gimple_call_set_lhs (g, t);
12124 gimple_seq_add_stmt_without_update (&seq, g);
12125 if (need_cvt)
12126 {
12127 t = make_ssa_name (orig_arg, NULL);
12128 g = gimple_build_assign_with_ops (NOP_EXPR, t,
12129 gimple_call_lhs (g),
12130 NULL_TREE);
12131 gimple_seq_add_stmt_without_update (&seq, g);
12132 }
12133 gsi_insert_seq_on_edge_immediate
12134 (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
12135
12136 entry_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
12137 int freq = compute_call_stmt_bb_frequency (current_function_decl,
12138 entry_bb);
d52f5295
ML
12139 node->create_edge (cgraph_node::get_create (fn),
12140 call, entry_bb->count, freq);
0136f8f0
AH
12141
12142 imm_use_iterator iter;
12143 use_operand_p use_p;
12144 gimple use_stmt;
12145 tree repl = gimple_get_lhs (g);
12146 FOR_EACH_IMM_USE_STMT (use_stmt, iter, def)
12147 if (is_gimple_debug (use_stmt) || use_stmt == call)
12148 continue;
12149 else
12150 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
12151 SET_USE (use_p, repl);
12152 }
12153 }
12154 else if (node->simdclone->args[i].arg_type
12155 == SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP)
12156 {
12157 tree orig_arg = node->simdclone->args[i].orig_arg;
12158 tree def = ssa_default_def (cfun, orig_arg);
12159 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
12160 || POINTER_TYPE_P (TREE_TYPE (orig_arg)));
ab04b46e 12161 if (def && !has_zero_uses (def))
0136f8f0
AH
12162 {
12163 iter1 = make_ssa_name (orig_arg, NULL);
12164 iter2 = make_ssa_name (orig_arg, NULL);
12165 phi = create_phi_node (iter1, body_bb);
12166 add_phi_arg (phi, def, preheader_edge, UNKNOWN_LOCATION);
12167 add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
12168 enum tree_code code = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
12169 ? PLUS_EXPR : POINTER_PLUS_EXPR;
12170 tree addtype = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
12171 ? TREE_TYPE (orig_arg) : sizetype;
12172 tree addcst
12173 = build_int_cst (addtype, node->simdclone->args[i].linear_step);
12174 g = gimple_build_assign_with_ops (code, iter2, iter1, addcst);
12175 gsi = gsi_last_bb (incr_bb);
12176 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
12177
12178 imm_use_iterator iter;
12179 use_operand_p use_p;
12180 gimple use_stmt;
12181 FOR_EACH_IMM_USE_STMT (use_stmt, iter, def)
12182 if (use_stmt == phi)
12183 continue;
12184 else
12185 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
12186 SET_USE (use_p, iter1);
12187 }
12188 }
12189
12190 calculate_dominance_info (CDI_DOMINATORS);
12191 add_loop (loop, loop->header->loop_father);
12192 update_ssa (TODO_update_ssa);
12193
12194 pop_cfun ();
12195}
12196
12197/* If the function in NODE is tagged as an elemental SIMD function,
12198 create the appropriate SIMD clones. */
12199
12200static void
12201expand_simd_clones (struct cgraph_node *node)
12202{
0136f8f0
AH
12203 tree attr = lookup_attribute ("omp declare simd",
12204 DECL_ATTRIBUTES (node->decl));
e06f9964
JJ
12205 if (attr == NULL_TREE
12206 || node->global.inlined_to
12207 || lookup_attribute ("noclone", DECL_ATTRIBUTES (node->decl)))
0136f8f0 12208 return;
e06f9964 12209
0136f8f0
AH
12210 /* Ignore
12211 #pragma omp declare simd
12212 extern int foo ();
12213 in C, there we don't know the argument types at all. */
12214 if (!node->definition
12215 && TYPE_ARG_TYPES (TREE_TYPE (node->decl)) == NULL_TREE)
12216 return;
12217
12218 do
12219 {
12220 /* Start with parsing the "omp declare simd" attribute(s). */
12221 bool inbranch_clause_specified;
12222 struct cgraph_simd_clone *clone_info
12223 = simd_clone_clauses_extract (node, TREE_VALUE (attr),
12224 &inbranch_clause_specified);
12225 if (clone_info == NULL)
12226 continue;
12227
12228 int orig_simdlen = clone_info->simdlen;
12229 tree base_type = simd_clone_compute_base_data_type (node, clone_info);
12230 /* The target can return 0 (no simd clones should be created),
12231 1 (just one ISA of simd clones should be created) or higher
12232 count of ISA variants. In that case, clone_info is initialized
12233 for the first ISA variant. */
12234 int count
12235 = targetm.simd_clone.compute_vecsize_and_simdlen (node, clone_info,
12236 base_type, 0);
12237 if (count == 0)
12238 continue;
12239
12240 /* Loop over all COUNT ISA variants, and if !INBRANCH_CLAUSE_SPECIFIED,
12241 also create one inbranch and one !inbranch clone of it. */
12242 for (int i = 0; i < count * 2; i++)
12243 {
12244 struct cgraph_simd_clone *clone = clone_info;
12245 if (inbranch_clause_specified && (i & 1) != 0)
12246 continue;
12247
12248 if (i != 0)
12249 {
12250 clone = simd_clone_struct_alloc (clone_info->nargs
0136f8f0
AH
12251 + ((i & 1) != 0));
12252 simd_clone_struct_copy (clone, clone_info);
12253 /* Undo changes targetm.simd_clone.compute_vecsize_and_simdlen
12254 and simd_clone_adjust_argument_types did to the first
12255 clone's info. */
12256 clone->nargs -= clone_info->inbranch;
12257 clone->simdlen = orig_simdlen;
12258 /* And call the target hook again to get the right ISA. */
12259 targetm.simd_clone.compute_vecsize_and_simdlen (node, clone,
12260 base_type,
12261 i / 2);
12262 if ((i & 1) != 0)
12263 clone->inbranch = 1;
12264 }
12265
12266 /* simd_clone_mangle might fail if such a clone has been created
12267 already. */
12268 tree id = simd_clone_mangle (node, clone);
12269 if (id == NULL_TREE)
12270 continue;
12271
12272 /* Only when we are sure we want to create the clone actually
12273 clone the function (or definitions) or create another
12274 extern FUNCTION_DECL (for prototypes without definitions). */
12275 struct cgraph_node *n = simd_clone_create (node);
12276 if (n == NULL)
12277 continue;
12278
12279 n->simdclone = clone;
12280 clone->origin = node;
12281 clone->next_clone = NULL;
12282 if (node->simd_clones == NULL)
12283 {
12284 clone->prev_clone = n;
12285 node->simd_clones = n;
12286 }
12287 else
12288 {
12289 clone->prev_clone = node->simd_clones->simdclone->prev_clone;
12290 clone->prev_clone->simdclone->next_clone = n;
12291 node->simd_clones->simdclone->prev_clone = n;
12292 }
3dafb85c 12293 symtab->change_decl_assembler_name (n->decl, id);
0136f8f0
AH
12294 /* And finally adjust the return type, parameters and for
12295 definitions also function body. */
12296 if (node->definition)
12297 simd_clone_adjust (n);
12298 else
12299 {
12300 simd_clone_adjust_return_type (n);
12301 simd_clone_adjust_argument_types (n);
12302 }
12303 }
12304 }
12305 while ((attr = lookup_attribute ("omp declare simd", TREE_CHAIN (attr))));
12306}
12307
12308/* Entry point for IPA simd clone creation pass. */
12309
12310static unsigned int
12311ipa_omp_simd_clone (void)
12312{
12313 struct cgraph_node *node;
12314 FOR_EACH_FUNCTION (node)
12315 expand_simd_clones (node);
12316 return 0;
12317}
12318
12319namespace {
12320
12321const pass_data pass_data_omp_simd_clone =
12322{
12323 SIMPLE_IPA_PASS, /* type */
12324 "simdclone", /* name */
12325 OPTGROUP_NONE, /* optinfo_flags */
0136f8f0
AH
12326 TV_NONE, /* tv_id */
12327 ( PROP_ssa | PROP_cfg ), /* properties_required */
12328 0, /* properties_provided */
12329 0, /* properties_destroyed */
12330 0, /* todo_flags_start */
12331 0, /* todo_flags_finish */
12332};
12333
12334class pass_omp_simd_clone : public simple_ipa_opt_pass
12335{
12336public:
12337 pass_omp_simd_clone(gcc::context *ctxt)
12338 : simple_ipa_opt_pass(pass_data_omp_simd_clone, ctxt)
12339 {}
12340
12341 /* opt_pass methods: */
1a3d085c 12342 virtual bool gate (function *);
be55bfe6 12343 virtual unsigned int execute (function *) { return ipa_omp_simd_clone (); }
0136f8f0
AH
12344};
12345
1a3d085c
TS
12346bool
12347pass_omp_simd_clone::gate (function *)
12348{
12349 return ((flag_openmp || flag_openmp_simd
12350 || flag_cilkplus
12351 || (in_lto_p && !flag_wpa))
12352 && (targetm.simd_clone.compute_vecsize_and_simdlen != NULL));
12353}
12354
0136f8f0
AH
12355} // anon namespace
12356
12357simple_ipa_opt_pass *
12358make_pass_omp_simd_clone (gcc::context *ctxt)
12359{
12360 return new pass_omp_simd_clone (ctxt);
12361}
27a4cd48 12362
953ff289 12363#include "gt-omp-low.h"