]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/omp-low.c
gcc-plugin.h: Move decls to plugin.h and include it.
[thirdparty/gcc.git] / gcc / omp-low.c
CommitLineData
41dbbb37
TS
1/* Lowering pass for OMP directives. Converts OMP directives into explicit
2 calls to the runtime library (libgomp), data marshalling to implement data
3 sharing and copying clauses, offloading to accelerators, and more.
4
953ff289
DN
5 Contributed by Diego Novillo <dnovillo@redhat.com>
6
5624e564 7 Copyright (C) 2005-2015 Free Software Foundation, Inc.
953ff289
DN
8
9This file is part of GCC.
10
11GCC is free software; you can redistribute it and/or modify it under
12the terms of the GNU General Public License as published by the Free
9dcd6f09 13Software Foundation; either version 3, or (at your option) any later
953ff289
DN
14version.
15
16GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17WARRANTY; without even the implied warranty of MERCHANTABILITY or
18FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19for more details.
20
21You should have received a copy of the GNU General Public License
9dcd6f09
NC
22along with GCC; see the file COPYING3. If not see
23<http://www.gnu.org/licenses/>. */
953ff289
DN
24
25#include "config.h"
26#include "system.h"
27#include "coretypes.h"
28#include "tm.h"
40e23961
MC
29#include "input.h"
30#include "alias.h"
31#include "symtab.h"
953ff289 32#include "tree.h"
40e23961 33#include "fold-const.h"
d8a2d370
DN
34#include "stringpool.h"
35#include "stor-layout.h"
953ff289 36#include "rtl.h"
60393bbc 37#include "predict.h"
60393bbc 38#include "hard-reg-set.h"
60393bbc
AM
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 "plugin-api.h"
60#include "ipa-ref.h"
442b4905
AM
61#include "cgraph.h"
62#include "tree-cfg.h"
63#include "tree-phinodes.h"
64#include "ssa-iterators.h"
65#include "tree-ssanames.h"
66#include "tree-into-ssa.h"
36566b39 67#include "flags.h"
36566b39
PK
68#include "insn-config.h"
69#include "expmed.h"
70#include "dojump.h"
71#include "explow.h"
72#include "calls.h"
73#include "emit-rtl.h"
74#include "varasm.h"
75#include "stmt.h"
d8a2d370 76#include "expr.h"
442b4905 77#include "tree-dfa.h"
7a300452 78#include "tree-ssa.h"
953ff289 79#include "tree-pass.h"
953ff289 80#include "except.h"
6be42dd4 81#include "splay-tree.h"
b0710fe1 82#include "insn-codes.h"
a509ebb5
RL
83#include "optabs.h"
84#include "cfgloop.h"
74bf76ed 85#include "target.h"
ec6fe917 86#include "common/common-target.h"
0645c1a2 87#include "omp-low.h"
4484a35a
AM
88#include "gimple-low.h"
89#include "tree-cfgcleanup.h"
0136f8f0 90#include "pretty-print.h"
c582198b 91#include "alloc-pool.h"
dd912cb8 92#include "symbol-summary.h"
0136f8f0 93#include "ipa-prop.h"
1fe37220 94#include "tree-nested.h"
0136f8f0 95#include "tree-eh.h"
9a771876 96#include "cilk.h"
1f6be682 97#include "context.h"
ec6fe917 98#include "lto-section-names.h"
41dbbb37 99#include "gomp-constants.h"
953ff289 100
726a989a 101
41dbbb37 102/* Lowering of OMP parallel and workshare constructs proceeds in two
953ff289
DN
103 phases. The first phase scans the function looking for OMP statements
104 and then for variables that must be replaced to satisfy data sharing
105 clauses. The second phase expands code for the constructs, as well as
c0220ea4 106 re-gimplifying things when variables have been replaced with complex
953ff289
DN
107 expressions.
108
7ebaeab5 109 Final code generation is done by pass_expand_omp. The flowgraph is
41dbbb37
TS
110 scanned for regions which are then moved to a new
111 function, to be invoked by the thread library, or offloaded. */
953ff289 112
41dbbb37 113/* OMP region information. Every parallel and workshare
0645c1a2
AM
114 directive is enclosed between two markers, the OMP_* directive
115 and a corresponding OMP_RETURN statement. */
116
117struct omp_region
118{
119 /* The enclosing region. */
120 struct omp_region *outer;
121
122 /* First child region. */
123 struct omp_region *inner;
124
125 /* Next peer region. */
126 struct omp_region *next;
127
128 /* Block containing the omp directive as its last stmt. */
129 basic_block entry;
130
131 /* Block containing the OMP_RETURN as its last stmt. */
132 basic_block exit;
133
134 /* Block containing the OMP_CONTINUE as its last stmt. */
135 basic_block cont;
136
137 /* If this is a combined parallel+workshare region, this is a list
138 of additional arguments needed by the combined parallel+workshare
139 library call. */
140 vec<tree, va_gc> *ws_args;
141
142 /* The code for the omp directive of this region. */
143 enum gimple_code type;
144
145 /* Schedule kind, only used for OMP_FOR type regions. */
146 enum omp_clause_schedule_kind sched_kind;
147
148 /* True if this is a combined parallel+workshare region. */
149 bool is_combined_parallel;
150};
151
41dbbb37
TS
152/* Levels of parallelism as defined by OpenACC. Increasing numbers
153 correspond to deeper loop nesting levels. */
154#define MASK_GANG 1
155#define MASK_WORKER 2
156#define MASK_VECTOR 4
157
953ff289
DN
158/* Context structure. Used to store information about each parallel
159 directive in the code. */
160
161typedef struct omp_context
162{
163 /* This field must be at the beginning, as we do "inheritance": Some
164 callback functions for tree-inline.c (e.g., omp_copy_decl)
165 receive a copy_body_data pointer that is up-casted to an
166 omp_context pointer. */
167 copy_body_data cb;
168
169 /* The tree of contexts corresponding to the encountered constructs. */
170 struct omp_context *outer;
726a989a 171 gimple stmt;
953ff289 172
b8698a0f 173 /* Map variables to fields in a structure that allows communication
953ff289
DN
174 between sending and receiving threads. */
175 splay_tree field_map;
176 tree record_type;
177 tree sender_decl;
178 tree receiver_decl;
179
a68ab351
JJ
180 /* These are used just by task contexts, if task firstprivate fn is
181 needed. srecord_type is used to communicate from the thread
182 that encountered the task construct to task firstprivate fn,
183 record_type is allocated by GOMP_task, initialized by task firstprivate
184 fn and passed to the task body fn. */
185 splay_tree sfield_map;
186 tree srecord_type;
187
953ff289
DN
188 /* A chain of variables to add to the top-level block surrounding the
189 construct. In the case of a parallel, this is in the child function. */
190 tree block_vars;
191
41dbbb37
TS
192 /* A map of reduction pointer variables. For accelerators, each
193 reduction variable is replaced with an array. Each thread, in turn,
194 is assigned to a slot on that array. */
195 splay_tree reduction_map;
196
acf0174b
JJ
197 /* Label to which GOMP_cancel{,llation_point} and explicit and implicit
198 barriers should jump to during omplower pass. */
199 tree cancel_label;
200
953ff289
DN
201 /* What to do with variables with implicitly determined sharing
202 attributes. */
203 enum omp_clause_default_kind default_kind;
204
205 /* Nesting depth of this context. Used to beautify error messages re
206 invalid gotos. The outermost ctx is depth 1, with depth 0 being
207 reserved for the main body of the function. */
208 int depth;
209
953ff289
DN
210 /* True if this parallel directive is nested within another. */
211 bool is_nested;
acf0174b
JJ
212
213 /* True if this construct can be cancelled. */
214 bool cancellable;
41dbbb37
TS
215
216 /* For OpenACC loops, a mask of gang, worker and vector used at
217 levels below this one. */
218 int gwv_below;
219 /* For OpenACC loops, a mask of gang, worker and vector used at
220 this level and above. For parallel and kernels clauses, a mask
221 indicating which of num_gangs/num_workers/num_vectors was used. */
222 int gwv_this;
953ff289
DN
223} omp_context;
224
41dbbb37
TS
225/* A structure holding the elements of:
226 for (V = N1; V cond N2; V += STEP) [...] */
953ff289 227
a68ab351
JJ
228struct omp_for_data_loop
229{
230 tree v, n1, n2, step;
231 enum tree_code cond_code;
232};
233
50674e96 234/* A structure describing the main elements of a parallel loop. */
953ff289 235
50674e96 236struct omp_for_data
953ff289 237{
a68ab351 238 struct omp_for_data_loop loop;
726a989a 239 tree chunk_size;
538dd0b7 240 gomp_for *for_stmt;
a68ab351
JJ
241 tree pre, iter_type;
242 int collapse;
953ff289
DN
243 bool have_nowait, have_ordered;
244 enum omp_clause_schedule_kind sched_kind;
a68ab351 245 struct omp_for_data_loop *loops;
953ff289
DN
246};
247
50674e96 248
953ff289 249static splay_tree all_contexts;
a68ab351 250static int taskreg_nesting_level;
acf0174b 251static int target_nesting_level;
0645c1a2 252static struct omp_region *root_omp_region;
a68ab351 253static bitmap task_shared_vars;
5771c391 254static vec<omp_context *> taskreg_contexts;
953ff289 255
26127932 256static void scan_omp (gimple_seq *, omp_context *);
726a989a
RB
257static tree scan_omp_1_op (tree *, int *, void *);
258
259#define WALK_SUBSTMTS \
260 case GIMPLE_BIND: \
261 case GIMPLE_TRY: \
262 case GIMPLE_CATCH: \
263 case GIMPLE_EH_FILTER: \
0a35513e 264 case GIMPLE_TRANSACTION: \
726a989a
RB
265 /* The sub-statements for these should be walked. */ \
266 *handled_ops_p = false; \
267 break;
268
41dbbb37
TS
269/* Helper function to get the name of the array containing the partial
270 reductions for OpenACC reductions. */
271static const char *
272oacc_get_reduction_array_id (tree node)
273{
274 const char *id = IDENTIFIER_POINTER (DECL_NAME (node));
275 int len = strlen ("OACC") + strlen (id);
276 char *temp_name = XALLOCAVEC (char, len + 1);
277 snprintf (temp_name, len + 1, "OACC%s", id);
278 return IDENTIFIER_POINTER (get_identifier (temp_name));
279}
280
281/* Determine the number of threads OpenACC threads used to determine the
282 size of the array of partial reductions. Currently, this is num_gangs
283 * vector_length. This value may be different than GOACC_GET_NUM_THREADS,
284 because it is independed of the device used. */
285
286static tree
287oacc_max_threads (omp_context *ctx)
288{
289 tree nthreads, vector_length, gangs, clauses;
290
291 gangs = fold_convert (sizetype, integer_one_node);
292 vector_length = gangs;
293
294 /* The reduction clause may be nested inside a loop directive.
295 Scan for the innermost vector_length clause. */
296 for (omp_context *oc = ctx; oc; oc = oc->outer)
297 {
298 if (gimple_code (oc->stmt) != GIMPLE_OMP_TARGET
299 || (gimple_omp_target_kind (oc->stmt)
300 != GF_OMP_TARGET_KIND_OACC_PARALLEL))
301 continue;
302
303 clauses = gimple_omp_target_clauses (oc->stmt);
304
305 vector_length = find_omp_clause (clauses, OMP_CLAUSE_VECTOR_LENGTH);
306 if (vector_length)
307 vector_length = fold_convert_loc (OMP_CLAUSE_LOCATION (vector_length),
308 sizetype,
309 OMP_CLAUSE_VECTOR_LENGTH_EXPR
310 (vector_length));
311 else
312 vector_length = fold_convert (sizetype, integer_one_node);
313
314 gangs = find_omp_clause (clauses, OMP_CLAUSE_NUM_GANGS);
315 if (gangs)
316 gangs = fold_convert_loc (OMP_CLAUSE_LOCATION (gangs), sizetype,
317 OMP_CLAUSE_NUM_GANGS_EXPR (gangs));
318 else
319 gangs = fold_convert (sizetype, integer_one_node);
320
321 break;
322 }
323
324 nthreads = fold_build2 (MULT_EXPR, sizetype, gangs, vector_length);
325
326 return nthreads;
327}
328
ec6fe917
IV
329/* Holds offload tables with decls. */
330vec<tree, va_gc> *offload_funcs, *offload_vars;
331
726a989a
RB
332/* Convenience function for calling scan_omp_1_op on tree operands. */
333
334static inline tree
335scan_omp_op (tree *tp, omp_context *ctx)
336{
337 struct walk_stmt_info wi;
338
339 memset (&wi, 0, sizeof (wi));
340 wi.info = ctx;
341 wi.want_locations = true;
342
343 return walk_tree (tp, scan_omp_1_op, &wi, NULL);
344}
345
355a7673 346static void lower_omp (gimple_seq *, omp_context *);
8ca5b2a2
JJ
347static tree lookup_decl_in_outer_ctx (tree, omp_context *);
348static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
953ff289 349
41dbbb37 350/* Find an OMP clause of type KIND within CLAUSES. */
953ff289 351
917948d3 352tree
e0c68ce9 353find_omp_clause (tree clauses, enum omp_clause_code kind)
953ff289
DN
354{
355 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
aaf46ef9 356 if (OMP_CLAUSE_CODE (clauses) == kind)
953ff289
DN
357 return clauses;
358
359 return NULL_TREE;
360}
361
362/* Return true if CTX is for an omp parallel. */
363
364static inline bool
365is_parallel_ctx (omp_context *ctx)
366{
726a989a 367 return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL;
953ff289
DN
368}
369
50674e96 370
a68ab351
JJ
371/* Return true if CTX is for an omp task. */
372
373static inline bool
374is_task_ctx (omp_context *ctx)
375{
726a989a 376 return gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
a68ab351
JJ
377}
378
379
380/* Return true if CTX is for an omp parallel or omp task. */
381
382static inline bool
383is_taskreg_ctx (omp_context *ctx)
384{
726a989a
RB
385 return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL
386 || gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
a68ab351
JJ
387}
388
389
50674e96 390/* Return true if REGION is a combined parallel+workshare region. */
953ff289
DN
391
392static inline bool
50674e96
DN
393is_combined_parallel (struct omp_region *region)
394{
395 return region->is_combined_parallel;
396}
397
398
399/* Extract the header elements of parallel loop FOR_STMT and store
400 them into *FD. */
401
402static void
538dd0b7 403extract_omp_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
a68ab351 404 struct omp_for_data_loop *loops)
50674e96 405{
a68ab351
JJ
406 tree t, var, *collapse_iter, *collapse_count;
407 tree count = NULL_TREE, iter_type = long_integer_type_node;
408 struct omp_for_data_loop *loop;
409 int i;
410 struct omp_for_data_loop dummy_loop;
db3927fb 411 location_t loc = gimple_location (for_stmt);
0aadce73 412 bool simd = gimple_omp_for_kind (for_stmt) & GF_OMP_FOR_SIMD;
acf0174b
JJ
413 bool distribute = gimple_omp_for_kind (for_stmt)
414 == GF_OMP_FOR_KIND_DISTRIBUTE;
50674e96
DN
415
416 fd->for_stmt = for_stmt;
417 fd->pre = NULL;
726a989a 418 fd->collapse = gimple_omp_for_collapse (for_stmt);
a68ab351
JJ
419 if (fd->collapse > 1)
420 fd->loops = loops;
421 else
422 fd->loops = &fd->loop;
50674e96 423
acf0174b
JJ
424 fd->have_nowait = distribute || simd;
425 fd->have_ordered = false;
50674e96
DN
426 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
427 fd->chunk_size = NULL_TREE;
9a771876
JJ
428 if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_CILKFOR)
429 fd->sched_kind = OMP_CLAUSE_SCHEDULE_CILKFOR;
a68ab351
JJ
430 collapse_iter = NULL;
431 collapse_count = NULL;
50674e96 432
726a989a 433 for (t = gimple_omp_for_clauses (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
aaf46ef9 434 switch (OMP_CLAUSE_CODE (t))
50674e96
DN
435 {
436 case OMP_CLAUSE_NOWAIT:
437 fd->have_nowait = true;
438 break;
439 case OMP_CLAUSE_ORDERED:
440 fd->have_ordered = true;
441 break;
442 case OMP_CLAUSE_SCHEDULE:
acf0174b 443 gcc_assert (!distribute);
50674e96
DN
444 fd->sched_kind = OMP_CLAUSE_SCHEDULE_KIND (t);
445 fd->chunk_size = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t);
446 break;
acf0174b
JJ
447 case OMP_CLAUSE_DIST_SCHEDULE:
448 gcc_assert (distribute);
449 fd->chunk_size = OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (t);
450 break;
a68ab351
JJ
451 case OMP_CLAUSE_COLLAPSE:
452 if (fd->collapse > 1)
453 {
454 collapse_iter = &OMP_CLAUSE_COLLAPSE_ITERVAR (t);
455 collapse_count = &OMP_CLAUSE_COLLAPSE_COUNT (t);
456 }
34f2124e 457 break;
50674e96
DN
458 default:
459 break;
460 }
461
a68ab351
JJ
462 /* FIXME: for now map schedule(auto) to schedule(static).
463 There should be analysis to determine whether all iterations
464 are approximately the same amount of work (then schedule(static)
1cbc62c0 465 is best) or if it varies (then schedule(dynamic,N) is better). */
a68ab351
JJ
466 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_AUTO)
467 {
468 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
469 gcc_assert (fd->chunk_size == NULL);
470 }
471 gcc_assert (fd->collapse == 1 || collapse_iter != NULL);
50674e96
DN
472 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
473 gcc_assert (fd->chunk_size == NULL);
474 else if (fd->chunk_size == NULL)
475 {
476 /* We only need to compute a default chunk size for ordered
477 static loops and dynamic loops. */
a68ab351 478 if (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
acf0174b 479 || fd->have_ordered)
50674e96
DN
480 fd->chunk_size = (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
481 ? integer_zero_node : integer_one_node;
482 }
a68ab351
JJ
483
484 for (i = 0; i < fd->collapse; i++)
485 {
486 if (fd->collapse == 1)
487 loop = &fd->loop;
488 else if (loops != NULL)
489 loop = loops + i;
490 else
491 loop = &dummy_loop;
492
726a989a 493 loop->v = gimple_omp_for_index (for_stmt, i);
a68ab351
JJ
494 gcc_assert (SSA_VAR_P (loop->v));
495 gcc_assert (TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
496 || TREE_CODE (TREE_TYPE (loop->v)) == POINTER_TYPE);
497 var = TREE_CODE (loop->v) == SSA_NAME ? SSA_NAME_VAR (loop->v) : loop->v;
726a989a 498 loop->n1 = gimple_omp_for_initial (for_stmt, i);
a68ab351 499
726a989a
RB
500 loop->cond_code = gimple_omp_for_cond (for_stmt, i);
501 loop->n2 = gimple_omp_for_final (for_stmt, i);
a68ab351
JJ
502 switch (loop->cond_code)
503 {
504 case LT_EXPR:
505 case GT_EXPR:
506 break;
c02065fc
AH
507 case NE_EXPR:
508 gcc_assert (gimple_omp_for_kind (for_stmt)
9a771876
JJ
509 == GF_OMP_FOR_KIND_CILKSIMD
510 || (gimple_omp_for_kind (for_stmt)
511 == GF_OMP_FOR_KIND_CILKFOR));
c02065fc 512 break;
a68ab351
JJ
513 case LE_EXPR:
514 if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
5d49b6a7 515 loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, 1);
a68ab351 516 else
db3927fb
AH
517 loop->n2 = fold_build2_loc (loc,
518 PLUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
a68ab351
JJ
519 build_int_cst (TREE_TYPE (loop->n2), 1));
520 loop->cond_code = LT_EXPR;
521 break;
522 case GE_EXPR:
523 if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
5d49b6a7 524 loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, -1);
a68ab351 525 else
db3927fb
AH
526 loop->n2 = fold_build2_loc (loc,
527 MINUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
a68ab351
JJ
528 build_int_cst (TREE_TYPE (loop->n2), 1));
529 loop->cond_code = GT_EXPR;
530 break;
531 default:
532 gcc_unreachable ();
533 }
534
726a989a 535 t = gimple_omp_for_incr (for_stmt, i);
a68ab351
JJ
536 gcc_assert (TREE_OPERAND (t, 0) == var);
537 switch (TREE_CODE (t))
538 {
539 case PLUS_EXPR:
a68ab351
JJ
540 loop->step = TREE_OPERAND (t, 1);
541 break;
56099f00
RG
542 case POINTER_PLUS_EXPR:
543 loop->step = fold_convert (ssizetype, TREE_OPERAND (t, 1));
544 break;
a68ab351
JJ
545 case MINUS_EXPR:
546 loop->step = TREE_OPERAND (t, 1);
db3927fb
AH
547 loop->step = fold_build1_loc (loc,
548 NEGATE_EXPR, TREE_TYPE (loop->step),
a68ab351
JJ
549 loop->step);
550 break;
551 default:
552 gcc_unreachable ();
553 }
554
acf0174b
JJ
555 if (simd
556 || (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
557 && !fd->have_ordered))
74bf76ed
JJ
558 {
559 if (fd->collapse == 1)
560 iter_type = TREE_TYPE (loop->v);
561 else if (i == 0
562 || TYPE_PRECISION (iter_type)
563 < TYPE_PRECISION (TREE_TYPE (loop->v)))
564 iter_type
565 = build_nonstandard_integer_type
acf0174b 566 (TYPE_PRECISION (TREE_TYPE (loop->v)), 1);
74bf76ed
JJ
567 }
568 else if (iter_type != long_long_unsigned_type_node)
a68ab351
JJ
569 {
570 if (POINTER_TYPE_P (TREE_TYPE (loop->v)))
571 iter_type = long_long_unsigned_type_node;
572 else if (TYPE_UNSIGNED (TREE_TYPE (loop->v))
573 && TYPE_PRECISION (TREE_TYPE (loop->v))
574 >= TYPE_PRECISION (iter_type))
575 {
576 tree n;
577
578 if (loop->cond_code == LT_EXPR)
db3927fb
AH
579 n = fold_build2_loc (loc,
580 PLUS_EXPR, TREE_TYPE (loop->v),
a68ab351
JJ
581 loop->n2, loop->step);
582 else
583 n = loop->n1;
584 if (TREE_CODE (n) != INTEGER_CST
585 || tree_int_cst_lt (TYPE_MAX_VALUE (iter_type), n))
586 iter_type = long_long_unsigned_type_node;
587 }
588 else if (TYPE_PRECISION (TREE_TYPE (loop->v))
589 > TYPE_PRECISION (iter_type))
590 {
591 tree n1, n2;
592
593 if (loop->cond_code == LT_EXPR)
594 {
595 n1 = loop->n1;
db3927fb
AH
596 n2 = fold_build2_loc (loc,
597 PLUS_EXPR, TREE_TYPE (loop->v),
a68ab351
JJ
598 loop->n2, loop->step);
599 }
600 else
601 {
db3927fb
AH
602 n1 = fold_build2_loc (loc,
603 MINUS_EXPR, TREE_TYPE (loop->v),
a68ab351
JJ
604 loop->n2, loop->step);
605 n2 = loop->n1;
606 }
607 if (TREE_CODE (n1) != INTEGER_CST
608 || TREE_CODE (n2) != INTEGER_CST
609 || !tree_int_cst_lt (TYPE_MIN_VALUE (iter_type), n1)
610 || !tree_int_cst_lt (n2, TYPE_MAX_VALUE (iter_type)))
611 iter_type = long_long_unsigned_type_node;
612 }
613 }
614
615 if (collapse_count && *collapse_count == NULL)
616 {
5a0f4dd3
JJ
617 t = fold_binary (loop->cond_code, boolean_type_node,
618 fold_convert (TREE_TYPE (loop->v), loop->n1),
619 fold_convert (TREE_TYPE (loop->v), loop->n2));
620 if (t && integer_zerop (t))
621 count = build_zero_cst (long_long_unsigned_type_node);
622 else if ((i == 0 || count != NULL_TREE)
623 && TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
624 && TREE_CONSTANT (loop->n1)
625 && TREE_CONSTANT (loop->n2)
626 && TREE_CODE (loop->step) == INTEGER_CST)
a68ab351
JJ
627 {
628 tree itype = TREE_TYPE (loop->v);
629
630 if (POINTER_TYPE_P (itype))
96f9265a 631 itype = signed_type_for (itype);
a68ab351 632 t = build_int_cst (itype, (loop->cond_code == LT_EXPR ? -1 : 1));
db3927fb
AH
633 t = fold_build2_loc (loc,
634 PLUS_EXPR, itype,
635 fold_convert_loc (loc, itype, loop->step), t);
636 t = fold_build2_loc (loc, PLUS_EXPR, itype, t,
637 fold_convert_loc (loc, itype, loop->n2));
638 t = fold_build2_loc (loc, MINUS_EXPR, itype, t,
639 fold_convert_loc (loc, itype, loop->n1));
a68ab351 640 if (TYPE_UNSIGNED (itype) && loop->cond_code == GT_EXPR)
db3927fb
AH
641 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
642 fold_build1_loc (loc, NEGATE_EXPR, itype, t),
643 fold_build1_loc (loc, NEGATE_EXPR, itype,
644 fold_convert_loc (loc, itype,
645 loop->step)));
a68ab351 646 else
db3927fb
AH
647 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
648 fold_convert_loc (loc, itype, loop->step));
649 t = fold_convert_loc (loc, long_long_unsigned_type_node, t);
a68ab351 650 if (count != NULL_TREE)
db3927fb
AH
651 count = fold_build2_loc (loc,
652 MULT_EXPR, long_long_unsigned_type_node,
a68ab351
JJ
653 count, t);
654 else
655 count = t;
656 if (TREE_CODE (count) != INTEGER_CST)
657 count = NULL_TREE;
658 }
5a0f4dd3 659 else if (count && !integer_zerop (count))
a68ab351
JJ
660 count = NULL_TREE;
661 }
662 }
663
74bf76ed 664 if (count
acf0174b
JJ
665 && !simd
666 && (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
667 || fd->have_ordered))
a68ab351
JJ
668 {
669 if (!tree_int_cst_lt (count, TYPE_MAX_VALUE (long_integer_type_node)))
670 iter_type = long_long_unsigned_type_node;
671 else
672 iter_type = long_integer_type_node;
673 }
674 else if (collapse_iter && *collapse_iter != NULL)
675 iter_type = TREE_TYPE (*collapse_iter);
676 fd->iter_type = iter_type;
677 if (collapse_iter && *collapse_iter == NULL)
678 *collapse_iter = create_tmp_var (iter_type, ".iter");
679 if (collapse_count && *collapse_count == NULL)
680 {
681 if (count)
db3927fb 682 *collapse_count = fold_convert_loc (loc, iter_type, count);
a68ab351
JJ
683 else
684 *collapse_count = create_tmp_var (iter_type, ".count");
685 }
686
687 if (fd->collapse > 1)
688 {
689 fd->loop.v = *collapse_iter;
690 fd->loop.n1 = build_int_cst (TREE_TYPE (fd->loop.v), 0);
691 fd->loop.n2 = *collapse_count;
692 fd->loop.step = build_int_cst (TREE_TYPE (fd->loop.v), 1);
693 fd->loop.cond_code = LT_EXPR;
694 }
41dbbb37
TS
695
696 /* For OpenACC loops, force a chunk size of one, as this avoids the default
697 scheduling where several subsequent iterations are being executed by the
698 same thread. */
699 if (gimple_omp_for_kind (for_stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
700 {
701 gcc_assert (fd->chunk_size == NULL_TREE);
702 fd->chunk_size = build_int_cst (TREE_TYPE (fd->loop.v), 1);
703 }
50674e96
DN
704}
705
706
707/* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
708 is the immediate dominator of PAR_ENTRY_BB, return true if there
709 are no data dependencies that would prevent expanding the parallel
710 directive at PAR_ENTRY_BB as a combined parallel+workshare region.
711
712 When expanding a combined parallel+workshare region, the call to
713 the child function may need additional arguments in the case of
726a989a
RB
714 GIMPLE_OMP_FOR regions. In some cases, these arguments are
715 computed out of variables passed in from the parent to the child
716 via 'struct .omp_data_s'. For instance:
50674e96
DN
717
718 #pragma omp parallel for schedule (guided, i * 4)
719 for (j ...)
720
721 Is lowered into:
722
723 # BLOCK 2 (PAR_ENTRY_BB)
724 .omp_data_o.i = i;
725 #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
b8698a0f 726
50674e96
DN
727 # BLOCK 3 (WS_ENTRY_BB)
728 .omp_data_i = &.omp_data_o;
729 D.1667 = .omp_data_i->i;
730 D.1598 = D.1667 * 4;
731 #pragma omp for schedule (guided, D.1598)
732
733 When we outline the parallel region, the call to the child function
734 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
735 that value is computed *after* the call site. So, in principle we
736 cannot do the transformation.
737
738 To see whether the code in WS_ENTRY_BB blocks the combined
739 parallel+workshare call, we collect all the variables used in the
726a989a 740 GIMPLE_OMP_FOR header check whether they appear on the LHS of any
50674e96
DN
741 statement in WS_ENTRY_BB. If so, then we cannot emit the combined
742 call.
743
744 FIXME. If we had the SSA form built at this point, we could merely
745 hoist the code in block 3 into block 2 and be done with it. But at
746 this point we don't have dataflow information and though we could
747 hack something up here, it is really not worth the aggravation. */
748
749static bool
0f900dfa 750workshare_safe_to_combine_p (basic_block ws_entry_bb)
50674e96
DN
751{
752 struct omp_for_data fd;
0f900dfa 753 gimple ws_stmt = last_stmt (ws_entry_bb);
50674e96 754
726a989a 755 if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
50674e96
DN
756 return true;
757
726a989a 758 gcc_assert (gimple_code (ws_stmt) == GIMPLE_OMP_FOR);
50674e96 759
538dd0b7 760 extract_omp_for_data (as_a <gomp_for *> (ws_stmt), &fd, NULL);
a68ab351
JJ
761
762 if (fd.collapse > 1 && TREE_CODE (fd.loop.n2) != INTEGER_CST)
763 return false;
764 if (fd.iter_type != long_integer_type_node)
765 return false;
50674e96
DN
766
767 /* FIXME. We give up too easily here. If any of these arguments
768 are not constants, they will likely involve variables that have
769 been mapped into fields of .omp_data_s for sharing with the child
770 function. With appropriate data flow, it would be possible to
771 see through this. */
a68ab351
JJ
772 if (!is_gimple_min_invariant (fd.loop.n1)
773 || !is_gimple_min_invariant (fd.loop.n2)
774 || !is_gimple_min_invariant (fd.loop.step)
50674e96
DN
775 || (fd.chunk_size && !is_gimple_min_invariant (fd.chunk_size)))
776 return false;
777
778 return true;
779}
780
781
782/* Collect additional arguments needed to emit a combined
783 parallel+workshare call. WS_STMT is the workshare directive being
784 expanded. */
785
9771b263 786static vec<tree, va_gc> *
acf0174b 787get_ws_args_for (gimple par_stmt, gimple ws_stmt)
50674e96
DN
788{
789 tree t;
db3927fb 790 location_t loc = gimple_location (ws_stmt);
9771b263 791 vec<tree, va_gc> *ws_args;
50674e96 792
538dd0b7 793 if (gomp_for *for_stmt = dyn_cast <gomp_for *> (ws_stmt))
50674e96
DN
794 {
795 struct omp_for_data fd;
acf0174b 796 tree n1, n2;
50674e96 797
538dd0b7 798 extract_omp_for_data (for_stmt, &fd, NULL);
acf0174b
JJ
799 n1 = fd.loop.n1;
800 n2 = fd.loop.n2;
801
538dd0b7 802 if (gimple_omp_for_combined_into_p (for_stmt))
acf0174b
JJ
803 {
804 tree innerc
805 = find_omp_clause (gimple_omp_parallel_clauses (par_stmt),
806 OMP_CLAUSE__LOOPTEMP_);
807 gcc_assert (innerc);
808 n1 = OMP_CLAUSE_DECL (innerc);
809 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
810 OMP_CLAUSE__LOOPTEMP_);
811 gcc_assert (innerc);
812 n2 = OMP_CLAUSE_DECL (innerc);
813 }
50674e96 814
9771b263 815 vec_alloc (ws_args, 3 + (fd.chunk_size != 0));
50674e96 816
acf0174b 817 t = fold_convert_loc (loc, long_integer_type_node, n1);
9771b263 818 ws_args->quick_push (t);
50674e96 819
acf0174b 820 t = fold_convert_loc (loc, long_integer_type_node, n2);
9771b263 821 ws_args->quick_push (t);
50674e96 822
3bb06db4 823 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.step);
9771b263 824 ws_args->quick_push (t);
3bb06db4
NF
825
826 if (fd.chunk_size)
827 {
828 t = fold_convert_loc (loc, long_integer_type_node, fd.chunk_size);
9771b263 829 ws_args->quick_push (t);
3bb06db4 830 }
50674e96
DN
831
832 return ws_args;
833 }
726a989a 834 else if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
50674e96 835 {
e5c95afe 836 /* Number of sections is equal to the number of edges from the
726a989a
RB
837 GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
838 the exit of the sections region. */
839 basic_block bb = single_succ (gimple_bb (ws_stmt));
e5c95afe 840 t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
9771b263
DN
841 vec_alloc (ws_args, 1);
842 ws_args->quick_push (t);
3bb06db4 843 return ws_args;
50674e96
DN
844 }
845
846 gcc_unreachable ();
847}
848
849
850/* Discover whether REGION is a combined parallel+workshare region. */
851
852static void
853determine_parallel_type (struct omp_region *region)
953ff289 854{
50674e96
DN
855 basic_block par_entry_bb, par_exit_bb;
856 basic_block ws_entry_bb, ws_exit_bb;
857
d3c673c7 858 if (region == NULL || region->inner == NULL
e5c95afe
ZD
859 || region->exit == NULL || region->inner->exit == NULL
860 || region->inner->cont == NULL)
50674e96
DN
861 return;
862
863 /* We only support parallel+for and parallel+sections. */
726a989a
RB
864 if (region->type != GIMPLE_OMP_PARALLEL
865 || (region->inner->type != GIMPLE_OMP_FOR
866 && region->inner->type != GIMPLE_OMP_SECTIONS))
50674e96
DN
867 return;
868
869 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
870 WS_EXIT_BB -> PAR_EXIT_BB. */
777f7f9a
RH
871 par_entry_bb = region->entry;
872 par_exit_bb = region->exit;
873 ws_entry_bb = region->inner->entry;
874 ws_exit_bb = region->inner->exit;
50674e96
DN
875
876 if (single_succ (par_entry_bb) == ws_entry_bb
877 && single_succ (ws_exit_bb) == par_exit_bb
0f900dfa 878 && workshare_safe_to_combine_p (ws_entry_bb)
726a989a 879 && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb))
69f1837b
JJ
880 || (last_and_only_stmt (ws_entry_bb)
881 && last_and_only_stmt (par_exit_bb))))
50674e96 882 {
acf0174b 883 gimple par_stmt = last_stmt (par_entry_bb);
726a989a 884 gimple ws_stmt = last_stmt (ws_entry_bb);
777f7f9a 885
726a989a 886 if (region->inner->type == GIMPLE_OMP_FOR)
50674e96
DN
887 {
888 /* If this is a combined parallel loop, we need to determine
889 whether or not to use the combined library calls. There
890 are two cases where we do not apply the transformation:
891 static loops and any kind of ordered loop. In the first
892 case, we already open code the loop so there is no need
893 to do anything else. In the latter case, the combined
894 parallel loop call would still need extra synchronization
895 to implement ordered semantics, so there would not be any
896 gain in using the combined call. */
726a989a 897 tree clauses = gimple_omp_for_clauses (ws_stmt);
50674e96
DN
898 tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
899 if (c == NULL
900 || OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_STATIC
901 || find_omp_clause (clauses, OMP_CLAUSE_ORDERED))
902 {
903 region->is_combined_parallel = false;
904 region->inner->is_combined_parallel = false;
905 return;
906 }
907 }
908
909 region->is_combined_parallel = true;
910 region->inner->is_combined_parallel = true;
acf0174b 911 region->ws_args = get_ws_args_for (par_stmt, ws_stmt);
50674e96 912 }
953ff289
DN
913}
914
50674e96 915
953ff289
DN
916/* Return true if EXPR is variable sized. */
917
918static inline bool
22ea9ec0 919is_variable_sized (const_tree expr)
953ff289
DN
920{
921 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
922}
923
924/* Return true if DECL is a reference type. */
925
926static inline bool
927is_reference (tree decl)
928{
929 return lang_hooks.decls.omp_privatize_by_reference (decl);
930}
931
41dbbb37
TS
932/* Return the type of a decl. If the decl is reference type,
933 return its base type. */
934static inline tree
935get_base_type (tree decl)
936{
937 tree type = TREE_TYPE (decl);
938 if (is_reference (decl))
939 type = TREE_TYPE (type);
940 return type;
941}
942
943/* Lookup variables. The "maybe" form
953ff289
DN
944 allows for the variable form to not have been entered, otherwise we
945 assert that the variable must have been entered. */
946
947static inline tree
948lookup_decl (tree var, omp_context *ctx)
949{
b787e7a2 950 tree *n = ctx->cb.decl_map->get (var);
6be42dd4 951 return *n;
953ff289
DN
952}
953
954static inline tree
7c8f7639 955maybe_lookup_decl (const_tree var, omp_context *ctx)
953ff289 956{
b787e7a2 957 tree *n = ctx->cb.decl_map->get (const_cast<tree> (var));
6be42dd4 958 return n ? *n : NULL_TREE;
953ff289
DN
959}
960
961static inline tree
962lookup_field (tree var, omp_context *ctx)
963{
964 splay_tree_node n;
965 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
966 return (tree) n->value;
967}
968
a68ab351
JJ
969static inline tree
970lookup_sfield (tree var, omp_context *ctx)
971{
972 splay_tree_node n;
973 n = splay_tree_lookup (ctx->sfield_map
974 ? ctx->sfield_map : ctx->field_map,
975 (splay_tree_key) var);
976 return (tree) n->value;
977}
978
953ff289
DN
979static inline tree
980maybe_lookup_field (tree var, omp_context *ctx)
981{
982 splay_tree_node n;
983 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
984 return n ? (tree) n->value : NULL_TREE;
985}
986
41dbbb37
TS
987static inline tree
988lookup_oacc_reduction (const char *id, omp_context *ctx)
989{
990 splay_tree_node n;
991 n = splay_tree_lookup (ctx->reduction_map, (splay_tree_key) id);
992 return (tree) n->value;
993}
994
995static inline tree
996maybe_lookup_oacc_reduction (tree var, omp_context *ctx)
997{
998 splay_tree_node n = NULL;
999 if (ctx->reduction_map)
1000 n = splay_tree_lookup (ctx->reduction_map, (splay_tree_key) var);
1001 return n ? (tree) n->value : NULL_TREE;
1002}
1003
7c8f7639
JJ
1004/* Return true if DECL should be copied by pointer. SHARED_CTX is
1005 the parallel context if DECL is to be shared. */
953ff289
DN
1006
1007static bool
a68ab351 1008use_pointer_for_field (tree decl, omp_context *shared_ctx)
953ff289
DN
1009{
1010 if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
1011 return true;
1012
6fc0bb99 1013 /* We can only use copy-in/copy-out semantics for shared variables
953ff289 1014 when we know the value is not accessible from an outer scope. */
7c8f7639 1015 if (shared_ctx)
953ff289 1016 {
41dbbb37
TS
1017 gcc_assert (!is_gimple_omp_oacc (shared_ctx->stmt));
1018
953ff289
DN
1019 /* ??? Trivially accessible from anywhere. But why would we even
1020 be passing an address in this case? Should we simply assert
1021 this to be false, or should we have a cleanup pass that removes
1022 these from the list of mappings? */
1023 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
1024 return true;
1025
1026 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
1027 without analyzing the expression whether or not its location
1028 is accessible to anyone else. In the case of nested parallel
1029 regions it certainly may be. */
077b0dfb 1030 if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
953ff289
DN
1031 return true;
1032
1033 /* Do not use copy-in/copy-out for variables that have their
1034 address taken. */
1035 if (TREE_ADDRESSABLE (decl))
1036 return true;
7c8f7639 1037
6d840d99
JJ
1038 /* lower_send_shared_vars only uses copy-in, but not copy-out
1039 for these. */
1040 if (TREE_READONLY (decl)
1041 || ((TREE_CODE (decl) == RESULT_DECL
1042 || TREE_CODE (decl) == PARM_DECL)
1043 && DECL_BY_REFERENCE (decl)))
1044 return false;
1045
7c8f7639
JJ
1046 /* Disallow copy-in/out in nested parallel if
1047 decl is shared in outer parallel, otherwise
1048 each thread could store the shared variable
1049 in its own copy-in location, making the
1050 variable no longer really shared. */
6d840d99 1051 if (shared_ctx->is_nested)
7c8f7639
JJ
1052 {
1053 omp_context *up;
1054
1055 for (up = shared_ctx->outer; up; up = up->outer)
d9c194cb 1056 if (is_taskreg_ctx (up) && maybe_lookup_decl (decl, up))
7c8f7639
JJ
1057 break;
1058
d9c194cb 1059 if (up)
7c8f7639
JJ
1060 {
1061 tree c;
1062
726a989a 1063 for (c = gimple_omp_taskreg_clauses (up->stmt);
7c8f7639
JJ
1064 c; c = OMP_CLAUSE_CHAIN (c))
1065 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
1066 && OMP_CLAUSE_DECL (c) == decl)
1067 break;
1068
1069 if (c)
25142650 1070 goto maybe_mark_addressable_and_ret;
7c8f7639
JJ
1071 }
1072 }
a68ab351 1073
6d840d99 1074 /* For tasks avoid using copy-in/out. As tasks can be
a68ab351
JJ
1075 deferred or executed in different thread, when GOMP_task
1076 returns, the task hasn't necessarily terminated. */
6d840d99 1077 if (is_task_ctx (shared_ctx))
a68ab351 1078 {
25142650
JJ
1079 tree outer;
1080 maybe_mark_addressable_and_ret:
1081 outer = maybe_lookup_decl_in_outer_ctx (decl, shared_ctx);
a68ab351
JJ
1082 if (is_gimple_reg (outer))
1083 {
1084 /* Taking address of OUTER in lower_send_shared_vars
1085 might need regimplification of everything that uses the
1086 variable. */
1087 if (!task_shared_vars)
1088 task_shared_vars = BITMAP_ALLOC (NULL);
1089 bitmap_set_bit (task_shared_vars, DECL_UID (outer));
1090 TREE_ADDRESSABLE (outer) = 1;
1091 }
1092 return true;
1093 }
953ff289
DN
1094 }
1095
1096 return false;
1097}
1098
917948d3
ZD
1099/* Construct a new automatic decl similar to VAR. */
1100
1101static tree
1102omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
1103{
1104 tree copy = copy_var_decl (var, name, type);
1105
1106 DECL_CONTEXT (copy) = current_function_decl;
910ad8de 1107 DECL_CHAIN (copy) = ctx->block_vars;
953ff289
DN
1108 ctx->block_vars = copy;
1109
1110 return copy;
1111}
1112
1113static tree
1114omp_copy_decl_1 (tree var, omp_context *ctx)
1115{
1116 return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
1117}
1118
a9a58711
JJ
1119/* Build COMPONENT_REF and set TREE_THIS_VOLATILE and TREE_READONLY on it
1120 as appropriate. */
1121static tree
1122omp_build_component_ref (tree obj, tree field)
1123{
1124 tree ret = build3 (COMPONENT_REF, TREE_TYPE (field), obj, field, NULL);
1125 if (TREE_THIS_VOLATILE (field))
1126 TREE_THIS_VOLATILE (ret) |= 1;
1127 if (TREE_READONLY (field))
1128 TREE_READONLY (ret) |= 1;
1129 return ret;
1130}
1131
953ff289
DN
1132/* Build tree nodes to access the field for VAR on the receiver side. */
1133
1134static tree
1135build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
1136{
1137 tree x, field = lookup_field (var, ctx);
1138
1139 /* If the receiver record type was remapped in the child function,
1140 remap the field into the new record type. */
1141 x = maybe_lookup_field (field, ctx);
1142 if (x != NULL)
1143 field = x;
1144
70f34814 1145 x = build_simple_mem_ref (ctx->receiver_decl);
a9a58711 1146 x = omp_build_component_ref (x, field);
953ff289 1147 if (by_ref)
70f34814 1148 x = build_simple_mem_ref (x);
953ff289
DN
1149
1150 return x;
1151}
1152
1153/* Build tree nodes to access VAR in the scope outer to CTX. In the case
1154 of a parallel, this is a component reference; for workshare constructs
1155 this is some variable. */
1156
1157static tree
1158build_outer_var_ref (tree var, omp_context *ctx)
1159{
1160 tree x;
1161
8ca5b2a2 1162 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
953ff289
DN
1163 x = var;
1164 else if (is_variable_sized (var))
1165 {
1166 x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
1167 x = build_outer_var_ref (x, ctx);
70f34814 1168 x = build_simple_mem_ref (x);
953ff289 1169 }
a68ab351 1170 else if (is_taskreg_ctx (ctx))
953ff289 1171 {
7c8f7639 1172 bool by_ref = use_pointer_for_field (var, NULL);
953ff289
DN
1173 x = build_receiver_ref (var, by_ref, ctx);
1174 }
74bf76ed 1175 else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
0aadce73 1176 && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
74bf76ed
JJ
1177 {
1178 /* #pragma omp simd isn't a worksharing construct, and can reference even
1179 private vars in its linear etc. clauses. */
1180 x = NULL_TREE;
1181 if (ctx->outer && is_taskreg_ctx (ctx))
1182 x = lookup_decl (var, ctx->outer);
1183 else if (ctx->outer)
f3b331d1 1184 x = maybe_lookup_decl_in_outer_ctx (var, ctx);
74bf76ed
JJ
1185 if (x == NULL_TREE)
1186 x = var;
1187 }
953ff289
DN
1188 else if (ctx->outer)
1189 x = lookup_decl (var, ctx->outer);
eeb1d9e0
JJ
1190 else if (is_reference (var))
1191 /* This can happen with orphaned constructs. If var is reference, it is
1192 possible it is shared and as such valid. */
1193 x = var;
953ff289
DN
1194 else
1195 gcc_unreachable ();
1196
1197 if (is_reference (var))
70f34814 1198 x = build_simple_mem_ref (x);
953ff289
DN
1199
1200 return x;
1201}
1202
1203/* Build tree nodes to access the field for VAR on the sender side. */
1204
1205static tree
1206build_sender_ref (tree var, omp_context *ctx)
1207{
a68ab351 1208 tree field = lookup_sfield (var, ctx);
a9a58711 1209 return omp_build_component_ref (ctx->sender_decl, field);
953ff289
DN
1210}
1211
1212/* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
1213
1214static void
a68ab351 1215install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
953ff289 1216{
a68ab351 1217 tree field, type, sfield = NULL_TREE;
953ff289 1218
a68ab351
JJ
1219 gcc_assert ((mask & 1) == 0
1220 || !splay_tree_lookup (ctx->field_map, (splay_tree_key) var));
1221 gcc_assert ((mask & 2) == 0 || !ctx->sfield_map
1222 || !splay_tree_lookup (ctx->sfield_map, (splay_tree_key) var));
41dbbb37
TS
1223 gcc_assert ((mask & 3) == 3
1224 || !is_gimple_omp_oacc (ctx->stmt));
953ff289
DN
1225
1226 type = TREE_TYPE (var);
acf0174b
JJ
1227 if (mask & 4)
1228 {
1229 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
1230 type = build_pointer_type (build_pointer_type (type));
1231 }
1232 else if (by_ref)
953ff289 1233 type = build_pointer_type (type);
a68ab351
JJ
1234 else if ((mask & 3) == 1 && is_reference (var))
1235 type = TREE_TYPE (type);
953ff289 1236
c2255bc4
AH
1237 field = build_decl (DECL_SOURCE_LOCATION (var),
1238 FIELD_DECL, DECL_NAME (var), type);
953ff289
DN
1239
1240 /* Remember what variable this field was created for. This does have a
1241 side effect of making dwarf2out ignore this member, so for helpful
1242 debugging we clear it later in delete_omp_context. */
1243 DECL_ABSTRACT_ORIGIN (field) = var;
a68ab351
JJ
1244 if (type == TREE_TYPE (var))
1245 {
1246 DECL_ALIGN (field) = DECL_ALIGN (var);
1247 DECL_USER_ALIGN (field) = DECL_USER_ALIGN (var);
1248 TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (var);
1249 }
1250 else
1251 DECL_ALIGN (field) = TYPE_ALIGN (type);
953ff289 1252
a68ab351
JJ
1253 if ((mask & 3) == 3)
1254 {
1255 insert_field_into_struct (ctx->record_type, field);
1256 if (ctx->srecord_type)
1257 {
c2255bc4
AH
1258 sfield = build_decl (DECL_SOURCE_LOCATION (var),
1259 FIELD_DECL, DECL_NAME (var), type);
a68ab351
JJ
1260 DECL_ABSTRACT_ORIGIN (sfield) = var;
1261 DECL_ALIGN (sfield) = DECL_ALIGN (field);
1262 DECL_USER_ALIGN (sfield) = DECL_USER_ALIGN (field);
1263 TREE_THIS_VOLATILE (sfield) = TREE_THIS_VOLATILE (field);
1264 insert_field_into_struct (ctx->srecord_type, sfield);
1265 }
1266 }
1267 else
1268 {
1269 if (ctx->srecord_type == NULL_TREE)
1270 {
1271 tree t;
1272
1273 ctx->srecord_type = lang_hooks.types.make_type (RECORD_TYPE);
1274 ctx->sfield_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1275 for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
1276 {
c2255bc4
AH
1277 sfield = build_decl (DECL_SOURCE_LOCATION (var),
1278 FIELD_DECL, DECL_NAME (t), TREE_TYPE (t));
a68ab351
JJ
1279 DECL_ABSTRACT_ORIGIN (sfield) = DECL_ABSTRACT_ORIGIN (t);
1280 insert_field_into_struct (ctx->srecord_type, sfield);
1281 splay_tree_insert (ctx->sfield_map,
1282 (splay_tree_key) DECL_ABSTRACT_ORIGIN (t),
1283 (splay_tree_value) sfield);
1284 }
1285 }
1286 sfield = field;
1287 insert_field_into_struct ((mask & 1) ? ctx->record_type
1288 : ctx->srecord_type, field);
1289 }
953ff289 1290
a68ab351
JJ
1291 if (mask & 1)
1292 splay_tree_insert (ctx->field_map, (splay_tree_key) var,
1293 (splay_tree_value) field);
1294 if ((mask & 2) && ctx->sfield_map)
1295 splay_tree_insert (ctx->sfield_map, (splay_tree_key) var,
1296 (splay_tree_value) sfield);
953ff289
DN
1297}
1298
1299static tree
1300install_var_local (tree var, omp_context *ctx)
1301{
1302 tree new_var = omp_copy_decl_1 (var, ctx);
1303 insert_decl_map (&ctx->cb, var, new_var);
1304 return new_var;
1305}
1306
1307/* Adjust the replacement for DECL in CTX for the new context. This means
1308 copying the DECL_VALUE_EXPR, and fixing up the type. */
1309
1310static void
1311fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
1312{
1313 tree new_decl, size;
1314
1315 new_decl = lookup_decl (decl, ctx);
1316
1317 TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
1318
1319 if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
1320 && DECL_HAS_VALUE_EXPR_P (decl))
1321 {
1322 tree ve = DECL_VALUE_EXPR (decl);
726a989a 1323 walk_tree (&ve, copy_tree_body_r, &ctx->cb, NULL);
953ff289
DN
1324 SET_DECL_VALUE_EXPR (new_decl, ve);
1325 DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
1326 }
1327
1328 if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
1329 {
1330 size = remap_decl (DECL_SIZE (decl), &ctx->cb);
1331 if (size == error_mark_node)
1332 size = TYPE_SIZE (TREE_TYPE (new_decl));
1333 DECL_SIZE (new_decl) = size;
1334
1335 size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
1336 if (size == error_mark_node)
1337 size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
1338 DECL_SIZE_UNIT (new_decl) = size;
1339 }
1340}
1341
1342/* The callback for remap_decl. Search all containing contexts for a
1343 mapping of the variable; this avoids having to duplicate the splay
1344 tree ahead of time. We know a mapping doesn't already exist in the
1345 given context. Create new mappings to implement default semantics. */
1346
1347static tree
1348omp_copy_decl (tree var, copy_body_data *cb)
1349{
1350 omp_context *ctx = (omp_context *) cb;
1351 tree new_var;
1352
953ff289
DN
1353 if (TREE_CODE (var) == LABEL_DECL)
1354 {
c2255bc4 1355 new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
50674e96 1356 DECL_CONTEXT (new_var) = current_function_decl;
953ff289
DN
1357 insert_decl_map (&ctx->cb, var, new_var);
1358 return new_var;
1359 }
1360
a68ab351 1361 while (!is_taskreg_ctx (ctx))
953ff289
DN
1362 {
1363 ctx = ctx->outer;
1364 if (ctx == NULL)
1365 return var;
1366 new_var = maybe_lookup_decl (var, ctx);
1367 if (new_var)
1368 return new_var;
1369 }
1370
8ca5b2a2
JJ
1371 if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
1372 return var;
1373
953ff289
DN
1374 return error_mark_node;
1375}
1376
50674e96 1377
50674e96
DN
1378/* Debugging dumps for parallel regions. */
1379void dump_omp_region (FILE *, struct omp_region *, int);
1380void debug_omp_region (struct omp_region *);
1381void debug_all_omp_regions (void);
1382
1383/* Dump the parallel region tree rooted at REGION. */
1384
1385void
1386dump_omp_region (FILE *file, struct omp_region *region, int indent)
1387{
777f7f9a 1388 fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
726a989a 1389 gimple_code_name[region->type]);
50674e96
DN
1390
1391 if (region->inner)
1392 dump_omp_region (file, region->inner, indent + 4);
1393
777f7f9a
RH
1394 if (region->cont)
1395 {
726a989a 1396 fprintf (file, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent, "",
777f7f9a
RH
1397 region->cont->index);
1398 }
b8698a0f 1399
50674e96 1400 if (region->exit)
726a989a 1401 fprintf (file, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent, "",
777f7f9a 1402 region->exit->index);
50674e96 1403 else
777f7f9a 1404 fprintf (file, "%*s[no exit marker]\n", indent, "");
50674e96
DN
1405
1406 if (region->next)
777f7f9a 1407 dump_omp_region (file, region->next, indent);
50674e96
DN
1408}
1409
24e47c76 1410DEBUG_FUNCTION void
50674e96
DN
1411debug_omp_region (struct omp_region *region)
1412{
1413 dump_omp_region (stderr, region, 0);
1414}
1415
24e47c76 1416DEBUG_FUNCTION void
50674e96
DN
1417debug_all_omp_regions (void)
1418{
1419 dump_omp_region (stderr, root_omp_region, 0);
1420}
1421
1422
1423/* Create a new parallel region starting at STMT inside region PARENT. */
1424
0645c1a2 1425static struct omp_region *
726a989a
RB
1426new_omp_region (basic_block bb, enum gimple_code type,
1427 struct omp_region *parent)
50674e96 1428{
d3bfe4de 1429 struct omp_region *region = XCNEW (struct omp_region);
50674e96
DN
1430
1431 region->outer = parent;
777f7f9a
RH
1432 region->entry = bb;
1433 region->type = type;
50674e96
DN
1434
1435 if (parent)
1436 {
1437 /* This is a nested region. Add it to the list of inner
1438 regions in PARENT. */
1439 region->next = parent->inner;
1440 parent->inner = region;
1441 }
777f7f9a 1442 else
50674e96
DN
1443 {
1444 /* This is a toplevel region. Add it to the list of toplevel
1445 regions in ROOT_OMP_REGION. */
1446 region->next = root_omp_region;
1447 root_omp_region = region;
1448 }
777f7f9a
RH
1449
1450 return region;
1451}
1452
1453/* Release the memory associated with the region tree rooted at REGION. */
1454
1455static void
1456free_omp_region_1 (struct omp_region *region)
1457{
1458 struct omp_region *i, *n;
1459
1460 for (i = region->inner; i ; i = n)
50674e96 1461 {
777f7f9a
RH
1462 n = i->next;
1463 free_omp_region_1 (i);
50674e96
DN
1464 }
1465
777f7f9a
RH
1466 free (region);
1467}
50674e96 1468
777f7f9a
RH
1469/* Release the memory for the entire omp region tree. */
1470
1471void
1472free_omp_regions (void)
1473{
1474 struct omp_region *r, *n;
1475 for (r = root_omp_region; r ; r = n)
1476 {
1477 n = r->next;
1478 free_omp_region_1 (r);
1479 }
1480 root_omp_region = NULL;
50674e96
DN
1481}
1482
1483
953ff289
DN
1484/* Create a new context, with OUTER_CTX being the surrounding context. */
1485
1486static omp_context *
726a989a 1487new_omp_context (gimple stmt, omp_context *outer_ctx)
953ff289
DN
1488{
1489 omp_context *ctx = XCNEW (omp_context);
1490
1491 splay_tree_insert (all_contexts, (splay_tree_key) stmt,
1492 (splay_tree_value) ctx);
1493 ctx->stmt = stmt;
1494
1495 if (outer_ctx)
1496 {
1497 ctx->outer = outer_ctx;
1498 ctx->cb = outer_ctx->cb;
1499 ctx->cb.block = NULL;
1500 ctx->depth = outer_ctx->depth + 1;
41dbbb37 1501 ctx->reduction_map = outer_ctx->reduction_map;
953ff289
DN
1502 }
1503 else
1504 {
1505 ctx->cb.src_fn = current_function_decl;
1506 ctx->cb.dst_fn = current_function_decl;
d52f5295 1507 ctx->cb.src_node = cgraph_node::get (current_function_decl);
fe660d7b 1508 gcc_checking_assert (ctx->cb.src_node);
953ff289
DN
1509 ctx->cb.dst_node = ctx->cb.src_node;
1510 ctx->cb.src_cfun = cfun;
1511 ctx->cb.copy_decl = omp_copy_decl;
1d65f45c 1512 ctx->cb.eh_lp_nr = 0;
953ff289
DN
1513 ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
1514 ctx->depth = 1;
1515 }
1516
b787e7a2 1517 ctx->cb.decl_map = new hash_map<tree, tree>;
953ff289
DN
1518
1519 return ctx;
1520}
1521
726a989a 1522static gimple_seq maybe_catch_exception (gimple_seq);
2368a460
JJ
1523
1524/* Finalize task copyfn. */
1525
1526static void
538dd0b7 1527finalize_task_copyfn (gomp_task *task_stmt)
2368a460
JJ
1528{
1529 struct function *child_cfun;
af16bc76 1530 tree child_fn;
355a7673 1531 gimple_seq seq = NULL, new_seq;
538dd0b7 1532 gbind *bind;
2368a460 1533
726a989a 1534 child_fn = gimple_omp_task_copy_fn (task_stmt);
2368a460
JJ
1535 if (child_fn == NULL_TREE)
1536 return;
1537
1538 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
d7ed20db 1539 DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
2368a460 1540
2368a460 1541 push_cfun (child_cfun);
3ad065ef 1542 bind = gimplify_body (child_fn, false);
726a989a
RB
1543 gimple_seq_add_stmt (&seq, bind);
1544 new_seq = maybe_catch_exception (seq);
1545 if (new_seq != seq)
1546 {
1547 bind = gimple_build_bind (NULL, new_seq, NULL);
355a7673 1548 seq = NULL;
726a989a
RB
1549 gimple_seq_add_stmt (&seq, bind);
1550 }
1551 gimple_set_body (child_fn, seq);
2368a460 1552 pop_cfun ();
2368a460 1553
d7ed20db 1554 /* Inform the callgraph about the new function. */
d52f5295 1555 cgraph_node::add_new_function (child_fn, false);
a79b7ec5 1556 cgraph_node::get (child_fn)->parallelized_function = 1;
2368a460
JJ
1557}
1558
953ff289
DN
1559/* Destroy a omp_context data structures. Called through the splay tree
1560 value delete callback. */
1561
1562static void
1563delete_omp_context (splay_tree_value value)
1564{
1565 omp_context *ctx = (omp_context *) value;
1566
b787e7a2 1567 delete ctx->cb.decl_map;
953ff289
DN
1568
1569 if (ctx->field_map)
1570 splay_tree_delete (ctx->field_map);
a68ab351
JJ
1571 if (ctx->sfield_map)
1572 splay_tree_delete (ctx->sfield_map);
3713412b
JJ
1573 /* Reduction map is copied to nested contexts, so only delete it in the
1574 owner. */
41dbbb37 1575 if (ctx->reduction_map
3713412b
JJ
1576 && gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
1577 && is_gimple_omp_offloaded (ctx->stmt)
1578 && is_gimple_omp_oacc (ctx->stmt))
41dbbb37 1579 splay_tree_delete (ctx->reduction_map);
953ff289
DN
1580
1581 /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
1582 it produces corrupt debug information. */
1583 if (ctx->record_type)
1584 {
1585 tree t;
910ad8de 1586 for (t = TYPE_FIELDS (ctx->record_type); t ; t = DECL_CHAIN (t))
953ff289
DN
1587 DECL_ABSTRACT_ORIGIN (t) = NULL;
1588 }
a68ab351
JJ
1589 if (ctx->srecord_type)
1590 {
1591 tree t;
910ad8de 1592 for (t = TYPE_FIELDS (ctx->srecord_type); t ; t = DECL_CHAIN (t))
a68ab351
JJ
1593 DECL_ABSTRACT_ORIGIN (t) = NULL;
1594 }
953ff289 1595
2368a460 1596 if (is_task_ctx (ctx))
538dd0b7 1597 finalize_task_copyfn (as_a <gomp_task *> (ctx->stmt));
2368a460 1598
953ff289
DN
1599 XDELETE (ctx);
1600}
1601
1602/* Fix up RECEIVER_DECL with a type that has been remapped to the child
1603 context. */
1604
1605static void
1606fixup_child_record_type (omp_context *ctx)
1607{
1608 tree f, type = ctx->record_type;
1609
1610 /* ??? It isn't sufficient to just call remap_type here, because
1611 variably_modified_type_p doesn't work the way we expect for
1612 record types. Testing each field for whether it needs remapping
1613 and creating a new record by hand works, however. */
910ad8de 1614 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
953ff289
DN
1615 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
1616 break;
1617 if (f)
1618 {
1619 tree name, new_fields = NULL;
1620
1621 type = lang_hooks.types.make_type (RECORD_TYPE);
1622 name = DECL_NAME (TYPE_NAME (ctx->record_type));
c2255bc4
AH
1623 name = build_decl (DECL_SOURCE_LOCATION (ctx->receiver_decl),
1624 TYPE_DECL, name, type);
953ff289
DN
1625 TYPE_NAME (type) = name;
1626
910ad8de 1627 for (f = TYPE_FIELDS (ctx->record_type); f ; f = DECL_CHAIN (f))
953ff289
DN
1628 {
1629 tree new_f = copy_node (f);
1630 DECL_CONTEXT (new_f) = type;
1631 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
910ad8de 1632 DECL_CHAIN (new_f) = new_fields;
726a989a
RB
1633 walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &ctx->cb, NULL);
1634 walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r,
1635 &ctx->cb, NULL);
1636 walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
1637 &ctx->cb, NULL);
953ff289
DN
1638 new_fields = new_f;
1639
1640 /* Arrange to be able to look up the receiver field
1641 given the sender field. */
1642 splay_tree_insert (ctx->field_map, (splay_tree_key) f,
1643 (splay_tree_value) new_f);
1644 }
1645 TYPE_FIELDS (type) = nreverse (new_fields);
1646 layout_type (type);
1647 }
1648
a2a2fe4b
RB
1649 TREE_TYPE (ctx->receiver_decl)
1650 = build_qualified_type (build_reference_type (type), TYPE_QUAL_RESTRICT);
953ff289
DN
1651}
1652
1653/* Instantiate decls as necessary in CTX to satisfy the data sharing
1654 specified by CLAUSES. */
1655
1656static void
1657scan_sharing_clauses (tree clauses, omp_context *ctx)
1658{
1659 tree c, decl;
1660 bool scan_array_reductions = false;
1661
1662 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1663 {
1664 bool by_ref;
1665
aaf46ef9 1666 switch (OMP_CLAUSE_CODE (c))
953ff289
DN
1667 {
1668 case OMP_CLAUSE_PRIVATE:
1669 decl = OMP_CLAUSE_DECL (c);
a68ab351
JJ
1670 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
1671 goto do_private;
1672 else if (!is_variable_sized (decl))
953ff289
DN
1673 install_var_local (decl, ctx);
1674 break;
1675
1676 case OMP_CLAUSE_SHARED:
9cf32741 1677 decl = OMP_CLAUSE_DECL (c);
acf0174b
JJ
1678 /* Ignore shared directives in teams construct. */
1679 if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
9cf32741
JJ
1680 {
1681 /* Global variables don't need to be copied,
1682 the receiver side will use them directly. */
1683 tree odecl = maybe_lookup_decl_in_outer_ctx (decl, ctx);
1684 if (is_global_var (odecl))
1685 break;
1686 insert_decl_map (&ctx->cb, decl, odecl);
1687 break;
1688 }
a68ab351 1689 gcc_assert (is_taskreg_ctx (ctx));
5da250fc
JJ
1690 gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl))
1691 || !is_variable_sized (decl));
8ca5b2a2
JJ
1692 /* Global variables don't need to be copied,
1693 the receiver side will use them directly. */
1694 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1695 break;
a68ab351 1696 by_ref = use_pointer_for_field (decl, ctx);
953ff289
DN
1697 if (! TREE_READONLY (decl)
1698 || TREE_ADDRESSABLE (decl)
1699 || by_ref
1700 || is_reference (decl))
1701 {
a68ab351 1702 install_var_field (decl, by_ref, 3, ctx);
953ff289
DN
1703 install_var_local (decl, ctx);
1704 break;
1705 }
1706 /* We don't need to copy const scalar vars back. */
aaf46ef9 1707 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
953ff289
DN
1708 goto do_private;
1709
1710 case OMP_CLAUSE_LASTPRIVATE:
1711 /* Let the corresponding firstprivate clause create
1712 the variable. */
1713 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1714 break;
1715 /* FALLTHRU */
1716
1717 case OMP_CLAUSE_FIRSTPRIVATE:
41dbbb37
TS
1718 if (is_gimple_omp_oacc (ctx->stmt))
1719 {
1720 sorry ("clause not supported yet");
1721 break;
1722 }
1723 /* FALLTHRU */
953ff289 1724 case OMP_CLAUSE_REDUCTION:
74bf76ed 1725 case OMP_CLAUSE_LINEAR:
953ff289
DN
1726 decl = OMP_CLAUSE_DECL (c);
1727 do_private:
1728 if (is_variable_sized (decl))
953ff289 1729 {
a68ab351
JJ
1730 if (is_task_ctx (ctx))
1731 install_var_field (decl, false, 1, ctx);
1732 break;
1733 }
1734 else if (is_taskreg_ctx (ctx))
1735 {
1736 bool global
1737 = is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx));
7c8f7639 1738 by_ref = use_pointer_for_field (decl, NULL);
a68ab351
JJ
1739
1740 if (is_task_ctx (ctx)
1741 && (global || by_ref || is_reference (decl)))
1742 {
1743 install_var_field (decl, false, 1, ctx);
1744 if (!global)
1745 install_var_field (decl, by_ref, 2, ctx);
1746 }
1747 else if (!global)
1748 install_var_field (decl, by_ref, 3, ctx);
953ff289
DN
1749 }
1750 install_var_local (decl, ctx);
41dbbb37
TS
1751 if (is_gimple_omp_oacc (ctx->stmt)
1752 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
1753 {
1754 /* Create a decl for the reduction array. */
1755 tree var = OMP_CLAUSE_DECL (c);
1756 tree type = get_base_type (var);
1757 tree ptype = build_pointer_type (type);
1758 tree array = create_tmp_var (ptype,
1759 oacc_get_reduction_array_id (var));
1760 omp_context *c = (ctx->field_map ? ctx : ctx->outer);
1761 install_var_field (array, true, 3, c);
1762 install_var_local (array, c);
1763
1764 /* Insert it into the current context. */
1765 splay_tree_insert (ctx->reduction_map, (splay_tree_key)
1766 oacc_get_reduction_array_id (var),
1767 (splay_tree_value) array);
1768 splay_tree_insert (ctx->reduction_map,
1769 (splay_tree_key) array,
1770 (splay_tree_value) array);
1771 }
953ff289
DN
1772 break;
1773
acf0174b
JJ
1774 case OMP_CLAUSE__LOOPTEMP_:
1775 gcc_assert (is_parallel_ctx (ctx));
1776 decl = OMP_CLAUSE_DECL (c);
1777 install_var_field (decl, false, 3, ctx);
1778 install_var_local (decl, ctx);
1779 break;
1780
953ff289 1781 case OMP_CLAUSE_COPYPRIVATE:
953ff289
DN
1782 case OMP_CLAUSE_COPYIN:
1783 decl = OMP_CLAUSE_DECL (c);
7c8f7639 1784 by_ref = use_pointer_for_field (decl, NULL);
a68ab351 1785 install_var_field (decl, by_ref, 3, ctx);
953ff289
DN
1786 break;
1787
1788 case OMP_CLAUSE_DEFAULT:
1789 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
1790 break;
1791
20906c66 1792 case OMP_CLAUSE_FINAL:
953ff289
DN
1793 case OMP_CLAUSE_IF:
1794 case OMP_CLAUSE_NUM_THREADS:
acf0174b
JJ
1795 case OMP_CLAUSE_NUM_TEAMS:
1796 case OMP_CLAUSE_THREAD_LIMIT:
1797 case OMP_CLAUSE_DEVICE:
953ff289 1798 case OMP_CLAUSE_SCHEDULE:
acf0174b
JJ
1799 case OMP_CLAUSE_DIST_SCHEDULE:
1800 case OMP_CLAUSE_DEPEND:
9a771876 1801 case OMP_CLAUSE__CILK_FOR_COUNT_:
41dbbb37
TS
1802 case OMP_CLAUSE_NUM_GANGS:
1803 case OMP_CLAUSE_NUM_WORKERS:
1804 case OMP_CLAUSE_VECTOR_LENGTH:
953ff289 1805 if (ctx->outer)
726a989a 1806 scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
953ff289
DN
1807 break;
1808
acf0174b
JJ
1809 case OMP_CLAUSE_TO:
1810 case OMP_CLAUSE_FROM:
1811 case OMP_CLAUSE_MAP:
1812 if (ctx->outer)
1813 scan_omp_op (&OMP_CLAUSE_SIZE (c), ctx->outer);
1814 decl = OMP_CLAUSE_DECL (c);
1815 /* Global variables with "omp declare target" attribute
1816 don't need to be copied, the receiver side will use them
1817 directly. */
1818 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
1819 && DECL_P (decl)
1820 && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
1f6be682 1821 && varpool_node::get_create (decl)->offloadable)
acf0174b
JJ
1822 break;
1823 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
41dbbb37 1824 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER)
acf0174b 1825 {
41dbbb37
TS
1826 /* Ignore GOMP_MAP_POINTER kind for arrays in regions that are
1827 not offloaded; there is nothing to map for those. */
1828 if (!is_gimple_omp_offloaded (ctx->stmt)
b8910447
JJ
1829 && !POINTER_TYPE_P (TREE_TYPE (decl))
1830 && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
acf0174b
JJ
1831 break;
1832 }
1833 if (DECL_P (decl))
1834 {
1835 if (DECL_SIZE (decl)
1836 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
1837 {
1838 tree decl2 = DECL_VALUE_EXPR (decl);
1839 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
1840 decl2 = TREE_OPERAND (decl2, 0);
1841 gcc_assert (DECL_P (decl2));
1842 install_var_field (decl2, true, 3, ctx);
1843 install_var_local (decl2, ctx);
1844 install_var_local (decl, ctx);
1845 }
1846 else
1847 {
1848 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
41dbbb37 1849 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
acf0174b
JJ
1850 && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
1851 && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
1852 install_var_field (decl, true, 7, ctx);
1853 else
1854 install_var_field (decl, true, 3, ctx);
41dbbb37 1855 if (is_gimple_omp_offloaded (ctx->stmt))
acf0174b
JJ
1856 install_var_local (decl, ctx);
1857 }
1858 }
1859 else
1860 {
1861 tree base = get_base_address (decl);
1862 tree nc = OMP_CLAUSE_CHAIN (c);
1863 if (DECL_P (base)
1864 && nc != NULL_TREE
1865 && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
1866 && OMP_CLAUSE_DECL (nc) == base
41dbbb37 1867 && OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_POINTER
acf0174b
JJ
1868 && integer_zerop (OMP_CLAUSE_SIZE (nc)))
1869 {
1870 OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c) = 1;
1871 OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (nc) = 1;
1872 }
1873 else
1874 {
f014c653
JJ
1875 if (ctx->outer)
1876 {
1877 scan_omp_op (&OMP_CLAUSE_DECL (c), ctx->outer);
1878 decl = OMP_CLAUSE_DECL (c);
1879 }
acf0174b
JJ
1880 gcc_assert (!splay_tree_lookup (ctx->field_map,
1881 (splay_tree_key) decl));
1882 tree field
1883 = build_decl (OMP_CLAUSE_LOCATION (c),
1884 FIELD_DECL, NULL_TREE, ptr_type_node);
1885 DECL_ALIGN (field) = TYPE_ALIGN (ptr_type_node);
1886 insert_field_into_struct (ctx->record_type, field);
1887 splay_tree_insert (ctx->field_map, (splay_tree_key) decl,
1888 (splay_tree_value) field);
1889 }
1890 }
1891 break;
1892
953ff289
DN
1893 case OMP_CLAUSE_NOWAIT:
1894 case OMP_CLAUSE_ORDERED:
a68ab351
JJ
1895 case OMP_CLAUSE_COLLAPSE:
1896 case OMP_CLAUSE_UNTIED:
20906c66 1897 case OMP_CLAUSE_MERGEABLE:
acf0174b 1898 case OMP_CLAUSE_PROC_BIND:
74bf76ed 1899 case OMP_CLAUSE_SAFELEN:
41dbbb37
TS
1900 case OMP_CLAUSE_ASYNC:
1901 case OMP_CLAUSE_WAIT:
1902 case OMP_CLAUSE_GANG:
1903 case OMP_CLAUSE_WORKER:
1904 case OMP_CLAUSE_VECTOR:
953ff289
DN
1905 break;
1906
acf0174b
JJ
1907 case OMP_CLAUSE_ALIGNED:
1908 decl = OMP_CLAUSE_DECL (c);
1909 if (is_global_var (decl)
1910 && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
1911 install_var_local (decl, ctx);
1912 break;
1913
41dbbb37
TS
1914 case OMP_CLAUSE_DEVICE_RESIDENT:
1915 case OMP_CLAUSE_USE_DEVICE:
1916 case OMP_CLAUSE__CACHE_:
1917 case OMP_CLAUSE_INDEPENDENT:
1918 case OMP_CLAUSE_AUTO:
1919 case OMP_CLAUSE_SEQ:
1920 sorry ("Clause not supported yet");
1921 break;
1922
953ff289
DN
1923 default:
1924 gcc_unreachable ();
1925 }
1926 }
1927
1928 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1929 {
aaf46ef9 1930 switch (OMP_CLAUSE_CODE (c))
953ff289
DN
1931 {
1932 case OMP_CLAUSE_LASTPRIVATE:
1933 /* Let the corresponding firstprivate clause create
1934 the variable. */
726a989a 1935 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
a68ab351 1936 scan_array_reductions = true;
953ff289
DN
1937 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1938 break;
1939 /* FALLTHRU */
1940
953ff289 1941 case OMP_CLAUSE_FIRSTPRIVATE:
41dbbb37
TS
1942 if (is_gimple_omp_oacc (ctx->stmt))
1943 {
1944 sorry ("clause not supported yet");
1945 break;
1946 }
1947 /* FALLTHRU */
1948 case OMP_CLAUSE_PRIVATE:
953ff289 1949 case OMP_CLAUSE_REDUCTION:
74bf76ed 1950 case OMP_CLAUSE_LINEAR:
953ff289
DN
1951 decl = OMP_CLAUSE_DECL (c);
1952 if (is_variable_sized (decl))
1953 install_var_local (decl, ctx);
1954 fixup_remapped_decl (decl, ctx,
aaf46ef9 1955 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
953ff289 1956 && OMP_CLAUSE_PRIVATE_DEBUG (c));
aaf46ef9 1957 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
953ff289
DN
1958 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1959 scan_array_reductions = true;
f7468577
JJ
1960 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
1961 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
1962 scan_array_reductions = true;
953ff289
DN
1963 break;
1964
1965 case OMP_CLAUSE_SHARED:
acf0174b
JJ
1966 /* Ignore shared directives in teams construct. */
1967 if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
1968 break;
953ff289 1969 decl = OMP_CLAUSE_DECL (c);
8ca5b2a2
JJ
1970 if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1971 fixup_remapped_decl (decl, ctx, false);
953ff289
DN
1972 break;
1973
acf0174b 1974 case OMP_CLAUSE_MAP:
41dbbb37 1975 if (!is_gimple_omp_offloaded (ctx->stmt))
acf0174b
JJ
1976 break;
1977 decl = OMP_CLAUSE_DECL (c);
1978 if (DECL_P (decl)
1979 && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
1f6be682 1980 && varpool_node::get_create (decl)->offloadable)
acf0174b
JJ
1981 break;
1982 if (DECL_P (decl))
1983 {
41dbbb37 1984 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
acf0174b
JJ
1985 && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
1986 && !COMPLETE_TYPE_P (TREE_TYPE (decl)))
1987 {
1988 tree new_decl = lookup_decl (decl, ctx);
1989 TREE_TYPE (new_decl)
1990 = remap_type (TREE_TYPE (decl), &ctx->cb);
1991 }
1992 else if (DECL_SIZE (decl)
1993 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
1994 {
1995 tree decl2 = DECL_VALUE_EXPR (decl);
1996 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
1997 decl2 = TREE_OPERAND (decl2, 0);
1998 gcc_assert (DECL_P (decl2));
1999 fixup_remapped_decl (decl2, ctx, false);
2000 fixup_remapped_decl (decl, ctx, true);
2001 }
2002 else
2003 fixup_remapped_decl (decl, ctx, false);
2004 }
2005 break;
2006
953ff289
DN
2007 case OMP_CLAUSE_COPYPRIVATE:
2008 case OMP_CLAUSE_COPYIN:
2009 case OMP_CLAUSE_DEFAULT:
2010 case OMP_CLAUSE_IF:
2011 case OMP_CLAUSE_NUM_THREADS:
acf0174b
JJ
2012 case OMP_CLAUSE_NUM_TEAMS:
2013 case OMP_CLAUSE_THREAD_LIMIT:
2014 case OMP_CLAUSE_DEVICE:
953ff289 2015 case OMP_CLAUSE_SCHEDULE:
acf0174b 2016 case OMP_CLAUSE_DIST_SCHEDULE:
953ff289
DN
2017 case OMP_CLAUSE_NOWAIT:
2018 case OMP_CLAUSE_ORDERED:
a68ab351
JJ
2019 case OMP_CLAUSE_COLLAPSE:
2020 case OMP_CLAUSE_UNTIED:
20906c66
JJ
2021 case OMP_CLAUSE_FINAL:
2022 case OMP_CLAUSE_MERGEABLE:
acf0174b 2023 case OMP_CLAUSE_PROC_BIND:
74bf76ed 2024 case OMP_CLAUSE_SAFELEN:
acf0174b
JJ
2025 case OMP_CLAUSE_ALIGNED:
2026 case OMP_CLAUSE_DEPEND:
2027 case OMP_CLAUSE__LOOPTEMP_:
2028 case OMP_CLAUSE_TO:
2029 case OMP_CLAUSE_FROM:
9a771876 2030 case OMP_CLAUSE__CILK_FOR_COUNT_:
41dbbb37
TS
2031 case OMP_CLAUSE_ASYNC:
2032 case OMP_CLAUSE_WAIT:
2033 case OMP_CLAUSE_NUM_GANGS:
2034 case OMP_CLAUSE_NUM_WORKERS:
2035 case OMP_CLAUSE_VECTOR_LENGTH:
2036 case OMP_CLAUSE_GANG:
2037 case OMP_CLAUSE_WORKER:
2038 case OMP_CLAUSE_VECTOR:
2039 break;
2040
2041 case OMP_CLAUSE_DEVICE_RESIDENT:
2042 case OMP_CLAUSE_USE_DEVICE:
2043 case OMP_CLAUSE__CACHE_:
2044 case OMP_CLAUSE_INDEPENDENT:
2045 case OMP_CLAUSE_AUTO:
2046 case OMP_CLAUSE_SEQ:
2047 sorry ("Clause not supported yet");
953ff289
DN
2048 break;
2049
2050 default:
2051 gcc_unreachable ();
2052 }
2053 }
2054
41dbbb37
TS
2055 gcc_checking_assert (!scan_array_reductions
2056 || !is_gimple_omp_oacc (ctx->stmt));
953ff289
DN
2057 if (scan_array_reductions)
2058 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
aaf46ef9 2059 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
953ff289
DN
2060 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2061 {
26127932
JJ
2062 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
2063 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
953ff289 2064 }
a68ab351 2065 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
726a989a 2066 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
26127932 2067 scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
f7468577
JJ
2068 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
2069 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
2070 scan_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
953ff289
DN
2071}
2072
9a771876
JJ
2073/* Create a new name for omp child function. Returns an identifier. If
2074 IS_CILK_FOR is true then the suffix for the child function is
2075 "_cilk_for_fn." */
953ff289 2076
953ff289 2077static tree
9a771876 2078create_omp_child_function_name (bool task_copy, bool is_cilk_for)
953ff289 2079{
9a771876
JJ
2080 if (is_cilk_for)
2081 return clone_function_name (current_function_decl, "_cilk_for_fn");
2082 return clone_function_name (current_function_decl,
2083 task_copy ? "_omp_cpyfn" : "_omp_fn");
2084}
2085
2086/* Returns the type of the induction variable for the child function for
2087 _Cilk_for and the types for _high and _low variables based on TYPE. */
2088
2089static tree
2090cilk_for_check_loop_diff_type (tree type)
2091{
2092 if (TYPE_PRECISION (type) <= TYPE_PRECISION (uint32_type_node))
2093 {
2094 if (TYPE_UNSIGNED (type))
2095 return uint32_type_node;
2096 else
2097 return integer_type_node;
2098 }
2099 else
2100 {
2101 if (TYPE_UNSIGNED (type))
2102 return uint64_type_node;
2103 else
2104 return long_long_integer_type_node;
2105 }
953ff289
DN
2106}
2107
2108/* Build a decl for the omp child function. It'll not contain a body
2109 yet, just the bare decl. */
2110
2111static void
a68ab351 2112create_omp_child_function (omp_context *ctx, bool task_copy)
953ff289
DN
2113{
2114 tree decl, type, name, t;
2115
9a771876
JJ
2116 tree cilk_for_count
2117 = (flag_cilkplus && gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
2118 ? find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2119 OMP_CLAUSE__CILK_FOR_COUNT_) : NULL_TREE;
2120 tree cilk_var_type = NULL_TREE;
2121
2122 name = create_omp_child_function_name (task_copy,
2123 cilk_for_count != NULL_TREE);
a68ab351
JJ
2124 if (task_copy)
2125 type = build_function_type_list (void_type_node, ptr_type_node,
2126 ptr_type_node, NULL_TREE);
9a771876
JJ
2127 else if (cilk_for_count)
2128 {
2129 type = TREE_TYPE (OMP_CLAUSE_OPERAND (cilk_for_count, 0));
2130 cilk_var_type = cilk_for_check_loop_diff_type (type);
2131 type = build_function_type_list (void_type_node, ptr_type_node,
2132 cilk_var_type, cilk_var_type, NULL_TREE);
2133 }
a68ab351
JJ
2134 else
2135 type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
953ff289 2136
9a771876 2137 decl = build_decl (gimple_location (ctx->stmt), FUNCTION_DECL, name, type);
953ff289 2138
41dbbb37
TS
2139 gcc_checking_assert (!is_gimple_omp_oacc (ctx->stmt)
2140 || !task_copy);
a68ab351
JJ
2141 if (!task_copy)
2142 ctx->cb.dst_fn = decl;
2143 else
726a989a 2144 gimple_omp_task_set_copy_fn (ctx->stmt, decl);
953ff289
DN
2145
2146 TREE_STATIC (decl) = 1;
2147 TREE_USED (decl) = 1;
2148 DECL_ARTIFICIAL (decl) = 1;
2149 DECL_IGNORED_P (decl) = 0;
2150 TREE_PUBLIC (decl) = 0;
2151 DECL_UNINLINABLE (decl) = 1;
2152 DECL_EXTERNAL (decl) = 0;
2153 DECL_CONTEXT (decl) = NULL_TREE;
50674e96 2154 DECL_INITIAL (decl) = make_node (BLOCK);
1f6be682
IV
2155 if (cgraph_node::get (current_function_decl)->offloadable)
2156 cgraph_node::get_create (decl)->offloadable = 1;
acf0174b
JJ
2157 else
2158 {
2159 omp_context *octx;
2160 for (octx = ctx; octx; octx = octx->outer)
41dbbb37 2161 if (is_gimple_omp_offloaded (octx->stmt))
acf0174b 2162 {
1f6be682 2163 cgraph_node::get_create (decl)->offloadable = 1;
844b0125 2164#ifdef ENABLE_OFFLOADING
1f6be682 2165 g->have_offload = true;
844b0125 2166#endif
acf0174b
JJ
2167 break;
2168 }
2169 }
953ff289 2170
d7823208
BS
2171 if (cgraph_node::get_create (decl)->offloadable
2172 && !lookup_attribute ("omp declare target",
2173 DECL_ATTRIBUTES (current_function_decl)))
2174 DECL_ATTRIBUTES (decl)
2175 = tree_cons (get_identifier ("omp target entrypoint"),
2176 NULL_TREE, DECL_ATTRIBUTES (decl));
2177
c2255bc4
AH
2178 t = build_decl (DECL_SOURCE_LOCATION (decl),
2179 RESULT_DECL, NULL_TREE, void_type_node);
953ff289
DN
2180 DECL_ARTIFICIAL (t) = 1;
2181 DECL_IGNORED_P (t) = 1;
07485407 2182 DECL_CONTEXT (t) = decl;
953ff289
DN
2183 DECL_RESULT (decl) = t;
2184
9a771876
JJ
2185 /* _Cilk_for's child function requires two extra parameters called
2186 __low and __high that are set the by Cilk runtime when it calls this
2187 function. */
2188 if (cilk_for_count)
2189 {
2190 t = build_decl (DECL_SOURCE_LOCATION (decl),
2191 PARM_DECL, get_identifier ("__high"), cilk_var_type);
2192 DECL_ARTIFICIAL (t) = 1;
2193 DECL_NAMELESS (t) = 1;
2194 DECL_ARG_TYPE (t) = ptr_type_node;
2195 DECL_CONTEXT (t) = current_function_decl;
2196 TREE_USED (t) = 1;
2197 DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
2198 DECL_ARGUMENTS (decl) = t;
2199
2200 t = build_decl (DECL_SOURCE_LOCATION (decl),
2201 PARM_DECL, get_identifier ("__low"), cilk_var_type);
2202 DECL_ARTIFICIAL (t) = 1;
2203 DECL_NAMELESS (t) = 1;
2204 DECL_ARG_TYPE (t) = ptr_type_node;
2205 DECL_CONTEXT (t) = current_function_decl;
2206 TREE_USED (t) = 1;
2207 DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
2208 DECL_ARGUMENTS (decl) = t;
2209 }
2210
2211 tree data_name = get_identifier (".omp_data_i");
2212 t = build_decl (DECL_SOURCE_LOCATION (decl), PARM_DECL, data_name,
2213 ptr_type_node);
953ff289 2214 DECL_ARTIFICIAL (t) = 1;
cd3f04c8 2215 DECL_NAMELESS (t) = 1;
953ff289 2216 DECL_ARG_TYPE (t) = ptr_type_node;
50674e96 2217 DECL_CONTEXT (t) = current_function_decl;
953ff289 2218 TREE_USED (t) = 1;
9a771876
JJ
2219 if (cilk_for_count)
2220 DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
953ff289 2221 DECL_ARGUMENTS (decl) = t;
a68ab351
JJ
2222 if (!task_copy)
2223 ctx->receiver_decl = t;
2224 else
2225 {
c2255bc4
AH
2226 t = build_decl (DECL_SOURCE_LOCATION (decl),
2227 PARM_DECL, get_identifier (".omp_data_o"),
a68ab351
JJ
2228 ptr_type_node);
2229 DECL_ARTIFICIAL (t) = 1;
cd3f04c8 2230 DECL_NAMELESS (t) = 1;
a68ab351
JJ
2231 DECL_ARG_TYPE (t) = ptr_type_node;
2232 DECL_CONTEXT (t) = current_function_decl;
2233 TREE_USED (t) = 1;
628c189e 2234 TREE_ADDRESSABLE (t) = 1;
910ad8de 2235 DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
a68ab351
JJ
2236 DECL_ARGUMENTS (decl) = t;
2237 }
953ff289 2238
b8698a0f 2239 /* Allocate memory for the function structure. The call to
50674e96 2240 allocate_struct_function clobbers CFUN, so we need to restore
953ff289 2241 it afterward. */
db2960f4 2242 push_struct_function (decl);
726a989a 2243 cfun->function_end_locus = gimple_location (ctx->stmt);
db2960f4 2244 pop_cfun ();
953ff289
DN
2245}
2246
acf0174b
JJ
2247/* Callback for walk_gimple_seq. Check if combined parallel
2248 contains gimple_omp_for_combined_into_p OMP_FOR. */
2249
2250static tree
2251find_combined_for (gimple_stmt_iterator *gsi_p,
2252 bool *handled_ops_p,
2253 struct walk_stmt_info *wi)
2254{
2255 gimple stmt = gsi_stmt (*gsi_p);
2256
2257 *handled_ops_p = true;
2258 switch (gimple_code (stmt))
2259 {
2260 WALK_SUBSTMTS;
2261
2262 case GIMPLE_OMP_FOR:
2263 if (gimple_omp_for_combined_into_p (stmt)
2264 && gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR)
2265 {
2266 wi->info = stmt;
2267 return integer_zero_node;
2268 }
2269 break;
2270 default:
2271 break;
2272 }
2273 return NULL;
2274}
2275
953ff289
DN
2276/* Scan an OpenMP parallel directive. */
2277
2278static void
726a989a 2279scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
953ff289
DN
2280{
2281 omp_context *ctx;
2282 tree name;
538dd0b7 2283 gomp_parallel *stmt = as_a <gomp_parallel *> (gsi_stmt (*gsi));
953ff289
DN
2284
2285 /* Ignore parallel directives with empty bodies, unless there
2286 are copyin clauses. */
2287 if (optimize > 0
726a989a
RB
2288 && empty_body_p (gimple_omp_body (stmt))
2289 && find_omp_clause (gimple_omp_parallel_clauses (stmt),
2290 OMP_CLAUSE_COPYIN) == NULL)
953ff289 2291 {
726a989a 2292 gsi_replace (gsi, gimple_build_nop (), false);
953ff289
DN
2293 return;
2294 }
2295
acf0174b
JJ
2296 if (gimple_omp_parallel_combined_p (stmt))
2297 {
acf0174b
JJ
2298 struct walk_stmt_info wi;
2299
2300 memset (&wi, 0, sizeof (wi));
2301 wi.val_only = true;
2302 walk_gimple_seq (gimple_omp_body (stmt),
2303 find_combined_for, NULL, &wi);
538dd0b7 2304 if (wi.info)
acf0174b 2305 {
538dd0b7 2306 gomp_for *for_stmt = as_a <gomp_for *> ((gimple) wi.info);
acf0174b
JJ
2307 struct omp_for_data fd;
2308 extract_omp_for_data (for_stmt, &fd, NULL);
2309 /* We need two temporaries with fd.loop.v type (istart/iend)
2310 and then (fd.collapse - 1) temporaries with the same
2311 type for count2 ... countN-1 vars if not constant. */
2312 size_t count = 2, i;
2313 tree type = fd.iter_type;
2314 if (fd.collapse > 1
2315 && TREE_CODE (fd.loop.n2) != INTEGER_CST)
2316 count += fd.collapse - 1;
2317 for (i = 0; i < count; i++)
2318 {
b731b390 2319 tree temp = create_tmp_var (type);
acf0174b
JJ
2320 tree c = build_omp_clause (UNKNOWN_LOCATION,
2321 OMP_CLAUSE__LOOPTEMP_);
f014c653 2322 insert_decl_map (&outer_ctx->cb, temp, temp);
acf0174b
JJ
2323 OMP_CLAUSE_DECL (c) = temp;
2324 OMP_CLAUSE_CHAIN (c) = gimple_omp_parallel_clauses (stmt);
2325 gimple_omp_parallel_set_clauses (stmt, c);
2326 }
2327 }
2328 }
2329
726a989a 2330 ctx = new_omp_context (stmt, outer_ctx);
5771c391 2331 taskreg_contexts.safe_push (ctx);
a68ab351 2332 if (taskreg_nesting_level > 1)
50674e96 2333 ctx->is_nested = true;
953ff289 2334 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
953ff289
DN
2335 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
2336 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
953ff289 2337 name = create_tmp_var_name (".omp_data_s");
c2255bc4
AH
2338 name = build_decl (gimple_location (stmt),
2339 TYPE_DECL, name, ctx->record_type);
cd3f04c8
JJ
2340 DECL_ARTIFICIAL (name) = 1;
2341 DECL_NAMELESS (name) = 1;
953ff289 2342 TYPE_NAME (ctx->record_type) = name;
f7484978 2343 TYPE_ARTIFICIAL (ctx->record_type) = 1;
a68ab351 2344 create_omp_child_function (ctx, false);
726a989a 2345 gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
953ff289 2346
726a989a 2347 scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
26127932 2348 scan_omp (gimple_omp_body_ptr (stmt), ctx);
953ff289
DN
2349
2350 if (TYPE_FIELDS (ctx->record_type) == NULL)
2351 ctx->record_type = ctx->receiver_decl = NULL;
953ff289
DN
2352}
2353
a68ab351
JJ
2354/* Scan an OpenMP task directive. */
2355
2356static void
726a989a 2357scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
a68ab351
JJ
2358{
2359 omp_context *ctx;
726a989a 2360 tree name, t;
538dd0b7 2361 gomp_task *stmt = as_a <gomp_task *> (gsi_stmt (*gsi));
a68ab351
JJ
2362
2363 /* Ignore task directives with empty bodies. */
2364 if (optimize > 0
726a989a 2365 && empty_body_p (gimple_omp_body (stmt)))
a68ab351 2366 {
726a989a 2367 gsi_replace (gsi, gimple_build_nop (), false);
a68ab351
JJ
2368 return;
2369 }
2370
726a989a 2371 ctx = new_omp_context (stmt, outer_ctx);
5771c391 2372 taskreg_contexts.safe_push (ctx);
a68ab351
JJ
2373 if (taskreg_nesting_level > 1)
2374 ctx->is_nested = true;
2375 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
2376 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
2377 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
2378 name = create_tmp_var_name (".omp_data_s");
c2255bc4
AH
2379 name = build_decl (gimple_location (stmt),
2380 TYPE_DECL, name, ctx->record_type);
cd3f04c8
JJ
2381 DECL_ARTIFICIAL (name) = 1;
2382 DECL_NAMELESS (name) = 1;
a68ab351 2383 TYPE_NAME (ctx->record_type) = name;
f7484978 2384 TYPE_ARTIFICIAL (ctx->record_type) = 1;
a68ab351 2385 create_omp_child_function (ctx, false);
726a989a 2386 gimple_omp_task_set_child_fn (stmt, ctx->cb.dst_fn);
a68ab351 2387
726a989a 2388 scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);
a68ab351
JJ
2389
2390 if (ctx->srecord_type)
2391 {
2392 name = create_tmp_var_name (".omp_data_a");
c2255bc4
AH
2393 name = build_decl (gimple_location (stmt),
2394 TYPE_DECL, name, ctx->srecord_type);
cd3f04c8
JJ
2395 DECL_ARTIFICIAL (name) = 1;
2396 DECL_NAMELESS (name) = 1;
a68ab351 2397 TYPE_NAME (ctx->srecord_type) = name;
f7484978 2398 TYPE_ARTIFICIAL (ctx->srecord_type) = 1;
a68ab351
JJ
2399 create_omp_child_function (ctx, true);
2400 }
2401
26127932 2402 scan_omp (gimple_omp_body_ptr (stmt), ctx);
a68ab351
JJ
2403
2404 if (TYPE_FIELDS (ctx->record_type) == NULL)
2405 {
2406 ctx->record_type = ctx->receiver_decl = NULL;
726a989a
RB
2407 t = build_int_cst (long_integer_type_node, 0);
2408 gimple_omp_task_set_arg_size (stmt, t);
2409 t = build_int_cst (long_integer_type_node, 1);
2410 gimple_omp_task_set_arg_align (stmt, t);
a68ab351 2411 }
5771c391
JJ
2412}
2413
2414
2415/* If any decls have been made addressable during scan_omp,
2416 adjust their fields if needed, and layout record types
2417 of parallel/task constructs. */
2418
2419static void
2420finish_taskreg_scan (omp_context *ctx)
2421{
2422 if (ctx->record_type == NULL_TREE)
2423 return;
2424
2425 /* If any task_shared_vars were needed, verify all
2426 OMP_CLAUSE_SHARED clauses on GIMPLE_OMP_{PARALLEL,TASK}
2427 statements if use_pointer_for_field hasn't changed
2428 because of that. If it did, update field types now. */
2429 if (task_shared_vars)
2430 {
2431 tree c;
2432
2433 for (c = gimple_omp_taskreg_clauses (ctx->stmt);
2434 c; c = OMP_CLAUSE_CHAIN (c))
2435 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED)
2436 {
2437 tree decl = OMP_CLAUSE_DECL (c);
2438
2439 /* Global variables don't need to be copied,
2440 the receiver side will use them directly. */
2441 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
2442 continue;
2443 if (!bitmap_bit_p (task_shared_vars, DECL_UID (decl))
2444 || !use_pointer_for_field (decl, ctx))
2445 continue;
2446 tree field = lookup_field (decl, ctx);
2447 if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE
2448 && TREE_TYPE (TREE_TYPE (field)) == TREE_TYPE (decl))
2449 continue;
2450 TREE_TYPE (field) = build_pointer_type (TREE_TYPE (decl));
2451 TREE_THIS_VOLATILE (field) = 0;
2452 DECL_USER_ALIGN (field) = 0;
2453 DECL_ALIGN (field) = TYPE_ALIGN (TREE_TYPE (field));
2454 if (TYPE_ALIGN (ctx->record_type) < DECL_ALIGN (field))
2455 TYPE_ALIGN (ctx->record_type) = DECL_ALIGN (field);
2456 if (ctx->srecord_type)
2457 {
2458 tree sfield = lookup_sfield (decl, ctx);
2459 TREE_TYPE (sfield) = TREE_TYPE (field);
2460 TREE_THIS_VOLATILE (sfield) = 0;
2461 DECL_USER_ALIGN (sfield) = 0;
2462 DECL_ALIGN (sfield) = DECL_ALIGN (field);
2463 if (TYPE_ALIGN (ctx->srecord_type) < DECL_ALIGN (sfield))
2464 TYPE_ALIGN (ctx->srecord_type) = DECL_ALIGN (sfield);
2465 }
2466 }
2467 }
2468
2469 if (gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
2470 {
2471 layout_type (ctx->record_type);
2472 fixup_child_record_type (ctx);
2473 }
a68ab351
JJ
2474 else
2475 {
5771c391 2476 location_t loc = gimple_location (ctx->stmt);
a68ab351
JJ
2477 tree *p, vla_fields = NULL_TREE, *q = &vla_fields;
2478 /* Move VLA fields to the end. */
2479 p = &TYPE_FIELDS (ctx->record_type);
2480 while (*p)
2481 if (!TYPE_SIZE_UNIT (TREE_TYPE (*p))
2482 || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p))))
2483 {
2484 *q = *p;
2485 *p = TREE_CHAIN (*p);
2486 TREE_CHAIN (*q) = NULL_TREE;
2487 q = &TREE_CHAIN (*q);
2488 }
2489 else
910ad8de 2490 p = &DECL_CHAIN (*p);
a68ab351
JJ
2491 *p = vla_fields;
2492 layout_type (ctx->record_type);
2493 fixup_child_record_type (ctx);
2494 if (ctx->srecord_type)
2495 layout_type (ctx->srecord_type);
5771c391
JJ
2496 tree t = fold_convert_loc (loc, long_integer_type_node,
2497 TYPE_SIZE_UNIT (ctx->record_type));
2498 gimple_omp_task_set_arg_size (ctx->stmt, t);
726a989a 2499 t = build_int_cst (long_integer_type_node,
a68ab351 2500 TYPE_ALIGN_UNIT (ctx->record_type));
5771c391 2501 gimple_omp_task_set_arg_align (ctx->stmt, t);
a68ab351
JJ
2502 }
2503}
2504
953ff289 2505
41dbbb37
TS
2506static omp_context *
2507enclosing_target_ctx (omp_context *ctx)
2508{
2509 while (ctx != NULL
2510 && gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET)
2511 ctx = ctx->outer;
2512 gcc_assert (ctx != NULL);
2513 return ctx;
2514}
2515
2516static bool
2517oacc_loop_or_target_p (gimple stmt)
2518{
2519 enum gimple_code outer_type = gimple_code (stmt);
2520 return ((outer_type == GIMPLE_OMP_TARGET
2521 && ((gimple_omp_target_kind (stmt)
2522 == GF_OMP_TARGET_KIND_OACC_PARALLEL)
2523 || (gimple_omp_target_kind (stmt)
2524 == GF_OMP_TARGET_KIND_OACC_KERNELS)))
2525 || (outer_type == GIMPLE_OMP_FOR
2526 && gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_OACC_LOOP));
2527}
2528
2529/* Scan a GIMPLE_OMP_FOR. */
953ff289
DN
2530
2531static void
538dd0b7 2532scan_omp_for (gomp_for *stmt, omp_context *outer_ctx)
953ff289 2533{
41dbbb37 2534 enum gimple_code outer_type = GIMPLE_ERROR_MARK;
50674e96 2535 omp_context *ctx;
726a989a 2536 size_t i;
41dbbb37
TS
2537 tree clauses = gimple_omp_for_clauses (stmt);
2538
2539 if (outer_ctx)
2540 outer_type = gimple_code (outer_ctx->stmt);
953ff289 2541
50674e96 2542 ctx = new_omp_context (stmt, outer_ctx);
953ff289 2543
41dbbb37
TS
2544 if (is_gimple_omp_oacc (stmt))
2545 {
2546 if (outer_ctx && outer_type == GIMPLE_OMP_FOR)
2547 ctx->gwv_this = outer_ctx->gwv_this;
2548 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
2549 {
2550 int val;
2551 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_GANG)
2552 val = MASK_GANG;
2553 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_WORKER)
2554 val = MASK_WORKER;
2555 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_VECTOR)
2556 val = MASK_VECTOR;
2557 else
2558 continue;
2559 ctx->gwv_this |= val;
2560 if (!outer_ctx)
2561 {
2562 /* Skip; not nested inside a region. */
2563 continue;
2564 }
2565 if (!oacc_loop_or_target_p (outer_ctx->stmt))
2566 {
2567 /* Skip; not nested inside an OpenACC region. */
2568 continue;
2569 }
2570 if (outer_type == GIMPLE_OMP_FOR)
2571 outer_ctx->gwv_below |= val;
2572 if (OMP_CLAUSE_OPERAND (c, 0) != NULL_TREE)
2573 {
2574 omp_context *enclosing = enclosing_target_ctx (outer_ctx);
2575 if (gimple_omp_target_kind (enclosing->stmt)
2576 == GF_OMP_TARGET_KIND_OACC_PARALLEL)
2577 error_at (gimple_location (stmt),
2578 "no arguments allowed to gang, worker and vector clauses inside parallel");
2579 }
2580 }
2581 }
2582
2583 scan_sharing_clauses (clauses, ctx);
953ff289 2584
26127932 2585 scan_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
726a989a 2586 for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
a68ab351 2587 {
726a989a
RB
2588 scan_omp_op (gimple_omp_for_index_ptr (stmt, i), ctx);
2589 scan_omp_op (gimple_omp_for_initial_ptr (stmt, i), ctx);
2590 scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
2591 scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
a68ab351 2592 }
26127932 2593 scan_omp (gimple_omp_body_ptr (stmt), ctx);
41dbbb37
TS
2594
2595 if (is_gimple_omp_oacc (stmt))
2596 {
2597 if (ctx->gwv_this & ctx->gwv_below)
2598 error_at (gimple_location (stmt),
2599 "gang, worker and vector may occur only once in a loop nest");
2600 else if (ctx->gwv_below != 0
2601 && ctx->gwv_this > ctx->gwv_below)
2602 error_at (gimple_location (stmt),
2603 "gang, worker and vector must occur in this order in a loop nest");
2604 if (outer_ctx && outer_type == GIMPLE_OMP_FOR)
2605 outer_ctx->gwv_below |= ctx->gwv_below;
2606 }
953ff289
DN
2607}
2608
2609/* Scan an OpenMP sections directive. */
2610
2611static void
538dd0b7 2612scan_omp_sections (gomp_sections *stmt, omp_context *outer_ctx)
953ff289 2613{
953ff289
DN
2614 omp_context *ctx;
2615
2616 ctx = new_omp_context (stmt, outer_ctx);
726a989a 2617 scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
26127932 2618 scan_omp (gimple_omp_body_ptr (stmt), ctx);
953ff289
DN
2619}
2620
2621/* Scan an OpenMP single directive. */
2622
2623static void
538dd0b7 2624scan_omp_single (gomp_single *stmt, omp_context *outer_ctx)
953ff289 2625{
953ff289
DN
2626 omp_context *ctx;
2627 tree name;
2628
2629 ctx = new_omp_context (stmt, outer_ctx);
2630 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
2631 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
2632 name = create_tmp_var_name (".omp_copy_s");
c2255bc4
AH
2633 name = build_decl (gimple_location (stmt),
2634 TYPE_DECL, name, ctx->record_type);
953ff289
DN
2635 TYPE_NAME (ctx->record_type) = name;
2636
726a989a 2637 scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
26127932 2638 scan_omp (gimple_omp_body_ptr (stmt), ctx);
953ff289
DN
2639
2640 if (TYPE_FIELDS (ctx->record_type) == NULL)
2641 ctx->record_type = NULL;
2642 else
2643 layout_type (ctx->record_type);
2644}
2645
41dbbb37 2646/* Scan a GIMPLE_OMP_TARGET. */
acf0174b
JJ
2647
2648static void
538dd0b7 2649scan_omp_target (gomp_target *stmt, omp_context *outer_ctx)
acf0174b
JJ
2650{
2651 omp_context *ctx;
2652 tree name;
41dbbb37
TS
2653 bool offloaded = is_gimple_omp_offloaded (stmt);
2654 tree clauses = gimple_omp_target_clauses (stmt);
acf0174b
JJ
2655
2656 ctx = new_omp_context (stmt, outer_ctx);
2657 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
2658 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
2659 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
2660 name = create_tmp_var_name (".omp_data_t");
2661 name = build_decl (gimple_location (stmt),
2662 TYPE_DECL, name, ctx->record_type);
2663 DECL_ARTIFICIAL (name) = 1;
2664 DECL_NAMELESS (name) = 1;
2665 TYPE_NAME (ctx->record_type) = name;
f7484978 2666 TYPE_ARTIFICIAL (ctx->record_type) = 1;
41dbbb37 2667 if (offloaded)
acf0174b 2668 {
41dbbb37
TS
2669 if (is_gimple_omp_oacc (stmt))
2670 ctx->reduction_map = splay_tree_new (splay_tree_compare_pointers,
2671 0, 0);
2672
acf0174b
JJ
2673 create_omp_child_function (ctx, false);
2674 gimple_omp_target_set_child_fn (stmt, ctx->cb.dst_fn);
2675 }
2676
41dbbb37
TS
2677 if (is_gimple_omp_oacc (stmt))
2678 {
2679 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
2680 {
2681 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_GANGS)
2682 ctx->gwv_this |= MASK_GANG;
2683 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_WORKERS)
2684 ctx->gwv_this |= MASK_WORKER;
2685 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_VECTOR_LENGTH)
2686 ctx->gwv_this |= MASK_VECTOR;
2687 }
2688 }
2689
2690 scan_sharing_clauses (clauses, ctx);
acf0174b
JJ
2691 scan_omp (gimple_omp_body_ptr (stmt), ctx);
2692
2693 if (TYPE_FIELDS (ctx->record_type) == NULL)
2694 ctx->record_type = ctx->receiver_decl = NULL;
2695 else
2696 {
2697 TYPE_FIELDS (ctx->record_type)
2698 = nreverse (TYPE_FIELDS (ctx->record_type));
2699#ifdef ENABLE_CHECKING
2700 tree field;
2701 unsigned int align = DECL_ALIGN (TYPE_FIELDS (ctx->record_type));
2702 for (field = TYPE_FIELDS (ctx->record_type);
2703 field;
2704 field = DECL_CHAIN (field))
2705 gcc_assert (DECL_ALIGN (field) == align);
2706#endif
2707 layout_type (ctx->record_type);
41dbbb37 2708 if (offloaded)
acf0174b
JJ
2709 fixup_child_record_type (ctx);
2710 }
2711}
2712
2713/* Scan an OpenMP teams directive. */
2714
2715static void
538dd0b7 2716scan_omp_teams (gomp_teams *stmt, omp_context *outer_ctx)
acf0174b
JJ
2717{
2718 omp_context *ctx = new_omp_context (stmt, outer_ctx);
2719 scan_sharing_clauses (gimple_omp_teams_clauses (stmt), ctx);
2720 scan_omp (gimple_omp_body_ptr (stmt), ctx);
2721}
953ff289 2722
41dbbb37 2723/* Check nesting restrictions. */
26127932
JJ
2724static bool
2725check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
a6fc8e21 2726{
41dbbb37
TS
2727 /* No nesting of non-OpenACC STMT (that is, an OpenMP one, or a GOMP builtin)
2728 inside an OpenACC CTX. */
2729 if (!(is_gimple_omp (stmt)
2730 && is_gimple_omp_oacc (stmt)))
2731 {
2732 for (omp_context *ctx_ = ctx; ctx_ != NULL; ctx_ = ctx_->outer)
2733 if (is_gimple_omp (ctx_->stmt)
2734 && is_gimple_omp_oacc (ctx_->stmt))
2735 {
2736 error_at (gimple_location (stmt),
2737 "non-OpenACC construct inside of OpenACC region");
2738 return false;
2739 }
2740 }
2741
74bf76ed
JJ
2742 if (ctx != NULL)
2743 {
2744 if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
0aadce73 2745 && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
74bf76ed
JJ
2746 {
2747 error_at (gimple_location (stmt),
2748 "OpenMP constructs may not be nested inside simd region");
2749 return false;
2750 }
acf0174b
JJ
2751 else if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
2752 {
2753 if ((gimple_code (stmt) != GIMPLE_OMP_FOR
2754 || (gimple_omp_for_kind (stmt)
2755 != GF_OMP_FOR_KIND_DISTRIBUTE))
2756 && gimple_code (stmt) != GIMPLE_OMP_PARALLEL)
2757 {
2758 error_at (gimple_location (stmt),
2759 "only distribute or parallel constructs are allowed to "
2760 "be closely nested inside teams construct");
2761 return false;
2762 }
2763 }
74bf76ed 2764 }
726a989a 2765 switch (gimple_code (stmt))
a6fc8e21 2766 {
726a989a 2767 case GIMPLE_OMP_FOR:
0aadce73 2768 if (gimple_omp_for_kind (stmt) & GF_OMP_FOR_SIMD)
74bf76ed 2769 return true;
acf0174b
JJ
2770 if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_DISTRIBUTE)
2771 {
2772 if (ctx != NULL && gimple_code (ctx->stmt) != GIMPLE_OMP_TEAMS)
2773 {
2774 error_at (gimple_location (stmt),
2775 "distribute construct must be closely nested inside "
2776 "teams construct");
2777 return false;
2778 }
2779 return true;
2780 }
2781 /* FALLTHRU */
2782 case GIMPLE_CALL:
2783 if (is_gimple_call (stmt)
2784 && (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2785 == BUILT_IN_GOMP_CANCEL
2786 || DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2787 == BUILT_IN_GOMP_CANCELLATION_POINT))
2788 {
2789 const char *bad = NULL;
2790 const char *kind = NULL;
2791 if (ctx == NULL)
2792 {
2793 error_at (gimple_location (stmt), "orphaned %qs construct",
2794 DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2795 == BUILT_IN_GOMP_CANCEL
2796 ? "#pragma omp cancel"
2797 : "#pragma omp cancellation point");
2798 return false;
2799 }
9541ffee 2800 switch (tree_fits_shwi_p (gimple_call_arg (stmt, 0))
9439e9a1 2801 ? tree_to_shwi (gimple_call_arg (stmt, 0))
acf0174b
JJ
2802 : 0)
2803 {
2804 case 1:
2805 if (gimple_code (ctx->stmt) != GIMPLE_OMP_PARALLEL)
2806 bad = "#pragma omp parallel";
2807 else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2808 == BUILT_IN_GOMP_CANCEL
2809 && !integer_zerop (gimple_call_arg (stmt, 1)))
2810 ctx->cancellable = true;
2811 kind = "parallel";
2812 break;
2813 case 2:
2814 if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
2815 || gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR)
2816 bad = "#pragma omp for";
2817 else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2818 == BUILT_IN_GOMP_CANCEL
2819 && !integer_zerop (gimple_call_arg (stmt, 1)))
2820 {
2821 ctx->cancellable = true;
2822 if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
2823 OMP_CLAUSE_NOWAIT))
2824 warning_at (gimple_location (stmt), 0,
2825 "%<#pragma omp cancel for%> inside "
2826 "%<nowait%> for construct");
2827 if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
2828 OMP_CLAUSE_ORDERED))
2829 warning_at (gimple_location (stmt), 0,
2830 "%<#pragma omp cancel for%> inside "
2831 "%<ordered%> for construct");
2832 }
2833 kind = "for";
2834 break;
2835 case 4:
2836 if (gimple_code (ctx->stmt) != GIMPLE_OMP_SECTIONS
2837 && gimple_code (ctx->stmt) != GIMPLE_OMP_SECTION)
2838 bad = "#pragma omp sections";
2839 else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2840 == BUILT_IN_GOMP_CANCEL
2841 && !integer_zerop (gimple_call_arg (stmt, 1)))
2842 {
2843 if (gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS)
2844 {
2845 ctx->cancellable = true;
2846 if (find_omp_clause (gimple_omp_sections_clauses
2847 (ctx->stmt),
2848 OMP_CLAUSE_NOWAIT))
2849 warning_at (gimple_location (stmt), 0,
2850 "%<#pragma omp cancel sections%> inside "
2851 "%<nowait%> sections construct");
2852 }
2853 else
2854 {
2855 gcc_assert (ctx->outer
2856 && gimple_code (ctx->outer->stmt)
2857 == GIMPLE_OMP_SECTIONS);
2858 ctx->outer->cancellable = true;
2859 if (find_omp_clause (gimple_omp_sections_clauses
2860 (ctx->outer->stmt),
2861 OMP_CLAUSE_NOWAIT))
2862 warning_at (gimple_location (stmt), 0,
2863 "%<#pragma omp cancel sections%> inside "
2864 "%<nowait%> sections construct");
2865 }
2866 }
2867 kind = "sections";
2868 break;
2869 case 8:
2870 if (gimple_code (ctx->stmt) != GIMPLE_OMP_TASK)
2871 bad = "#pragma omp task";
2872 else
2873 ctx->cancellable = true;
2874 kind = "taskgroup";
2875 break;
2876 default:
2877 error_at (gimple_location (stmt), "invalid arguments");
2878 return false;
2879 }
2880 if (bad)
2881 {
2882 error_at (gimple_location (stmt),
2883 "%<%s %s%> construct not closely nested inside of %qs",
2884 DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2885 == BUILT_IN_GOMP_CANCEL
2886 ? "#pragma omp cancel"
2887 : "#pragma omp cancellation point", kind, bad);
2888 return false;
2889 }
2890 }
74bf76ed 2891 /* FALLTHRU */
726a989a
RB
2892 case GIMPLE_OMP_SECTIONS:
2893 case GIMPLE_OMP_SINGLE:
a6fc8e21 2894 for (; ctx != NULL; ctx = ctx->outer)
726a989a 2895 switch (gimple_code (ctx->stmt))
a6fc8e21 2896 {
726a989a
RB
2897 case GIMPLE_OMP_FOR:
2898 case GIMPLE_OMP_SECTIONS:
2899 case GIMPLE_OMP_SINGLE:
2900 case GIMPLE_OMP_ORDERED:
2901 case GIMPLE_OMP_MASTER:
2902 case GIMPLE_OMP_TASK:
acf0174b 2903 case GIMPLE_OMP_CRITICAL:
726a989a 2904 if (is_gimple_call (stmt))
a68ab351 2905 {
acf0174b
JJ
2906 if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2907 != BUILT_IN_GOMP_BARRIER)
2908 return true;
26127932
JJ
2909 error_at (gimple_location (stmt),
2910 "barrier region may not be closely nested inside "
2911 "of work-sharing, critical, ordered, master or "
2912 "explicit task region");
2913 return false;
a68ab351 2914 }
26127932
JJ
2915 error_at (gimple_location (stmt),
2916 "work-sharing region may not be closely nested inside "
2917 "of work-sharing, critical, ordered, master or explicit "
2918 "task region");
2919 return false;
726a989a 2920 case GIMPLE_OMP_PARALLEL:
26127932 2921 return true;
a6fc8e21
JJ
2922 default:
2923 break;
2924 }
2925 break;
726a989a 2926 case GIMPLE_OMP_MASTER:
a6fc8e21 2927 for (; ctx != NULL; ctx = ctx->outer)
726a989a 2928 switch (gimple_code (ctx->stmt))
a6fc8e21 2929 {
726a989a
RB
2930 case GIMPLE_OMP_FOR:
2931 case GIMPLE_OMP_SECTIONS:
2932 case GIMPLE_OMP_SINGLE:
2933 case GIMPLE_OMP_TASK:
26127932
JJ
2934 error_at (gimple_location (stmt),
2935 "master region may not be closely nested inside "
2936 "of work-sharing or explicit task region");
2937 return false;
726a989a 2938 case GIMPLE_OMP_PARALLEL:
26127932 2939 return true;
a6fc8e21
JJ
2940 default:
2941 break;
2942 }
2943 break;
726a989a 2944 case GIMPLE_OMP_ORDERED:
a6fc8e21 2945 for (; ctx != NULL; ctx = ctx->outer)
726a989a 2946 switch (gimple_code (ctx->stmt))
a6fc8e21 2947 {
726a989a
RB
2948 case GIMPLE_OMP_CRITICAL:
2949 case GIMPLE_OMP_TASK:
26127932
JJ
2950 error_at (gimple_location (stmt),
2951 "ordered region may not be closely nested inside "
2952 "of critical or explicit task region");
2953 return false;
726a989a
RB
2954 case GIMPLE_OMP_FOR:
2955 if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
a6fc8e21 2956 OMP_CLAUSE_ORDERED) == NULL)
26127932
JJ
2957 {
2958 error_at (gimple_location (stmt),
2959 "ordered region must be closely nested inside "
a6fc8e21 2960 "a loop region with an ordered clause");
26127932
JJ
2961 return false;
2962 }
2963 return true;
726a989a 2964 case GIMPLE_OMP_PARALLEL:
acf0174b
JJ
2965 error_at (gimple_location (stmt),
2966 "ordered region must be closely nested inside "
2967 "a loop region with an ordered clause");
2968 return false;
a6fc8e21
JJ
2969 default:
2970 break;
2971 }
2972 break;
726a989a 2973 case GIMPLE_OMP_CRITICAL:
538dd0b7
DM
2974 {
2975 tree this_stmt_name
2976 = gimple_omp_critical_name (as_a <gomp_critical *> (stmt));
2977 for (; ctx != NULL; ctx = ctx->outer)
2978 if (gomp_critical *other_crit
2979 = dyn_cast <gomp_critical *> (ctx->stmt))
2980 if (this_stmt_name == gimple_omp_critical_name (other_crit))
2981 {
2982 error_at (gimple_location (stmt),
2983 "critical region may not be nested inside a critical "
2984 "region with the same name");
2985 return false;
2986 }
2987 }
a6fc8e21 2988 break;
acf0174b
JJ
2989 case GIMPLE_OMP_TEAMS:
2990 if (ctx == NULL
2991 || gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET
2992 || gimple_omp_target_kind (ctx->stmt) != GF_OMP_TARGET_KIND_REGION)
2993 {
2994 error_at (gimple_location (stmt),
2995 "teams construct not closely nested inside of target "
2996 "region");
2997 return false;
2998 }
2999 break;
f014c653
JJ
3000 case GIMPLE_OMP_TARGET:
3001 for (; ctx != NULL; ctx = ctx->outer)
41dbbb37
TS
3002 {
3003 if (gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET)
3004 {
3005 if (is_gimple_omp (stmt)
3006 && is_gimple_omp_oacc (stmt)
3007 && is_gimple_omp (ctx->stmt))
3008 {
3009 error_at (gimple_location (stmt),
3010 "OpenACC construct inside of non-OpenACC region");
3011 return false;
3012 }
3013 continue;
3014 }
3015
3016 const char *stmt_name, *ctx_stmt_name;
3017 switch (gimple_omp_target_kind (stmt))
3018 {
3019 case GF_OMP_TARGET_KIND_REGION: stmt_name = "target"; break;
3020 case GF_OMP_TARGET_KIND_DATA: stmt_name = "target data"; break;
3021 case GF_OMP_TARGET_KIND_UPDATE: stmt_name = "target update"; break;
3022 case GF_OMP_TARGET_KIND_OACC_PARALLEL: stmt_name = "parallel"; break;
3023 case GF_OMP_TARGET_KIND_OACC_KERNELS: stmt_name = "kernels"; break;
3024 case GF_OMP_TARGET_KIND_OACC_DATA: stmt_name = "data"; break;
3025 case GF_OMP_TARGET_KIND_OACC_UPDATE: stmt_name = "update"; break;
3026 case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA: stmt_name = "enter/exit data"; break;
3027 default: gcc_unreachable ();
3028 }
3029 switch (gimple_omp_target_kind (ctx->stmt))
3030 {
3031 case GF_OMP_TARGET_KIND_REGION: ctx_stmt_name = "target"; break;
3032 case GF_OMP_TARGET_KIND_DATA: ctx_stmt_name = "target data"; break;
3033 case GF_OMP_TARGET_KIND_OACC_PARALLEL: ctx_stmt_name = "parallel"; break;
3034 case GF_OMP_TARGET_KIND_OACC_KERNELS: ctx_stmt_name = "kernels"; break;
3035 case GF_OMP_TARGET_KIND_OACC_DATA: ctx_stmt_name = "data"; break;
3036 default: gcc_unreachable ();
3037 }
3038
3039 /* OpenACC/OpenMP mismatch? */
3040 if (is_gimple_omp_oacc (stmt)
3041 != is_gimple_omp_oacc (ctx->stmt))
3042 {
3043 error_at (gimple_location (stmt),
3044 "%s %s construct inside of %s %s region",
3045 (is_gimple_omp_oacc (stmt)
3046 ? "OpenACC" : "OpenMP"), stmt_name,
3047 (is_gimple_omp_oacc (ctx->stmt)
3048 ? "OpenACC" : "OpenMP"), ctx_stmt_name);
3049 return false;
3050 }
3051 if (is_gimple_omp_offloaded (ctx->stmt))
3052 {
3053 /* No GIMPLE_OMP_TARGET inside offloaded OpenACC CTX. */
3054 if (is_gimple_omp_oacc (ctx->stmt))
3055 {
3056 error_at (gimple_location (stmt),
3057 "%s construct inside of %s region",
3058 stmt_name, ctx_stmt_name);
3059 return false;
3060 }
3061 else
3062 {
3063 gcc_checking_assert (!is_gimple_omp_oacc (stmt));
3064 warning_at (gimple_location (stmt), 0,
3065 "%s construct inside of %s region",
3066 stmt_name, ctx_stmt_name);
3067 }
3068 }
3069 }
f014c653 3070 break;
a6fc8e21
JJ
3071 default:
3072 break;
3073 }
26127932 3074 return true;
a6fc8e21
JJ
3075}
3076
3077
726a989a
RB
3078/* Helper function scan_omp.
3079
3080 Callback for walk_tree or operators in walk_gimple_stmt used to
41dbbb37 3081 scan for OMP directives in TP. */
953ff289
DN
3082
3083static tree
726a989a 3084scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
953ff289 3085{
d3bfe4de
KG
3086 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
3087 omp_context *ctx = (omp_context *) wi->info;
953ff289
DN
3088 tree t = *tp;
3089
726a989a
RB
3090 switch (TREE_CODE (t))
3091 {
3092 case VAR_DECL:
3093 case PARM_DECL:
3094 case LABEL_DECL:
3095 case RESULT_DECL:
3096 if (ctx)
3097 *tp = remap_decl (t, &ctx->cb);
3098 break;
3099
3100 default:
3101 if (ctx && TYPE_P (t))
3102 *tp = remap_type (t, &ctx->cb);
3103 else if (!DECL_P (t))
a900ae6b
JJ
3104 {
3105 *walk_subtrees = 1;
3106 if (ctx)
70f34814
RG
3107 {
3108 tree tem = remap_type (TREE_TYPE (t), &ctx->cb);
3109 if (tem != TREE_TYPE (t))
3110 {
3111 if (TREE_CODE (t) == INTEGER_CST)
807e902e 3112 *tp = wide_int_to_tree (tem, t);
70f34814
RG
3113 else
3114 TREE_TYPE (t) = tem;
3115 }
3116 }
a900ae6b 3117 }
726a989a
RB
3118 break;
3119 }
3120
3121 return NULL_TREE;
3122}
3123
c02065fc
AH
3124/* Return true if FNDECL is a setjmp or a longjmp. */
3125
3126static bool
3127setjmp_or_longjmp_p (const_tree fndecl)
3128{
3129 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
3130 && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SETJMP
3131 || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LONGJMP))
3132 return true;
3133
3134 tree declname = DECL_NAME (fndecl);
3135 if (!declname)
3136 return false;
3137 const char *name = IDENTIFIER_POINTER (declname);
3138 return !strcmp (name, "setjmp") || !strcmp (name, "longjmp");
3139}
3140
726a989a
RB
3141
3142/* Helper function for scan_omp.
3143
41dbbb37 3144 Callback for walk_gimple_stmt used to scan for OMP directives in
726a989a
RB
3145 the current statement in GSI. */
3146
3147static tree
3148scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
3149 struct walk_stmt_info *wi)
3150{
3151 gimple stmt = gsi_stmt (*gsi);
3152 omp_context *ctx = (omp_context *) wi->info;
3153
3154 if (gimple_has_location (stmt))
3155 input_location = gimple_location (stmt);
953ff289 3156
41dbbb37 3157 /* Check the nesting restrictions. */
acf0174b
JJ
3158 bool remove = false;
3159 if (is_gimple_omp (stmt))
3160 remove = !check_omp_nesting_restrictions (stmt, ctx);
3161 else if (is_gimple_call (stmt))
3162 {
3163 tree fndecl = gimple_call_fndecl (stmt);
c02065fc
AH
3164 if (fndecl)
3165 {
3166 if (setjmp_or_longjmp_p (fndecl)
3167 && ctx
3168 && gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
0aadce73 3169 && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
c02065fc
AH
3170 {
3171 remove = true;
3172 error_at (gimple_location (stmt),
3173 "setjmp/longjmp inside simd construct");
3174 }
3175 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3176 switch (DECL_FUNCTION_CODE (fndecl))
3177 {
3178 case BUILT_IN_GOMP_BARRIER:
3179 case BUILT_IN_GOMP_CANCEL:
3180 case BUILT_IN_GOMP_CANCELLATION_POINT:
3181 case BUILT_IN_GOMP_TASKYIELD:
3182 case BUILT_IN_GOMP_TASKWAIT:
3183 case BUILT_IN_GOMP_TASKGROUP_START:
3184 case BUILT_IN_GOMP_TASKGROUP_END:
3185 remove = !check_omp_nesting_restrictions (stmt, ctx);
3186 break;
3187 default:
3188 break;
3189 }
3190 }
acf0174b
JJ
3191 }
3192 if (remove)
3193 {
3194 stmt = gimple_build_nop ();
3195 gsi_replace (gsi, stmt, false);
a68ab351 3196 }
a6fc8e21 3197
726a989a
RB
3198 *handled_ops_p = true;
3199
3200 switch (gimple_code (stmt))
953ff289 3201 {
726a989a 3202 case GIMPLE_OMP_PARALLEL:
a68ab351 3203 taskreg_nesting_level++;
726a989a 3204 scan_omp_parallel (gsi, ctx);
a68ab351
JJ
3205 taskreg_nesting_level--;
3206 break;
3207
726a989a 3208 case GIMPLE_OMP_TASK:
a68ab351 3209 taskreg_nesting_level++;
726a989a 3210 scan_omp_task (gsi, ctx);
a68ab351 3211 taskreg_nesting_level--;
953ff289
DN
3212 break;
3213
726a989a 3214 case GIMPLE_OMP_FOR:
538dd0b7 3215 scan_omp_for (as_a <gomp_for *> (stmt), ctx);
953ff289
DN
3216 break;
3217
726a989a 3218 case GIMPLE_OMP_SECTIONS:
538dd0b7 3219 scan_omp_sections (as_a <gomp_sections *> (stmt), ctx);
953ff289
DN
3220 break;
3221
726a989a 3222 case GIMPLE_OMP_SINGLE:
538dd0b7 3223 scan_omp_single (as_a <gomp_single *> (stmt), ctx);
953ff289
DN
3224 break;
3225
726a989a
RB
3226 case GIMPLE_OMP_SECTION:
3227 case GIMPLE_OMP_MASTER:
acf0174b 3228 case GIMPLE_OMP_TASKGROUP:
726a989a
RB
3229 case GIMPLE_OMP_ORDERED:
3230 case GIMPLE_OMP_CRITICAL:
3231 ctx = new_omp_context (stmt, ctx);
26127932 3232 scan_omp (gimple_omp_body_ptr (stmt), ctx);
953ff289
DN
3233 break;
3234
acf0174b 3235 case GIMPLE_OMP_TARGET:
538dd0b7 3236 scan_omp_target (as_a <gomp_target *> (stmt), ctx);
acf0174b
JJ
3237 break;
3238
3239 case GIMPLE_OMP_TEAMS:
538dd0b7 3240 scan_omp_teams (as_a <gomp_teams *> (stmt), ctx);
acf0174b
JJ
3241 break;
3242
726a989a 3243 case GIMPLE_BIND:
953ff289
DN
3244 {
3245 tree var;
953ff289 3246
726a989a
RB
3247 *handled_ops_p = false;
3248 if (ctx)
538dd0b7
DM
3249 for (var = gimple_bind_vars (as_a <gbind *> (stmt));
3250 var ;
3251 var = DECL_CHAIN (var))
726a989a 3252 insert_decl_map (&ctx->cb, var, var);
953ff289
DN
3253 }
3254 break;
953ff289 3255 default:
726a989a 3256 *handled_ops_p = false;
953ff289
DN
3257 break;
3258 }
3259
3260 return NULL_TREE;
3261}
3262
3263
726a989a 3264/* Scan all the statements starting at the current statement. CTX
41dbbb37 3265 contains context information about the OMP directives and
726a989a 3266 clauses found during the scan. */
953ff289
DN
3267
3268static void
26127932 3269scan_omp (gimple_seq *body_p, omp_context *ctx)
953ff289
DN
3270{
3271 location_t saved_location;
3272 struct walk_stmt_info wi;
3273
3274 memset (&wi, 0, sizeof (wi));
953ff289 3275 wi.info = ctx;
953ff289
DN
3276 wi.want_locations = true;
3277
3278 saved_location = input_location;
26127932 3279 walk_gimple_seq_mod (body_p, scan_omp_1_stmt, scan_omp_1_op, &wi);
953ff289
DN
3280 input_location = saved_location;
3281}
3282\f
3283/* Re-gimplification and code generation routines. */
3284
3285/* Build a call to GOMP_barrier. */
3286
acf0174b
JJ
3287static gimple
3288build_omp_barrier (tree lhs)
3289{
3290 tree fndecl = builtin_decl_explicit (lhs ? BUILT_IN_GOMP_BARRIER_CANCEL
3291 : BUILT_IN_GOMP_BARRIER);
538dd0b7 3292 gcall *g = gimple_build_call (fndecl, 0);
acf0174b
JJ
3293 if (lhs)
3294 gimple_call_set_lhs (g, lhs);
3295 return g;
953ff289
DN
3296}
3297
3298/* If a context was created for STMT when it was scanned, return it. */
3299
3300static omp_context *
726a989a 3301maybe_lookup_ctx (gimple stmt)
953ff289
DN
3302{
3303 splay_tree_node n;
3304 n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
3305 return n ? (omp_context *) n->value : NULL;
3306}
3307
50674e96
DN
3308
3309/* Find the mapping for DECL in CTX or the immediately enclosing
3310 context that has a mapping for DECL.
3311
3312 If CTX is a nested parallel directive, we may have to use the decl
3313 mappings created in CTX's parent context. Suppose that we have the
3314 following parallel nesting (variable UIDs showed for clarity):
3315
3316 iD.1562 = 0;
3317 #omp parallel shared(iD.1562) -> outer parallel
3318 iD.1562 = iD.1562 + 1;
3319
3320 #omp parallel shared (iD.1562) -> inner parallel
3321 iD.1562 = iD.1562 - 1;
3322
3323 Each parallel structure will create a distinct .omp_data_s structure
3324 for copying iD.1562 in/out of the directive:
3325
3326 outer parallel .omp_data_s.1.i -> iD.1562
3327 inner parallel .omp_data_s.2.i -> iD.1562
3328
3329 A shared variable mapping will produce a copy-out operation before
3330 the parallel directive and a copy-in operation after it. So, in
3331 this case we would have:
3332
3333 iD.1562 = 0;
3334 .omp_data_o.1.i = iD.1562;
3335 #omp parallel shared(iD.1562) -> outer parallel
3336 .omp_data_i.1 = &.omp_data_o.1
3337 .omp_data_i.1->i = .omp_data_i.1->i + 1;
3338
3339 .omp_data_o.2.i = iD.1562; -> **
3340 #omp parallel shared(iD.1562) -> inner parallel
3341 .omp_data_i.2 = &.omp_data_o.2
3342 .omp_data_i.2->i = .omp_data_i.2->i - 1;
3343
3344
3345 ** This is a problem. The symbol iD.1562 cannot be referenced
3346 inside the body of the outer parallel region. But since we are
3347 emitting this copy operation while expanding the inner parallel
3348 directive, we need to access the CTX structure of the outer
3349 parallel directive to get the correct mapping:
3350
3351 .omp_data_o.2.i = .omp_data_i.1->i
3352
3353 Since there may be other workshare or parallel directives enclosing
3354 the parallel directive, it may be necessary to walk up the context
3355 parent chain. This is not a problem in general because nested
3356 parallelism happens only rarely. */
3357
3358static tree
3359lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
3360{
3361 tree t;
3362 omp_context *up;
3363
50674e96
DN
3364 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
3365 t = maybe_lookup_decl (decl, up);
3366
d2dda7fe 3367 gcc_assert (!ctx->is_nested || t || is_global_var (decl));
50674e96 3368
64964499 3369 return t ? t : decl;
50674e96
DN
3370}
3371
3372
8ca5b2a2
JJ
3373/* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
3374 in outer contexts. */
3375
3376static tree
3377maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
3378{
3379 tree t = NULL;
3380 omp_context *up;
3381
d2dda7fe
JJ
3382 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
3383 t = maybe_lookup_decl (decl, up);
8ca5b2a2
JJ
3384
3385 return t ? t : decl;
3386}
3387
3388
953ff289
DN
3389/* Construct the initialization value for reduction CLAUSE. */
3390
3391tree
3392omp_reduction_init (tree clause, tree type)
3393{
db3927fb 3394 location_t loc = OMP_CLAUSE_LOCATION (clause);
953ff289
DN
3395 switch (OMP_CLAUSE_REDUCTION_CODE (clause))
3396 {
3397 case PLUS_EXPR:
3398 case MINUS_EXPR:
3399 case BIT_IOR_EXPR:
3400 case BIT_XOR_EXPR:
3401 case TRUTH_OR_EXPR:
3402 case TRUTH_ORIF_EXPR:
3403 case TRUTH_XOR_EXPR:
3404 case NE_EXPR:
e8160c9a 3405 return build_zero_cst (type);
953ff289
DN
3406
3407 case MULT_EXPR:
3408 case TRUTH_AND_EXPR:
3409 case TRUTH_ANDIF_EXPR:
3410 case EQ_EXPR:
db3927fb 3411 return fold_convert_loc (loc, type, integer_one_node);
953ff289
DN
3412
3413 case BIT_AND_EXPR:
db3927fb 3414 return fold_convert_loc (loc, type, integer_minus_one_node);
953ff289
DN
3415
3416 case MAX_EXPR:
3417 if (SCALAR_FLOAT_TYPE_P (type))
3418 {
3419 REAL_VALUE_TYPE max, min;
3d3dbadd 3420 if (HONOR_INFINITIES (type))
953ff289
DN
3421 {
3422 real_inf (&max);
3423 real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
3424 }
3425 else
3426 real_maxval (&min, 1, TYPE_MODE (type));
3427 return build_real (type, min);
3428 }
3429 else
3430 {
3431 gcc_assert (INTEGRAL_TYPE_P (type));
3432 return TYPE_MIN_VALUE (type);
3433 }
3434
3435 case MIN_EXPR:
3436 if (SCALAR_FLOAT_TYPE_P (type))
3437 {
3438 REAL_VALUE_TYPE max;
3d3dbadd 3439 if (HONOR_INFINITIES (type))
953ff289
DN
3440 real_inf (&max);
3441 else
3442 real_maxval (&max, 0, TYPE_MODE (type));
3443 return build_real (type, max);
3444 }
3445 else
3446 {
3447 gcc_assert (INTEGRAL_TYPE_P (type));
3448 return TYPE_MAX_VALUE (type);
3449 }
3450
3451 default:
3452 gcc_unreachable ();
3453 }
3454}
3455
acf0174b
JJ
3456/* Return alignment to be assumed for var in CLAUSE, which should be
3457 OMP_CLAUSE_ALIGNED. */
3458
3459static tree
3460omp_clause_aligned_alignment (tree clause)
3461{
3462 if (OMP_CLAUSE_ALIGNED_ALIGNMENT (clause))
3463 return OMP_CLAUSE_ALIGNED_ALIGNMENT (clause);
3464
3465 /* Otherwise return implementation defined alignment. */
3466 unsigned int al = 1;
ef4bddc2 3467 machine_mode mode, vmode;
acf0174b
JJ
3468 int vs = targetm.vectorize.autovectorize_vector_sizes ();
3469 if (vs)
3470 vs = 1 << floor_log2 (vs);
3471 static enum mode_class classes[]
3472 = { MODE_INT, MODE_VECTOR_INT, MODE_FLOAT, MODE_VECTOR_FLOAT };
3473 for (int i = 0; i < 4; i += 2)
3474 for (mode = GET_CLASS_NARROWEST_MODE (classes[i]);
3475 mode != VOIDmode;
3476 mode = GET_MODE_WIDER_MODE (mode))
3477 {
3478 vmode = targetm.vectorize.preferred_simd_mode (mode);
3479 if (GET_MODE_CLASS (vmode) != classes[i + 1])
3480 continue;
3481 while (vs
3482 && GET_MODE_SIZE (vmode) < vs
3483 && GET_MODE_2XWIDER_MODE (vmode) != VOIDmode)
3484 vmode = GET_MODE_2XWIDER_MODE (vmode);
3485
3486 tree type = lang_hooks.types.type_for_mode (mode, 1);
3487 if (type == NULL_TREE || TYPE_MODE (type) != mode)
3488 continue;
3489 type = build_vector_type (type, GET_MODE_SIZE (vmode)
3490 / GET_MODE_SIZE (mode));
3491 if (TYPE_MODE (type) != vmode)
3492 continue;
3493 if (TYPE_ALIGN_UNIT (type) > al)
3494 al = TYPE_ALIGN_UNIT (type);
3495 }
3496 return build_int_cst (integer_type_node, al);
3497}
3498
74bf76ed
JJ
3499/* Return maximum possible vectorization factor for the target. */
3500
3501static int
3502omp_max_vf (void)
3503{
3504 if (!optimize
3505 || optimize_debug
ab2ffbeb 3506 || !flag_tree_loop_optimize
ea0f3e87
XDL
3507 || (!flag_tree_loop_vectorize
3508 && (global_options_set.x_flag_tree_loop_vectorize
3509 || global_options_set.x_flag_tree_vectorize)))
74bf76ed
JJ
3510 return 1;
3511
3512 int vs = targetm.vectorize.autovectorize_vector_sizes ();
3513 if (vs)
3514 {
3515 vs = 1 << floor_log2 (vs);
3516 return vs;
3517 }
ef4bddc2 3518 machine_mode vqimode = targetm.vectorize.preferred_simd_mode (QImode);
74bf76ed
JJ
3519 if (GET_MODE_CLASS (vqimode) == MODE_VECTOR_INT)
3520 return GET_MODE_NUNITS (vqimode);
3521 return 1;
3522}
3523
3524/* Helper function of lower_rec_input_clauses, used for #pragma omp simd
3525 privatization. */
3526
3527static bool
3528lower_rec_simd_input_clauses (tree new_var, omp_context *ctx, int &max_vf,
3529 tree &idx, tree &lane, tree &ivar, tree &lvar)
3530{
3531 if (max_vf == 0)
3532 {
3533 max_vf = omp_max_vf ();
3534 if (max_vf > 1)
3535 {
3536 tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
3537 OMP_CLAUSE_SAFELEN);
b46ebd6c
JJ
3538 if (c && TREE_CODE (OMP_CLAUSE_SAFELEN_EXPR (c)) != INTEGER_CST)
3539 max_vf = 1;
3540 else if (c && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c),
3541 max_vf) == -1)
9439e9a1 3542 max_vf = tree_to_shwi (OMP_CLAUSE_SAFELEN_EXPR (c));
74bf76ed
JJ
3543 }
3544 if (max_vf > 1)
3545 {
b731b390
JJ
3546 idx = create_tmp_var (unsigned_type_node);
3547 lane = create_tmp_var (unsigned_type_node);
74bf76ed
JJ
3548 }
3549 }
3550 if (max_vf == 1)
3551 return false;
3552
3553 tree atype = build_array_type_nelts (TREE_TYPE (new_var), max_vf);
b731b390 3554 tree avar = create_tmp_var_raw (atype);
74bf76ed
JJ
3555 if (TREE_ADDRESSABLE (new_var))
3556 TREE_ADDRESSABLE (avar) = 1;
3557 DECL_ATTRIBUTES (avar)
3558 = tree_cons (get_identifier ("omp simd array"), NULL,
3559 DECL_ATTRIBUTES (avar));
3560 gimple_add_tmp_var (avar);
3561 ivar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, idx,
3562 NULL_TREE, NULL_TREE);
3563 lvar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, lane,
3564 NULL_TREE, NULL_TREE);
acf0174b
JJ
3565 if (DECL_P (new_var))
3566 {
3567 SET_DECL_VALUE_EXPR (new_var, lvar);
3568 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
3569 }
74bf76ed
JJ
3570 return true;
3571}
3572
decaaec8
JJ
3573/* Helper function of lower_rec_input_clauses. For a reference
3574 in simd reduction, add an underlying variable it will reference. */
3575
3576static void
3577handle_simd_reference (location_t loc, tree new_vard, gimple_seq *ilist)
3578{
3579 tree z = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_vard)));
3580 if (TREE_CONSTANT (z))
3581 {
3582 const char *name = NULL;
3583 if (DECL_NAME (new_vard))
3584 name = IDENTIFIER_POINTER (DECL_NAME (new_vard));
3585
3586 z = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_vard)), name);
3587 gimple_add_tmp_var (z);
3588 TREE_ADDRESSABLE (z) = 1;
3589 z = build_fold_addr_expr_loc (loc, z);
3590 gimplify_assign (new_vard, z, ilist);
3591 }
3592}
3593
953ff289
DN
3594/* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
3595 from the receiver (aka child) side and initializers for REFERENCE_TYPE
3596 private variables. Initialization statements go in ILIST, while calls
3597 to destructors go in DLIST. */
3598
3599static void
726a989a 3600lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
acf0174b 3601 omp_context *ctx, struct omp_for_data *fd)
953ff289 3602{
5039610b 3603 tree c, dtor, copyin_seq, x, ptr;
953ff289 3604 bool copyin_by_ref = false;
8ca5b2a2 3605 bool lastprivate_firstprivate = false;
acf0174b 3606 bool reduction_omp_orig_ref = false;
953ff289 3607 int pass;
74bf76ed 3608 bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
0aadce73 3609 && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD);
74bf76ed
JJ
3610 int max_vf = 0;
3611 tree lane = NULL_TREE, idx = NULL_TREE;
3612 tree ivar = NULL_TREE, lvar = NULL_TREE;
3613 gimple_seq llist[2] = { NULL, NULL };
953ff289 3614
953ff289
DN
3615 copyin_seq = NULL;
3616
74bf76ed
JJ
3617 /* Set max_vf=1 (which will later enforce safelen=1) in simd loops
3618 with data sharing clauses referencing variable sized vars. That
3619 is unnecessarily hard to support and very unlikely to result in
3620 vectorized code anyway. */
3621 if (is_simd)
3622 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
3623 switch (OMP_CLAUSE_CODE (c))
3624 {
da6f124d
JJ
3625 case OMP_CLAUSE_LINEAR:
3626 if (OMP_CLAUSE_LINEAR_ARRAY (c))
3627 max_vf = 1;
3628 /* FALLTHRU */
74bf76ed 3629 case OMP_CLAUSE_REDUCTION:
74bf76ed
JJ
3630 case OMP_CLAUSE_PRIVATE:
3631 case OMP_CLAUSE_FIRSTPRIVATE:
3632 case OMP_CLAUSE_LASTPRIVATE:
74bf76ed
JJ
3633 if (is_variable_sized (OMP_CLAUSE_DECL (c)))
3634 max_vf = 1;
3635 break;
3636 default:
3637 continue;
3638 }
3639
953ff289
DN
3640 /* Do all the fixed sized types in the first pass, and the variable sized
3641 types in the second pass. This makes sure that the scalar arguments to
b8698a0f 3642 the variable sized types are processed before we use them in the
953ff289
DN
3643 variable sized operations. */
3644 for (pass = 0; pass < 2; ++pass)
3645 {
3646 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
3647 {
aaf46ef9 3648 enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
953ff289
DN
3649 tree var, new_var;
3650 bool by_ref;
db3927fb 3651 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
953ff289
DN
3652
3653 switch (c_kind)
3654 {
3655 case OMP_CLAUSE_PRIVATE:
3656 if (OMP_CLAUSE_PRIVATE_DEBUG (c))
3657 continue;
3658 break;
3659 case OMP_CLAUSE_SHARED:
acf0174b
JJ
3660 /* Ignore shared directives in teams construct. */
3661 if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
3662 continue;
8ca5b2a2
JJ
3663 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
3664 {
3665 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c)));
3666 continue;
3667 }
953ff289 3668 case OMP_CLAUSE_FIRSTPRIVATE:
953ff289 3669 case OMP_CLAUSE_COPYIN:
acf0174b
JJ
3670 case OMP_CLAUSE_LINEAR:
3671 break;
953ff289 3672 case OMP_CLAUSE_REDUCTION:
acf0174b
JJ
3673 if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
3674 reduction_omp_orig_ref = true;
953ff289 3675 break;
acf0174b
JJ
3676 case OMP_CLAUSE__LOOPTEMP_:
3677 /* Handle _looptemp_ clauses only on parallel. */
3678 if (fd)
3679 continue;
74bf76ed 3680 break;
077b0dfb 3681 case OMP_CLAUSE_LASTPRIVATE:
8ca5b2a2
JJ
3682 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
3683 {
3684 lastprivate_firstprivate = true;
3685 if (pass != 0)
3686 continue;
3687 }
92d28cbb
JJ
3688 /* Even without corresponding firstprivate, if
3689 decl is Fortran allocatable, it needs outer var
3690 reference. */
3691 else if (pass == 0
3692 && lang_hooks.decls.omp_private_outer_ref
3693 (OMP_CLAUSE_DECL (c)))
3694 lastprivate_firstprivate = true;
077b0dfb 3695 break;
acf0174b
JJ
3696 case OMP_CLAUSE_ALIGNED:
3697 if (pass == 0)
3698 continue;
3699 var = OMP_CLAUSE_DECL (c);
3700 if (TREE_CODE (TREE_TYPE (var)) == POINTER_TYPE
3701 && !is_global_var (var))
3702 {
3703 new_var = maybe_lookup_decl (var, ctx);
3704 if (new_var == NULL_TREE)
3705 new_var = maybe_lookup_decl_in_outer_ctx (var, ctx);
3706 x = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
3707 x = build_call_expr_loc (clause_loc, x, 2, new_var,
3708 omp_clause_aligned_alignment (c));
3709 x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
3710 x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
3711 gimplify_and_add (x, ilist);
3712 }
3713 else if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE
3714 && is_global_var (var))
3715 {
3716 tree ptype = build_pointer_type (TREE_TYPE (var)), t, t2;
3717 new_var = lookup_decl (var, ctx);
3718 t = maybe_lookup_decl_in_outer_ctx (var, ctx);
3719 t = build_fold_addr_expr_loc (clause_loc, t);
3720 t2 = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
3721 t = build_call_expr_loc (clause_loc, t2, 2, t,
3722 omp_clause_aligned_alignment (c));
3723 t = fold_convert_loc (clause_loc, ptype, t);
b731b390 3724 x = create_tmp_var (ptype);
acf0174b
JJ
3725 t = build2 (MODIFY_EXPR, ptype, x, t);
3726 gimplify_and_add (t, ilist);
3727 t = build_simple_mem_ref_loc (clause_loc, x);
3728 SET_DECL_VALUE_EXPR (new_var, t);
3729 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
3730 }
3731 continue;
953ff289
DN
3732 default:
3733 continue;
3734 }
3735
3736 new_var = var = OMP_CLAUSE_DECL (c);
3737 if (c_kind != OMP_CLAUSE_COPYIN)
3738 new_var = lookup_decl (var, ctx);
3739
3740 if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
3741 {
3742 if (pass != 0)
3743 continue;
3744 }
953ff289
DN
3745 else if (is_variable_sized (var))
3746 {
50674e96
DN
3747 /* For variable sized types, we need to allocate the
3748 actual storage here. Call alloca and store the
3749 result in the pointer decl that we created elsewhere. */
953ff289
DN
3750 if (pass == 0)
3751 continue;
3752
a68ab351
JJ
3753 if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
3754 {
538dd0b7 3755 gcall *stmt;
e79983f4 3756 tree tmp, atmp;
726a989a 3757
a68ab351
JJ
3758 ptr = DECL_VALUE_EXPR (new_var);
3759 gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
3760 ptr = TREE_OPERAND (ptr, 0);
3761 gcc_assert (DECL_P (ptr));
3762 x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
726a989a
RB
3763
3764 /* void *tmp = __builtin_alloca */
e79983f4
MM
3765 atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
3766 stmt = gimple_build_call (atmp, 1, x);
b731b390 3767 tmp = create_tmp_var_raw (ptr_type_node);
726a989a
RB
3768 gimple_add_tmp_var (tmp);
3769 gimple_call_set_lhs (stmt, tmp);
3770
3771 gimple_seq_add_stmt (ilist, stmt);
3772
db3927fb 3773 x = fold_convert_loc (clause_loc, TREE_TYPE (ptr), tmp);
726a989a 3774 gimplify_assign (ptr, x, ilist);
a68ab351 3775 }
953ff289 3776 }
953ff289
DN
3777 else if (is_reference (var))
3778 {
50674e96
DN
3779 /* For references that are being privatized for Fortran,
3780 allocate new backing storage for the new pointer
3781 variable. This allows us to avoid changing all the
3782 code that expects a pointer to something that expects
acf0174b 3783 a direct variable. */
953ff289
DN
3784 if (pass == 0)
3785 continue;
3786
3787 x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
a68ab351
JJ
3788 if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
3789 {
3790 x = build_receiver_ref (var, false, ctx);
db3927fb 3791 x = build_fold_addr_expr_loc (clause_loc, x);
a68ab351
JJ
3792 }
3793 else if (TREE_CONSTANT (x))
953ff289 3794 {
decaaec8
JJ
3795 /* For reduction in SIMD loop, defer adding the
3796 initialization of the reference, because if we decide
3797 to use SIMD array for it, the initilization could cause
3798 expansion ICE. */
3799 if (c_kind == OMP_CLAUSE_REDUCTION && is_simd)
4ceffa27
JJ
3800 x = NULL_TREE;
3801 else
3802 {
3803 const char *name = NULL;
3804 if (DECL_NAME (var))
3805 name = IDENTIFIER_POINTER (DECL_NAME (new_var));
3806
3807 x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
3808 name);
3809 gimple_add_tmp_var (x);
3810 TREE_ADDRESSABLE (x) = 1;
3811 x = build_fold_addr_expr_loc (clause_loc, x);
3812 }
953ff289
DN
3813 }
3814 else
3815 {
e79983f4
MM
3816 tree atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
3817 x = build_call_expr_loc (clause_loc, atmp, 1, x);
953ff289
DN
3818 }
3819
4ceffa27
JJ
3820 if (x)
3821 {
3822 x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
3823 gimplify_assign (new_var, x, ilist);
3824 }
953ff289 3825
70f34814 3826 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
953ff289
DN
3827 }
3828 else if (c_kind == OMP_CLAUSE_REDUCTION
3829 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
3830 {
3831 if (pass == 0)
3832 continue;
3833 }
3834 else if (pass != 0)
3835 continue;
3836
aaf46ef9 3837 switch (OMP_CLAUSE_CODE (c))
953ff289
DN
3838 {
3839 case OMP_CLAUSE_SHARED:
acf0174b
JJ
3840 /* Ignore shared directives in teams construct. */
3841 if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
3842 continue;
8ca5b2a2
JJ
3843 /* Shared global vars are just accessed directly. */
3844 if (is_global_var (new_var))
3845 break;
953ff289
DN
3846 /* Set up the DECL_VALUE_EXPR for shared variables now. This
3847 needs to be delayed until after fixup_child_record_type so
3848 that we get the correct type during the dereference. */
7c8f7639 3849 by_ref = use_pointer_for_field (var, ctx);
953ff289
DN
3850 x = build_receiver_ref (var, by_ref, ctx);
3851 SET_DECL_VALUE_EXPR (new_var, x);
3852 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
3853
3854 /* ??? If VAR is not passed by reference, and the variable
3855 hasn't been initialized yet, then we'll get a warning for
3856 the store into the omp_data_s structure. Ideally, we'd be
b8698a0f 3857 able to notice this and not store anything at all, but
953ff289
DN
3858 we're generating code too early. Suppress the warning. */
3859 if (!by_ref)
3860 TREE_NO_WARNING (var) = 1;
3861 break;
3862
3863 case OMP_CLAUSE_LASTPRIVATE:
3864 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
3865 break;
3866 /* FALLTHRU */
3867
3868 case OMP_CLAUSE_PRIVATE:
a68ab351
JJ
3869 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE)
3870 x = build_outer_var_ref (var, ctx);
3871 else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
3872 {
3873 if (is_task_ctx (ctx))
3874 x = build_receiver_ref (var, false, ctx);
3875 else
3876 x = build_outer_var_ref (var, ctx);
3877 }
3878 else
3879 x = NULL;
74bf76ed 3880 do_private:
acf0174b
JJ
3881 tree nx;
3882 nx = lang_hooks.decls.omp_clause_default_ctor (c, new_var, x);
74bf76ed
JJ
3883 if (is_simd)
3884 {
3885 tree y = lang_hooks.decls.omp_clause_dtor (c, new_var);
acf0174b 3886 if ((TREE_ADDRESSABLE (new_var) || nx || y
74bf76ed
JJ
3887 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
3888 && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
3889 idx, lane, ivar, lvar))
3890 {
acf0174b 3891 if (nx)
74bf76ed
JJ
3892 x = lang_hooks.decls.omp_clause_default_ctor
3893 (c, unshare_expr (ivar), x);
acf0174b 3894 if (nx && x)
74bf76ed
JJ
3895 gimplify_and_add (x, &llist[0]);
3896 if (y)
3897 {
3898 y = lang_hooks.decls.omp_clause_dtor (c, ivar);
3899 if (y)
3900 {
3901 gimple_seq tseq = NULL;
3902
3903 dtor = y;
3904 gimplify_stmt (&dtor, &tseq);
3905 gimple_seq_add_seq (&llist[1], tseq);
3906 }
3907 }
3908 break;
3909 }
3910 }
acf0174b
JJ
3911 if (nx)
3912 gimplify_and_add (nx, ilist);
953ff289
DN
3913 /* FALLTHRU */
3914
3915 do_dtor:
3916 x = lang_hooks.decls.omp_clause_dtor (c, new_var);
3917 if (x)
3918 {
726a989a
RB
3919 gimple_seq tseq = NULL;
3920
953ff289 3921 dtor = x;
726a989a 3922 gimplify_stmt (&dtor, &tseq);
355a7673 3923 gimple_seq_add_seq (dlist, tseq);
953ff289
DN
3924 }
3925 break;
3926
74bf76ed
JJ
3927 case OMP_CLAUSE_LINEAR:
3928 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
3929 goto do_firstprivate;
3930 if (OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
3931 x = NULL;
3932 else
3933 x = build_outer_var_ref (var, ctx);
3934 goto do_private;
3935
953ff289 3936 case OMP_CLAUSE_FIRSTPRIVATE:
a68ab351
JJ
3937 if (is_task_ctx (ctx))
3938 {
3939 if (is_reference (var) || is_variable_sized (var))
3940 goto do_dtor;
3941 else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var,
3942 ctx))
3943 || use_pointer_for_field (var, NULL))
3944 {
3945 x = build_receiver_ref (var, false, ctx);
3946 SET_DECL_VALUE_EXPR (new_var, x);
3947 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
3948 goto do_dtor;
3949 }
3950 }
74bf76ed 3951 do_firstprivate:
953ff289 3952 x = build_outer_var_ref (var, ctx);
74bf76ed
JJ
3953 if (is_simd)
3954 {
acf0174b
JJ
3955 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
3956 && gimple_omp_for_combined_into_p (ctx->stmt))
3957 {
da6f124d
JJ
3958 tree t = OMP_CLAUSE_LINEAR_STEP (c);
3959 tree stept = TREE_TYPE (t);
3960 tree ct = find_omp_clause (clauses,
3961 OMP_CLAUSE__LOOPTEMP_);
3962 gcc_assert (ct);
3963 tree l = OMP_CLAUSE_DECL (ct);
56ad0e38
JJ
3964 tree n1 = fd->loop.n1;
3965 tree step = fd->loop.step;
3966 tree itype = TREE_TYPE (l);
3967 if (POINTER_TYPE_P (itype))
3968 itype = signed_type_for (itype);
3969 l = fold_build2 (MINUS_EXPR, itype, l, n1);
3970 if (TYPE_UNSIGNED (itype)
3971 && fd->loop.cond_code == GT_EXPR)
3972 l = fold_build2 (TRUNC_DIV_EXPR, itype,
3973 fold_build1 (NEGATE_EXPR, itype, l),
3974 fold_build1 (NEGATE_EXPR,
3975 itype, step));
3976 else
3977 l = fold_build2 (TRUNC_DIV_EXPR, itype, l, step);
acf0174b
JJ
3978 t = fold_build2 (MULT_EXPR, stept,
3979 fold_convert (stept, l), t);
da6f124d
JJ
3980
3981 if (OMP_CLAUSE_LINEAR_ARRAY (c))
3982 {
3983 x = lang_hooks.decls.omp_clause_linear_ctor
3984 (c, new_var, x, t);
3985 gimplify_and_add (x, ilist);
3986 goto do_dtor;
3987 }
3988
acf0174b
JJ
3989 if (POINTER_TYPE_P (TREE_TYPE (x)))
3990 x = fold_build2 (POINTER_PLUS_EXPR,
3991 TREE_TYPE (x), x, t);
3992 else
3993 x = fold_build2 (PLUS_EXPR, TREE_TYPE (x), x, t);
3994 }
3995
74bf76ed
JJ
3996 if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
3997 || TREE_ADDRESSABLE (new_var))
3998 && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
3999 idx, lane, ivar, lvar))
4000 {
4001 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
4002 {
b731b390 4003 tree iv = create_tmp_var (TREE_TYPE (new_var));
74bf76ed
JJ
4004 x = lang_hooks.decls.omp_clause_copy_ctor (c, iv, x);
4005 gimplify_and_add (x, ilist);
4006 gimple_stmt_iterator gsi
4007 = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt));
538dd0b7 4008 gassign *g
74bf76ed
JJ
4009 = gimple_build_assign (unshare_expr (lvar), iv);
4010 gsi_insert_before_without_update (&gsi, g,
4011 GSI_SAME_STMT);
da6f124d 4012 tree t = OMP_CLAUSE_LINEAR_STEP (c);
74bf76ed
JJ
4013 enum tree_code code = PLUS_EXPR;
4014 if (POINTER_TYPE_P (TREE_TYPE (new_var)))
4015 code = POINTER_PLUS_EXPR;
0d0e4a03 4016 g = gimple_build_assign (iv, code, iv, t);
74bf76ed
JJ
4017 gsi_insert_before_without_update (&gsi, g,
4018 GSI_SAME_STMT);
4019 break;
4020 }
4021 x = lang_hooks.decls.omp_clause_copy_ctor
4022 (c, unshare_expr (ivar), x);
4023 gimplify_and_add (x, &llist[0]);
4024 x = lang_hooks.decls.omp_clause_dtor (c, ivar);
4025 if (x)
4026 {
4027 gimple_seq tseq = NULL;
4028
4029 dtor = x;
4030 gimplify_stmt (&dtor, &tseq);
4031 gimple_seq_add_seq (&llist[1], tseq);
4032 }
4033 break;
4034 }
4035 }
953ff289
DN
4036 x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
4037 gimplify_and_add (x, ilist);
4038 goto do_dtor;
953ff289 4039
acf0174b
JJ
4040 case OMP_CLAUSE__LOOPTEMP_:
4041 gcc_assert (is_parallel_ctx (ctx));
4042 x = build_outer_var_ref (var, ctx);
4043 x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
4044 gimplify_and_add (x, ilist);
4045 break;
4046
953ff289 4047 case OMP_CLAUSE_COPYIN:
7c8f7639 4048 by_ref = use_pointer_for_field (var, NULL);
953ff289
DN
4049 x = build_receiver_ref (var, by_ref, ctx);
4050 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
4051 append_to_statement_list (x, &copyin_seq);
4052 copyin_by_ref |= by_ref;
4053 break;
4054
4055 case OMP_CLAUSE_REDUCTION:
4056 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
4057 {
a68ab351 4058 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
acf0174b 4059 gimple tseq;
a68ab351
JJ
4060 x = build_outer_var_ref (var, ctx);
4061
acf0174b
JJ
4062 if (is_reference (var)
4063 && !useless_type_conversion_p (TREE_TYPE (placeholder),
4064 TREE_TYPE (x)))
db3927fb 4065 x = build_fold_addr_expr_loc (clause_loc, x);
a68ab351
JJ
4066 SET_DECL_VALUE_EXPR (placeholder, x);
4067 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
acf0174b
JJ
4068 tree new_vard = new_var;
4069 if (is_reference (var))
4070 {
4071 gcc_assert (TREE_CODE (new_var) == MEM_REF);
4072 new_vard = TREE_OPERAND (new_var, 0);
4073 gcc_assert (DECL_P (new_vard));
4074 }
74bf76ed
JJ
4075 if (is_simd
4076 && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
4077 idx, lane, ivar, lvar))
4078 {
acf0174b
JJ
4079 if (new_vard == new_var)
4080 {
4081 gcc_assert (DECL_VALUE_EXPR (new_var) == lvar);
4082 SET_DECL_VALUE_EXPR (new_var, ivar);
4083 }
4084 else
4085 {
4086 SET_DECL_VALUE_EXPR (new_vard,
4087 build_fold_addr_expr (ivar));
4088 DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
4089 }
4090 x = lang_hooks.decls.omp_clause_default_ctor
4091 (c, unshare_expr (ivar),
4092 build_outer_var_ref (var, ctx));
4093 if (x)
4094 gimplify_and_add (x, &llist[0]);
4095 if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
4096 {
4097 tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
4098 lower_omp (&tseq, ctx);
4099 gimple_seq_add_seq (&llist[0], tseq);
4100 }
4101 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
4102 tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
4103 lower_omp (&tseq, ctx);
4104 gimple_seq_add_seq (&llist[1], tseq);
4105 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
4106 DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
4107 if (new_vard == new_var)
4108 SET_DECL_VALUE_EXPR (new_var, lvar);
4109 else
4110 SET_DECL_VALUE_EXPR (new_vard,
4111 build_fold_addr_expr (lvar));
4112 x = lang_hooks.decls.omp_clause_dtor (c, ivar);
4113 if (x)
4114 {
4115 tseq = NULL;
4116 dtor = x;
4117 gimplify_stmt (&dtor, &tseq);
4118 gimple_seq_add_seq (&llist[1], tseq);
4119 }
4120 break;
4121 }
4ceffa27
JJ
4122 /* If this is a reference to constant size reduction var
4123 with placeholder, we haven't emitted the initializer
4124 for it because it is undesirable if SIMD arrays are used.
4125 But if they aren't used, we need to emit the deferred
4126 initialization now. */
4127 else if (is_reference (var) && is_simd)
decaaec8 4128 handle_simd_reference (clause_loc, new_vard, ilist);
acf0174b 4129 x = lang_hooks.decls.omp_clause_default_ctor
92d28cbb
JJ
4130 (c, unshare_expr (new_var),
4131 build_outer_var_ref (var, ctx));
acf0174b
JJ
4132 if (x)
4133 gimplify_and_add (x, ilist);
4134 if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
4135 {
4136 tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
4137 lower_omp (&tseq, ctx);
4138 gimple_seq_add_seq (ilist, tseq);
4139 }
4140 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
4141 if (is_simd)
4142 {
4143 tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
4144 lower_omp (&tseq, ctx);
4145 gimple_seq_add_seq (dlist, tseq);
4146 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
4147 }
4148 DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
4149 goto do_dtor;
4150 }
4151 else
4152 {
4153 x = omp_reduction_init (c, TREE_TYPE (new_var));
4154 gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
e9792e1d
JJ
4155 enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
4156
4157 /* reduction(-:var) sums up the partial results, so it
4158 acts identically to reduction(+:var). */
4159 if (code == MINUS_EXPR)
4160 code = PLUS_EXPR;
4161
decaaec8
JJ
4162 tree new_vard = new_var;
4163 if (is_simd && is_reference (var))
4164 {
4165 gcc_assert (TREE_CODE (new_var) == MEM_REF);
4166 new_vard = TREE_OPERAND (new_var, 0);
4167 gcc_assert (DECL_P (new_vard));
4168 }
acf0174b
JJ
4169 if (is_simd
4170 && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
4171 idx, lane, ivar, lvar))
4172 {
acf0174b
JJ
4173 tree ref = build_outer_var_ref (var, ctx);
4174
4175 gimplify_assign (unshare_expr (ivar), x, &llist[0]);
4176
acf0174b 4177 x = build2 (code, TREE_TYPE (ref), ref, ivar);
74bf76ed
JJ
4178 ref = build_outer_var_ref (var, ctx);
4179 gimplify_assign (ref, x, &llist[1]);
decaaec8
JJ
4180
4181 if (new_vard != new_var)
4182 {
4183 SET_DECL_VALUE_EXPR (new_vard,
4184 build_fold_addr_expr (lvar));
4185 DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
4186 }
74bf76ed
JJ
4187 }
4188 else
4189 {
decaaec8
JJ
4190 if (is_reference (var) && is_simd)
4191 handle_simd_reference (clause_loc, new_vard, ilist);
74bf76ed
JJ
4192 gimplify_assign (new_var, x, ilist);
4193 if (is_simd)
e9792e1d
JJ
4194 {
4195 tree ref = build_outer_var_ref (var, ctx);
4196
4197 x = build2 (code, TREE_TYPE (ref), ref, new_var);
4198 ref = build_outer_var_ref (var, ctx);
4199 gimplify_assign (ref, x, dlist);
4200 }
74bf76ed 4201 }
953ff289
DN
4202 }
4203 break;
4204
4205 default:
4206 gcc_unreachable ();
4207 }
4208 }
4209 }
4210
74bf76ed
JJ
4211 if (lane)
4212 {
4213 tree uid = create_tmp_var (ptr_type_node, "simduid");
8928eff3
JJ
4214 /* Don't want uninit warnings on simduid, it is always uninitialized,
4215 but we use it not for the value, but for the DECL_UID only. */
4216 TREE_NO_WARNING (uid) = 1;
74bf76ed
JJ
4217 gimple g
4218 = gimple_build_call_internal (IFN_GOMP_SIMD_LANE, 1, uid);
4219 gimple_call_set_lhs (g, lane);
4220 gimple_stmt_iterator gsi = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt));
4221 gsi_insert_before_without_update (&gsi, g, GSI_SAME_STMT);
4222 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SIMDUID_);
4223 OMP_CLAUSE__SIMDUID__DECL (c) = uid;
4224 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
4225 gimple_omp_for_set_clauses (ctx->stmt, c);
0d0e4a03
JJ
4226 g = gimple_build_assign (lane, INTEGER_CST,
4227 build_int_cst (unsigned_type_node, 0));
74bf76ed
JJ
4228 gimple_seq_add_stmt (ilist, g);
4229 for (int i = 0; i < 2; i++)
4230 if (llist[i])
4231 {
b731b390 4232 tree vf = create_tmp_var (unsigned_type_node);
74bf76ed
JJ
4233 g = gimple_build_call_internal (IFN_GOMP_SIMD_VF, 1, uid);
4234 gimple_call_set_lhs (g, vf);
4235 gimple_seq *seq = i == 0 ? ilist : dlist;
4236 gimple_seq_add_stmt (seq, g);
4237 tree t = build_int_cst (unsigned_type_node, 0);
0d0e4a03 4238 g = gimple_build_assign (idx, INTEGER_CST, t);
74bf76ed
JJ
4239 gimple_seq_add_stmt (seq, g);
4240 tree body = create_artificial_label (UNKNOWN_LOCATION);
4241 tree header = create_artificial_label (UNKNOWN_LOCATION);
4242 tree end = create_artificial_label (UNKNOWN_LOCATION);
4243 gimple_seq_add_stmt (seq, gimple_build_goto (header));
4244 gimple_seq_add_stmt (seq, gimple_build_label (body));
4245 gimple_seq_add_seq (seq, llist[i]);
4246 t = build_int_cst (unsigned_type_node, 1);
0d0e4a03 4247 g = gimple_build_assign (idx, PLUS_EXPR, idx, t);
74bf76ed
JJ
4248 gimple_seq_add_stmt (seq, g);
4249 gimple_seq_add_stmt (seq, gimple_build_label (header));
4250 g = gimple_build_cond (LT_EXPR, idx, vf, body, end);
4251 gimple_seq_add_stmt (seq, g);
4252 gimple_seq_add_stmt (seq, gimple_build_label (end));
4253 }
4254 }
4255
953ff289
DN
4256 /* The copyin sequence is not to be executed by the main thread, since
4257 that would result in self-copies. Perhaps not visible to scalars,
4258 but it certainly is to C++ operator=. */
4259 if (copyin_seq)
4260 {
e79983f4
MM
4261 x = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM),
4262 0);
953ff289
DN
4263 x = build2 (NE_EXPR, boolean_type_node, x,
4264 build_int_cst (TREE_TYPE (x), 0));
4265 x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
4266 gimplify_and_add (x, ilist);
4267 }
4268
4269 /* If any copyin variable is passed by reference, we must ensure the
4270 master thread doesn't modify it before it is copied over in all
8ca5b2a2
JJ
4271 threads. Similarly for variables in both firstprivate and
4272 lastprivate clauses we need to ensure the lastprivate copying
acf0174b
JJ
4273 happens after firstprivate copying in all threads. And similarly
4274 for UDRs if initializer expression refers to omp_orig. */
4275 if (copyin_by_ref || lastprivate_firstprivate || reduction_omp_orig_ref)
74bf76ed
JJ
4276 {
4277 /* Don't add any barrier for #pragma omp simd or
4278 #pragma omp distribute. */
4279 if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
e2110f8f 4280 || gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_FOR)
acf0174b 4281 gimple_seq_add_stmt (ilist, build_omp_barrier (NULL_TREE));
74bf76ed
JJ
4282 }
4283
4284 /* If max_vf is non-zero, then we can use only a vectorization factor
4285 up to the max_vf we chose. So stick it into the safelen clause. */
4286 if (max_vf)
4287 {
4288 tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
4289 OMP_CLAUSE_SAFELEN);
4290 if (c == NULL_TREE
b46ebd6c
JJ
4291 || (TREE_CODE (OMP_CLAUSE_SAFELEN_EXPR (c)) == INTEGER_CST
4292 && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c),
4293 max_vf) == 1))
74bf76ed
JJ
4294 {
4295 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
4296 OMP_CLAUSE_SAFELEN_EXPR (c) = build_int_cst (integer_type_node,
4297 max_vf);
4298 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
4299 gimple_omp_for_set_clauses (ctx->stmt, c);
4300 }
4301 }
953ff289
DN
4302}
4303
50674e96 4304
953ff289
DN
4305/* Generate code to implement the LASTPRIVATE clauses. This is used for
4306 both parallel and workshare constructs. PREDICATE may be NULL if it's
4307 always true. */
4308
4309static void
726a989a 4310lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
acf0174b 4311 omp_context *ctx)
953ff289 4312{
74bf76ed 4313 tree x, c, label = NULL, orig_clauses = clauses;
a68ab351 4314 bool par_clauses = false;
74bf76ed 4315 tree simduid = NULL, lastlane = NULL;
953ff289 4316
74bf76ed
JJ
4317 /* Early exit if there are no lastprivate or linear clauses. */
4318 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
4319 if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LASTPRIVATE
4320 || (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LINEAR
4321 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (clauses)))
4322 break;
953ff289
DN
4323 if (clauses == NULL)
4324 {
4325 /* If this was a workshare clause, see if it had been combined
4326 with its parallel. In that case, look for the clauses on the
4327 parallel statement itself. */
4328 if (is_parallel_ctx (ctx))
4329 return;
4330
4331 ctx = ctx->outer;
4332 if (ctx == NULL || !is_parallel_ctx (ctx))
4333 return;
4334
726a989a 4335 clauses = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
953ff289
DN
4336 OMP_CLAUSE_LASTPRIVATE);
4337 if (clauses == NULL)
4338 return;
a68ab351 4339 par_clauses = true;
953ff289
DN
4340 }
4341
726a989a
RB
4342 if (predicate)
4343 {
538dd0b7 4344 gcond *stmt;
726a989a
RB
4345 tree label_true, arm1, arm2;
4346
c2255bc4
AH
4347 label = create_artificial_label (UNKNOWN_LOCATION);
4348 label_true = create_artificial_label (UNKNOWN_LOCATION);
726a989a
RB
4349 arm1 = TREE_OPERAND (predicate, 0);
4350 arm2 = TREE_OPERAND (predicate, 1);
4351 gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
4352 gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
4353 stmt = gimple_build_cond (TREE_CODE (predicate), arm1, arm2,
4354 label_true, label);
4355 gimple_seq_add_stmt (stmt_list, stmt);
4356 gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
4357 }
953ff289 4358
74bf76ed 4359 if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
0aadce73 4360 && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
74bf76ed
JJ
4361 {
4362 simduid = find_omp_clause (orig_clauses, OMP_CLAUSE__SIMDUID_);
4363 if (simduid)
4364 simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
4365 }
4366
a68ab351 4367 for (c = clauses; c ;)
953ff289
DN
4368 {
4369 tree var, new_var;
db3927fb 4370 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
953ff289 4371
74bf76ed
JJ
4372 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
4373 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
4374 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
a68ab351
JJ
4375 {
4376 var = OMP_CLAUSE_DECL (c);
4377 new_var = lookup_decl (var, ctx);
953ff289 4378
74bf76ed
JJ
4379 if (simduid && DECL_HAS_VALUE_EXPR_P (new_var))
4380 {
4381 tree val = DECL_VALUE_EXPR (new_var);
4382 if (TREE_CODE (val) == ARRAY_REF
4383 && VAR_P (TREE_OPERAND (val, 0))
4384 && lookup_attribute ("omp simd array",
4385 DECL_ATTRIBUTES (TREE_OPERAND (val,
4386 0))))
4387 {
4388 if (lastlane == NULL)
4389 {
b731b390 4390 lastlane = create_tmp_var (unsigned_type_node);
538dd0b7 4391 gcall *g
74bf76ed
JJ
4392 = gimple_build_call_internal (IFN_GOMP_SIMD_LAST_LANE,
4393 2, simduid,
4394 TREE_OPERAND (val, 1));
4395 gimple_call_set_lhs (g, lastlane);
4396 gimple_seq_add_stmt (stmt_list, g);
4397 }
4398 new_var = build4 (ARRAY_REF, TREE_TYPE (val),
4399 TREE_OPERAND (val, 0), lastlane,
4400 NULL_TREE, NULL_TREE);
4401 }
4402 }
4403
4404 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
4405 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
726a989a 4406 {
355a7673 4407 lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
726a989a
RB
4408 gimple_seq_add_seq (stmt_list,
4409 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
74bf76ed 4410 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
726a989a 4411 }
f7468577
JJ
4412 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
4413 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
4414 {
4415 lower_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
4416 gimple_seq_add_seq (stmt_list,
4417 OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
4418 OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) = NULL;
4419 }
953ff289 4420
a68ab351
JJ
4421 x = build_outer_var_ref (var, ctx);
4422 if (is_reference (var))
70f34814 4423 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
a68ab351 4424 x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
726a989a 4425 gimplify_and_add (x, stmt_list);
a68ab351
JJ
4426 }
4427 c = OMP_CLAUSE_CHAIN (c);
4428 if (c == NULL && !par_clauses)
4429 {
4430 /* If this was a workshare clause, see if it had been combined
4431 with its parallel. In that case, continue looking for the
4432 clauses also on the parallel statement itself. */
4433 if (is_parallel_ctx (ctx))
4434 break;
4435
4436 ctx = ctx->outer;
4437 if (ctx == NULL || !is_parallel_ctx (ctx))
4438 break;
4439
726a989a 4440 c = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
a68ab351
JJ
4441 OMP_CLAUSE_LASTPRIVATE);
4442 par_clauses = true;
4443 }
953ff289
DN
4444 }
4445
726a989a
RB
4446 if (label)
4447 gimple_seq_add_stmt (stmt_list, gimple_build_label (label));
953ff289
DN
4448}
4449
41dbbb37
TS
4450static void
4451oacc_lower_reduction_var_helper (gimple_seq *stmt_seqp, omp_context *ctx,
4452 tree tid, tree var, tree new_var)
4453{
4454 /* The atomic add at the end of the sum creates unnecessary
4455 write contention on accelerators. To work around this,
4456 create an array to store the partial reductions. Later, in
4457 lower_omp_for (for openacc), the values of array will be
4458 combined. */
4459
4460 tree t = NULL_TREE, array, x;
4461 tree type = get_base_type (var);
4462 gimple stmt;
4463
4464 /* Now insert the partial reductions into the array. */
4465
4466 /* Find the reduction array. */
4467
4468 tree ptype = build_pointer_type (type);
4469
4470 t = lookup_oacc_reduction (oacc_get_reduction_array_id (var), ctx);
4471 t = build_receiver_ref (t, false, ctx->outer);
4472
4473 array = create_tmp_var (ptype);
4474 gimplify_assign (array, t, stmt_seqp);
4475
4476 tree ptr = create_tmp_var (TREE_TYPE (array));
4477
4478 /* Find the reduction array. */
4479
4480 /* testing a unary conversion. */
4481 tree offset = create_tmp_var (sizetype);
4482 gimplify_assign (offset, TYPE_SIZE_UNIT (type),
4483 stmt_seqp);
4484 t = create_tmp_var (sizetype);
4485 gimplify_assign (t, unshare_expr (fold_build1 (NOP_EXPR, sizetype, tid)),
4486 stmt_seqp);
4487 stmt = gimple_build_assign (offset, MULT_EXPR, offset, t);
4488 gimple_seq_add_stmt (stmt_seqp, stmt);
4489
4490 /* Offset expression. Does the POINTER_PLUS_EXPR take care
4491 of adding sizeof(var) to the array? */
4492 ptr = create_tmp_var (ptype);
4493 stmt = gimple_build_assign (unshare_expr (ptr), POINTER_PLUS_EXPR, array,
4494 offset);
4495 gimple_seq_add_stmt (stmt_seqp, stmt);
4496
4497 /* Move the local sum to gfc$sum[i]. */
4498 x = unshare_expr (build_simple_mem_ref (ptr));
4499 stmt = gimplify_assign (x, new_var, stmt_seqp);
4500}
50674e96 4501
953ff289
DN
4502/* Generate code to implement the REDUCTION clauses. */
4503
4504static void
726a989a 4505lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
953ff289 4506{
726a989a
RB
4507 gimple_seq sub_seq = NULL;
4508 gimple stmt;
41dbbb37 4509 tree x, c, tid = NULL_TREE;
953ff289
DN
4510 int count = 0;
4511
74bf76ed
JJ
4512 /* SIMD reductions are handled in lower_rec_input_clauses. */
4513 if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
0aadce73 4514 && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
74bf76ed
JJ
4515 return;
4516
953ff289
DN
4517 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
4518 update in that case, otherwise use a lock. */
4519 for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
aaf46ef9 4520 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
953ff289
DN
4521 {
4522 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
4523 {
acf0174b 4524 /* Never use OMP_ATOMIC for array reductions or UDRs. */
953ff289
DN
4525 count = -1;
4526 break;
4527 }
4528 count++;
4529 }
4530
4531 if (count == 0)
4532 return;
4533
41dbbb37
TS
4534 /* Initialize thread info for OpenACC. */
4535 if (is_gimple_omp_oacc (ctx->stmt))
4536 {
4537 /* Get the current thread id. */
4538 tree call = builtin_decl_explicit (BUILT_IN_GOACC_GET_THREAD_NUM);
4539 tid = create_tmp_var (TREE_TYPE (TREE_TYPE (call)));
4540 gimple stmt = gimple_build_call (call, 0);
4541 gimple_call_set_lhs (stmt, tid);
4542 gimple_seq_add_stmt (stmt_seqp, stmt);
4543 }
4544
953ff289
DN
4545 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
4546 {
4547 tree var, ref, new_var;
4548 enum tree_code code;
db3927fb 4549 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
953ff289 4550
aaf46ef9 4551 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
953ff289
DN
4552 continue;
4553
4554 var = OMP_CLAUSE_DECL (c);
4555 new_var = lookup_decl (var, ctx);
4556 if (is_reference (var))
70f34814 4557 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
953ff289
DN
4558 ref = build_outer_var_ref (var, ctx);
4559 code = OMP_CLAUSE_REDUCTION_CODE (c);
50674e96
DN
4560
4561 /* reduction(-:var) sums up the partial results, so it acts
4562 identically to reduction(+:var). */
953ff289
DN
4563 if (code == MINUS_EXPR)
4564 code = PLUS_EXPR;
4565
41dbbb37
TS
4566 if (is_gimple_omp_oacc (ctx->stmt))
4567 {
4568 gcc_checking_assert (!OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
4569
4570 oacc_lower_reduction_var_helper (stmt_seqp, ctx, tid, var, new_var);
4571 }
4572 else if (count == 1)
953ff289 4573 {
db3927fb 4574 tree addr = build_fold_addr_expr_loc (clause_loc, ref);
953ff289
DN
4575
4576 addr = save_expr (addr);
4577 ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
db3927fb 4578 x = fold_build2_loc (clause_loc, code, TREE_TYPE (ref), ref, new_var);
953ff289 4579 x = build2 (OMP_ATOMIC, void_type_node, addr, x);
726a989a 4580 gimplify_and_add (x, stmt_seqp);
953ff289
DN
4581 return;
4582 }
41dbbb37 4583 else if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
953ff289
DN
4584 {
4585 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
4586
acf0174b
JJ
4587 if (is_reference (var)
4588 && !useless_type_conversion_p (TREE_TYPE (placeholder),
4589 TREE_TYPE (ref)))
db3927fb 4590 ref = build_fold_addr_expr_loc (clause_loc, ref);
953ff289
DN
4591 SET_DECL_VALUE_EXPR (placeholder, ref);
4592 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
355a7673 4593 lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
726a989a
RB
4594 gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
4595 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
953ff289
DN
4596 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
4597 }
4598 else
4599 {
4600 x = build2 (code, TREE_TYPE (ref), ref, new_var);
4601 ref = build_outer_var_ref (var, ctx);
726a989a 4602 gimplify_assign (ref, x, &sub_seq);
953ff289
DN
4603 }
4604 }
4605
41dbbb37
TS
4606 if (is_gimple_omp_oacc (ctx->stmt))
4607 return;
4608
e79983f4
MM
4609 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START),
4610 0);
726a989a 4611 gimple_seq_add_stmt (stmt_seqp, stmt);
953ff289 4612
726a989a 4613 gimple_seq_add_seq (stmt_seqp, sub_seq);
953ff289 4614
e79983f4
MM
4615 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END),
4616 0);
726a989a 4617 gimple_seq_add_stmt (stmt_seqp, stmt);
953ff289
DN
4618}
4619
50674e96 4620
953ff289
DN
4621/* Generate code to implement the COPYPRIVATE clauses. */
4622
4623static void
726a989a 4624lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist,
953ff289
DN
4625 omp_context *ctx)
4626{
4627 tree c;
4628
4629 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
4630 {
78db7d92 4631 tree var, new_var, ref, x;
953ff289 4632 bool by_ref;
db3927fb 4633 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
953ff289 4634
aaf46ef9 4635 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
953ff289
DN
4636 continue;
4637
4638 var = OMP_CLAUSE_DECL (c);
7c8f7639 4639 by_ref = use_pointer_for_field (var, NULL);
953ff289
DN
4640
4641 ref = build_sender_ref (var, ctx);
78db7d92
JJ
4642 x = new_var = lookup_decl_in_outer_ctx (var, ctx);
4643 if (by_ref)
4644 {
4645 x = build_fold_addr_expr_loc (clause_loc, new_var);
4646 x = fold_convert_loc (clause_loc, TREE_TYPE (ref), x);
4647 }
726a989a 4648 gimplify_assign (ref, x, slist);
953ff289 4649
78db7d92
JJ
4650 ref = build_receiver_ref (var, false, ctx);
4651 if (by_ref)
4652 {
4653 ref = fold_convert_loc (clause_loc,
4654 build_pointer_type (TREE_TYPE (new_var)),
4655 ref);
4656 ref = build_fold_indirect_ref_loc (clause_loc, ref);
4657 }
953ff289
DN
4658 if (is_reference (var))
4659 {
78db7d92 4660 ref = fold_convert_loc (clause_loc, TREE_TYPE (new_var), ref);
70f34814
RG
4661 ref = build_simple_mem_ref_loc (clause_loc, ref);
4662 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
953ff289 4663 }
78db7d92 4664 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, ref);
953ff289
DN
4665 gimplify_and_add (x, rlist);
4666 }
4667}
4668
50674e96 4669
953ff289
DN
4670/* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
4671 and REDUCTION from the sender (aka parent) side. */
4672
4673static void
726a989a
RB
4674lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist,
4675 omp_context *ctx)
953ff289
DN
4676{
4677 tree c;
4678
4679 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
4680 {
50674e96 4681 tree val, ref, x, var;
953ff289 4682 bool by_ref, do_in = false, do_out = false;
db3927fb 4683 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
953ff289 4684
aaf46ef9 4685 switch (OMP_CLAUSE_CODE (c))
953ff289 4686 {
a68ab351
JJ
4687 case OMP_CLAUSE_PRIVATE:
4688 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
4689 break;
4690 continue;
953ff289
DN
4691 case OMP_CLAUSE_FIRSTPRIVATE:
4692 case OMP_CLAUSE_COPYIN:
4693 case OMP_CLAUSE_LASTPRIVATE:
4694 case OMP_CLAUSE_REDUCTION:
acf0174b 4695 case OMP_CLAUSE__LOOPTEMP_:
953ff289
DN
4696 break;
4697 default:
4698 continue;
4699 }
4700
d2dda7fe
JJ
4701 val = OMP_CLAUSE_DECL (c);
4702 var = lookup_decl_in_outer_ctx (val, ctx);
50674e96 4703
8ca5b2a2
JJ
4704 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
4705 && is_global_var (var))
4706 continue;
953ff289
DN
4707 if (is_variable_sized (val))
4708 continue;
7c8f7639 4709 by_ref = use_pointer_for_field (val, NULL);
953ff289 4710
aaf46ef9 4711 switch (OMP_CLAUSE_CODE (c))
953ff289 4712 {
a68ab351 4713 case OMP_CLAUSE_PRIVATE:
953ff289
DN
4714 case OMP_CLAUSE_FIRSTPRIVATE:
4715 case OMP_CLAUSE_COPYIN:
acf0174b 4716 case OMP_CLAUSE__LOOPTEMP_:
953ff289
DN
4717 do_in = true;
4718 break;
4719
4720 case OMP_CLAUSE_LASTPRIVATE:
4721 if (by_ref || is_reference (val))
4722 {
4723 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
4724 continue;
4725 do_in = true;
4726 }
4727 else
a68ab351
JJ
4728 {
4729 do_out = true;
4730 if (lang_hooks.decls.omp_private_outer_ref (val))
4731 do_in = true;
4732 }
953ff289
DN
4733 break;
4734
4735 case OMP_CLAUSE_REDUCTION:
4736 do_in = true;
4737 do_out = !(by_ref || is_reference (val));
4738 break;
4739
4740 default:
4741 gcc_unreachable ();
4742 }
4743
4744 if (do_in)
4745 {
4746 ref = build_sender_ref (val, ctx);
db3927fb 4747 x = by_ref ? build_fold_addr_expr_loc (clause_loc, var) : var;
726a989a 4748 gimplify_assign (ref, x, ilist);
a68ab351
JJ
4749 if (is_task_ctx (ctx))
4750 DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref, 1)) = NULL;
953ff289 4751 }
50674e96 4752
953ff289
DN
4753 if (do_out)
4754 {
4755 ref = build_sender_ref (val, ctx);
726a989a 4756 gimplify_assign (var, ref, olist);
953ff289
DN
4757 }
4758 }
4759}
4760
726a989a
RB
4761/* Generate code to implement SHARED from the sender (aka parent)
4762 side. This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
4763 list things that got automatically shared. */
953ff289
DN
4764
4765static void
726a989a 4766lower_send_shared_vars (gimple_seq *ilist, gimple_seq *olist, omp_context *ctx)
953ff289 4767{
a68ab351 4768 tree var, ovar, nvar, f, x, record_type;
953ff289
DN
4769
4770 if (ctx->record_type == NULL)
4771 return;
50674e96 4772
a68ab351 4773 record_type = ctx->srecord_type ? ctx->srecord_type : ctx->record_type;
910ad8de 4774 for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
953ff289
DN
4775 {
4776 ovar = DECL_ABSTRACT_ORIGIN (f);
4777 nvar = maybe_lookup_decl (ovar, ctx);
4778 if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
4779 continue;
4780
50674e96
DN
4781 /* If CTX is a nested parallel directive. Find the immediately
4782 enclosing parallel or workshare construct that contains a
4783 mapping for OVAR. */
d2dda7fe 4784 var = lookup_decl_in_outer_ctx (ovar, ctx);
50674e96 4785
7c8f7639 4786 if (use_pointer_for_field (ovar, ctx))
953ff289
DN
4787 {
4788 x = build_sender_ref (ovar, ctx);
50674e96 4789 var = build_fold_addr_expr (var);
726a989a 4790 gimplify_assign (x, var, ilist);
953ff289
DN
4791 }
4792 else
4793 {
4794 x = build_sender_ref (ovar, ctx);
726a989a 4795 gimplify_assign (x, var, ilist);
953ff289 4796
14e5b285
RG
4797 if (!TREE_READONLY (var)
4798 /* We don't need to receive a new reference to a result
4799 or parm decl. In fact we may not store to it as we will
4800 invalidate any pending RSO and generate wrong gimple
4801 during inlining. */
4802 && !((TREE_CODE (var) == RESULT_DECL
4803 || TREE_CODE (var) == PARM_DECL)
4804 && DECL_BY_REFERENCE (var)))
a68ab351
JJ
4805 {
4806 x = build_sender_ref (ovar, ctx);
726a989a 4807 gimplify_assign (var, x, olist);
a68ab351 4808 }
953ff289
DN
4809 }
4810 }
4811}
4812
726a989a
RB
4813
4814/* A convenience function to build an empty GIMPLE_COND with just the
4815 condition. */
4816
538dd0b7 4817static gcond *
726a989a
RB
4818gimple_build_cond_empty (tree cond)
4819{
4820 enum tree_code pred_code;
4821 tree lhs, rhs;
4822
4823 gimple_cond_get_ops_from_tree (cond, &pred_code, &lhs, &rhs);
4824 return gimple_build_cond (pred_code, lhs, rhs, NULL_TREE, NULL_TREE);
4825}
4826
4827
b8698a0f 4828/* Build the function calls to GOMP_parallel_start etc to actually
50674e96
DN
4829 generate the parallel operation. REGION is the parallel region
4830 being expanded. BB is the block where to insert the code. WS_ARGS
4831 will be set if this is a call to a combined parallel+workshare
4832 construct, it contains the list of additional arguments needed by
4833 the workshare construct. */
953ff289
DN
4834
4835static void
777f7f9a 4836expand_parallel_call (struct omp_region *region, basic_block bb,
538dd0b7
DM
4837 gomp_parallel *entry_stmt,
4838 vec<tree, va_gc> *ws_args)
953ff289 4839{
acf0174b 4840 tree t, t1, t2, val, cond, c, clauses, flags;
726a989a
RB
4841 gimple_stmt_iterator gsi;
4842 gimple stmt;
e79983f4
MM
4843 enum built_in_function start_ix;
4844 int start_ix2;
db3927fb 4845 location_t clause_loc;
9771b263 4846 vec<tree, va_gc> *args;
50674e96 4847
726a989a 4848 clauses = gimple_omp_parallel_clauses (entry_stmt);
50674e96 4849
acf0174b 4850 /* Determine what flavor of GOMP_parallel we will be
50674e96 4851 emitting. */
acf0174b 4852 start_ix = BUILT_IN_GOMP_PARALLEL;
50674e96
DN
4853 if (is_combined_parallel (region))
4854 {
777f7f9a 4855 switch (region->inner->type)
50674e96 4856 {
726a989a 4857 case GIMPLE_OMP_FOR:
a68ab351 4858 gcc_assert (region->inner->sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
acf0174b 4859 start_ix2 = ((int)BUILT_IN_GOMP_PARALLEL_LOOP_STATIC
e79983f4
MM
4860 + (region->inner->sched_kind
4861 == OMP_CLAUSE_SCHEDULE_RUNTIME
4862 ? 3 : region->inner->sched_kind));
4863 start_ix = (enum built_in_function)start_ix2;
777f7f9a 4864 break;
726a989a 4865 case GIMPLE_OMP_SECTIONS:
acf0174b 4866 start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS;
777f7f9a
RH
4867 break;
4868 default:
4869 gcc_unreachable ();
50674e96 4870 }
50674e96 4871 }
953ff289
DN
4872
4873 /* By default, the value of NUM_THREADS is zero (selected at run time)
4874 and there is no conditional. */
4875 cond = NULL_TREE;
4876 val = build_int_cst (unsigned_type_node, 0);
acf0174b 4877 flags = build_int_cst (unsigned_type_node, 0);
953ff289
DN
4878
4879 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
4880 if (c)
4881 cond = OMP_CLAUSE_IF_EXPR (c);
4882
4883 c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
4884 if (c)
db3927fb
AH
4885 {
4886 val = OMP_CLAUSE_NUM_THREADS_EXPR (c);
4887 clause_loc = OMP_CLAUSE_LOCATION (c);
4888 }
4889 else
4890 clause_loc = gimple_location (entry_stmt);
953ff289 4891
acf0174b
JJ
4892 c = find_omp_clause (clauses, OMP_CLAUSE_PROC_BIND);
4893 if (c)
4894 flags = build_int_cst (unsigned_type_node, OMP_CLAUSE_PROC_BIND_KIND (c));
4895
953ff289 4896 /* Ensure 'val' is of the correct type. */
db3927fb 4897 val = fold_convert_loc (clause_loc, unsigned_type_node, val);
953ff289
DN
4898
4899 /* If we found the clause 'if (cond)', build either
4900 (cond != 0) or (cond ? val : 1u). */
4901 if (cond)
4902 {
50674e96
DN
4903 cond = gimple_boolify (cond);
4904
953ff289 4905 if (integer_zerop (val))
db3927fb
AH
4906 val = fold_build2_loc (clause_loc,
4907 EQ_EXPR, unsigned_type_node, cond,
917948d3 4908 build_int_cst (TREE_TYPE (cond), 0));
953ff289 4909 else
50674e96
DN
4910 {
4911 basic_block cond_bb, then_bb, else_bb;
917948d3 4912 edge e, e_then, e_else;
726a989a 4913 tree tmp_then, tmp_else, tmp_join, tmp_var;
917948d3 4914
b731b390 4915 tmp_var = create_tmp_var (TREE_TYPE (val));
917948d3
ZD
4916 if (gimple_in_ssa_p (cfun))
4917 {
b731b390
JJ
4918 tmp_then = make_ssa_name (tmp_var);
4919 tmp_else = make_ssa_name (tmp_var);
4920 tmp_join = make_ssa_name (tmp_var);
917948d3
ZD
4921 }
4922 else
4923 {
4924 tmp_then = tmp_var;
4925 tmp_else = tmp_var;
4926 tmp_join = tmp_var;
4927 }
50674e96 4928
c4d281b2 4929 e = split_block_after_labels (bb);
50674e96
DN
4930 cond_bb = e->src;
4931 bb = e->dest;
4932 remove_edge (e);
4933
4934 then_bb = create_empty_bb (cond_bb);
4935 else_bb = create_empty_bb (then_bb);
917948d3
ZD
4936 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
4937 set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
50674e96 4938
726a989a
RB
4939 stmt = gimple_build_cond_empty (cond);
4940 gsi = gsi_start_bb (cond_bb);
4941 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
50674e96 4942
726a989a
RB
4943 gsi = gsi_start_bb (then_bb);
4944 stmt = gimple_build_assign (tmp_then, val);
4945 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
50674e96 4946
726a989a
RB
4947 gsi = gsi_start_bb (else_bb);
4948 stmt = gimple_build_assign
4949 (tmp_else, build_int_cst (unsigned_type_node, 1));
4950 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
50674e96
DN
4951
4952 make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
4953 make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
726338f4
RB
4954 add_bb_to_loop (then_bb, cond_bb->loop_father);
4955 add_bb_to_loop (else_bb, cond_bb->loop_father);
917948d3
ZD
4956 e_then = make_edge (then_bb, bb, EDGE_FALLTHRU);
4957 e_else = make_edge (else_bb, bb, EDGE_FALLTHRU);
50674e96 4958
917948d3
ZD
4959 if (gimple_in_ssa_p (cfun))
4960 {
538dd0b7 4961 gphi *phi = create_phi_node (tmp_join, bb);
9e227d60
DC
4962 add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION);
4963 add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION);
917948d3
ZD
4964 }
4965
4966 val = tmp_join;
50674e96
DN
4967 }
4968
726a989a
RB
4969 gsi = gsi_start_bb (bb);
4970 val = force_gimple_operand_gsi (&gsi, val, true, NULL_TREE,
4971 false, GSI_CONTINUE_LINKING);
953ff289
DN
4972 }
4973
726a989a
RB
4974 gsi = gsi_last_bb (bb);
4975 t = gimple_omp_parallel_data_arg (entry_stmt);
953ff289 4976 if (t == NULL)
5039610b 4977 t1 = null_pointer_node;
953ff289 4978 else
5039610b 4979 t1 = build_fold_addr_expr (t);
726a989a 4980 t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
50674e96 4981
acf0174b 4982 vec_alloc (args, 4 + vec_safe_length (ws_args));
9771b263
DN
4983 args->quick_push (t2);
4984 args->quick_push (t1);
4985 args->quick_push (val);
4986 if (ws_args)
4987 args->splice (*ws_args);
acf0174b 4988 args->quick_push (flags);
3bb06db4
NF
4989
4990 t = build_call_expr_loc_vec (UNKNOWN_LOCATION,
e79983f4 4991 builtin_decl_explicit (start_ix), args);
50674e96 4992
726a989a
RB
4993 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4994 false, GSI_CONTINUE_LINKING);
953ff289
DN
4995}
4996
9a771876
JJ
4997/* Insert a function call whose name is FUNC_NAME with the information from
4998 ENTRY_STMT into the basic_block BB. */
4999
5000static void
538dd0b7 5001expand_cilk_for_call (basic_block bb, gomp_parallel *entry_stmt,
9a771876
JJ
5002 vec <tree, va_gc> *ws_args)
5003{
5004 tree t, t1, t2;
5005 gimple_stmt_iterator gsi;
5006 vec <tree, va_gc> *args;
5007
5008 gcc_assert (vec_safe_length (ws_args) == 2);
5009 tree func_name = (*ws_args)[0];
5010 tree grain = (*ws_args)[1];
5011
5012 tree clauses = gimple_omp_parallel_clauses (entry_stmt);
5013 tree count = find_omp_clause (clauses, OMP_CLAUSE__CILK_FOR_COUNT_);
5014 gcc_assert (count != NULL_TREE);
5015 count = OMP_CLAUSE_OPERAND (count, 0);
5016
5017 gsi = gsi_last_bb (bb);
5018 t = gimple_omp_parallel_data_arg (entry_stmt);
5019 if (t == NULL)
5020 t1 = null_pointer_node;
5021 else
5022 t1 = build_fold_addr_expr (t);
5023 t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
5024
5025 vec_alloc (args, 4);
5026 args->quick_push (t2);
5027 args->quick_push (t1);
5028 args->quick_push (count);
5029 args->quick_push (grain);
5030 t = build_call_expr_loc_vec (UNKNOWN_LOCATION, func_name, args);
5031
5032 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, false,
5033 GSI_CONTINUE_LINKING);
5034}
50674e96 5035
a68ab351
JJ
5036/* Build the function call to GOMP_task to actually
5037 generate the task operation. BB is the block where to insert the code. */
5038
5039static void
538dd0b7 5040expand_task_call (basic_block bb, gomp_task *entry_stmt)
a68ab351 5041{
acf0174b 5042 tree t, t1, t2, t3, flags, cond, c, c2, clauses, depend;
726a989a 5043 gimple_stmt_iterator gsi;
db3927fb 5044 location_t loc = gimple_location (entry_stmt);
a68ab351 5045
726a989a 5046 clauses = gimple_omp_task_clauses (entry_stmt);
a68ab351 5047
a68ab351
JJ
5048 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
5049 if (c)
5050 cond = gimple_boolify (OMP_CLAUSE_IF_EXPR (c));
5051 else
5052 cond = boolean_true_node;
5053
5054 c = find_omp_clause (clauses, OMP_CLAUSE_UNTIED);
20906c66 5055 c2 = find_omp_clause (clauses, OMP_CLAUSE_MERGEABLE);
acf0174b 5056 depend = find_omp_clause (clauses, OMP_CLAUSE_DEPEND);
20906c66 5057 flags = build_int_cst (unsigned_type_node,
acf0174b 5058 (c ? 1 : 0) + (c2 ? 4 : 0) + (depend ? 8 : 0));
20906c66
JJ
5059
5060 c = find_omp_clause (clauses, OMP_CLAUSE_FINAL);
5061 if (c)
5062 {
5063 c = gimple_boolify (OMP_CLAUSE_FINAL_EXPR (c));
5064 c = fold_build3_loc (loc, COND_EXPR, unsigned_type_node, c,
5065 build_int_cst (unsigned_type_node, 2),
5066 build_int_cst (unsigned_type_node, 0));
5067 flags = fold_build2_loc (loc, PLUS_EXPR, unsigned_type_node, flags, c);
5068 }
acf0174b
JJ
5069 if (depend)
5070 depend = OMP_CLAUSE_DECL (depend);
5071 else
5072 depend = build_int_cst (ptr_type_node, 0);
a68ab351 5073
726a989a
RB
5074 gsi = gsi_last_bb (bb);
5075 t = gimple_omp_task_data_arg (entry_stmt);
a68ab351
JJ
5076 if (t == NULL)
5077 t2 = null_pointer_node;
5078 else
db3927fb
AH
5079 t2 = build_fold_addr_expr_loc (loc, t);
5080 t1 = build_fold_addr_expr_loc (loc, gimple_omp_task_child_fn (entry_stmt));
726a989a 5081 t = gimple_omp_task_copy_fn (entry_stmt);
a68ab351
JJ
5082 if (t == NULL)
5083 t3 = null_pointer_node;
5084 else
db3927fb 5085 t3 = build_fold_addr_expr_loc (loc, t);
a68ab351 5086
e79983f4 5087 t = build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_TASK),
acf0174b 5088 8, t1, t2, t3,
726a989a 5089 gimple_omp_task_arg_size (entry_stmt),
acf0174b
JJ
5090 gimple_omp_task_arg_align (entry_stmt), cond, flags,
5091 depend);
a68ab351 5092
726a989a
RB
5093 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
5094 false, GSI_CONTINUE_LINKING);
a68ab351
JJ
5095}
5096
5097
726a989a
RB
5098/* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
5099 catch handler and return it. This prevents programs from violating the
5100 structured block semantics with throws. */
953ff289 5101
726a989a
RB
5102static gimple_seq
5103maybe_catch_exception (gimple_seq body)
953ff289 5104{
1d65f45c
RH
5105 gimple g;
5106 tree decl;
953ff289
DN
5107
5108 if (!flag_exceptions)
726a989a 5109 return body;
953ff289 5110
3b06d379
SB
5111 if (lang_hooks.eh_protect_cleanup_actions != NULL)
5112 decl = lang_hooks.eh_protect_cleanup_actions ();
953ff289 5113 else
e79983f4 5114 decl = builtin_decl_explicit (BUILT_IN_TRAP);
726a989a 5115
1d65f45c
RH
5116 g = gimple_build_eh_must_not_throw (decl);
5117 g = gimple_build_try (body, gimple_seq_alloc_with_stmt (g),
726a989a 5118 GIMPLE_TRY_CATCH);
953ff289 5119
1d65f45c 5120 return gimple_seq_alloc_with_stmt (g);
953ff289
DN
5121}
5122
50674e96 5123/* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
953ff289 5124
50674e96 5125static tree
9771b263 5126vec2chain (vec<tree, va_gc> *v)
953ff289 5127{
c021f10b
NF
5128 tree chain = NULL_TREE, t;
5129 unsigned ix;
953ff289 5130
9771b263 5131 FOR_EACH_VEC_SAFE_ELT_REVERSE (v, ix, t)
50674e96 5132 {
910ad8de 5133 DECL_CHAIN (t) = chain;
c021f10b 5134 chain = t;
50674e96 5135 }
953ff289 5136
c021f10b 5137 return chain;
50674e96 5138}
953ff289 5139
953ff289 5140
50674e96 5141/* Remove barriers in REGION->EXIT's block. Note that this is only
726a989a
RB
5142 valid for GIMPLE_OMP_PARALLEL regions. Since the end of a parallel region
5143 is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
5144 left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
50674e96 5145 removed. */
953ff289 5146
50674e96
DN
5147static void
5148remove_exit_barrier (struct omp_region *region)
5149{
726a989a 5150 gimple_stmt_iterator gsi;
50674e96 5151 basic_block exit_bb;
777f7f9a
RH
5152 edge_iterator ei;
5153 edge e;
726a989a 5154 gimple stmt;
03742a9b 5155 int any_addressable_vars = -1;
953ff289 5156
777f7f9a 5157 exit_bb = region->exit;
953ff289 5158
2aee3e57
JJ
5159 /* If the parallel region doesn't return, we don't have REGION->EXIT
5160 block at all. */
5161 if (! exit_bb)
5162 return;
5163
726a989a
RB
5164 /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN. The
5165 workshare's GIMPLE_OMP_RETURN will be in a preceding block. The kinds of
777f7f9a
RH
5166 statements that can appear in between are extremely limited -- no
5167 memory operations at all. Here, we allow nothing at all, so the
726a989a
RB
5168 only thing we allow to precede this GIMPLE_OMP_RETURN is a label. */
5169 gsi = gsi_last_bb (exit_bb);
5170 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
5171 gsi_prev (&gsi);
5172 if (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
50674e96 5173 return;
953ff289 5174
777f7f9a
RH
5175 FOR_EACH_EDGE (e, ei, exit_bb->preds)
5176 {
726a989a
RB
5177 gsi = gsi_last_bb (e->src);
5178 if (gsi_end_p (gsi))
777f7f9a 5179 continue;
726a989a 5180 stmt = gsi_stmt (gsi);
03742a9b
JJ
5181 if (gimple_code (stmt) == GIMPLE_OMP_RETURN
5182 && !gimple_omp_return_nowait_p (stmt))
5183 {
5184 /* OpenMP 3.0 tasks unfortunately prevent this optimization
5185 in many cases. If there could be tasks queued, the barrier
5186 might be needed to let the tasks run before some local
5187 variable of the parallel that the task uses as shared
5188 runs out of scope. The task can be spawned either
5189 from within current function (this would be easy to check)
5190 or from some function it calls and gets passed an address
5191 of such a variable. */
5192 if (any_addressable_vars < 0)
5193 {
538dd0b7
DM
5194 gomp_parallel *parallel_stmt
5195 = as_a <gomp_parallel *> (last_stmt (region->entry));
03742a9b 5196 tree child_fun = gimple_omp_parallel_child_fn (parallel_stmt);
c021f10b
NF
5197 tree local_decls, block, decl;
5198 unsigned ix;
03742a9b
JJ
5199
5200 any_addressable_vars = 0;
c021f10b
NF
5201 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (child_fun), ix, decl)
5202 if (TREE_ADDRESSABLE (decl))
03742a9b
JJ
5203 {
5204 any_addressable_vars = 1;
5205 break;
5206 }
5207 for (block = gimple_block (stmt);
5208 !any_addressable_vars
5209 && block
5210 && TREE_CODE (block) == BLOCK;
5211 block = BLOCK_SUPERCONTEXT (block))
5212 {
5213 for (local_decls = BLOCK_VARS (block);
5214 local_decls;
910ad8de 5215 local_decls = DECL_CHAIN (local_decls))
03742a9b
JJ
5216 if (TREE_ADDRESSABLE (local_decls))
5217 {
5218 any_addressable_vars = 1;
5219 break;
5220 }
5221 if (block == gimple_block (parallel_stmt))
5222 break;
5223 }
5224 }
5225 if (!any_addressable_vars)
5226 gimple_omp_return_set_nowait (stmt);
5227 }
777f7f9a 5228 }
953ff289
DN
5229}
5230
777f7f9a
RH
5231static void
5232remove_exit_barriers (struct omp_region *region)
5233{
726a989a 5234 if (region->type == GIMPLE_OMP_PARALLEL)
777f7f9a
RH
5235 remove_exit_barrier (region);
5236
5237 if (region->inner)
5238 {
5239 region = region->inner;
5240 remove_exit_barriers (region);
5241 while (region->next)
5242 {
5243 region = region->next;
5244 remove_exit_barriers (region);
5245 }
5246 }
5247}
50674e96 5248
2b4cf991
JJ
5249/* Optimize omp_get_thread_num () and omp_get_num_threads ()
5250 calls. These can't be declared as const functions, but
5251 within one parallel body they are constant, so they can be
5252 transformed there into __builtin_omp_get_{thread_num,num_threads} ()
a68ab351
JJ
5253 which are declared const. Similarly for task body, except
5254 that in untied task omp_get_thread_num () can change at any task
5255 scheduling point. */
2b4cf991
JJ
5256
5257static void
726a989a 5258optimize_omp_library_calls (gimple entry_stmt)
2b4cf991
JJ
5259{
5260 basic_block bb;
726a989a 5261 gimple_stmt_iterator gsi;
e79983f4
MM
5262 tree thr_num_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
5263 tree thr_num_id = DECL_ASSEMBLER_NAME (thr_num_tree);
5264 tree num_thr_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
5265 tree num_thr_id = DECL_ASSEMBLER_NAME (num_thr_tree);
726a989a
RB
5266 bool untied_task = (gimple_code (entry_stmt) == GIMPLE_OMP_TASK
5267 && find_omp_clause (gimple_omp_task_clauses (entry_stmt),
a68ab351 5268 OMP_CLAUSE_UNTIED) != NULL);
2b4cf991 5269
11cd3bed 5270 FOR_EACH_BB_FN (bb, cfun)
726a989a 5271 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2b4cf991 5272 {
726a989a 5273 gimple call = gsi_stmt (gsi);
2b4cf991
JJ
5274 tree decl;
5275
726a989a
RB
5276 if (is_gimple_call (call)
5277 && (decl = gimple_call_fndecl (call))
2b4cf991
JJ
5278 && DECL_EXTERNAL (decl)
5279 && TREE_PUBLIC (decl)
5280 && DECL_INITIAL (decl) == NULL)
5281 {
5282 tree built_in;
5283
5284 if (DECL_NAME (decl) == thr_num_id)
a68ab351
JJ
5285 {
5286 /* In #pragma omp task untied omp_get_thread_num () can change
5287 during the execution of the task region. */
5288 if (untied_task)
5289 continue;
e79983f4 5290 built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
a68ab351 5291 }
2b4cf991 5292 else if (DECL_NAME (decl) == num_thr_id)
e79983f4 5293 built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
2b4cf991
JJ
5294 else
5295 continue;
5296
5297 if (DECL_ASSEMBLER_NAME (decl) != DECL_ASSEMBLER_NAME (built_in)
726a989a 5298 || gimple_call_num_args (call) != 0)
2b4cf991
JJ
5299 continue;
5300
5301 if (flag_exceptions && !TREE_NOTHROW (decl))
5302 continue;
5303
5304 if (TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE
9600efe1
MM
5305 || !types_compatible_p (TREE_TYPE (TREE_TYPE (decl)),
5306 TREE_TYPE (TREE_TYPE (built_in))))
2b4cf991
JJ
5307 continue;
5308
7c9577be 5309 gimple_call_set_fndecl (call, built_in);
2b4cf991
JJ
5310 }
5311 }
5312}
5313
5a0f4dd3
JJ
5314/* Callback for expand_omp_build_assign. Return non-NULL if *tp needs to be
5315 regimplified. */
5316
5317static tree
5318expand_omp_regimplify_p (tree *tp, int *walk_subtrees, void *)
5319{
5320 tree t = *tp;
5321
5322 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
5323 if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
5324 return t;
5325
5326 if (TREE_CODE (t) == ADDR_EXPR)
5327 recompute_tree_invariant_for_addr_expr (t);
5328
5329 *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
5330 return NULL_TREE;
5331}
5332
74bf76ed
JJ
5333/* Prepend TO = FROM assignment before *GSI_P. */
5334
5335static void
5336expand_omp_build_assign (gimple_stmt_iterator *gsi_p, tree to, tree from)
5337{
5338 bool simple_p = DECL_P (to) && TREE_ADDRESSABLE (to);
5339 from = force_gimple_operand_gsi (gsi_p, from, simple_p, NULL_TREE,
5340 true, GSI_SAME_STMT);
5341 gimple stmt = gimple_build_assign (to, from);
5342 gsi_insert_before (gsi_p, stmt, GSI_SAME_STMT);
5343 if (walk_tree (&from, expand_omp_regimplify_p, NULL, NULL)
5344 || walk_tree (&to, expand_omp_regimplify_p, NULL, NULL))
5345 {
5346 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
5347 gimple_regimplify_operands (stmt, &gsi);
5348 }
5349}
5350
a68ab351 5351/* Expand the OpenMP parallel or task directive starting at REGION. */
953ff289
DN
5352
5353static void
a68ab351 5354expand_omp_taskreg (struct omp_region *region)
953ff289 5355{
50674e96 5356 basic_block entry_bb, exit_bb, new_bb;
db2960f4 5357 struct function *child_cfun;
3bb06db4 5358 tree child_fn, block, t;
726a989a
RB
5359 gimple_stmt_iterator gsi;
5360 gimple entry_stmt, stmt;
50674e96 5361 edge e;
9771b263 5362 vec<tree, va_gc> *ws_args;
50674e96 5363
777f7f9a 5364 entry_stmt = last_stmt (region->entry);
726a989a 5365 child_fn = gimple_omp_taskreg_child_fn (entry_stmt);
50674e96 5366 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
50674e96 5367
777f7f9a 5368 entry_bb = region->entry;
b37dddbc
JJ
5369 if (gimple_code (entry_stmt) == GIMPLE_OMP_TASK)
5370 exit_bb = region->cont;
5371 else
5372 exit_bb = region->exit;
50674e96 5373
9a771876
JJ
5374 bool is_cilk_for
5375 = (flag_cilkplus
5376 && gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL
5377 && find_omp_clause (gimple_omp_parallel_clauses (entry_stmt),
5378 OMP_CLAUSE__CILK_FOR_COUNT_) != NULL_TREE);
5379
5380 if (is_cilk_for)
5381 /* If it is a _Cilk_for statement, it is modelled *like* a parallel for,
5382 and the inner statement contains the name of the built-in function
5383 and grain. */
5384 ws_args = region->inner->ws_args;
5385 else if (is_combined_parallel (region))
777f7f9a 5386 ws_args = region->ws_args;
50674e96 5387 else
3bb06db4 5388 ws_args = NULL;
953ff289 5389
777f7f9a 5390 if (child_cfun->cfg)
953ff289 5391 {
50674e96
DN
5392 /* Due to inlining, it may happen that we have already outlined
5393 the region, in which case all we need to do is make the
5394 sub-graph unreachable and emit the parallel call. */
5395 edge entry_succ_e, exit_succ_e;
50674e96
DN
5396
5397 entry_succ_e = single_succ_edge (entry_bb);
50674e96 5398
726a989a
RB
5399 gsi = gsi_last_bb (entry_bb);
5400 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_PARALLEL
5401 || gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_TASK);
5402 gsi_remove (&gsi, true);
50674e96
DN
5403
5404 new_bb = entry_bb;
d3c673c7
JJ
5405 if (exit_bb)
5406 {
5407 exit_succ_e = single_succ_edge (exit_bb);
5408 make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
5409 }
917948d3 5410 remove_edge_and_dominated_blocks (entry_succ_e);
953ff289 5411 }
50674e96
DN
5412 else
5413 {
2fed2012 5414 unsigned srcidx, dstidx, num;
c021f10b 5415
50674e96 5416 /* If the parallel region needs data sent from the parent
b570947c
JJ
5417 function, then the very first statement (except possible
5418 tree profile counter updates) of the parallel body
50674e96
DN
5419 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
5420 &.OMP_DATA_O is passed as an argument to the child function,
5421 we need to replace it with the argument as seen by the child
5422 function.
5423
5424 In most cases, this will end up being the identity assignment
5425 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
5426 a function call that has been inlined, the original PARM_DECL
5427 .OMP_DATA_I may have been converted into a different local
5428 variable. In which case, we need to keep the assignment. */
726a989a 5429 if (gimple_omp_taskreg_data_arg (entry_stmt))
50674e96 5430 {
b37dddbc
JJ
5431 basic_block entry_succ_bb
5432 = single_succ_p (entry_bb) ? single_succ (entry_bb)
5433 : FALLTHRU_EDGE (entry_bb)->dest;
726a989a
RB
5434 tree arg, narg;
5435 gimple parcopy_stmt = NULL;
953ff289 5436
726a989a 5437 for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
b570947c 5438 {
726a989a 5439 gimple stmt;
b570947c 5440
726a989a
RB
5441 gcc_assert (!gsi_end_p (gsi));
5442 stmt = gsi_stmt (gsi);
5443 if (gimple_code (stmt) != GIMPLE_ASSIGN)
018b899b
JJ
5444 continue;
5445
726a989a 5446 if (gimple_num_ops (stmt) == 2)
b570947c 5447 {
726a989a
RB
5448 tree arg = gimple_assign_rhs1 (stmt);
5449
5450 /* We're ignore the subcode because we're
5451 effectively doing a STRIP_NOPS. */
5452
5453 if (TREE_CODE (arg) == ADDR_EXPR
5454 && TREE_OPERAND (arg, 0)
5455 == gimple_omp_taskreg_data_arg (entry_stmt))
5456 {
5457 parcopy_stmt = stmt;
5458 break;
5459 }
b570947c
JJ
5460 }
5461 }
917948d3 5462
726a989a 5463 gcc_assert (parcopy_stmt != NULL);
917948d3
ZD
5464 arg = DECL_ARGUMENTS (child_fn);
5465
5466 if (!gimple_in_ssa_p (cfun))
5467 {
726a989a
RB
5468 if (gimple_assign_lhs (parcopy_stmt) == arg)
5469 gsi_remove (&gsi, true);
917948d3 5470 else
726a989a
RB
5471 {
5472 /* ?? Is setting the subcode really necessary ?? */
5473 gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (arg));
5474 gimple_assign_set_rhs1 (parcopy_stmt, arg);
5475 }
917948d3
ZD
5476 }
5477 else
5478 {
5479 /* If we are in ssa form, we must load the value from the default
5480 definition of the argument. That should not be defined now,
5481 since the argument is not used uninitialized. */
32244553 5482 gcc_assert (ssa_default_def (cfun, arg) == NULL);
726a989a 5483 narg = make_ssa_name (arg, gimple_build_nop ());
32244553 5484 set_ssa_default_def (cfun, arg, narg);
726a989a
RB
5485 /* ?? Is setting the subcode really necessary ?? */
5486 gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (narg));
5487 gimple_assign_set_rhs1 (parcopy_stmt, narg);
917948d3
ZD
5488 update_stmt (parcopy_stmt);
5489 }
50674e96
DN
5490 }
5491
5492 /* Declare local variables needed in CHILD_CFUN. */
5493 block = DECL_INITIAL (child_fn);
c021f10b 5494 BLOCK_VARS (block) = vec2chain (child_cfun->local_decls);
4f0ae266
JJ
5495 /* The gimplifier could record temporaries in parallel/task block
5496 rather than in containing function's local_decls chain,
5497 which would mean cgraph missed finalizing them. Do it now. */
910ad8de 5498 for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
4f0ae266
JJ
5499 if (TREE_CODE (t) == VAR_DECL
5500 && TREE_STATIC (t)
5501 && !DECL_EXTERNAL (t))
9041d2e6 5502 varpool_node::finalize_decl (t);
726a989a 5503 DECL_SAVED_TREE (child_fn) = NULL;
355a7673
MM
5504 /* We'll create a CFG for child_fn, so no gimple body is needed. */
5505 gimple_set_body (child_fn, NULL);
b357f682 5506 TREE_USED (block) = 1;
50674e96 5507
917948d3 5508 /* Reset DECL_CONTEXT on function arguments. */
910ad8de 5509 for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
50674e96
DN
5510 DECL_CONTEXT (t) = child_fn;
5511
726a989a
RB
5512 /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
5513 so that it can be moved to the child function. */
5514 gsi = gsi_last_bb (entry_bb);
5515 stmt = gsi_stmt (gsi);
5516 gcc_assert (stmt && (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
5517 || gimple_code (stmt) == GIMPLE_OMP_TASK));
726a989a 5518 e = split_block (entry_bb, stmt);
b13c907a 5519 gsi_remove (&gsi, true);
50674e96 5520 entry_bb = e->dest;
b37dddbc
JJ
5521 edge e2 = NULL;
5522 if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
5523 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
5524 else
5525 {
5526 e2 = make_edge (e->src, BRANCH_EDGE (entry_bb)->dest, EDGE_ABNORMAL);
5527 gcc_assert (e2->dest == region->exit);
5528 remove_edge (BRANCH_EDGE (entry_bb));
5529 set_immediate_dominator (CDI_DOMINATORS, e2->dest, e->src);
5530 gsi = gsi_last_bb (region->exit);
5531 gcc_assert (!gsi_end_p (gsi)
5532 && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
5533 gsi_remove (&gsi, true);
5534 }
50674e96 5535
b37dddbc 5536 /* Convert GIMPLE_OMP_{RETURN,CONTINUE} into a RETURN_EXPR. */
2aee3e57
JJ
5537 if (exit_bb)
5538 {
726a989a
RB
5539 gsi = gsi_last_bb (exit_bb);
5540 gcc_assert (!gsi_end_p (gsi)
b37dddbc
JJ
5541 && (gimple_code (gsi_stmt (gsi))
5542 == (e2 ? GIMPLE_OMP_CONTINUE : GIMPLE_OMP_RETURN)));
726a989a
RB
5543 stmt = gimple_build_return (NULL);
5544 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
5545 gsi_remove (&gsi, true);
2aee3e57 5546 }
917948d3
ZD
5547
5548 /* Move the parallel region into CHILD_CFUN. */
b8698a0f 5549
917948d3
ZD
5550 if (gimple_in_ssa_p (cfun))
5551 {
5db9ba0c 5552 init_tree_ssa (child_cfun);
3828719a
RG
5553 init_ssa_operands (child_cfun);
5554 child_cfun->gimple_df->in_ssa_p = true;
b357f682 5555 block = NULL_TREE;
917948d3 5556 }
b357f682 5557 else
726a989a 5558 block = gimple_block (entry_stmt);
b357f682
JJ
5559
5560 new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
917948d3
ZD
5561 if (exit_bb)
5562 single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
b37dddbc
JJ
5563 if (e2)
5564 {
5565 basic_block dest_bb = e2->dest;
5566 if (!exit_bb)
5567 make_edge (new_bb, dest_bb, EDGE_FALLTHRU);
5568 remove_edge (e2);
5569 set_immediate_dominator (CDI_DOMINATORS, dest_bb, new_bb);
5570 }
6093bc06
RB
5571 /* When the OMP expansion process cannot guarantee an up-to-date
5572 loop tree arrange for the child function to fixup loops. */
5573 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
5574 child_cfun->x_current_loops->state |= LOOPS_NEED_FIXUP;
917948d3 5575
b357f682 5576 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
9771b263 5577 num = vec_safe_length (child_cfun->local_decls);
2fed2012
JJ
5578 for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
5579 {
9771b263 5580 t = (*child_cfun->local_decls)[srcidx];
2fed2012
JJ
5581 if (DECL_CONTEXT (t) == cfun->decl)
5582 continue;
5583 if (srcidx != dstidx)
9771b263 5584 (*child_cfun->local_decls)[dstidx] = t;
2fed2012
JJ
5585 dstidx++;
5586 }
5587 if (dstidx != num)
9771b263 5588 vec_safe_truncate (child_cfun->local_decls, dstidx);
b357f682 5589
917948d3 5590 /* Inform the callgraph about the new function. */
d7ed20db 5591 DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
d52f5295 5592 cgraph_node::add_new_function (child_fn, true);
a79b7ec5 5593 cgraph_node::get (child_fn)->parallelized_function = 1;
917948d3
ZD
5594
5595 /* Fix the callgraph edges for child_cfun. Those for cfun will be
5596 fixed in a following pass. */
5597 push_cfun (child_cfun);
2b4cf991 5598 if (optimize)
a68ab351 5599 optimize_omp_library_calls (entry_stmt);
3dafb85c 5600 cgraph_edge::rebuild_edges ();
99819c63
JJ
5601
5602 /* Some EH regions might become dead, see PR34608. If
5603 pass_cleanup_cfg isn't the first pass to happen with the
5604 new child, these dead EH edges might cause problems.
5605 Clean them up now. */
5606 if (flag_exceptions)
5607 {
5608 basic_block bb;
99819c63
JJ
5609 bool changed = false;
5610
11cd3bed 5611 FOR_EACH_BB_FN (bb, cfun)
726a989a 5612 changed |= gimple_purge_dead_eh_edges (bb);
99819c63
JJ
5613 if (changed)
5614 cleanup_tree_cfg ();
99819c63 5615 }
5006671f
RG
5616 if (gimple_in_ssa_p (cfun))
5617 update_ssa (TODO_update_ssa);
917948d3 5618 pop_cfun ();
50674e96 5619 }
b8698a0f 5620
50674e96 5621 /* Emit a library call to launch the children threads. */
9a771876 5622 if (is_cilk_for)
538dd0b7
DM
5623 expand_cilk_for_call (new_bb,
5624 as_a <gomp_parallel *> (entry_stmt), ws_args);
9a771876 5625 else if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
538dd0b7
DM
5626 expand_parallel_call (region, new_bb,
5627 as_a <gomp_parallel *> (entry_stmt), ws_args);
a68ab351 5628 else
538dd0b7 5629 expand_task_call (new_bb, as_a <gomp_task *> (entry_stmt));
a5efada7
RG
5630 if (gimple_in_ssa_p (cfun))
5631 update_ssa (TODO_update_ssa_only_virtuals);
953ff289
DN
5632}
5633
50674e96 5634
74bf76ed
JJ
5635/* Helper function for expand_omp_{for_*,simd}. If this is the outermost
5636 of the combined collapse > 1 loop constructs, generate code like:
5637 if (__builtin_expect (N32 cond3 N31, 0)) goto ZERO_ITER_BB;
5638 if (cond3 is <)
5639 adj = STEP3 - 1;
5640 else
5641 adj = STEP3 + 1;
5642 count3 = (adj + N32 - N31) / STEP3;
5643 if (__builtin_expect (N22 cond2 N21, 0)) goto ZERO_ITER_BB;
5644 if (cond2 is <)
5645 adj = STEP2 - 1;
5646 else
5647 adj = STEP2 + 1;
5648 count2 = (adj + N22 - N21) / STEP2;
5649 if (__builtin_expect (N12 cond1 N11, 0)) goto ZERO_ITER_BB;
5650 if (cond1 is <)
5651 adj = STEP1 - 1;
5652 else
5653 adj = STEP1 + 1;
5654 count1 = (adj + N12 - N11) / STEP1;
5655 count = count1 * count2 * count3;
5656 Furthermore, if ZERO_ITER_BB is NULL, create a BB which does:
5657 count = 0;
acf0174b
JJ
5658 and set ZERO_ITER_BB to that bb. If this isn't the outermost
5659 of the combined loop constructs, just initialize COUNTS array
5660 from the _looptemp_ clauses. */
74bf76ed
JJ
5661
5662/* NOTE: It *could* be better to moosh all of the BBs together,
5663 creating one larger BB with all the computation and the unexpected
5664 jump at the end. I.e.
5665
5666 bool zero3, zero2, zero1, zero;
5667
5668 zero3 = N32 c3 N31;
5669 count3 = (N32 - N31) /[cl] STEP3;
5670 zero2 = N22 c2 N21;
5671 count2 = (N22 - N21) /[cl] STEP2;
5672 zero1 = N12 c1 N11;
5673 count1 = (N12 - N11) /[cl] STEP1;
5674 zero = zero3 || zero2 || zero1;
5675 count = count1 * count2 * count3;
5676 if (__builtin_expect(zero, false)) goto zero_iter_bb;
5677
5678 After all, we expect the zero=false, and thus we expect to have to
5679 evaluate all of the comparison expressions, so short-circuiting
5680 oughtn't be a win. Since the condition isn't protecting a
5681 denominator, we're not concerned about divide-by-zero, so we can
5682 fully evaluate count even if a numerator turned out to be wrong.
5683
5684 It seems like putting this all together would create much better
5685 scheduling opportunities, and less pressure on the chip's branch
5686 predictor. */
5687
5688static void
5689expand_omp_for_init_counts (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
5690 basic_block &entry_bb, tree *counts,
5691 basic_block &zero_iter_bb, int &first_zero_iter,
5692 basic_block &l2_dom_bb)
5693{
5694 tree t, type = TREE_TYPE (fd->loop.v);
74bf76ed
JJ
5695 edge e, ne;
5696 int i;
5697
5698 /* Collapsed loops need work for expansion into SSA form. */
5699 gcc_assert (!gimple_in_ssa_p (cfun));
5700
acf0174b
JJ
5701 if (gimple_omp_for_combined_into_p (fd->for_stmt)
5702 && TREE_CODE (fd->loop.n2) != INTEGER_CST)
5703 {
5704 /* First two _looptemp_ clauses are for istart/iend, counts[0]
5705 isn't supposed to be handled, as the inner loop doesn't
5706 use it. */
5707 tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
5708 OMP_CLAUSE__LOOPTEMP_);
5709 gcc_assert (innerc);
5710 for (i = 0; i < fd->collapse; i++)
5711 {
5712 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
5713 OMP_CLAUSE__LOOPTEMP_);
5714 gcc_assert (innerc);
5715 if (i)
5716 counts[i] = OMP_CLAUSE_DECL (innerc);
5717 else
5718 counts[0] = NULL_TREE;
5719 }
5720 return;
5721 }
5722
74bf76ed
JJ
5723 for (i = 0; i < fd->collapse; i++)
5724 {
5725 tree itype = TREE_TYPE (fd->loops[i].v);
5726
5727 if (SSA_VAR_P (fd->loop.n2)
5728 && ((t = fold_binary (fd->loops[i].cond_code, boolean_type_node,
5729 fold_convert (itype, fd->loops[i].n1),
5730 fold_convert (itype, fd->loops[i].n2)))
5731 == NULL_TREE || !integer_onep (t)))
5732 {
538dd0b7 5733 gcond *cond_stmt;
74bf76ed
JJ
5734 tree n1, n2;
5735 n1 = fold_convert (itype, unshare_expr (fd->loops[i].n1));
5736 n1 = force_gimple_operand_gsi (gsi, n1, true, NULL_TREE,
5737 true, GSI_SAME_STMT);
5738 n2 = fold_convert (itype, unshare_expr (fd->loops[i].n2));
5739 n2 = force_gimple_operand_gsi (gsi, n2, true, NULL_TREE,
5740 true, GSI_SAME_STMT);
538dd0b7
DM
5741 cond_stmt = gimple_build_cond (fd->loops[i].cond_code, n1, n2,
5742 NULL_TREE, NULL_TREE);
5743 gsi_insert_before (gsi, cond_stmt, GSI_SAME_STMT);
5744 if (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
74bf76ed 5745 expand_omp_regimplify_p, NULL, NULL)
538dd0b7 5746 || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
74bf76ed
JJ
5747 expand_omp_regimplify_p, NULL, NULL))
5748 {
538dd0b7
DM
5749 *gsi = gsi_for_stmt (cond_stmt);
5750 gimple_regimplify_operands (cond_stmt, gsi);
74bf76ed 5751 }
538dd0b7 5752 e = split_block (entry_bb, cond_stmt);
74bf76ed
JJ
5753 if (zero_iter_bb == NULL)
5754 {
538dd0b7 5755 gassign *assign_stmt;
74bf76ed
JJ
5756 first_zero_iter = i;
5757 zero_iter_bb = create_empty_bb (entry_bb);
726338f4 5758 add_bb_to_loop (zero_iter_bb, entry_bb->loop_father);
74bf76ed 5759 *gsi = gsi_after_labels (zero_iter_bb);
538dd0b7
DM
5760 assign_stmt = gimple_build_assign (fd->loop.n2,
5761 build_zero_cst (type));
5762 gsi_insert_before (gsi, assign_stmt, GSI_SAME_STMT);
74bf76ed
JJ
5763 set_immediate_dominator (CDI_DOMINATORS, zero_iter_bb,
5764 entry_bb);
5765 }
5766 ne = make_edge (entry_bb, zero_iter_bb, EDGE_FALSE_VALUE);
5767 ne->probability = REG_BR_PROB_BASE / 2000 - 1;
5768 e->flags = EDGE_TRUE_VALUE;
5769 e->probability = REG_BR_PROB_BASE - ne->probability;
5770 if (l2_dom_bb == NULL)
5771 l2_dom_bb = entry_bb;
5772 entry_bb = e->dest;
5773 *gsi = gsi_last_bb (entry_bb);
5774 }
5775
5776 if (POINTER_TYPE_P (itype))
5777 itype = signed_type_for (itype);
5778 t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR
5779 ? -1 : 1));
5780 t = fold_build2 (PLUS_EXPR, itype,
5781 fold_convert (itype, fd->loops[i].step), t);
5782 t = fold_build2 (PLUS_EXPR, itype, t,
5783 fold_convert (itype, fd->loops[i].n2));
5784 t = fold_build2 (MINUS_EXPR, itype, t,
5785 fold_convert (itype, fd->loops[i].n1));
5786 /* ?? We could probably use CEIL_DIV_EXPR instead of
5787 TRUNC_DIV_EXPR and adjusting by hand. Unless we can't
5788 generate the same code in the end because generically we
5789 don't know that the values involved must be negative for
5790 GT?? */
5791 if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
5792 t = fold_build2 (TRUNC_DIV_EXPR, itype,
5793 fold_build1 (NEGATE_EXPR, itype, t),
5794 fold_build1 (NEGATE_EXPR, itype,
5795 fold_convert (itype,
5796 fd->loops[i].step)));
5797 else
5798 t = fold_build2 (TRUNC_DIV_EXPR, itype, t,
5799 fold_convert (itype, fd->loops[i].step));
5800 t = fold_convert (type, t);
5801 if (TREE_CODE (t) == INTEGER_CST)
5802 counts[i] = t;
5803 else
5804 {
5805 counts[i] = create_tmp_reg (type, ".count");
5806 expand_omp_build_assign (gsi, counts[i], t);
5807 }
5808 if (SSA_VAR_P (fd->loop.n2))
5809 {
5810 if (i == 0)
5811 t = counts[0];
5812 else
5813 t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
5814 expand_omp_build_assign (gsi, fd->loop.n2, t);
5815 }
5816 }
5817}
5818
5819
5820/* Helper function for expand_omp_{for_*,simd}. Generate code like:
5821 T = V;
5822 V3 = N31 + (T % count3) * STEP3;
5823 T = T / count3;
5824 V2 = N21 + (T % count2) * STEP2;
5825 T = T / count2;
5826 V1 = N11 + T * STEP1;
acf0174b
JJ
5827 if this loop doesn't have an inner loop construct combined with it.
5828 If it does have an inner loop construct combined with it and the
5829 iteration count isn't known constant, store values from counts array
5830 into its _looptemp_ temporaries instead. */
74bf76ed
JJ
5831
5832static void
5833expand_omp_for_init_vars (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
acf0174b 5834 tree *counts, gimple inner_stmt, tree startvar)
74bf76ed
JJ
5835{
5836 int i;
acf0174b
JJ
5837 if (gimple_omp_for_combined_p (fd->for_stmt))
5838 {
5839 /* If fd->loop.n2 is constant, then no propagation of the counts
5840 is needed, they are constant. */
5841 if (TREE_CODE (fd->loop.n2) == INTEGER_CST)
5842 return;
5843
5844 tree clauses = gimple_code (inner_stmt) == GIMPLE_OMP_PARALLEL
5845 ? gimple_omp_parallel_clauses (inner_stmt)
5846 : gimple_omp_for_clauses (inner_stmt);
5847 /* First two _looptemp_ clauses are for istart/iend, counts[0]
5848 isn't supposed to be handled, as the inner loop doesn't
5849 use it. */
5850 tree innerc = find_omp_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
5851 gcc_assert (innerc);
5852 for (i = 0; i < fd->collapse; i++)
5853 {
5854 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
5855 OMP_CLAUSE__LOOPTEMP_);
5856 gcc_assert (innerc);
5857 if (i)
5858 {
5859 tree tem = OMP_CLAUSE_DECL (innerc);
5860 tree t = fold_convert (TREE_TYPE (tem), counts[i]);
5861 t = force_gimple_operand_gsi (gsi, t, false, NULL_TREE,
5862 false, GSI_CONTINUE_LINKING);
538dd0b7 5863 gassign *stmt = gimple_build_assign (tem, t);
acf0174b
JJ
5864 gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
5865 }
5866 }
5867 return;
5868 }
5869
74bf76ed
JJ
5870 tree type = TREE_TYPE (fd->loop.v);
5871 tree tem = create_tmp_reg (type, ".tem");
538dd0b7 5872 gassign *stmt = gimple_build_assign (tem, startvar);
74bf76ed
JJ
5873 gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
5874
5875 for (i = fd->collapse - 1; i >= 0; i--)
5876 {
5877 tree vtype = TREE_TYPE (fd->loops[i].v), itype, t;
5878 itype = vtype;
5879 if (POINTER_TYPE_P (vtype))
5880 itype = signed_type_for (vtype);
5881 if (i != 0)
5882 t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
5883 else
5884 t = tem;
5885 t = fold_convert (itype, t);
5886 t = fold_build2 (MULT_EXPR, itype, t,
5887 fold_convert (itype, fd->loops[i].step));
5888 if (POINTER_TYPE_P (vtype))
5889 t = fold_build_pointer_plus (fd->loops[i].n1, t);
5890 else
5891 t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
5892 t = force_gimple_operand_gsi (gsi, t,
5893 DECL_P (fd->loops[i].v)
5894 && TREE_ADDRESSABLE (fd->loops[i].v),
5895 NULL_TREE, false,
5896 GSI_CONTINUE_LINKING);
5897 stmt = gimple_build_assign (fd->loops[i].v, t);
5898 gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
5899 if (i != 0)
5900 {
5901 t = fold_build2 (TRUNC_DIV_EXPR, type, tem, counts[i]);
5902 t = force_gimple_operand_gsi (gsi, t, false, NULL_TREE,
5903 false, GSI_CONTINUE_LINKING);
5904 stmt = gimple_build_assign (tem, t);
5905 gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
5906 }
5907 }
5908}
5909
5910
5911/* Helper function for expand_omp_for_*. Generate code like:
5912 L10:
5913 V3 += STEP3;
5914 if (V3 cond3 N32) goto BODY_BB; else goto L11;
5915 L11:
5916 V3 = N31;
5917 V2 += STEP2;
5918 if (V2 cond2 N22) goto BODY_BB; else goto L12;
5919 L12:
5920 V2 = N21;
5921 V1 += STEP1;
5922 goto BODY_BB; */
5923
5924static basic_block
5925extract_omp_for_update_vars (struct omp_for_data *fd, basic_block cont_bb,
5926 basic_block body_bb)
5927{
5928 basic_block last_bb, bb, collapse_bb = NULL;
5929 int i;
5930 gimple_stmt_iterator gsi;
5931 edge e;
5932 tree t;
5933 gimple stmt;
5934
5935 last_bb = cont_bb;
5936 for (i = fd->collapse - 1; i >= 0; i--)
5937 {
5938 tree vtype = TREE_TYPE (fd->loops[i].v);
5939
5940 bb = create_empty_bb (last_bb);
726338f4 5941 add_bb_to_loop (bb, last_bb->loop_father);
74bf76ed
JJ
5942 gsi = gsi_start_bb (bb);
5943
5944 if (i < fd->collapse - 1)
5945 {
5946 e = make_edge (last_bb, bb, EDGE_FALSE_VALUE);
5947 e->probability = REG_BR_PROB_BASE / 8;
5948
5949 t = fd->loops[i + 1].n1;
5950 t = force_gimple_operand_gsi (&gsi, t,
5951 DECL_P (fd->loops[i + 1].v)
5952 && TREE_ADDRESSABLE (fd->loops[i
5953 + 1].v),
5954 NULL_TREE, false,
5955 GSI_CONTINUE_LINKING);
5956 stmt = gimple_build_assign (fd->loops[i + 1].v, t);
5957 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
5958 }
5959 else
5960 collapse_bb = bb;
5961
5962 set_immediate_dominator (CDI_DOMINATORS, bb, last_bb);
5963
5964 if (POINTER_TYPE_P (vtype))
5965 t = fold_build_pointer_plus (fd->loops[i].v, fd->loops[i].step);
5966 else
5967 t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v, fd->loops[i].step);
5968 t = force_gimple_operand_gsi (&gsi, t,
5969 DECL_P (fd->loops[i].v)
5970 && TREE_ADDRESSABLE (fd->loops[i].v),
5971 NULL_TREE, false, GSI_CONTINUE_LINKING);
5972 stmt = gimple_build_assign (fd->loops[i].v, t);
5973 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
5974
5975 if (i > 0)
5976 {
5977 t = fd->loops[i].n2;
5978 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
5979 false, GSI_CONTINUE_LINKING);
5980 tree v = fd->loops[i].v;
5981 if (DECL_P (v) && TREE_ADDRESSABLE (v))
5982 v = force_gimple_operand_gsi (&gsi, v, true, NULL_TREE,
5983 false, GSI_CONTINUE_LINKING);
5984 t = fold_build2 (fd->loops[i].cond_code, boolean_type_node, v, t);
5985 stmt = gimple_build_cond_empty (t);
5986 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
5987 e = make_edge (bb, body_bb, EDGE_TRUE_VALUE);
5988 e->probability = REG_BR_PROB_BASE * 7 / 8;
5989 }
5990 else
5991 make_edge (bb, body_bb, EDGE_FALLTHRU);
5992 last_bb = bb;
5993 }
5994
5995 return collapse_bb;
5996}
5997
5998
50674e96 5999/* A subroutine of expand_omp_for. Generate code for a parallel
953ff289
DN
6000 loop with any schedule. Given parameters:
6001
6002 for (V = N1; V cond N2; V += STEP) BODY;
6003
6004 where COND is "<" or ">", we generate pseudocode
6005
6006 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
50674e96 6007 if (more) goto L0; else goto L3;
953ff289
DN
6008 L0:
6009 V = istart0;
6010 iend = iend0;
6011 L1:
6012 BODY;
6013 V += STEP;
50674e96 6014 if (V cond iend) goto L1; else goto L2;
953ff289 6015 L2:
50674e96
DN
6016 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
6017 L3:
953ff289 6018
50674e96 6019 If this is a combined omp parallel loop, instead of the call to
a68ab351 6020 GOMP_loop_foo_start, we call GOMP_loop_foo_next.
acf0174b
JJ
6021 If this is gimple_omp_for_combined_p loop, then instead of assigning
6022 V and iend in L0 we assign the first two _looptemp_ clause decls of the
6023 inner GIMPLE_OMP_FOR and V += STEP; and
6024 if (V cond iend) goto L1; else goto L2; are removed.
a68ab351
JJ
6025
6026 For collapsed loops, given parameters:
6027 collapse(3)
6028 for (V1 = N11; V1 cond1 N12; V1 += STEP1)
6029 for (V2 = N21; V2 cond2 N22; V2 += STEP2)
6030 for (V3 = N31; V3 cond3 N32; V3 += STEP3)
6031 BODY;
6032
6033 we generate pseudocode
6034
5a0f4dd3 6035 if (__builtin_expect (N32 cond3 N31, 0)) goto Z0;
a68ab351
JJ
6036 if (cond3 is <)
6037 adj = STEP3 - 1;
6038 else
6039 adj = STEP3 + 1;
6040 count3 = (adj + N32 - N31) / STEP3;
5a0f4dd3 6041 if (__builtin_expect (N22 cond2 N21, 0)) goto Z0;
a68ab351
JJ
6042 if (cond2 is <)
6043 adj = STEP2 - 1;
6044 else
6045 adj = STEP2 + 1;
6046 count2 = (adj + N22 - N21) / STEP2;
5a0f4dd3 6047 if (__builtin_expect (N12 cond1 N11, 0)) goto Z0;
a68ab351
JJ
6048 if (cond1 is <)
6049 adj = STEP1 - 1;
6050 else
6051 adj = STEP1 + 1;
6052 count1 = (adj + N12 - N11) / STEP1;
6053 count = count1 * count2 * count3;
5a0f4dd3
JJ
6054 goto Z1;
6055 Z0:
6056 count = 0;
6057 Z1:
a68ab351
JJ
6058 more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
6059 if (more) goto L0; else goto L3;
6060 L0:
6061 V = istart0;
6062 T = V;
6063 V3 = N31 + (T % count3) * STEP3;
6064 T = T / count3;
6065 V2 = N21 + (T % count2) * STEP2;
6066 T = T / count2;
6067 V1 = N11 + T * STEP1;
6068 iend = iend0;
6069 L1:
6070 BODY;
6071 V += 1;
6072 if (V < iend) goto L10; else goto L2;
6073 L10:
6074 V3 += STEP3;
6075 if (V3 cond3 N32) goto L1; else goto L11;
6076 L11:
6077 V3 = N31;
6078 V2 += STEP2;
6079 if (V2 cond2 N22) goto L1; else goto L12;
6080 L12:
6081 V2 = N21;
6082 V1 += STEP1;
6083 goto L1;
6084 L2:
6085 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
6086 L3:
6087
6088 */
953ff289 6089
777f7f9a 6090static void
50674e96
DN
6091expand_omp_for_generic (struct omp_region *region,
6092 struct omp_for_data *fd,
953ff289 6093 enum built_in_function start_fn,
acf0174b
JJ
6094 enum built_in_function next_fn,
6095 gimple inner_stmt)
953ff289 6096{
726a989a 6097 tree type, istart0, iend0, iend;
a68ab351
JJ
6098 tree t, vmain, vback, bias = NULL_TREE;
6099 basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, collapse_bb;
d3c673c7 6100 basic_block l2_bb = NULL, l3_bb = NULL;
726a989a 6101 gimple_stmt_iterator gsi;
538dd0b7 6102 gassign *assign_stmt;
50674e96 6103 bool in_combined_parallel = is_combined_parallel (region);
e5c95afe 6104 bool broken_loop = region->cont == NULL;
917948d3 6105 edge e, ne;
a68ab351
JJ
6106 tree *counts = NULL;
6107 int i;
e5c95afe
ZD
6108
6109 gcc_assert (!broken_loop || !in_combined_parallel);
a68ab351
JJ
6110 gcc_assert (fd->iter_type == long_integer_type_node
6111 || !in_combined_parallel);
953ff289 6112
a68ab351
JJ
6113 type = TREE_TYPE (fd->loop.v);
6114 istart0 = create_tmp_var (fd->iter_type, ".istart0");
6115 iend0 = create_tmp_var (fd->iter_type, ".iend0");
5b4fc8fb
JJ
6116 TREE_ADDRESSABLE (istart0) = 1;
6117 TREE_ADDRESSABLE (iend0) = 1;
953ff289 6118
a68ab351
JJ
6119 /* See if we need to bias by LLONG_MIN. */
6120 if (fd->iter_type == long_long_unsigned_type_node
6121 && TREE_CODE (type) == INTEGER_TYPE
6122 && !TYPE_UNSIGNED (type))
6123 {
6124 tree n1, n2;
6125
6126 if (fd->loop.cond_code == LT_EXPR)
6127 {
6128 n1 = fd->loop.n1;
6129 n2 = fold_build2 (PLUS_EXPR, type, fd->loop.n2, fd->loop.step);
6130 }
6131 else
6132 {
6133 n1 = fold_build2 (MINUS_EXPR, type, fd->loop.n2, fd->loop.step);
6134 n2 = fd->loop.n1;
6135 }
6136 if (TREE_CODE (n1) != INTEGER_CST
6137 || TREE_CODE (n2) != INTEGER_CST
6138 || ((tree_int_cst_sgn (n1) < 0) ^ (tree_int_cst_sgn (n2) < 0)))
6139 bias = fold_convert (fd->iter_type, TYPE_MIN_VALUE (type));
6140 }
6141
777f7f9a 6142 entry_bb = region->entry;
d3c673c7 6143 cont_bb = region->cont;
a68ab351 6144 collapse_bb = NULL;
e5c95afe
ZD
6145 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
6146 gcc_assert (broken_loop
6147 || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
6148 l0_bb = split_edge (FALLTHRU_EDGE (entry_bb));
6149 l1_bb = single_succ (l0_bb);
6150 if (!broken_loop)
d3c673c7
JJ
6151 {
6152 l2_bb = create_empty_bb (cont_bb);
e5c95afe
ZD
6153 gcc_assert (BRANCH_EDGE (cont_bb)->dest == l1_bb);
6154 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
d3c673c7 6155 }
e5c95afe
ZD
6156 else
6157 l2_bb = NULL;
6158 l3_bb = BRANCH_EDGE (entry_bb)->dest;
6159 exit_bb = region->exit;
50674e96 6160
726a989a 6161 gsi = gsi_last_bb (entry_bb);
a68ab351 6162
726a989a 6163 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
a68ab351
JJ
6164 if (fd->collapse > 1)
6165 {
5a0f4dd3 6166 int first_zero_iter = -1;
74bf76ed 6167 basic_block zero_iter_bb = NULL, l2_dom_bb = NULL;
5a0f4dd3 6168
74bf76ed
JJ
6169 counts = XALLOCAVEC (tree, fd->collapse);
6170 expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
6171 zero_iter_bb, first_zero_iter,
6172 l2_dom_bb);
a68ab351 6173
5a0f4dd3
JJ
6174 if (zero_iter_bb)
6175 {
6176 /* Some counts[i] vars might be uninitialized if
6177 some loop has zero iterations. But the body shouldn't
6178 be executed in that case, so just avoid uninit warnings. */
6179 for (i = first_zero_iter; i < fd->collapse; i++)
6180 if (SSA_VAR_P (counts[i]))
6181 TREE_NO_WARNING (counts[i]) = 1;
6182 gsi_prev (&gsi);
6183 e = split_block (entry_bb, gsi_stmt (gsi));
6184 entry_bb = e->dest;
6185 make_edge (zero_iter_bb, entry_bb, EDGE_FALLTHRU);
6186 gsi = gsi_last_bb (entry_bb);
6187 set_immediate_dominator (CDI_DOMINATORS, entry_bb,
6188 get_immediate_dominator (CDI_DOMINATORS,
6189 zero_iter_bb));
6190 }
a68ab351 6191 }
917948d3
ZD
6192 if (in_combined_parallel)
6193 {
6194 /* In a combined parallel loop, emit a call to
6195 GOMP_loop_foo_next. */
e79983f4 6196 t = build_call_expr (builtin_decl_explicit (next_fn), 2,
917948d3
ZD
6197 build_fold_addr_expr (istart0),
6198 build_fold_addr_expr (iend0));
6199 }
6200 else
953ff289 6201 {
5039610b 6202 tree t0, t1, t2, t3, t4;
50674e96
DN
6203 /* If this is not a combined parallel loop, emit a call to
6204 GOMP_loop_foo_start in ENTRY_BB. */
5039610b
SL
6205 t4 = build_fold_addr_expr (iend0);
6206 t3 = build_fold_addr_expr (istart0);
a68ab351 6207 t2 = fold_convert (fd->iter_type, fd->loop.step);
74bf76ed
JJ
6208 t1 = fd->loop.n2;
6209 t0 = fd->loop.n1;
acf0174b
JJ
6210 if (gimple_omp_for_combined_into_p (fd->for_stmt))
6211 {
6212 tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
6213 OMP_CLAUSE__LOOPTEMP_);
6214 gcc_assert (innerc);
6215 t0 = OMP_CLAUSE_DECL (innerc);
6216 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
6217 OMP_CLAUSE__LOOPTEMP_);
6218 gcc_assert (innerc);
6219 t1 = OMP_CLAUSE_DECL (innerc);
6220 }
74bf76ed
JJ
6221 if (POINTER_TYPE_P (TREE_TYPE (t0))
6222 && TYPE_PRECISION (TREE_TYPE (t0))
6223 != TYPE_PRECISION (fd->iter_type))
c6ff4493
SE
6224 {
6225 /* Avoid casting pointers to integer of a different size. */
96f9265a 6226 tree itype = signed_type_for (type);
74bf76ed
JJ
6227 t1 = fold_convert (fd->iter_type, fold_convert (itype, t1));
6228 t0 = fold_convert (fd->iter_type, fold_convert (itype, t0));
c6ff4493
SE
6229 }
6230 else
6231 {
74bf76ed
JJ
6232 t1 = fold_convert (fd->iter_type, t1);
6233 t0 = fold_convert (fd->iter_type, t0);
c6ff4493 6234 }
a68ab351 6235 if (bias)
953ff289 6236 {
a68ab351
JJ
6237 t1 = fold_build2 (PLUS_EXPR, fd->iter_type, t1, bias);
6238 t0 = fold_build2 (PLUS_EXPR, fd->iter_type, t0, bias);
6239 }
6240 if (fd->iter_type == long_integer_type_node)
6241 {
6242 if (fd->chunk_size)
6243 {
6244 t = fold_convert (fd->iter_type, fd->chunk_size);
e79983f4
MM
6245 t = build_call_expr (builtin_decl_explicit (start_fn),
6246 6, t0, t1, t2, t, t3, t4);
a68ab351
JJ
6247 }
6248 else
e79983f4
MM
6249 t = build_call_expr (builtin_decl_explicit (start_fn),
6250 5, t0, t1, t2, t3, t4);
953ff289 6251 }
5039610b 6252 else
a68ab351
JJ
6253 {
6254 tree t5;
6255 tree c_bool_type;
e79983f4 6256 tree bfn_decl;
a68ab351
JJ
6257
6258 /* The GOMP_loop_ull_*start functions have additional boolean
6259 argument, true for < loops and false for > loops.
6260 In Fortran, the C bool type can be different from
6261 boolean_type_node. */
e79983f4
MM
6262 bfn_decl = builtin_decl_explicit (start_fn);
6263 c_bool_type = TREE_TYPE (TREE_TYPE (bfn_decl));
a68ab351
JJ
6264 t5 = build_int_cst (c_bool_type,
6265 fd->loop.cond_code == LT_EXPR ? 1 : 0);
6266 if (fd->chunk_size)
6267 {
e79983f4 6268 tree bfn_decl = builtin_decl_explicit (start_fn);
a68ab351 6269 t = fold_convert (fd->iter_type, fd->chunk_size);
e79983f4 6270 t = build_call_expr (bfn_decl, 7, t5, t0, t1, t2, t, t3, t4);
a68ab351
JJ
6271 }
6272 else
e79983f4
MM
6273 t = build_call_expr (builtin_decl_explicit (start_fn),
6274 6, t5, t0, t1, t2, t3, t4);
a68ab351 6275 }
953ff289 6276 }
a68ab351
JJ
6277 if (TREE_TYPE (t) != boolean_type_node)
6278 t = fold_build2 (NE_EXPR, boolean_type_node,
6279 t, build_int_cst (TREE_TYPE (t), 0));
726a989a
RB
6280 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
6281 true, GSI_SAME_STMT);
6282 gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
917948d3 6283
726a989a
RB
6284 /* Remove the GIMPLE_OMP_FOR statement. */
6285 gsi_remove (&gsi, true);
953ff289 6286
50674e96 6287 /* Iteration setup for sequential loop goes in L0_BB. */
74bf76ed
JJ
6288 tree startvar = fd->loop.v;
6289 tree endvar = NULL_TREE;
6290
acf0174b
JJ
6291 if (gimple_omp_for_combined_p (fd->for_stmt))
6292 {
6293 gcc_assert (gimple_code (inner_stmt) == GIMPLE_OMP_FOR
6294 && gimple_omp_for_kind (inner_stmt)
6295 == GF_OMP_FOR_KIND_SIMD);
6296 tree innerc = find_omp_clause (gimple_omp_for_clauses (inner_stmt),
6297 OMP_CLAUSE__LOOPTEMP_);
6298 gcc_assert (innerc);
6299 startvar = OMP_CLAUSE_DECL (innerc);
6300 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
6301 OMP_CLAUSE__LOOPTEMP_);
6302 gcc_assert (innerc);
6303 endvar = OMP_CLAUSE_DECL (innerc);
6304 }
6305
726a989a 6306 gsi = gsi_start_bb (l0_bb);
550918ca 6307 t = istart0;
a68ab351 6308 if (bias)
550918ca 6309 t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
74bf76ed
JJ
6310 if (POINTER_TYPE_P (TREE_TYPE (startvar)))
6311 t = fold_convert (signed_type_for (TREE_TYPE (startvar)), t);
6312 t = fold_convert (TREE_TYPE (startvar), t);
ea3a0fde 6313 t = force_gimple_operand_gsi (&gsi, t,
74bf76ed
JJ
6314 DECL_P (startvar)
6315 && TREE_ADDRESSABLE (startvar),
ea3a0fde 6316 NULL_TREE, false, GSI_CONTINUE_LINKING);
538dd0b7
DM
6317 assign_stmt = gimple_build_assign (startvar, t);
6318 gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
953ff289 6319
550918ca 6320 t = iend0;
a68ab351 6321 if (bias)
550918ca 6322 t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
74bf76ed
JJ
6323 if (POINTER_TYPE_P (TREE_TYPE (startvar)))
6324 t = fold_convert (signed_type_for (TREE_TYPE (startvar)), t);
6325 t = fold_convert (TREE_TYPE (startvar), t);
726a989a
RB
6326 iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
6327 false, GSI_CONTINUE_LINKING);
74bf76ed 6328 if (endvar)
a68ab351 6329 {
538dd0b7
DM
6330 assign_stmt = gimple_build_assign (endvar, iend);
6331 gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
95782571 6332 if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (iend)))
538dd0b7 6333 assign_stmt = gimple_build_assign (fd->loop.v, iend);
95782571 6334 else
0d0e4a03 6335 assign_stmt = gimple_build_assign (fd->loop.v, NOP_EXPR, iend);
538dd0b7 6336 gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
a68ab351 6337 }
74bf76ed 6338 if (fd->collapse > 1)
acf0174b 6339 expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
50674e96 6340
e5c95afe 6341 if (!broken_loop)
d3c673c7 6342 {
e5c95afe
ZD
6343 /* Code to control the increment and predicate for the sequential
6344 loop goes in the CONT_BB. */
726a989a 6345 gsi = gsi_last_bb (cont_bb);
538dd0b7
DM
6346 gomp_continue *cont_stmt = as_a <gomp_continue *> (gsi_stmt (gsi));
6347 gcc_assert (gimple_code (cont_stmt) == GIMPLE_OMP_CONTINUE);
6348 vmain = gimple_omp_continue_control_use (cont_stmt);
6349 vback = gimple_omp_continue_control_def (cont_stmt);
917948d3 6350
acf0174b 6351 if (!gimple_omp_for_combined_p (fd->for_stmt))
74bf76ed
JJ
6352 {
6353 if (POINTER_TYPE_P (type))
6354 t = fold_build_pointer_plus (vmain, fd->loop.step);
6355 else
6356 t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
6357 t = force_gimple_operand_gsi (&gsi, t,
6358 DECL_P (vback)
6359 && TREE_ADDRESSABLE (vback),
6360 NULL_TREE, true, GSI_SAME_STMT);
538dd0b7
DM
6361 assign_stmt = gimple_build_assign (vback, t);
6362 gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
74bf76ed
JJ
6363
6364 t = build2 (fd->loop.cond_code, boolean_type_node,
6365 DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback,
6366 iend);
538dd0b7
DM
6367 gcond *cond_stmt = gimple_build_cond_empty (t);
6368 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
74bf76ed 6369 }
50674e96 6370
726a989a
RB
6371 /* Remove GIMPLE_OMP_CONTINUE. */
6372 gsi_remove (&gsi, true);
50674e96 6373
acf0174b 6374 if (fd->collapse > 1 && !gimple_omp_for_combined_p (fd->for_stmt))
74bf76ed 6375 collapse_bb = extract_omp_for_update_vars (fd, cont_bb, l1_bb);
a68ab351 6376
e5c95afe 6377 /* Emit code to get the next parallel iteration in L2_BB. */
726a989a 6378 gsi = gsi_start_bb (l2_bb);
50674e96 6379
e79983f4 6380 t = build_call_expr (builtin_decl_explicit (next_fn), 2,
e5c95afe
ZD
6381 build_fold_addr_expr (istart0),
6382 build_fold_addr_expr (iend0));
726a989a
RB
6383 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
6384 false, GSI_CONTINUE_LINKING);
a68ab351
JJ
6385 if (TREE_TYPE (t) != boolean_type_node)
6386 t = fold_build2 (NE_EXPR, boolean_type_node,
6387 t, build_int_cst (TREE_TYPE (t), 0));
538dd0b7
DM
6388 gcond *cond_stmt = gimple_build_cond_empty (t);
6389 gsi_insert_after (&gsi, cond_stmt, GSI_CONTINUE_LINKING);
e5c95afe 6390 }
953ff289 6391
777f7f9a 6392 /* Add the loop cleanup function. */
726a989a
RB
6393 gsi = gsi_last_bb (exit_bb);
6394 if (gimple_omp_return_nowait_p (gsi_stmt (gsi)))
e79983f4 6395 t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_NOWAIT);
acf0174b
JJ
6396 else if (gimple_omp_return_lhs (gsi_stmt (gsi)))
6397 t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_CANCEL);
777f7f9a 6398 else
e79983f4 6399 t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END);
538dd0b7 6400 gcall *call_stmt = gimple_build_call (t, 0);
acf0174b 6401 if (gimple_omp_return_lhs (gsi_stmt (gsi)))
538dd0b7
DM
6402 gimple_call_set_lhs (call_stmt, gimple_omp_return_lhs (gsi_stmt (gsi)));
6403 gsi_insert_after (&gsi, call_stmt, GSI_SAME_STMT);
726a989a 6404 gsi_remove (&gsi, true);
50674e96
DN
6405
6406 /* Connect the new blocks. */
917948d3
ZD
6407 find_edge (entry_bb, l0_bb)->flags = EDGE_TRUE_VALUE;
6408 find_edge (entry_bb, l3_bb)->flags = EDGE_FALSE_VALUE;
953ff289 6409
e5c95afe
ZD
6410 if (!broken_loop)
6411 {
726a989a
RB
6412 gimple_seq phis;
6413
917948d3
ZD
6414 e = find_edge (cont_bb, l3_bb);
6415 ne = make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
6416
726a989a
RB
6417 phis = phi_nodes (l3_bb);
6418 for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
6419 {
6420 gimple phi = gsi_stmt (gsi);
6421 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, ne),
6422 PHI_ARG_DEF_FROM_EDGE (phi, e));
6423 }
917948d3
ZD
6424 remove_edge (e);
6425
e5c95afe 6426 make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
726338f4 6427 add_bb_to_loop (l2_bb, cont_bb->loop_father);
74bf76ed 6428 e = find_edge (cont_bb, l1_bb);
acf0174b
JJ
6429 if (gimple_omp_for_combined_p (fd->for_stmt))
6430 {
6431 remove_edge (e);
6432 e = NULL;
6433 }
74bf76ed 6434 else if (fd->collapse > 1)
a68ab351 6435 {
a68ab351
JJ
6436 remove_edge (e);
6437 e = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
6438 }
6439 else
74bf76ed
JJ
6440 e->flags = EDGE_TRUE_VALUE;
6441 if (e)
a68ab351 6442 {
74bf76ed
JJ
6443 e->probability = REG_BR_PROB_BASE * 7 / 8;
6444 find_edge (cont_bb, l2_bb)->probability = REG_BR_PROB_BASE / 8;
6445 }
6446 else
6447 {
6448 e = find_edge (cont_bb, l2_bb);
6449 e->flags = EDGE_FALLTHRU;
a68ab351 6450 }
e5c95afe 6451 make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
917948d3
ZD
6452
6453 set_immediate_dominator (CDI_DOMINATORS, l2_bb,
6454 recompute_dominator (CDI_DOMINATORS, l2_bb));
6455 set_immediate_dominator (CDI_DOMINATORS, l3_bb,
6456 recompute_dominator (CDI_DOMINATORS, l3_bb));
6457 set_immediate_dominator (CDI_DOMINATORS, l0_bb,
6458 recompute_dominator (CDI_DOMINATORS, l0_bb));
6459 set_immediate_dominator (CDI_DOMINATORS, l1_bb,
6460 recompute_dominator (CDI_DOMINATORS, l1_bb));
6093bc06
RB
6461
6462 struct loop *outer_loop = alloc_loop ();
6463 outer_loop->header = l0_bb;
6464 outer_loop->latch = l2_bb;
6465 add_loop (outer_loop, l0_bb->loop_father);
6466
acf0174b 6467 if (!gimple_omp_for_combined_p (fd->for_stmt))
74bf76ed
JJ
6468 {
6469 struct loop *loop = alloc_loop ();
6470 loop->header = l1_bb;
6471 /* The loop may have multiple latches. */
6472 add_loop (loop, outer_loop);
6473 }
e5c95afe 6474 }
953ff289
DN
6475}
6476
6477
50674e96
DN
6478/* A subroutine of expand_omp_for. Generate code for a parallel
6479 loop with static schedule and no specified chunk size. Given
6480 parameters:
953ff289
DN
6481
6482 for (V = N1; V cond N2; V += STEP) BODY;
6483
6484 where COND is "<" or ">", we generate pseudocode
6485
5a0f4dd3 6486 if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
953ff289
DN
6487 if (cond is <)
6488 adj = STEP - 1;
6489 else
6490 adj = STEP + 1;
a68ab351
JJ
6491 if ((__typeof (V)) -1 > 0 && cond is >)
6492 n = -(adj + N2 - N1) / -STEP;
6493 else
6494 n = (adj + N2 - N1) / STEP;
953ff289 6495 q = n / nthreads;
fb79f500
JJ
6496 tt = n % nthreads;
6497 if (threadid < tt) goto L3; else goto L4;
6498 L3:
6499 tt = 0;
6500 q = q + 1;
6501 L4:
6502 s0 = q * threadid + tt;
6503 e0 = s0 + q;
917948d3 6504 V = s0 * STEP + N1;
953ff289
DN
6505 if (s0 >= e0) goto L2; else goto L0;
6506 L0:
953ff289
DN
6507 e = e0 * STEP + N1;
6508 L1:
6509 BODY;
6510 V += STEP;
6511 if (V cond e) goto L1;
953ff289
DN
6512 L2:
6513*/
6514
777f7f9a 6515static void
50674e96 6516expand_omp_for_static_nochunk (struct omp_region *region,
acf0174b
JJ
6517 struct omp_for_data *fd,
6518 gimple inner_stmt)
953ff289 6519{
fb79f500 6520 tree n, q, s0, e0, e, t, tt, nthreads, threadid;
a68ab351 6521 tree type, itype, vmain, vback;
fb79f500 6522 basic_block entry_bb, second_bb, third_bb, exit_bb, seq_start_bb;
acf0174b 6523 basic_block body_bb, cont_bb, collapse_bb = NULL;
777f7f9a 6524 basic_block fin_bb;
726a989a 6525 gimple_stmt_iterator gsi;
fb79f500 6526 edge ep;
acf0174b
JJ
6527 bool broken_loop = region->cont == NULL;
6528 tree *counts = NULL;
6529 tree n1, n2, step;
953ff289 6530
41dbbb37
TS
6531 gcc_checking_assert ((gimple_omp_for_kind (fd->for_stmt)
6532 != GF_OMP_FOR_KIND_OACC_LOOP)
6533 || !inner_stmt);
6534
a68ab351
JJ
6535 itype = type = TREE_TYPE (fd->loop.v);
6536 if (POINTER_TYPE_P (type))
96f9265a 6537 itype = signed_type_for (type);
953ff289 6538
777f7f9a 6539 entry_bb = region->entry;
777f7f9a 6540 cont_bb = region->cont;
e5c95afe 6541 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
acf0174b
JJ
6542 fin_bb = BRANCH_EDGE (entry_bb)->dest;
6543 gcc_assert (broken_loop
6544 || (fin_bb == FALLTHRU_EDGE (cont_bb)->dest));
e5c95afe
ZD
6545 seq_start_bb = split_edge (FALLTHRU_EDGE (entry_bb));
6546 body_bb = single_succ (seq_start_bb);
acf0174b
JJ
6547 if (!broken_loop)
6548 {
6549 gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
6550 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
6551 }
777f7f9a
RH
6552 exit_bb = region->exit;
6553
50674e96 6554 /* Iteration space partitioning goes in ENTRY_BB. */
726a989a
RB
6555 gsi = gsi_last_bb (entry_bb);
6556 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
777f7f9a 6557
acf0174b
JJ
6558 if (fd->collapse > 1)
6559 {
6560 int first_zero_iter = -1;
6561 basic_block l2_dom_bb = NULL;
6562
6563 counts = XALLOCAVEC (tree, fd->collapse);
6564 expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
6565 fin_bb, first_zero_iter,
6566 l2_dom_bb);
6567 t = NULL_TREE;
6568 }
6569 else if (gimple_omp_for_combined_into_p (fd->for_stmt))
6570 t = integer_one_node;
6571 else
6572 t = fold_binary (fd->loop.cond_code, boolean_type_node,
6573 fold_convert (type, fd->loop.n1),
6574 fold_convert (type, fd->loop.n2));
6575 if (fd->collapse == 1
6576 && TYPE_UNSIGNED (type)
5a0f4dd3
JJ
6577 && (t == NULL_TREE || !integer_onep (t)))
6578 {
5a0f4dd3
JJ
6579 n1 = fold_convert (type, unshare_expr (fd->loop.n1));
6580 n1 = force_gimple_operand_gsi (&gsi, n1, true, NULL_TREE,
6581 true, GSI_SAME_STMT);
6582 n2 = fold_convert (type, unshare_expr (fd->loop.n2));
6583 n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE,
6584 true, GSI_SAME_STMT);
538dd0b7
DM
6585 gcond *cond_stmt = gimple_build_cond (fd->loop.cond_code, n1, n2,
6586 NULL_TREE, NULL_TREE);
6587 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
6588 if (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
5a0f4dd3 6589 expand_omp_regimplify_p, NULL, NULL)
538dd0b7 6590 || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
5a0f4dd3
JJ
6591 expand_omp_regimplify_p, NULL, NULL))
6592 {
538dd0b7
DM
6593 gsi = gsi_for_stmt (cond_stmt);
6594 gimple_regimplify_operands (cond_stmt, &gsi);
5a0f4dd3 6595 }
538dd0b7 6596 ep = split_block (entry_bb, cond_stmt);
5a0f4dd3
JJ
6597 ep->flags = EDGE_TRUE_VALUE;
6598 entry_bb = ep->dest;
6599 ep->probability = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1);
6600 ep = make_edge (ep->src, fin_bb, EDGE_FALSE_VALUE);
6601 ep->probability = REG_BR_PROB_BASE / 2000 - 1;
6602 if (gimple_in_ssa_p (cfun))
6603 {
6604 int dest_idx = find_edge (entry_bb, fin_bb)->dest_idx;
538dd0b7
DM
6605 for (gphi_iterator gpi = gsi_start_phis (fin_bb);
6606 !gsi_end_p (gpi); gsi_next (&gpi))
5a0f4dd3 6607 {
538dd0b7 6608 gphi *phi = gpi.phi ();
5a0f4dd3
JJ
6609 add_phi_arg (phi, gimple_phi_arg_def (phi, dest_idx),
6610 ep, UNKNOWN_LOCATION);
6611 }
6612 }
6613 gsi = gsi_last_bb (entry_bb);
6614 }
6615
41dbbb37
TS
6616 switch (gimple_omp_for_kind (fd->for_stmt))
6617 {
6618 case GF_OMP_FOR_KIND_FOR:
6619 nthreads = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
6620 threadid = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
6621 break;
6622 case GF_OMP_FOR_KIND_DISTRIBUTE:
6623 nthreads = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_TEAMS);
6624 threadid = builtin_decl_explicit (BUILT_IN_OMP_GET_TEAM_NUM);
6625 break;
6626 case GF_OMP_FOR_KIND_OACC_LOOP:
6627 nthreads = builtin_decl_explicit (BUILT_IN_GOACC_GET_NUM_THREADS);
6628 threadid = builtin_decl_explicit (BUILT_IN_GOACC_GET_THREAD_NUM);
6629 break;
6630 default:
6631 gcc_unreachable ();
6632 }
6633 nthreads = build_call_expr (nthreads, 0);
6634 nthreads = fold_convert (itype, nthreads);
6635 nthreads = force_gimple_operand_gsi (&gsi, nthreads, true, NULL_TREE,
726a989a 6636 true, GSI_SAME_STMT);
41dbbb37
TS
6637 threadid = build_call_expr (threadid, 0);
6638 threadid = fold_convert (itype, threadid);
6639 threadid = force_gimple_operand_gsi (&gsi, threadid, true, NULL_TREE,
726a989a 6640 true, GSI_SAME_STMT);
953ff289 6641
acf0174b
JJ
6642 n1 = fd->loop.n1;
6643 n2 = fd->loop.n2;
6644 step = fd->loop.step;
6645 if (gimple_omp_for_combined_into_p (fd->for_stmt))
6646 {
6647 tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
6648 OMP_CLAUSE__LOOPTEMP_);
6649 gcc_assert (innerc);
6650 n1 = OMP_CLAUSE_DECL (innerc);
6651 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
6652 OMP_CLAUSE__LOOPTEMP_);
6653 gcc_assert (innerc);
6654 n2 = OMP_CLAUSE_DECL (innerc);
6655 }
6656 n1 = force_gimple_operand_gsi (&gsi, fold_convert (type, n1),
6657 true, NULL_TREE, true, GSI_SAME_STMT);
6658 n2 = force_gimple_operand_gsi (&gsi, fold_convert (itype, n2),
6659 true, NULL_TREE, true, GSI_SAME_STMT);
6660 step = force_gimple_operand_gsi (&gsi, fold_convert (itype, step),
6661 true, NULL_TREE, true, GSI_SAME_STMT);
a68ab351
JJ
6662
6663 t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
acf0174b
JJ
6664 t = fold_build2 (PLUS_EXPR, itype, step, t);
6665 t = fold_build2 (PLUS_EXPR, itype, t, n2);
6666 t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, n1));
a68ab351
JJ
6667 if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
6668 t = fold_build2 (TRUNC_DIV_EXPR, itype,
6669 fold_build1 (NEGATE_EXPR, itype, t),
acf0174b 6670 fold_build1 (NEGATE_EXPR, itype, step));
a68ab351 6671 else
acf0174b 6672 t = fold_build2 (TRUNC_DIV_EXPR, itype, t, step);
a68ab351 6673 t = fold_convert (itype, t);
726a989a 6674 n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
953ff289 6675
7cc434a3 6676 q = create_tmp_reg (itype, "q");
a68ab351 6677 t = fold_build2 (TRUNC_DIV_EXPR, itype, n, nthreads);
fb79f500
JJ
6678 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
6679 gsi_insert_before (&gsi, gimple_build_assign (q, t), GSI_SAME_STMT);
6680
7cc434a3 6681 tt = create_tmp_reg (itype, "tt");
fb79f500
JJ
6682 t = fold_build2 (TRUNC_MOD_EXPR, itype, n, nthreads);
6683 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
6684 gsi_insert_before (&gsi, gimple_build_assign (tt, t), GSI_SAME_STMT);
953ff289 6685
fb79f500 6686 t = build2 (LT_EXPR, boolean_type_node, threadid, tt);
538dd0b7
DM
6687 gcond *cond_stmt = gimple_build_cond_empty (t);
6688 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
fb79f500 6689
538dd0b7 6690 second_bb = split_block (entry_bb, cond_stmt)->dest;
fb79f500
JJ
6691 gsi = gsi_last_bb (second_bb);
6692 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
6693
6694 gsi_insert_before (&gsi, gimple_build_assign (tt, build_int_cst (itype, 0)),
6695 GSI_SAME_STMT);
538dd0b7 6696 gassign *assign_stmt
0d0e4a03 6697 = gimple_build_assign (q, PLUS_EXPR, q, build_int_cst (itype, 1));
538dd0b7 6698 gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
fb79f500 6699
538dd0b7 6700 third_bb = split_block (second_bb, assign_stmt)->dest;
fb79f500
JJ
6701 gsi = gsi_last_bb (third_bb);
6702 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
953ff289 6703
a68ab351 6704 t = build2 (MULT_EXPR, itype, q, threadid);
fb79f500 6705 t = build2 (PLUS_EXPR, itype, t, tt);
726a989a 6706 s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
953ff289 6707
a68ab351 6708 t = fold_build2 (PLUS_EXPR, itype, s0, q);
726a989a 6709 e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
917948d3 6710
953ff289 6711 t = build2 (GE_EXPR, boolean_type_node, s0, e0);
726a989a 6712 gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
50674e96 6713
726a989a
RB
6714 /* Remove the GIMPLE_OMP_FOR statement. */
6715 gsi_remove (&gsi, true);
50674e96
DN
6716
6717 /* Setup code for sequential iteration goes in SEQ_START_BB. */
726a989a 6718 gsi = gsi_start_bb (seq_start_bb);
953ff289 6719
acf0174b
JJ
6720 tree startvar = fd->loop.v;
6721 tree endvar = NULL_TREE;
6722
6723 if (gimple_omp_for_combined_p (fd->for_stmt))
6724 {
6725 tree clauses = gimple_code (inner_stmt) == GIMPLE_OMP_PARALLEL
6726 ? gimple_omp_parallel_clauses (inner_stmt)
6727 : gimple_omp_for_clauses (inner_stmt);
6728 tree innerc = find_omp_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
6729 gcc_assert (innerc);
6730 startvar = OMP_CLAUSE_DECL (innerc);
6731 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
6732 OMP_CLAUSE__LOOPTEMP_);
6733 gcc_assert (innerc);
6734 endvar = OMP_CLAUSE_DECL (innerc);
6735 }
a68ab351 6736 t = fold_convert (itype, s0);
acf0174b 6737 t = fold_build2 (MULT_EXPR, itype, t, step);
a68ab351 6738 if (POINTER_TYPE_P (type))
acf0174b 6739 t = fold_build_pointer_plus (n1, t);
a68ab351 6740 else
acf0174b
JJ
6741 t = fold_build2 (PLUS_EXPR, type, t, n1);
6742 t = fold_convert (TREE_TYPE (startvar), t);
ea3a0fde 6743 t = force_gimple_operand_gsi (&gsi, t,
acf0174b
JJ
6744 DECL_P (startvar)
6745 && TREE_ADDRESSABLE (startvar),
ea3a0fde 6746 NULL_TREE, false, GSI_CONTINUE_LINKING);
538dd0b7
DM
6747 assign_stmt = gimple_build_assign (startvar, t);
6748 gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
b8698a0f 6749
a68ab351 6750 t = fold_convert (itype, e0);
acf0174b 6751 t = fold_build2 (MULT_EXPR, itype, t, step);
a68ab351 6752 if (POINTER_TYPE_P (type))
acf0174b 6753 t = fold_build_pointer_plus (n1, t);
a68ab351 6754 else
acf0174b
JJ
6755 t = fold_build2 (PLUS_EXPR, type, t, n1);
6756 t = fold_convert (TREE_TYPE (startvar), t);
726a989a
RB
6757 e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
6758 false, GSI_CONTINUE_LINKING);
acf0174b
JJ
6759 if (endvar)
6760 {
538dd0b7
DM
6761 assign_stmt = gimple_build_assign (endvar, e);
6762 gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
95782571 6763 if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
538dd0b7 6764 assign_stmt = gimple_build_assign (fd->loop.v, e);
95782571 6765 else
0d0e4a03 6766 assign_stmt = gimple_build_assign (fd->loop.v, NOP_EXPR, e);
538dd0b7 6767 gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
acf0174b
JJ
6768 }
6769 if (fd->collapse > 1)
6770 expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
953ff289 6771
acf0174b
JJ
6772 if (!broken_loop)
6773 {
6774 /* The code controlling the sequential loop replaces the
6775 GIMPLE_OMP_CONTINUE. */
6776 gsi = gsi_last_bb (cont_bb);
538dd0b7
DM
6777 gomp_continue *cont_stmt = as_a <gomp_continue *> (gsi_stmt (gsi));
6778 gcc_assert (gimple_code (cont_stmt) == GIMPLE_OMP_CONTINUE);
6779 vmain = gimple_omp_continue_control_use (cont_stmt);
6780 vback = gimple_omp_continue_control_def (cont_stmt);
917948d3 6781
acf0174b
JJ
6782 if (!gimple_omp_for_combined_p (fd->for_stmt))
6783 {
6784 if (POINTER_TYPE_P (type))
6785 t = fold_build_pointer_plus (vmain, step);
6786 else
6787 t = fold_build2 (PLUS_EXPR, type, vmain, step);
6788 t = force_gimple_operand_gsi (&gsi, t,
6789 DECL_P (vback)
6790 && TREE_ADDRESSABLE (vback),
6791 NULL_TREE, true, GSI_SAME_STMT);
538dd0b7
DM
6792 assign_stmt = gimple_build_assign (vback, t);
6793 gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
917948d3 6794
acf0174b
JJ
6795 t = build2 (fd->loop.cond_code, boolean_type_node,
6796 DECL_P (vback) && TREE_ADDRESSABLE (vback)
6797 ? t : vback, e);
6798 gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
6799 }
953ff289 6800
acf0174b
JJ
6801 /* Remove the GIMPLE_OMP_CONTINUE statement. */
6802 gsi_remove (&gsi, true);
6803
6804 if (fd->collapse > 1 && !gimple_omp_for_combined_p (fd->for_stmt))
6805 collapse_bb = extract_omp_for_update_vars (fd, cont_bb, body_bb);
6806 }
50674e96 6807
726a989a
RB
6808 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
6809 gsi = gsi_last_bb (exit_bb);
6810 if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
acf0174b
JJ
6811 {
6812 t = gimple_omp_return_lhs (gsi_stmt (gsi));
41dbbb37
TS
6813 if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
6814 gcc_checking_assert (t == NULL_TREE);
6815 else
6816 gsi_insert_after (&gsi, build_omp_barrier (t), GSI_SAME_STMT);
acf0174b 6817 }
726a989a 6818 gsi_remove (&gsi, true);
50674e96
DN
6819
6820 /* Connect all the blocks. */
fb79f500
JJ
6821 ep = make_edge (entry_bb, third_bb, EDGE_FALSE_VALUE);
6822 ep->probability = REG_BR_PROB_BASE / 4 * 3;
6823 ep = find_edge (entry_bb, second_bb);
6824 ep->flags = EDGE_TRUE_VALUE;
6825 ep->probability = REG_BR_PROB_BASE / 4;
6826 find_edge (third_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
6827 find_edge (third_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
917948d3 6828
acf0174b
JJ
6829 if (!broken_loop)
6830 {
6831 ep = find_edge (cont_bb, body_bb);
6832 if (gimple_omp_for_combined_p (fd->for_stmt))
6833 {
6834 remove_edge (ep);
6835 ep = NULL;
6836 }
6837 else if (fd->collapse > 1)
6838 {
6839 remove_edge (ep);
6840 ep = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
6841 }
6842 else
6843 ep->flags = EDGE_TRUE_VALUE;
6844 find_edge (cont_bb, fin_bb)->flags
6845 = ep ? EDGE_FALSE_VALUE : EDGE_FALLTHRU;
6846 }
b8698a0f 6847
fb79f500
JJ
6848 set_immediate_dominator (CDI_DOMINATORS, second_bb, entry_bb);
6849 set_immediate_dominator (CDI_DOMINATORS, third_bb, entry_bb);
6850 set_immediate_dominator (CDI_DOMINATORS, seq_start_bb, third_bb);
acf0174b 6851
917948d3
ZD
6852 set_immediate_dominator (CDI_DOMINATORS, body_bb,
6853 recompute_dominator (CDI_DOMINATORS, body_bb));
6854 set_immediate_dominator (CDI_DOMINATORS, fin_bb,
6855 recompute_dominator (CDI_DOMINATORS, fin_bb));
6093bc06 6856
acf0174b
JJ
6857 if (!broken_loop && !gimple_omp_for_combined_p (fd->for_stmt))
6858 {
6859 struct loop *loop = alloc_loop ();
6860 loop->header = body_bb;
6861 if (collapse_bb == NULL)
6862 loop->latch = cont_bb;
6863 add_loop (loop, body_bb->loop_father);
6864 }
953ff289
DN
6865}
6866
50674e96
DN
6867
6868/* A subroutine of expand_omp_for. Generate code for a parallel
6869 loop with static schedule and a specified chunk size. Given
6870 parameters:
953ff289
DN
6871
6872 for (V = N1; V cond N2; V += STEP) BODY;
6873
6874 where COND is "<" or ">", we generate pseudocode
6875
5a0f4dd3 6876 if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
953ff289
DN
6877 if (cond is <)
6878 adj = STEP - 1;
6879 else
6880 adj = STEP + 1;
a68ab351
JJ
6881 if ((__typeof (V)) -1 > 0 && cond is >)
6882 n = -(adj + N2 - N1) / -STEP;
6883 else
6884 n = (adj + N2 - N1) / STEP;
953ff289 6885 trip = 0;
917948d3
ZD
6886 V = threadid * CHUNK * STEP + N1; -- this extra definition of V is
6887 here so that V is defined
6888 if the loop is not entered
953ff289
DN
6889 L0:
6890 s0 = (trip * nthreads + threadid) * CHUNK;
6891 e0 = min(s0 + CHUNK, n);
6892 if (s0 < n) goto L1; else goto L4;
6893 L1:
6894 V = s0 * STEP + N1;
6895 e = e0 * STEP + N1;
6896 L2:
6897 BODY;
6898 V += STEP;
6899 if (V cond e) goto L2; else goto L3;
6900 L3:
6901 trip += 1;
6902 goto L0;
6903 L4:
953ff289
DN
6904*/
6905
777f7f9a 6906static void
acf0174b
JJ
6907expand_omp_for_static_chunk (struct omp_region *region,
6908 struct omp_for_data *fd, gimple inner_stmt)
953ff289 6909{
726a989a 6910 tree n, s0, e0, e, t;
917948d3 6911 tree trip_var, trip_init, trip_main, trip_back, nthreads, threadid;
ed20ae98 6912 tree type, itype, vmain, vback, vextra;
50674e96 6913 basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
acf0174b 6914 basic_block trip_update_bb = NULL, cont_bb, collapse_bb = NULL, fin_bb;
ed20ae98 6915 gimple_stmt_iterator gsi;
726a989a 6916 edge se;
acf0174b
JJ
6917 bool broken_loop = region->cont == NULL;
6918 tree *counts = NULL;
6919 tree n1, n2, step;
953ff289 6920
41dbbb37
TS
6921 gcc_checking_assert ((gimple_omp_for_kind (fd->for_stmt)
6922 != GF_OMP_FOR_KIND_OACC_LOOP)
6923 || !inner_stmt);
6924
a68ab351
JJ
6925 itype = type = TREE_TYPE (fd->loop.v);
6926 if (POINTER_TYPE_P (type))
96f9265a 6927 itype = signed_type_for (type);
953ff289 6928
777f7f9a 6929 entry_bb = region->entry;
e5c95afe
ZD
6930 se = split_block (entry_bb, last_stmt (entry_bb));
6931 entry_bb = se->src;
6932 iter_part_bb = se->dest;
777f7f9a 6933 cont_bb = region->cont;
e5c95afe 6934 gcc_assert (EDGE_COUNT (iter_part_bb->succs) == 2);
acf0174b
JJ
6935 fin_bb = BRANCH_EDGE (iter_part_bb)->dest;
6936 gcc_assert (broken_loop
6937 || fin_bb == FALLTHRU_EDGE (cont_bb)->dest);
e5c95afe
ZD
6938 seq_start_bb = split_edge (FALLTHRU_EDGE (iter_part_bb));
6939 body_bb = single_succ (seq_start_bb);
acf0174b
JJ
6940 if (!broken_loop)
6941 {
6942 gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
6943 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
6944 trip_update_bb = split_edge (FALLTHRU_EDGE (cont_bb));
6945 }
777f7f9a 6946 exit_bb = region->exit;
50674e96 6947
50674e96 6948 /* Trip and adjustment setup goes in ENTRY_BB. */
ed20ae98
TS
6949 gsi = gsi_last_bb (entry_bb);
6950 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
50674e96 6951
acf0174b
JJ
6952 if (fd->collapse > 1)
6953 {
6954 int first_zero_iter = -1;
6955 basic_block l2_dom_bb = NULL;
6956
6957 counts = XALLOCAVEC (tree, fd->collapse);
ed20ae98 6958 expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
acf0174b
JJ
6959 fin_bb, first_zero_iter,
6960 l2_dom_bb);
6961 t = NULL_TREE;
6962 }
6963 else if (gimple_omp_for_combined_into_p (fd->for_stmt))
6964 t = integer_one_node;
6965 else
6966 t = fold_binary (fd->loop.cond_code, boolean_type_node,
6967 fold_convert (type, fd->loop.n1),
6968 fold_convert (type, fd->loop.n2));
6969 if (fd->collapse == 1
6970 && TYPE_UNSIGNED (type)
5a0f4dd3
JJ
6971 && (t == NULL_TREE || !integer_onep (t)))
6972 {
5a0f4dd3 6973 n1 = fold_convert (type, unshare_expr (fd->loop.n1));
ed20ae98 6974 n1 = force_gimple_operand_gsi (&gsi, n1, true, NULL_TREE,
5a0f4dd3
JJ
6975 true, GSI_SAME_STMT);
6976 n2 = fold_convert (type, unshare_expr (fd->loop.n2));
ed20ae98 6977 n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE,
5a0f4dd3 6978 true, GSI_SAME_STMT);
538dd0b7
DM
6979 gcond *cond_stmt = gimple_build_cond (fd->loop.cond_code, n1, n2,
6980 NULL_TREE, NULL_TREE);
6981 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
6982 if (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
5a0f4dd3 6983 expand_omp_regimplify_p, NULL, NULL)
538dd0b7 6984 || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
5a0f4dd3
JJ
6985 expand_omp_regimplify_p, NULL, NULL))
6986 {
538dd0b7
DM
6987 gsi = gsi_for_stmt (cond_stmt);
6988 gimple_regimplify_operands (cond_stmt, &gsi);
5a0f4dd3 6989 }
538dd0b7 6990 se = split_block (entry_bb, cond_stmt);
5a0f4dd3
JJ
6991 se->flags = EDGE_TRUE_VALUE;
6992 entry_bb = se->dest;
6993 se->probability = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1);
6994 se = make_edge (se->src, fin_bb, EDGE_FALSE_VALUE);
6995 se->probability = REG_BR_PROB_BASE / 2000 - 1;
6996 if (gimple_in_ssa_p (cfun))
6997 {
6998 int dest_idx = find_edge (entry_bb, fin_bb)->dest_idx;
538dd0b7
DM
6999 for (gphi_iterator gpi = gsi_start_phis (fin_bb);
7000 !gsi_end_p (gpi); gsi_next (&gpi))
5a0f4dd3 7001 {
538dd0b7 7002 gphi *phi = gpi.phi ();
5a0f4dd3
JJ
7003 add_phi_arg (phi, gimple_phi_arg_def (phi, dest_idx),
7004 se, UNKNOWN_LOCATION);
7005 }
7006 }
ed20ae98 7007 gsi = gsi_last_bb (entry_bb);
5a0f4dd3
JJ
7008 }
7009
41dbbb37
TS
7010 switch (gimple_omp_for_kind (fd->for_stmt))
7011 {
7012 case GF_OMP_FOR_KIND_FOR:
7013 nthreads = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
7014 threadid = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
7015 break;
7016 case GF_OMP_FOR_KIND_DISTRIBUTE:
7017 nthreads = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_TEAMS);
7018 threadid = builtin_decl_explicit (BUILT_IN_OMP_GET_TEAM_NUM);
7019 break;
7020 case GF_OMP_FOR_KIND_OACC_LOOP:
7021 nthreads = builtin_decl_explicit (BUILT_IN_GOACC_GET_NUM_THREADS);
7022 threadid = builtin_decl_explicit (BUILT_IN_GOACC_GET_THREAD_NUM);
7023 break;
7024 default:
7025 gcc_unreachable ();
7026 }
7027 nthreads = build_call_expr (nthreads, 0);
7028 nthreads = fold_convert (itype, nthreads);
7029 nthreads = force_gimple_operand_gsi (&gsi, nthreads, true, NULL_TREE,
726a989a 7030 true, GSI_SAME_STMT);
41dbbb37
TS
7031 threadid = build_call_expr (threadid, 0);
7032 threadid = fold_convert (itype, threadid);
7033 threadid = force_gimple_operand_gsi (&gsi, threadid, true, NULL_TREE,
726a989a 7034 true, GSI_SAME_STMT);
917948d3 7035
acf0174b
JJ
7036 n1 = fd->loop.n1;
7037 n2 = fd->loop.n2;
7038 step = fd->loop.step;
7039 if (gimple_omp_for_combined_into_p (fd->for_stmt))
7040 {
7041 tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
7042 OMP_CLAUSE__LOOPTEMP_);
7043 gcc_assert (innerc);
7044 n1 = OMP_CLAUSE_DECL (innerc);
7045 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
7046 OMP_CLAUSE__LOOPTEMP_);
7047 gcc_assert (innerc);
7048 n2 = OMP_CLAUSE_DECL (innerc);
7049 }
ed20ae98 7050 n1 = force_gimple_operand_gsi (&gsi, fold_convert (type, n1),
acf0174b 7051 true, NULL_TREE, true, GSI_SAME_STMT);
ed20ae98 7052 n2 = force_gimple_operand_gsi (&gsi, fold_convert (itype, n2),
acf0174b 7053 true, NULL_TREE, true, GSI_SAME_STMT);
ed20ae98 7054 step = force_gimple_operand_gsi (&gsi, fold_convert (itype, step),
acf0174b 7055 true, NULL_TREE, true, GSI_SAME_STMT);
917948d3 7056 fd->chunk_size
ed20ae98 7057 = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->chunk_size),
726a989a 7058 true, NULL_TREE, true, GSI_SAME_STMT);
a68ab351
JJ
7059
7060 t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
acf0174b
JJ
7061 t = fold_build2 (PLUS_EXPR, itype, step, t);
7062 t = fold_build2 (PLUS_EXPR, itype, t, n2);
7063 t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, n1));
a68ab351
JJ
7064 if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
7065 t = fold_build2 (TRUNC_DIV_EXPR, itype,
7066 fold_build1 (NEGATE_EXPR, itype, t),
acf0174b 7067 fold_build1 (NEGATE_EXPR, itype, step));
a68ab351 7068 else
acf0174b 7069 t = fold_build2 (TRUNC_DIV_EXPR, itype, t, step);
a68ab351 7070 t = fold_convert (itype, t);
ed20ae98 7071 n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
726a989a 7072 true, GSI_SAME_STMT);
917948d3 7073
a5efada7 7074 trip_var = create_tmp_reg (itype, ".trip");
917948d3
ZD
7075 if (gimple_in_ssa_p (cfun))
7076 {
b731b390
JJ
7077 trip_init = make_ssa_name (trip_var);
7078 trip_main = make_ssa_name (trip_var);
7079 trip_back = make_ssa_name (trip_var);
917948d3 7080 }
953ff289 7081 else
917948d3
ZD
7082 {
7083 trip_init = trip_var;
7084 trip_main = trip_var;
7085 trip_back = trip_var;
7086 }
953ff289 7087
538dd0b7
DM
7088 gassign *assign_stmt
7089 = gimple_build_assign (trip_init, build_int_cst (itype, 0));
7090 gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
50674e96 7091
a68ab351 7092 t = fold_build2 (MULT_EXPR, itype, threadid, fd->chunk_size);
acf0174b 7093 t = fold_build2 (MULT_EXPR, itype, t, step);
a68ab351 7094 if (POINTER_TYPE_P (type))
acf0174b 7095 t = fold_build_pointer_plus (n1, t);
a68ab351 7096 else
acf0174b 7097 t = fold_build2 (PLUS_EXPR, type, t, n1);
ed20ae98
TS
7098 vextra = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
7099 true, GSI_SAME_STMT);
917948d3 7100
726a989a 7101 /* Remove the GIMPLE_OMP_FOR. */
ed20ae98 7102 gsi_remove (&gsi, true);
50674e96
DN
7103
7104 /* Iteration space partitioning goes in ITER_PART_BB. */
ed20ae98 7105 gsi = gsi_last_bb (iter_part_bb);
953ff289 7106
a68ab351
JJ
7107 t = fold_build2 (MULT_EXPR, itype, trip_main, nthreads);
7108 t = fold_build2 (PLUS_EXPR, itype, t, threadid);
7109 t = fold_build2 (MULT_EXPR, itype, t, fd->chunk_size);
ed20ae98 7110 s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
726a989a 7111 false, GSI_CONTINUE_LINKING);
953ff289 7112
a68ab351
JJ
7113 t = fold_build2 (PLUS_EXPR, itype, s0, fd->chunk_size);
7114 t = fold_build2 (MIN_EXPR, itype, t, n);
ed20ae98 7115 e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
726a989a 7116 false, GSI_CONTINUE_LINKING);
953ff289
DN
7117
7118 t = build2 (LT_EXPR, boolean_type_node, s0, n);
ed20ae98 7119 gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_CONTINUE_LINKING);
50674e96
DN
7120
7121 /* Setup code for sequential iteration goes in SEQ_START_BB. */
ed20ae98 7122 gsi = gsi_start_bb (seq_start_bb);
953ff289 7123
acf0174b
JJ
7124 tree startvar = fd->loop.v;
7125 tree endvar = NULL_TREE;
7126
7127 if (gimple_omp_for_combined_p (fd->for_stmt))
7128 {
7129 tree clauses = gimple_code (inner_stmt) == GIMPLE_OMP_PARALLEL
7130 ? gimple_omp_parallel_clauses (inner_stmt)
7131 : gimple_omp_for_clauses (inner_stmt);
7132 tree innerc = find_omp_clause (clauses, OMP_CLAUSE__LOOPTEMP_);
7133 gcc_assert (innerc);
7134 startvar = OMP_CLAUSE_DECL (innerc);
7135 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
7136 OMP_CLAUSE__LOOPTEMP_);
7137 gcc_assert (innerc);
7138 endvar = OMP_CLAUSE_DECL (innerc);
7139 }
7140
a68ab351 7141 t = fold_convert (itype, s0);
acf0174b 7142 t = fold_build2 (MULT_EXPR, itype, t, step);
a68ab351 7143 if (POINTER_TYPE_P (type))
acf0174b 7144 t = fold_build_pointer_plus (n1, t);
a68ab351 7145 else
acf0174b
JJ
7146 t = fold_build2 (PLUS_EXPR, type, t, n1);
7147 t = fold_convert (TREE_TYPE (startvar), t);
ed20ae98 7148 t = force_gimple_operand_gsi (&gsi, t,
acf0174b
JJ
7149 DECL_P (startvar)
7150 && TREE_ADDRESSABLE (startvar),
ea3a0fde 7151 NULL_TREE, false, GSI_CONTINUE_LINKING);
538dd0b7
DM
7152 assign_stmt = gimple_build_assign (startvar, t);
7153 gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
953ff289 7154
a68ab351 7155 t = fold_convert (itype, e0);
acf0174b 7156 t = fold_build2 (MULT_EXPR, itype, t, step);
a68ab351 7157 if (POINTER_TYPE_P (type))
acf0174b 7158 t = fold_build_pointer_plus (n1, t);
a68ab351 7159 else
acf0174b
JJ
7160 t = fold_build2 (PLUS_EXPR, type, t, n1);
7161 t = fold_convert (TREE_TYPE (startvar), t);
ed20ae98 7162 e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
726a989a 7163 false, GSI_CONTINUE_LINKING);
acf0174b
JJ
7164 if (endvar)
7165 {
538dd0b7
DM
7166 assign_stmt = gimple_build_assign (endvar, e);
7167 gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
95782571 7168 if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
538dd0b7 7169 assign_stmt = gimple_build_assign (fd->loop.v, e);
95782571 7170 else
0d0e4a03 7171 assign_stmt = gimple_build_assign (fd->loop.v, NOP_EXPR, e);
538dd0b7 7172 gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
acf0174b
JJ
7173 }
7174 if (fd->collapse > 1)
ed20ae98 7175 expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
acf0174b
JJ
7176
7177 if (!broken_loop)
7178 {
7179 /* The code controlling the sequential loop goes in CONT_BB,
7180 replacing the GIMPLE_OMP_CONTINUE. */
ed20ae98 7181 gsi = gsi_last_bb (cont_bb);
538dd0b7
DM
7182 gomp_continue *cont_stmt = as_a <gomp_continue *> (gsi_stmt (gsi));
7183 vmain = gimple_omp_continue_control_use (cont_stmt);
7184 vback = gimple_omp_continue_control_def (cont_stmt);
953ff289 7185
acf0174b
JJ
7186 if (!gimple_omp_for_combined_p (fd->for_stmt))
7187 {
7188 if (POINTER_TYPE_P (type))
ed20ae98 7189 t = fold_build_pointer_plus (vmain, step);
acf0174b 7190 else
ed20ae98
TS
7191 t = fold_build2 (PLUS_EXPR, type, vmain, step);
7192 if (DECL_P (vback) && TREE_ADDRESSABLE (vback))
7193 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
acf0174b 7194 true, GSI_SAME_STMT);
538dd0b7
DM
7195 assign_stmt = gimple_build_assign (vback, t);
7196 gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
917948d3 7197
acf0174b 7198 t = build2 (fd->loop.cond_code, boolean_type_node,
ed20ae98
TS
7199 DECL_P (vback) && TREE_ADDRESSABLE (vback)
7200 ? t : vback, e);
7201 gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
acf0174b 7202 }
917948d3 7203
acf0174b 7204 /* Remove GIMPLE_OMP_CONTINUE. */
ed20ae98 7205 gsi_remove (&gsi, true);
b8698a0f 7206
acf0174b
JJ
7207 if (fd->collapse > 1 && !gimple_omp_for_combined_p (fd->for_stmt))
7208 collapse_bb = extract_omp_for_update_vars (fd, cont_bb, body_bb);
50674e96 7209
acf0174b 7210 /* Trip update code goes into TRIP_UPDATE_BB. */
ed20ae98 7211 gsi = gsi_start_bb (trip_update_bb);
953ff289 7212
acf0174b
JJ
7213 t = build_int_cst (itype, 1);
7214 t = build2 (PLUS_EXPR, itype, trip_main, t);
538dd0b7
DM
7215 assign_stmt = gimple_build_assign (trip_back, t);
7216 gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
acf0174b 7217 }
953ff289 7218
726a989a 7219 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
ed20ae98
TS
7220 gsi = gsi_last_bb (exit_bb);
7221 if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
acf0174b 7222 {
ed20ae98 7223 t = gimple_omp_return_lhs (gsi_stmt (gsi));
41dbbb37
TS
7224 if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
7225 gcc_checking_assert (t == NULL_TREE);
7226 else
7227 gsi_insert_after (&gsi, build_omp_barrier (t), GSI_SAME_STMT);
acf0174b 7228 }
ed20ae98 7229 gsi_remove (&gsi, true);
953ff289 7230
50674e96 7231 /* Connect the new blocks. */
e5c95afe
ZD
7232 find_edge (iter_part_bb, seq_start_bb)->flags = EDGE_TRUE_VALUE;
7233 find_edge (iter_part_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
917948d3 7234
acf0174b
JJ
7235 if (!broken_loop)
7236 {
7237 se = find_edge (cont_bb, body_bb);
7238 if (gimple_omp_for_combined_p (fd->for_stmt))
7239 {
7240 remove_edge (se);
7241 se = NULL;
7242 }
7243 else if (fd->collapse > 1)
7244 {
7245 remove_edge (se);
7246 se = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
7247 }
7248 else
7249 se->flags = EDGE_TRUE_VALUE;
7250 find_edge (cont_bb, trip_update_bb)->flags
7251 = se ? EDGE_FALSE_VALUE : EDGE_FALLTHRU;
917948d3 7252
acf0174b
JJ
7253 redirect_edge_and_branch (single_succ_edge (trip_update_bb), iter_part_bb);
7254 }
917948d3
ZD
7255
7256 if (gimple_in_ssa_p (cfun))
7257 {
538dd0b7
DM
7258 gphi_iterator psi;
7259 gphi *phi;
726a989a 7260 edge re, ene;
726a989a
RB
7261 edge_var_map *vm;
7262 size_t i;
7263
acf0174b
JJ
7264 gcc_assert (fd->collapse == 1 && !broken_loop);
7265
917948d3
ZD
7266 /* When we redirect the edge from trip_update_bb to iter_part_bb, we
7267 remove arguments of the phi nodes in fin_bb. We need to create
7268 appropriate phi nodes in iter_part_bb instead. */
7269 se = single_pred_edge (fin_bb);
7270 re = single_succ_edge (trip_update_bb);
b787e7a2 7271 vec<edge_var_map> *head = redirect_edge_var_map_vector (re);
917948d3
ZD
7272 ene = single_succ_edge (entry_bb);
7273
726a989a 7274 psi = gsi_start_phis (fin_bb);
9771b263 7275 for (i = 0; !gsi_end_p (psi) && head->iterate (i, &vm);
726a989a 7276 gsi_next (&psi), ++i)
917948d3 7277 {
538dd0b7 7278 gphi *nphi;
f5045c96 7279 source_location locus;
726a989a 7280
538dd0b7 7281 phi = psi.phi ();
726a989a
RB
7282 t = gimple_phi_result (phi);
7283 gcc_assert (t == redirect_edge_var_map_result (vm));
917948d3 7284 nphi = create_phi_node (t, iter_part_bb);
917948d3
ZD
7285
7286 t = PHI_ARG_DEF_FROM_EDGE (phi, se);
f5045c96
AM
7287 locus = gimple_phi_arg_location_from_edge (phi, se);
7288
a68ab351 7289 /* A special case -- fd->loop.v is not yet computed in
ed20ae98 7290 iter_part_bb, we need to use vextra instead. */
a68ab351 7291 if (t == fd->loop.v)
ed20ae98 7292 t = vextra;
9e227d60 7293 add_phi_arg (nphi, t, ene, locus);
f5045c96 7294 locus = redirect_edge_var_map_location (vm);
9e227d60 7295 add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus);
726a989a 7296 }
56f6033d 7297 gcc_assert (gsi_end_p (psi) && i == head->length ());
726a989a
RB
7298 redirect_edge_var_map_clear (re);
7299 while (1)
7300 {
7301 psi = gsi_start_phis (fin_bb);
7302 if (gsi_end_p (psi))
7303 break;
7304 remove_phi_node (&psi, false);
917948d3 7305 }
917948d3
ZD
7306
7307 /* Make phi node for trip. */
7308 phi = create_phi_node (trip_main, iter_part_bb);
f5045c96 7309 add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb),
9e227d60 7310 UNKNOWN_LOCATION);
f5045c96 7311 add_phi_arg (phi, trip_init, single_succ_edge (entry_bb),
9e227d60 7312 UNKNOWN_LOCATION);
917948d3
ZD
7313 }
7314
acf0174b
JJ
7315 if (!broken_loop)
7316 set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
917948d3
ZD
7317 set_immediate_dominator (CDI_DOMINATORS, iter_part_bb,
7318 recompute_dominator (CDI_DOMINATORS, iter_part_bb));
7319 set_immediate_dominator (CDI_DOMINATORS, fin_bb,
7320 recompute_dominator (CDI_DOMINATORS, fin_bb));
7321 set_immediate_dominator (CDI_DOMINATORS, seq_start_bb,
7322 recompute_dominator (CDI_DOMINATORS, seq_start_bb));
7323 set_immediate_dominator (CDI_DOMINATORS, body_bb,
7324 recompute_dominator (CDI_DOMINATORS, body_bb));
6093bc06 7325
acf0174b
JJ
7326 if (!broken_loop)
7327 {
7328 struct loop *trip_loop = alloc_loop ();
7329 trip_loop->header = iter_part_bb;
7330 trip_loop->latch = trip_update_bb;
7331 add_loop (trip_loop, iter_part_bb->loop_father);
6093bc06 7332
acf0174b
JJ
7333 if (!gimple_omp_for_combined_p (fd->for_stmt))
7334 {
7335 struct loop *loop = alloc_loop ();
7336 loop->header = body_bb;
01dde9b0
JJ
7337 if (collapse_bb == NULL)
7338 loop->latch = cont_bb;
acf0174b
JJ
7339 add_loop (loop, trip_loop);
7340 }
7341 }
953ff289
DN
7342}
7343
9a771876
JJ
7344/* A subroutine of expand_omp_for. Generate code for _Cilk_for loop.
7345 Given parameters:
7346 for (V = N1; V cond N2; V += STEP) BODY;
7347
7348 where COND is "<" or ">" or "!=", we generate pseudocode
7349
7350 for (ind_var = low; ind_var < high; ind_var++)
7351 {
7352 V = n1 + (ind_var * STEP)
7353
7354 <BODY>
7355 }
7356
7357 In the above pseudocode, low and high are function parameters of the
7358 child function. In the function below, we are inserting a temp.
7359 variable that will be making a call to two OMP functions that will not be
7360 found in the body of _Cilk_for (since OMP_FOR cannot be mixed
7361 with _Cilk_for). These functions are replaced with low and high
7362 by the function that handles taskreg. */
7363
7364
7365static void
7366expand_cilk_for (struct omp_region *region, struct omp_for_data *fd)
7367{
7368 bool broken_loop = region->cont == NULL;
7369 basic_block entry_bb = region->entry;
7370 basic_block cont_bb = region->cont;
7371
7372 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
7373 gcc_assert (broken_loop
7374 || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
7375 basic_block l0_bb = FALLTHRU_EDGE (entry_bb)->dest;
7376 basic_block l1_bb, l2_bb;
7377
7378 if (!broken_loop)
7379 {
7380 gcc_assert (BRANCH_EDGE (cont_bb)->dest == l0_bb);
7381 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
7382 l1_bb = split_block (cont_bb, last_stmt (cont_bb))->dest;
7383 l2_bb = BRANCH_EDGE (entry_bb)->dest;
7384 }
7385 else
7386 {
7387 BRANCH_EDGE (entry_bb)->flags &= ~EDGE_ABNORMAL;
7388 l1_bb = split_edge (BRANCH_EDGE (entry_bb));
7389 l2_bb = single_succ (l1_bb);
7390 }
7391 basic_block exit_bb = region->exit;
7392 basic_block l2_dom_bb = NULL;
7393
7394 gimple_stmt_iterator gsi = gsi_last_bb (entry_bb);
7395
7396 /* Below statements until the "tree high_val = ..." are pseudo statements
7397 used to pass information to be used by expand_omp_taskreg.
7398 low_val and high_val will be replaced by the __low and __high
7399 parameter from the child function.
7400
7401 The call_exprs part is a place-holder, it is mainly used
7402 to distinctly identify to the top-level part that this is
7403 where we should put low and high (reasoning given in header
7404 comment). */
7405
7406 tree child_fndecl
538dd0b7
DM
7407 = gimple_omp_parallel_child_fn (
7408 as_a <gomp_parallel *> (last_stmt (region->outer->entry)));
9a771876
JJ
7409 tree t, low_val = NULL_TREE, high_val = NULL_TREE;
7410 for (t = DECL_ARGUMENTS (child_fndecl); t; t = TREE_CHAIN (t))
7411 {
7412 if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__high"))
7413 high_val = t;
7414 else if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__low"))
7415 low_val = t;
7416 }
7417 gcc_assert (low_val && high_val);
7418
7419 tree type = TREE_TYPE (low_val);
7420 tree ind_var = create_tmp_reg (type, "__cilk_ind_var");
7421 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
7422
7423 /* Not needed in SSA form right now. */
7424 gcc_assert (!gimple_in_ssa_p (cfun));
7425 if (l2_dom_bb == NULL)
7426 l2_dom_bb = l1_bb;
7427
7428 tree n1 = low_val;
7429 tree n2 = high_val;
7430
7431 gimple stmt = gimple_build_assign (ind_var, n1);
7432
7433 /* Replace the GIMPLE_OMP_FOR statement. */
7434 gsi_replace (&gsi, stmt, true);
7435
7436 if (!broken_loop)
7437 {
7438 /* Code to control the increment goes in the CONT_BB. */
7439 gsi = gsi_last_bb (cont_bb);
7440 stmt = gsi_stmt (gsi);
7441 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
0d0e4a03
JJ
7442 stmt = gimple_build_assign (ind_var, PLUS_EXPR, ind_var,
7443 build_one_cst (type));
9a771876
JJ
7444
7445 /* Replace GIMPLE_OMP_CONTINUE. */
7446 gsi_replace (&gsi, stmt, true);
7447 }
7448
7449 /* Emit the condition in L1_BB. */
7450 gsi = gsi_after_labels (l1_bb);
7451 t = fold_build2 (MULT_EXPR, TREE_TYPE (fd->loop.step),
7452 fold_convert (TREE_TYPE (fd->loop.step), ind_var),
7453 fd->loop.step);
7454 if (POINTER_TYPE_P (TREE_TYPE (fd->loop.n1)))
7455 t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (fd->loop.n1),
7456 fd->loop.n1, fold_convert (sizetype, t));
7457 else
7458 t = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->loop.n1),
7459 fd->loop.n1, fold_convert (TREE_TYPE (fd->loop.n1), t));
7460 t = fold_convert (TREE_TYPE (fd->loop.v), t);
7461 expand_omp_build_assign (&gsi, fd->loop.v, t);
7462
7463 /* The condition is always '<' since the runtime will fill in the low
7464 and high values. */
7465 stmt = gimple_build_cond (LT_EXPR, ind_var, n2, NULL_TREE, NULL_TREE);
7466 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
7467
7468 /* Remove GIMPLE_OMP_RETURN. */
7469 gsi = gsi_last_bb (exit_bb);
7470 gsi_remove (&gsi, true);
7471
7472 /* Connect the new blocks. */
7473 remove_edge (FALLTHRU_EDGE (entry_bb));
7474
7475 edge e, ne;
7476 if (!broken_loop)
7477 {
7478 remove_edge (BRANCH_EDGE (entry_bb));
7479 make_edge (entry_bb, l1_bb, EDGE_FALLTHRU);
7480
7481 e = BRANCH_EDGE (l1_bb);
7482 ne = FALLTHRU_EDGE (l1_bb);
7483 e->flags = EDGE_TRUE_VALUE;
7484 }
7485 else
7486 {
7487 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
7488
7489 ne = single_succ_edge (l1_bb);
7490 e = make_edge (l1_bb, l0_bb, EDGE_TRUE_VALUE);
7491
7492 }
7493 ne->flags = EDGE_FALSE_VALUE;
7494 e->probability = REG_BR_PROB_BASE * 7 / 8;
7495 ne->probability = REG_BR_PROB_BASE / 8;
7496
7497 set_immediate_dominator (CDI_DOMINATORS, l1_bb, entry_bb);
7498 set_immediate_dominator (CDI_DOMINATORS, l2_bb, l2_dom_bb);
7499 set_immediate_dominator (CDI_DOMINATORS, l0_bb, l1_bb);
7500
7501 if (!broken_loop)
7502 {
7503 struct loop *loop = alloc_loop ();
7504 loop->header = l1_bb;
7505 loop->latch = cont_bb;
7506 add_loop (loop, l1_bb->loop_father);
7507 loop->safelen = INT_MAX;
7508 }
7509
7510 /* Pick the correct library function based on the precision of the
7511 induction variable type. */
7512 tree lib_fun = NULL_TREE;
7513 if (TYPE_PRECISION (type) == 32)
7514 lib_fun = cilk_for_32_fndecl;
7515 else if (TYPE_PRECISION (type) == 64)
7516 lib_fun = cilk_for_64_fndecl;
7517 else
7518 gcc_unreachable ();
7519
7520 gcc_assert (fd->sched_kind == OMP_CLAUSE_SCHEDULE_CILKFOR);
7521
7522 /* WS_ARGS contains the library function flavor to call:
7523 __libcilkrts_cilk_for_64 or __libcilkrts_cilk_for_32), and the
7524 user-defined grain value. If the user does not define one, then zero
7525 is passed in by the parser. */
7526 vec_alloc (region->ws_args, 2);
7527 region->ws_args->quick_push (lib_fun);
7528 region->ws_args->quick_push (fd->chunk_size);
7529}
acf0174b 7530
74bf76ed
JJ
7531/* A subroutine of expand_omp_for. Generate code for a simd non-worksharing
7532 loop. Given parameters:
7533
7534 for (V = N1; V cond N2; V += STEP) BODY;
7535
7536 where COND is "<" or ">", we generate pseudocode
7537
7538 V = N1;
7539 goto L1;
7540 L0:
7541 BODY;
7542 V += STEP;
7543 L1:
7544 if (V cond N2) goto L0; else goto L2;
7545 L2:
7546
7547 For collapsed loops, given parameters:
7548 collapse(3)
7549 for (V1 = N11; V1 cond1 N12; V1 += STEP1)
7550 for (V2 = N21; V2 cond2 N22; V2 += STEP2)
7551 for (V3 = N31; V3 cond3 N32; V3 += STEP3)
7552 BODY;
7553
7554 we generate pseudocode
7555
7556 if (cond3 is <)
7557 adj = STEP3 - 1;
7558 else
7559 adj = STEP3 + 1;
7560 count3 = (adj + N32 - N31) / STEP3;
7561 if (cond2 is <)
7562 adj = STEP2 - 1;
7563 else
7564 adj = STEP2 + 1;
7565 count2 = (adj + N22 - N21) / STEP2;
7566 if (cond1 is <)
7567 adj = STEP1 - 1;
7568 else
7569 adj = STEP1 + 1;
7570 count1 = (adj + N12 - N11) / STEP1;
7571 count = count1 * count2 * count3;
7572 V = 0;
7573 V1 = N11;
7574 V2 = N21;
7575 V3 = N31;
7576 goto L1;
7577 L0:
7578 BODY;
7579 V += 1;
7580 V3 += STEP3;
7581 V2 += (V3 cond3 N32) ? 0 : STEP2;
7582 V3 = (V3 cond3 N32) ? V3 : N31;
7583 V1 += (V2 cond2 N22) ? 0 : STEP1;
7584 V2 = (V2 cond2 N22) ? V2 : N21;
7585 L1:
7586 if (V < count) goto L0; else goto L2;
7587 L2:
7588
7589 */
7590
7591static void
7592expand_omp_simd (struct omp_region *region, struct omp_for_data *fd)
7593{
7594 tree type, t;
7595 basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, l2_bb, l2_dom_bb;
7596 gimple_stmt_iterator gsi;
7597 gimple stmt;
538dd0b7 7598 gcond *cond_stmt;
74bf76ed
JJ
7599 bool broken_loop = region->cont == NULL;
7600 edge e, ne;
7601 tree *counts = NULL;
7602 int i;
7603 tree safelen = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
7604 OMP_CLAUSE_SAFELEN);
7605 tree simduid = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
7606 OMP_CLAUSE__SIMDUID_);
acf0174b 7607 tree n1, n2;
74bf76ed
JJ
7608
7609 type = TREE_TYPE (fd->loop.v);
7610 entry_bb = region->entry;
7611 cont_bb = region->cont;
7612 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
7613 gcc_assert (broken_loop
7614 || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
7615 l0_bb = FALLTHRU_EDGE (entry_bb)->dest;
7616 if (!broken_loop)
7617 {
7618 gcc_assert (BRANCH_EDGE (cont_bb)->dest == l0_bb);
7619 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
7620 l1_bb = split_block (cont_bb, last_stmt (cont_bb))->dest;
7621 l2_bb = BRANCH_EDGE (entry_bb)->dest;
7622 }
7623 else
7624 {
7625 BRANCH_EDGE (entry_bb)->flags &= ~EDGE_ABNORMAL;
7626 l1_bb = split_edge (BRANCH_EDGE (entry_bb));
7627 l2_bb = single_succ (l1_bb);
7628 }
7629 exit_bb = region->exit;
7630 l2_dom_bb = NULL;
7631
7632 gsi = gsi_last_bb (entry_bb);
7633
7634 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
7635 /* Not needed in SSA form right now. */
7636 gcc_assert (!gimple_in_ssa_p (cfun));
7637 if (fd->collapse > 1)
7638 {
7639 int first_zero_iter = -1;
7640 basic_block zero_iter_bb = l2_bb;
7641
7642 counts = XALLOCAVEC (tree, fd->collapse);
7643 expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
7644 zero_iter_bb, first_zero_iter,
7645 l2_dom_bb);
7646 }
7647 if (l2_dom_bb == NULL)
7648 l2_dom_bb = l1_bb;
7649
acf0174b 7650 n1 = fd->loop.n1;
74bf76ed 7651 n2 = fd->loop.n2;
acf0174b
JJ
7652 if (gimple_omp_for_combined_into_p (fd->for_stmt))
7653 {
7654 tree innerc = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
7655 OMP_CLAUSE__LOOPTEMP_);
7656 gcc_assert (innerc);
7657 n1 = OMP_CLAUSE_DECL (innerc);
7658 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
7659 OMP_CLAUSE__LOOPTEMP_);
7660 gcc_assert (innerc);
7661 n2 = OMP_CLAUSE_DECL (innerc);
7662 expand_omp_build_assign (&gsi, fd->loop.v,
7663 fold_convert (type, n1));
7664 if (fd->collapse > 1)
7665 {
7666 gsi_prev (&gsi);
7667 expand_omp_for_init_vars (fd, &gsi, counts, NULL, n1);
7668 gsi_next (&gsi);
7669 }
7670 }
74bf76ed
JJ
7671 else
7672 {
7673 expand_omp_build_assign (&gsi, fd->loop.v,
7674 fold_convert (type, fd->loop.n1));
7675 if (fd->collapse > 1)
7676 for (i = 0; i < fd->collapse; i++)
7677 {
7678 tree itype = TREE_TYPE (fd->loops[i].v);
7679 if (POINTER_TYPE_P (itype))
7680 itype = signed_type_for (itype);
7681 t = fold_convert (TREE_TYPE (fd->loops[i].v), fd->loops[i].n1);
7682 expand_omp_build_assign (&gsi, fd->loops[i].v, t);
7683 }
7684 }
7685
7686 /* Remove the GIMPLE_OMP_FOR statement. */
7687 gsi_remove (&gsi, true);
7688
7689 if (!broken_loop)
7690 {
7691 /* Code to control the increment goes in the CONT_BB. */
7692 gsi = gsi_last_bb (cont_bb);
7693 stmt = gsi_stmt (gsi);
7694 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
7695
7696 if (POINTER_TYPE_P (type))
7697 t = fold_build_pointer_plus (fd->loop.v, fd->loop.step);
7698 else
7699 t = fold_build2 (PLUS_EXPR, type, fd->loop.v, fd->loop.step);
7700 expand_omp_build_assign (&gsi, fd->loop.v, t);
7701
7702 if (fd->collapse > 1)
7703 {
7704 i = fd->collapse - 1;
7705 if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i].v)))
7706 {
7707 t = fold_convert (sizetype, fd->loops[i].step);
7708 t = fold_build_pointer_plus (fd->loops[i].v, t);
7709 }
7710 else
7711 {
7712 t = fold_convert (TREE_TYPE (fd->loops[i].v),
7713 fd->loops[i].step);
7714 t = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->loops[i].v),
7715 fd->loops[i].v, t);
7716 }
7717 expand_omp_build_assign (&gsi, fd->loops[i].v, t);
7718
7719 for (i = fd->collapse - 1; i > 0; i--)
7720 {
7721 tree itype = TREE_TYPE (fd->loops[i].v);
7722 tree itype2 = TREE_TYPE (fd->loops[i - 1].v);
7723 if (POINTER_TYPE_P (itype2))
7724 itype2 = signed_type_for (itype2);
7725 t = build3 (COND_EXPR, itype2,
7726 build2 (fd->loops[i].cond_code, boolean_type_node,
7727 fd->loops[i].v,
7728 fold_convert (itype, fd->loops[i].n2)),
7729 build_int_cst (itype2, 0),
7730 fold_convert (itype2, fd->loops[i - 1].step));
7731 if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i - 1].v)))
7732 t = fold_build_pointer_plus (fd->loops[i - 1].v, t);
7733 else
7734 t = fold_build2 (PLUS_EXPR, itype2, fd->loops[i - 1].v, t);
7735 expand_omp_build_assign (&gsi, fd->loops[i - 1].v, t);
7736
7737 t = build3 (COND_EXPR, itype,
7738 build2 (fd->loops[i].cond_code, boolean_type_node,
7739 fd->loops[i].v,
7740 fold_convert (itype, fd->loops[i].n2)),
7741 fd->loops[i].v,
7742 fold_convert (itype, fd->loops[i].n1));
7743 expand_omp_build_assign (&gsi, fd->loops[i].v, t);
7744 }
7745 }
7746
7747 /* Remove GIMPLE_OMP_CONTINUE. */
7748 gsi_remove (&gsi, true);
7749 }
7750
7751 /* Emit the condition in L1_BB. */
7752 gsi = gsi_start_bb (l1_bb);
7753
7754 t = fold_convert (type, n2);
7755 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
7756 false, GSI_CONTINUE_LINKING);
7757 t = build2 (fd->loop.cond_code, boolean_type_node, fd->loop.v, t);
538dd0b7
DM
7758 cond_stmt = gimple_build_cond_empty (t);
7759 gsi_insert_after (&gsi, cond_stmt, GSI_CONTINUE_LINKING);
7760 if (walk_tree (gimple_cond_lhs_ptr (cond_stmt), expand_omp_regimplify_p,
74bf76ed 7761 NULL, NULL)
538dd0b7 7762 || walk_tree (gimple_cond_rhs_ptr (cond_stmt), expand_omp_regimplify_p,
74bf76ed
JJ
7763 NULL, NULL))
7764 {
538dd0b7
DM
7765 gsi = gsi_for_stmt (cond_stmt);
7766 gimple_regimplify_operands (cond_stmt, &gsi);
74bf76ed
JJ
7767 }
7768
7769 /* Remove GIMPLE_OMP_RETURN. */
7770 gsi = gsi_last_bb (exit_bb);
7771 gsi_remove (&gsi, true);
7772
7773 /* Connect the new blocks. */
7774 remove_edge (FALLTHRU_EDGE (entry_bb));
7775
7776 if (!broken_loop)
7777 {
7778 remove_edge (BRANCH_EDGE (entry_bb));
7779 make_edge (entry_bb, l1_bb, EDGE_FALLTHRU);
7780
7781 e = BRANCH_EDGE (l1_bb);
7782 ne = FALLTHRU_EDGE (l1_bb);
7783 e->flags = EDGE_TRUE_VALUE;
7784 }
7785 else
7786 {
7787 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
7788
7789 ne = single_succ_edge (l1_bb);
7790 e = make_edge (l1_bb, l0_bb, EDGE_TRUE_VALUE);
7791
7792 }
7793 ne->flags = EDGE_FALSE_VALUE;
7794 e->probability = REG_BR_PROB_BASE * 7 / 8;
7795 ne->probability = REG_BR_PROB_BASE / 8;
7796
7797 set_immediate_dominator (CDI_DOMINATORS, l1_bb, entry_bb);
7798 set_immediate_dominator (CDI_DOMINATORS, l2_bb, l2_dom_bb);
7799 set_immediate_dominator (CDI_DOMINATORS, l0_bb, l1_bb);
7800
7801 if (!broken_loop)
7802 {
7803 struct loop *loop = alloc_loop ();
7804 loop->header = l1_bb;
01dde9b0 7805 loop->latch = cont_bb;
74bf76ed
JJ
7806 add_loop (loop, l1_bb->loop_father);
7807 if (safelen == NULL_TREE)
7808 loop->safelen = INT_MAX;
7809 else
7810 {
7811 safelen = OMP_CLAUSE_SAFELEN_EXPR (safelen);
b46ebd6c
JJ
7812 if (TREE_CODE (safelen) != INTEGER_CST)
7813 loop->safelen = 0;
7814 else if (!tree_fits_uhwi_p (safelen)
7815 || tree_to_uhwi (safelen) > INT_MAX)
74bf76ed
JJ
7816 loop->safelen = INT_MAX;
7817 else
ae7e9ddd 7818 loop->safelen = tree_to_uhwi (safelen);
74bf76ed
JJ
7819 if (loop->safelen == 1)
7820 loop->safelen = 0;
7821 }
7822 if (simduid)
7823 {
7824 loop->simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
7825 cfun->has_simduid_loops = true;
7826 }
ea0f3e87 7827 /* If not -fno-tree-loop-vectorize, hint that we want to vectorize
74bf76ed 7828 the loop. */
ea0f3e87
XDL
7829 if ((flag_tree_loop_vectorize
7830 || (!global_options_set.x_flag_tree_loop_vectorize
7831 && !global_options_set.x_flag_tree_vectorize))
ab2ffbeb 7832 && flag_tree_loop_optimize
74bf76ed
JJ
7833 && loop->safelen > 1)
7834 {
b15b5979
EB
7835 loop->force_vectorize = true;
7836 cfun->has_force_vectorize_loops = true;
74bf76ed
JJ
7837 }
7838 }
7839}
7840
953ff289 7841
41dbbb37 7842/* Expand the OMP loop defined by REGION. */
953ff289 7843
50674e96 7844static void
acf0174b 7845expand_omp_for (struct omp_region *region, gimple inner_stmt)
50674e96
DN
7846{
7847 struct omp_for_data fd;
a68ab351 7848 struct omp_for_data_loop *loops;
953ff289 7849
a68ab351
JJ
7850 loops
7851 = (struct omp_for_data_loop *)
726a989a 7852 alloca (gimple_omp_for_collapse (last_stmt (region->entry))
a68ab351 7853 * sizeof (struct omp_for_data_loop));
538dd0b7
DM
7854 extract_omp_for_data (as_a <gomp_for *> (last_stmt (region->entry)),
7855 &fd, loops);
21a66e91 7856 region->sched_kind = fd.sched_kind;
953ff289 7857
135a171d
JJ
7858 gcc_assert (EDGE_COUNT (region->entry->succs) == 2);
7859 BRANCH_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
7860 FALLTHRU_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
7861 if (region->cont)
7862 {
7863 gcc_assert (EDGE_COUNT (region->cont->succs) == 2);
7864 BRANCH_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
7865 FALLTHRU_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
7866 }
6093bc06 7867 else
1aa95df7 7868 /* If there isn't a continue then this is a degerate case where
6093bc06
RB
7869 the introduction of abnormal edges during lowering will prevent
7870 original loops from being detected. Fix that up. */
7871 loops_state_set (LOOPS_NEED_FIXUP);
135a171d 7872
0aadce73 7873 if (gimple_omp_for_kind (fd.for_stmt) & GF_OMP_FOR_SIMD)
74bf76ed 7874 expand_omp_simd (region, &fd);
9a771876
JJ
7875 else if (gimple_omp_for_kind (fd.for_stmt) == GF_OMP_FOR_KIND_CILKFOR)
7876 expand_cilk_for (region, &fd);
74bf76ed 7877 else if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
acf0174b 7878 && !fd.have_ordered)
953ff289
DN
7879 {
7880 if (fd.chunk_size == NULL)
acf0174b 7881 expand_omp_for_static_nochunk (region, &fd, inner_stmt);
953ff289 7882 else
acf0174b 7883 expand_omp_for_static_chunk (region, &fd, inner_stmt);
953ff289
DN
7884 }
7885 else
7886 {
a68ab351
JJ
7887 int fn_index, start_ix, next_ix;
7888
74bf76ed
JJ
7889 gcc_assert (gimple_omp_for_kind (fd.for_stmt)
7890 == GF_OMP_FOR_KIND_FOR);
9abd5ed9
JJ
7891 if (fd.chunk_size == NULL
7892 && fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
7893 fd.chunk_size = integer_zero_node;
a68ab351
JJ
7894 gcc_assert (fd.sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
7895 fn_index = (fd.sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
726a989a 7896 ? 3 : fd.sched_kind;
a68ab351 7897 fn_index += fd.have_ordered * 4;
e79983f4
MM
7898 start_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_START) + fn_index;
7899 next_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_NEXT) + fn_index;
a68ab351
JJ
7900 if (fd.iter_type == long_long_unsigned_type_node)
7901 {
e79983f4
MM
7902 start_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_START
7903 - (int)BUILT_IN_GOMP_LOOP_STATIC_START);
7904 next_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT
7905 - (int)BUILT_IN_GOMP_LOOP_STATIC_NEXT);
a68ab351 7906 }
bbbbb16a 7907 expand_omp_for_generic (region, &fd, (enum built_in_function) start_ix,
acf0174b 7908 (enum built_in_function) next_ix, inner_stmt);
953ff289 7909 }
5f40b3cb 7910
a5efada7
RG
7911 if (gimple_in_ssa_p (cfun))
7912 update_ssa (TODO_update_ssa_only_virtuals);
953ff289
DN
7913}
7914
953ff289
DN
7915
7916/* Expand code for an OpenMP sections directive. In pseudo code, we generate
7917
953ff289
DN
7918 v = GOMP_sections_start (n);
7919 L0:
7920 switch (v)
7921 {
7922 case 0:
7923 goto L2;
7924 case 1:
7925 section 1;
7926 goto L1;
7927 case 2:
7928 ...
7929 case n:
7930 ...
953ff289
DN
7931 default:
7932 abort ();
7933 }
7934 L1:
7935 v = GOMP_sections_next ();
7936 goto L0;
7937 L2:
7938 reduction;
7939
50674e96 7940 If this is a combined parallel sections, replace the call to
917948d3 7941 GOMP_sections_start with call to GOMP_sections_next. */
953ff289
DN
7942
7943static void
50674e96 7944expand_omp_sections (struct omp_region *region)
953ff289 7945{
0f900dfa 7946 tree t, u, vin = NULL, vmain, vnext, l2;
726a989a 7947 unsigned len;
e5c95afe 7948 basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
726a989a 7949 gimple_stmt_iterator si, switch_si;
538dd0b7
DM
7950 gomp_sections *sections_stmt;
7951 gimple stmt;
7952 gomp_continue *cont;
c34938a8
JJ
7953 edge_iterator ei;
7954 edge e;
777f7f9a 7955 struct omp_region *inner;
726a989a 7956 unsigned i, casei;
e5c95afe 7957 bool exit_reachable = region->cont != NULL;
953ff289 7958
65e7bfe3 7959 gcc_assert (region->exit != NULL);
777f7f9a 7960 entry_bb = region->entry;
e5c95afe 7961 l0_bb = single_succ (entry_bb);
777f7f9a 7962 l1_bb = region->cont;
e5c95afe 7963 l2_bb = region->exit;
65e7bfe3
JJ
7964 if (single_pred_p (l2_bb) && single_pred (l2_bb) == l0_bb)
7965 l2 = gimple_block_label (l2_bb);
7966 else
d3c673c7 7967 {
65e7bfe3
JJ
7968 /* This can happen if there are reductions. */
7969 len = EDGE_COUNT (l0_bb->succs);
7970 gcc_assert (len > 0);
7971 e = EDGE_SUCC (l0_bb, len - 1);
7972 si = gsi_last_bb (e->dest);
7973 l2 = NULL_TREE;
7974 if (gsi_end_p (si)
7975 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
7976 l2 = gimple_block_label (e->dest);
c34938a8 7977 else
65e7bfe3
JJ
7978 FOR_EACH_EDGE (e, ei, l0_bb->succs)
7979 {
7980 si = gsi_last_bb (e->dest);
7981 if (gsi_end_p (si)
7982 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
c34938a8 7983 {
65e7bfe3
JJ
7984 l2 = gimple_block_label (e->dest);
7985 break;
c34938a8 7986 }
65e7bfe3 7987 }
d3c673c7 7988 }
65e7bfe3
JJ
7989 if (exit_reachable)
7990 default_bb = create_empty_bb (l1_bb->prev_bb);
d3c673c7 7991 else
65e7bfe3 7992 default_bb = create_empty_bb (l0_bb);
50674e96
DN
7993
7994 /* We will build a switch() with enough cases for all the
726a989a 7995 GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
50674e96 7996 and a default case to abort if something goes wrong. */
e5c95afe 7997 len = EDGE_COUNT (l0_bb->succs);
726a989a 7998
9771b263 7999 /* Use vec::quick_push on label_vec throughout, since we know the size
726a989a 8000 in advance. */
ef062b13 8001 auto_vec<tree> label_vec (len);
953ff289 8002
777f7f9a 8003 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
726a989a
RB
8004 GIMPLE_OMP_SECTIONS statement. */
8005 si = gsi_last_bb (entry_bb);
538dd0b7 8006 sections_stmt = as_a <gomp_sections *> (gsi_stmt (si));
726a989a
RB
8007 gcc_assert (gimple_code (sections_stmt) == GIMPLE_OMP_SECTIONS);
8008 vin = gimple_omp_sections_control (sections_stmt);
50674e96 8009 if (!is_combined_parallel (region))
953ff289 8010 {
50674e96
DN
8011 /* If we are not inside a combined parallel+sections region,
8012 call GOMP_sections_start. */
4befd127 8013 t = build_int_cst (unsigned_type_node, len - 1);
e79983f4 8014 u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START);
726a989a 8015 stmt = gimple_build_call (u, 1, t);
953ff289 8016 }
917948d3
ZD
8017 else
8018 {
8019 /* Otherwise, call GOMP_sections_next. */
e79983f4 8020 u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
726a989a 8021 stmt = gimple_build_call (u, 0);
917948d3 8022 }
726a989a
RB
8023 gimple_call_set_lhs (stmt, vin);
8024 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
8025 gsi_remove (&si, true);
8026
8027 /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
8028 L0_BB. */
8029 switch_si = gsi_last_bb (l0_bb);
8030 gcc_assert (gimple_code (gsi_stmt (switch_si)) == GIMPLE_OMP_SECTIONS_SWITCH);
917948d3
ZD
8031 if (exit_reachable)
8032 {
538dd0b7 8033 cont = as_a <gomp_continue *> (last_stmt (l1_bb));
726a989a
RB
8034 gcc_assert (gimple_code (cont) == GIMPLE_OMP_CONTINUE);
8035 vmain = gimple_omp_continue_control_use (cont);
8036 vnext = gimple_omp_continue_control_def (cont);
917948d3
ZD
8037 }
8038 else
8039 {
8040 vmain = vin;
8041 vnext = NULL_TREE;
8042 }
953ff289 8043
65e7bfe3 8044 t = build_case_label (build_int_cst (unsigned_type_node, 0), NULL, l2);
9771b263 8045 label_vec.quick_push (t);
65e7bfe3 8046 i = 1;
d3c673c7 8047
726a989a 8048 /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR. */
e5c95afe
ZD
8049 for (inner = region->inner, casei = 1;
8050 inner;
8051 inner = inner->next, i++, casei++)
953ff289 8052 {
50674e96
DN
8053 basic_block s_entry_bb, s_exit_bb;
8054
c34938a8 8055 /* Skip optional reduction region. */
726a989a 8056 if (inner->type == GIMPLE_OMP_ATOMIC_LOAD)
c34938a8
JJ
8057 {
8058 --i;
8059 --casei;
8060 continue;
8061 }
8062
777f7f9a
RH
8063 s_entry_bb = inner->entry;
8064 s_exit_bb = inner->exit;
953ff289 8065
726a989a 8066 t = gimple_block_label (s_entry_bb);
e5c95afe 8067 u = build_int_cst (unsigned_type_node, casei);
3d528853 8068 u = build_case_label (u, NULL, t);
9771b263 8069 label_vec.quick_push (u);
777f7f9a 8070
726a989a
RB
8071 si = gsi_last_bb (s_entry_bb);
8072 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SECTION);
8073 gcc_assert (i < len || gimple_omp_section_last_p (gsi_stmt (si)));
8074 gsi_remove (&si, true);
777f7f9a 8075 single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
d3c673c7
JJ
8076
8077 if (s_exit_bb == NULL)
8078 continue;
8079
726a989a
RB
8080 si = gsi_last_bb (s_exit_bb);
8081 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
8082 gsi_remove (&si, true);
d3c673c7 8083
50674e96 8084 single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
953ff289
DN
8085 }
8086
50674e96 8087 /* Error handling code goes in DEFAULT_BB. */
726a989a 8088 t = gimple_block_label (default_bb);
3d528853 8089 u = build_case_label (NULL, NULL, t);
777f7f9a 8090 make_edge (l0_bb, default_bb, 0);
726338f4 8091 add_bb_to_loop (default_bb, current_loops->tree_root);
953ff289 8092
fd8d363e 8093 stmt = gimple_build_switch (vmain, u, label_vec);
726a989a
RB
8094 gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
8095 gsi_remove (&switch_si, true);
726a989a
RB
8096
8097 si = gsi_start_bb (default_bb);
e79983f4 8098 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
726a989a 8099 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
50674e96 8100
e5c95afe 8101 if (exit_reachable)
d3c673c7 8102 {
e79983f4
MM
8103 tree bfn_decl;
8104
e5c95afe 8105 /* Code to get the next section goes in L1_BB. */
726a989a
RB
8106 si = gsi_last_bb (l1_bb);
8107 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CONTINUE);
953ff289 8108
e79983f4
MM
8109 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
8110 stmt = gimple_build_call (bfn_decl, 0);
726a989a
RB
8111 gimple_call_set_lhs (stmt, vnext);
8112 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
8113 gsi_remove (&si, true);
50674e96 8114
e5c95afe 8115 single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
d3c673c7 8116 }
50674e96 8117
65e7bfe3
JJ
8118 /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB. */
8119 si = gsi_last_bb (l2_bb);
8120 if (gimple_omp_return_nowait_p (gsi_stmt (si)))
8121 t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT);
acf0174b
JJ
8122 else if (gimple_omp_return_lhs (gsi_stmt (si)))
8123 t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_CANCEL);
65e7bfe3
JJ
8124 else
8125 t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END);
8126 stmt = gimple_build_call (t, 0);
acf0174b
JJ
8127 if (gimple_omp_return_lhs (gsi_stmt (si)))
8128 gimple_call_set_lhs (stmt, gimple_omp_return_lhs (gsi_stmt (si)));
65e7bfe3
JJ
8129 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
8130 gsi_remove (&si, true);
8131
917948d3 8132 set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb);
50674e96 8133}
953ff289 8134
953ff289 8135
777f7f9a
RH
8136/* Expand code for an OpenMP single directive. We've already expanded
8137 much of the code, here we simply place the GOMP_barrier call. */
8138
8139static void
8140expand_omp_single (struct omp_region *region)
8141{
8142 basic_block entry_bb, exit_bb;
726a989a 8143 gimple_stmt_iterator si;
777f7f9a
RH
8144
8145 entry_bb = region->entry;
8146 exit_bb = region->exit;
8147
726a989a 8148 si = gsi_last_bb (entry_bb);
726a989a
RB
8149 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE);
8150 gsi_remove (&si, true);
777f7f9a
RH
8151 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
8152
726a989a 8153 si = gsi_last_bb (exit_bb);
acf0174b
JJ
8154 if (!gimple_omp_return_nowait_p (gsi_stmt (si)))
8155 {
8156 tree t = gimple_omp_return_lhs (gsi_stmt (si));
8157 gsi_insert_after (&si, build_omp_barrier (t), GSI_SAME_STMT);
8158 }
726a989a 8159 gsi_remove (&si, true);
777f7f9a
RH
8160 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
8161}
8162
8163
8164/* Generic expansion for OpenMP synchronization directives: master,
8165 ordered and critical. All we need to do here is remove the entry
8166 and exit markers for REGION. */
50674e96
DN
8167
8168static void
8169expand_omp_synch (struct omp_region *region)
8170{
8171 basic_block entry_bb, exit_bb;
726a989a 8172 gimple_stmt_iterator si;
50674e96 8173
777f7f9a
RH
8174 entry_bb = region->entry;
8175 exit_bb = region->exit;
50674e96 8176
726a989a
RB
8177 si = gsi_last_bb (entry_bb);
8178 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE
8179 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASTER
acf0174b 8180 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_TASKGROUP
726a989a 8181 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ORDERED
acf0174b
JJ
8182 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CRITICAL
8183 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_TEAMS);
726a989a 8184 gsi_remove (&si, true);
50674e96
DN
8185 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
8186
d3c673c7
JJ
8187 if (exit_bb)
8188 {
726a989a
RB
8189 si = gsi_last_bb (exit_bb);
8190 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
8191 gsi_remove (&si, true);
d3c673c7
JJ
8192 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
8193 }
50674e96 8194}
953ff289 8195
20906c66
JJ
8196/* A subroutine of expand_omp_atomic. Attempt to implement the atomic
8197 operation as a normal volatile load. */
8198
8199static bool
05409788
RH
8200expand_omp_atomic_load (basic_block load_bb, tree addr,
8201 tree loaded_val, int index)
20906c66 8202{
05409788
RH
8203 enum built_in_function tmpbase;
8204 gimple_stmt_iterator gsi;
8205 basic_block store_bb;
8206 location_t loc;
8207 gimple stmt;
8208 tree decl, call, type, itype;
8209
8210 gsi = gsi_last_bb (load_bb);
8211 stmt = gsi_stmt (gsi);
8212 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
8213 loc = gimple_location (stmt);
8214
8215 /* ??? If the target does not implement atomic_load_optab[mode], and mode
8216 is smaller than word size, then expand_atomic_load assumes that the load
8217 is atomic. We could avoid the builtin entirely in this case. */
8218
8219 tmpbase = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
8220 decl = builtin_decl_explicit (tmpbase);
8221 if (decl == NULL_TREE)
8222 return false;
8223
8224 type = TREE_TYPE (loaded_val);
8225 itype = TREE_TYPE (TREE_TYPE (decl));
8226
8227 call = build_call_expr_loc (loc, decl, 2, addr,
acf0174b
JJ
8228 build_int_cst (NULL,
8229 gimple_omp_atomic_seq_cst_p (stmt)
8230 ? MEMMODEL_SEQ_CST
8231 : MEMMODEL_RELAXED));
05409788
RH
8232 if (!useless_type_conversion_p (type, itype))
8233 call = fold_build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
8234 call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
8235
8236 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
8237 gsi_remove (&gsi, true);
8238
8239 store_bb = single_succ (load_bb);
8240 gsi = gsi_last_bb (store_bb);
8241 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
8242 gsi_remove (&gsi, true);
8243
8244 if (gimple_in_ssa_p (cfun))
8245 update_ssa (TODO_update_ssa_no_phi);
8246
8247 return true;
20906c66
JJ
8248}
8249
8250/* A subroutine of expand_omp_atomic. Attempt to implement the atomic
8251 operation as a normal volatile store. */
8252
8253static bool
05409788
RH
8254expand_omp_atomic_store (basic_block load_bb, tree addr,
8255 tree loaded_val, tree stored_val, int index)
20906c66 8256{
05409788
RH
8257 enum built_in_function tmpbase;
8258 gimple_stmt_iterator gsi;
8259 basic_block store_bb = single_succ (load_bb);
8260 location_t loc;
8261 gimple stmt;
8262 tree decl, call, type, itype;
ef4bddc2 8263 machine_mode imode;
05409788
RH
8264 bool exchange;
8265
8266 gsi = gsi_last_bb (load_bb);
8267 stmt = gsi_stmt (gsi);
8268 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
8269
8270 /* If the load value is needed, then this isn't a store but an exchange. */
8271 exchange = gimple_omp_atomic_need_value_p (stmt);
8272
8273 gsi = gsi_last_bb (store_bb);
8274 stmt = gsi_stmt (gsi);
8275 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE);
8276 loc = gimple_location (stmt);
8277
8278 /* ??? If the target does not implement atomic_store_optab[mode], and mode
8279 is smaller than word size, then expand_atomic_store assumes that the store
8280 is atomic. We could avoid the builtin entirely in this case. */
8281
8282 tmpbase = (exchange ? BUILT_IN_ATOMIC_EXCHANGE_N : BUILT_IN_ATOMIC_STORE_N);
8283 tmpbase = (enum built_in_function) ((int) tmpbase + index + 1);
8284 decl = builtin_decl_explicit (tmpbase);
8285 if (decl == NULL_TREE)
8286 return false;
8287
8288 type = TREE_TYPE (stored_val);
8289
8290 /* Dig out the type of the function's second argument. */
8291 itype = TREE_TYPE (decl);
8292 itype = TYPE_ARG_TYPES (itype);
8293 itype = TREE_CHAIN (itype);
8294 itype = TREE_VALUE (itype);
8295 imode = TYPE_MODE (itype);
8296
8297 if (exchange && !can_atomic_exchange_p (imode, true))
8298 return false;
8299
8300 if (!useless_type_conversion_p (itype, type))
8301 stored_val = fold_build1_loc (loc, VIEW_CONVERT_EXPR, itype, stored_val);
8302 call = build_call_expr_loc (loc, decl, 3, addr, stored_val,
acf0174b
JJ
8303 build_int_cst (NULL,
8304 gimple_omp_atomic_seq_cst_p (stmt)
8305 ? MEMMODEL_SEQ_CST
8306 : MEMMODEL_RELAXED));
05409788
RH
8307 if (exchange)
8308 {
8309 if (!useless_type_conversion_p (type, itype))
8310 call = build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
8311 call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
8312 }
8313
8314 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
8315 gsi_remove (&gsi, true);
8316
8317 /* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above. */
8318 gsi = gsi_last_bb (load_bb);
8319 gsi_remove (&gsi, true);
8320
8321 if (gimple_in_ssa_p (cfun))
8322 update_ssa (TODO_update_ssa_no_phi);
8323
8324 return true;
20906c66
JJ
8325}
8326
a509ebb5 8327/* A subroutine of expand_omp_atomic. Attempt to implement the atomic
86951993 8328 operation as a __atomic_fetch_op builtin. INDEX is log2 of the
a509ebb5
RL
8329 size of the data type, and thus usable to find the index of the builtin
8330 decl. Returns false if the expression is not of the proper form. */
8331
8332static bool
8333expand_omp_atomic_fetch_op (basic_block load_bb,
8334 tree addr, tree loaded_val,
8335 tree stored_val, int index)
8336{
e79983f4 8337 enum built_in_function oldbase, newbase, tmpbase;
a509ebb5 8338 tree decl, itype, call;
20906c66 8339 tree lhs, rhs;
a509ebb5 8340 basic_block store_bb = single_succ (load_bb);
726a989a
RB
8341 gimple_stmt_iterator gsi;
8342 gimple stmt;
db3927fb 8343 location_t loc;
86951993 8344 enum tree_code code;
20906c66 8345 bool need_old, need_new;
ef4bddc2 8346 machine_mode imode;
acf0174b 8347 bool seq_cst;
a509ebb5
RL
8348
8349 /* We expect to find the following sequences:
b8698a0f 8350
a509ebb5 8351 load_bb:
726a989a 8352 GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
a509ebb5
RL
8353
8354 store_bb:
8355 val = tmp OP something; (or: something OP tmp)
b8698a0f 8356 GIMPLE_OMP_STORE (val)
a509ebb5 8357
b8698a0f 8358 ???FIXME: Allow a more flexible sequence.
a509ebb5 8359 Perhaps use data flow to pick the statements.
b8698a0f 8360
a509ebb5
RL
8361 */
8362
726a989a
RB
8363 gsi = gsi_after_labels (store_bb);
8364 stmt = gsi_stmt (gsi);
db3927fb 8365 loc = gimple_location (stmt);
726a989a 8366 if (!is_gimple_assign (stmt))
a509ebb5 8367 return false;
726a989a
RB
8368 gsi_next (&gsi);
8369 if (gimple_code (gsi_stmt (gsi)) != GIMPLE_OMP_ATOMIC_STORE)
a509ebb5 8370 return false;
20906c66
JJ
8371 need_new = gimple_omp_atomic_need_value_p (gsi_stmt (gsi));
8372 need_old = gimple_omp_atomic_need_value_p (last_stmt (load_bb));
acf0174b 8373 seq_cst = gimple_omp_atomic_seq_cst_p (last_stmt (load_bb));
20906c66 8374 gcc_checking_assert (!need_old || !need_new);
a509ebb5 8375
726a989a 8376 if (!operand_equal_p (gimple_assign_lhs (stmt), stored_val, 0))
a509ebb5
RL
8377 return false;
8378
a509ebb5 8379 /* Check for one of the supported fetch-op operations. */
86951993
AM
8380 code = gimple_assign_rhs_code (stmt);
8381 switch (code)
a509ebb5
RL
8382 {
8383 case PLUS_EXPR:
8384 case POINTER_PLUS_EXPR:
86951993
AM
8385 oldbase = BUILT_IN_ATOMIC_FETCH_ADD_N;
8386 newbase = BUILT_IN_ATOMIC_ADD_FETCH_N;
a509ebb5
RL
8387 break;
8388 case MINUS_EXPR:
86951993
AM
8389 oldbase = BUILT_IN_ATOMIC_FETCH_SUB_N;
8390 newbase = BUILT_IN_ATOMIC_SUB_FETCH_N;
a509ebb5
RL
8391 break;
8392 case BIT_AND_EXPR:
86951993
AM
8393 oldbase = BUILT_IN_ATOMIC_FETCH_AND_N;
8394 newbase = BUILT_IN_ATOMIC_AND_FETCH_N;
a509ebb5
RL
8395 break;
8396 case BIT_IOR_EXPR:
86951993
AM
8397 oldbase = BUILT_IN_ATOMIC_FETCH_OR_N;
8398 newbase = BUILT_IN_ATOMIC_OR_FETCH_N;
a509ebb5
RL
8399 break;
8400 case BIT_XOR_EXPR:
86951993
AM
8401 oldbase = BUILT_IN_ATOMIC_FETCH_XOR_N;
8402 newbase = BUILT_IN_ATOMIC_XOR_FETCH_N;
a509ebb5
RL
8403 break;
8404 default:
8405 return false;
8406 }
86951993 8407
a509ebb5 8408 /* Make sure the expression is of the proper form. */
726a989a
RB
8409 if (operand_equal_p (gimple_assign_rhs1 (stmt), loaded_val, 0))
8410 rhs = gimple_assign_rhs2 (stmt);
8411 else if (commutative_tree_code (gimple_assign_rhs_code (stmt))
8412 && operand_equal_p (gimple_assign_rhs2 (stmt), loaded_val, 0))
8413 rhs = gimple_assign_rhs1 (stmt);
a509ebb5
RL
8414 else
8415 return false;
8416
e79983f4
MM
8417 tmpbase = ((enum built_in_function)
8418 ((need_new ? newbase : oldbase) + index + 1));
8419 decl = builtin_decl_explicit (tmpbase);
20790697
JJ
8420 if (decl == NULL_TREE)
8421 return false;
a509ebb5 8422 itype = TREE_TYPE (TREE_TYPE (decl));
86951993 8423 imode = TYPE_MODE (itype);
a509ebb5 8424
86951993
AM
8425 /* We could test all of the various optabs involved, but the fact of the
8426 matter is that (with the exception of i486 vs i586 and xadd) all targets
8427 that support any atomic operaton optab also implements compare-and-swap.
8428 Let optabs.c take care of expanding any compare-and-swap loop. */
cedb4a1a 8429 if (!can_compare_and_swap_p (imode, true))
a509ebb5
RL
8430 return false;
8431
726a989a
RB
8432 gsi = gsi_last_bb (load_bb);
8433 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_LOAD);
86951993
AM
8434
8435 /* OpenMP does not imply any barrier-like semantics on its atomic ops.
8436 It only requires that the operation happen atomically. Thus we can
8437 use the RELAXED memory model. */
8438 call = build_call_expr_loc (loc, decl, 3, addr,
8439 fold_convert_loc (loc, itype, rhs),
acf0174b
JJ
8440 build_int_cst (NULL,
8441 seq_cst ? MEMMODEL_SEQ_CST
8442 : MEMMODEL_RELAXED));
86951993 8443
20906c66
JJ
8444 if (need_old || need_new)
8445 {
8446 lhs = need_old ? loaded_val : stored_val;
8447 call = fold_convert_loc (loc, TREE_TYPE (lhs), call);
8448 call = build2_loc (loc, MODIFY_EXPR, void_type_node, lhs, call);
8449 }
8450 else
8451 call = fold_convert_loc (loc, void_type_node, call);
726a989a
RB
8452 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
8453 gsi_remove (&gsi, true);
a509ebb5 8454
726a989a
RB
8455 gsi = gsi_last_bb (store_bb);
8456 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
8457 gsi_remove (&gsi, true);
8458 gsi = gsi_last_bb (store_bb);
8459 gsi_remove (&gsi, true);
a509ebb5
RL
8460
8461 if (gimple_in_ssa_p (cfun))
8462 update_ssa (TODO_update_ssa_no_phi);
8463
8464 return true;
8465}
8466
8467/* A subroutine of expand_omp_atomic. Implement the atomic operation as:
8468
8469 oldval = *addr;
8470 repeat:
8471 newval = rhs; // with oldval replacing *addr in rhs
8472 oldval = __sync_val_compare_and_swap (addr, oldval, newval);
8473 if (oldval != newval)
8474 goto repeat;
8475
8476 INDEX is log2 of the size of the data type, and thus usable to find the
8477 index of the builtin decl. */
8478
8479static bool
8480expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
8481 tree addr, tree loaded_val, tree stored_val,
8482 int index)
8483{
c18c98c0 8484 tree loadedi, storedi, initial, new_storedi, old_vali;
a509ebb5 8485 tree type, itype, cmpxchg, iaddr;
726a989a 8486 gimple_stmt_iterator si;
a509ebb5 8487 basic_block loop_header = single_succ (load_bb);
726a989a 8488 gimple phi, stmt;
a509ebb5 8489 edge e;
e79983f4 8490 enum built_in_function fncode;
a509ebb5 8491
86951993
AM
8492 /* ??? We need a non-pointer interface to __atomic_compare_exchange in
8493 order to use the RELAXED memory model effectively. */
e79983f4
MM
8494 fncode = (enum built_in_function)((int)BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
8495 + index + 1);
8496 cmpxchg = builtin_decl_explicit (fncode);
20790697
JJ
8497 if (cmpxchg == NULL_TREE)
8498 return false;
a509ebb5
RL
8499 type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
8500 itype = TREE_TYPE (TREE_TYPE (cmpxchg));
8501
cedb4a1a 8502 if (!can_compare_and_swap_p (TYPE_MODE (itype), true))
a509ebb5
RL
8503 return false;
8504
726a989a
RB
8505 /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */
8506 si = gsi_last_bb (load_bb);
8507 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
8508
c18c98c0
JJ
8509 /* For floating-point values, we'll need to view-convert them to integers
8510 so that we can perform the atomic compare and swap. Simplify the
8511 following code by always setting up the "i"ntegral variables. */
8512 if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
8513 {
726a989a
RB
8514 tree iaddr_val;
8515
7cc434a3 8516 iaddr = create_tmp_reg (build_pointer_type_for_mode (itype, ptr_mode,
b731b390 8517 true));
726a989a
RB
8518 iaddr_val
8519 = force_gimple_operand_gsi (&si,
8520 fold_convert (TREE_TYPE (iaddr), addr),
8521 false, NULL_TREE, true, GSI_SAME_STMT);
8522 stmt = gimple_build_assign (iaddr, iaddr_val);
8523 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
b731b390 8524 loadedi = create_tmp_var (itype);
c18c98c0 8525 if (gimple_in_ssa_p (cfun))
b731b390 8526 loadedi = make_ssa_name (loadedi);
c18c98c0
JJ
8527 }
8528 else
8529 {
8530 iaddr = addr;
8531 loadedi = loaded_val;
8532 }
726a989a 8533
8175be9a
JJ
8534 fncode = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
8535 tree loaddecl = builtin_decl_explicit (fncode);
8536 if (loaddecl)
8537 initial
8538 = fold_convert (TREE_TYPE (TREE_TYPE (iaddr)),
8539 build_call_expr (loaddecl, 2, iaddr,
8540 build_int_cst (NULL_TREE,
8541 MEMMODEL_RELAXED)));
8542 else
8543 initial = build2 (MEM_REF, TREE_TYPE (TREE_TYPE (iaddr)), iaddr,
8544 build_int_cst (TREE_TYPE (iaddr), 0));
8545
70f34814 8546 initial
8175be9a
JJ
8547 = force_gimple_operand_gsi (&si, initial, true, NULL_TREE, true,
8548 GSI_SAME_STMT);
c18c98c0
JJ
8549
8550 /* Move the value to the LOADEDI temporary. */
a509ebb5
RL
8551 if (gimple_in_ssa_p (cfun))
8552 {
726a989a 8553 gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header)));
c18c98c0 8554 phi = create_phi_node (loadedi, loop_header);
a509ebb5
RL
8555 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (load_bb)),
8556 initial);
8557 }
8558 else
726a989a
RB
8559 gsi_insert_before (&si,
8560 gimple_build_assign (loadedi, initial),
8561 GSI_SAME_STMT);
c18c98c0
JJ
8562 if (loadedi != loaded_val)
8563 {
726a989a
RB
8564 gimple_stmt_iterator gsi2;
8565 tree x;
c18c98c0
JJ
8566
8567 x = build1 (VIEW_CONVERT_EXPR, type, loadedi);
726a989a 8568 gsi2 = gsi_start_bb (loop_header);
c18c98c0
JJ
8569 if (gimple_in_ssa_p (cfun))
8570 {
538dd0b7 8571 gassign *stmt;
726a989a
RB
8572 x = force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
8573 true, GSI_SAME_STMT);
8574 stmt = gimple_build_assign (loaded_val, x);
8575 gsi_insert_before (&gsi2, stmt, GSI_SAME_STMT);
c18c98c0
JJ
8576 }
8577 else
8578 {
726a989a
RB
8579 x = build2 (MODIFY_EXPR, TREE_TYPE (loaded_val), loaded_val, x);
8580 force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
8581 true, GSI_SAME_STMT);
c18c98c0
JJ
8582 }
8583 }
726a989a 8584 gsi_remove (&si, true);
a509ebb5 8585
726a989a
RB
8586 si = gsi_last_bb (store_bb);
8587 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
a509ebb5 8588
c18c98c0
JJ
8589 if (iaddr == addr)
8590 storedi = stored_val;
a509ebb5 8591 else
c18c98c0 8592 storedi =
726a989a 8593 force_gimple_operand_gsi (&si,
c18c98c0
JJ
8594 build1 (VIEW_CONVERT_EXPR, itype,
8595 stored_val), true, NULL_TREE, true,
726a989a 8596 GSI_SAME_STMT);
a509ebb5
RL
8597
8598 /* Build the compare&swap statement. */
8599 new_storedi = build_call_expr (cmpxchg, 3, iaddr, loadedi, storedi);
726a989a 8600 new_storedi = force_gimple_operand_gsi (&si,
587aa063
RG
8601 fold_convert (TREE_TYPE (loadedi),
8602 new_storedi),
a509ebb5 8603 true, NULL_TREE,
726a989a 8604 true, GSI_SAME_STMT);
a509ebb5
RL
8605
8606 if (gimple_in_ssa_p (cfun))
8607 old_vali = loadedi;
8608 else
8609 {
b731b390 8610 old_vali = create_tmp_var (TREE_TYPE (loadedi));
726a989a
RB
8611 stmt = gimple_build_assign (old_vali, loadedi);
8612 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
a509ebb5 8613
726a989a
RB
8614 stmt = gimple_build_assign (loadedi, new_storedi);
8615 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
a509ebb5
RL
8616 }
8617
8618 /* Note that we always perform the comparison as an integer, even for
b8698a0f 8619 floating point. This allows the atomic operation to properly
a509ebb5 8620 succeed even with NaNs and -0.0. */
726a989a
RB
8621 stmt = gimple_build_cond_empty
8622 (build2 (NE_EXPR, boolean_type_node,
8623 new_storedi, old_vali));
8624 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
a509ebb5
RL
8625
8626 /* Update cfg. */
8627 e = single_succ_edge (store_bb);
8628 e->flags &= ~EDGE_FALLTHRU;
8629 e->flags |= EDGE_FALSE_VALUE;
8630
8631 e = make_edge (store_bb, loop_header, EDGE_TRUE_VALUE);
8632
c18c98c0 8633 /* Copy the new value to loadedi (we already did that before the condition
a509ebb5
RL
8634 if we are not in SSA). */
8635 if (gimple_in_ssa_p (cfun))
8636 {
726a989a 8637 phi = gimple_seq_first_stmt (phi_nodes (loop_header));
c18c98c0 8638 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), new_storedi);
a509ebb5
RL
8639 }
8640
726a989a
RB
8641 /* Remove GIMPLE_OMP_ATOMIC_STORE. */
8642 gsi_remove (&si, true);
a509ebb5 8643
6093bc06
RB
8644 struct loop *loop = alloc_loop ();
8645 loop->header = loop_header;
a1756c0a 8646 loop->latch = store_bb;
6093bc06
RB
8647 add_loop (loop, loop_header->loop_father);
8648
a509ebb5
RL
8649 if (gimple_in_ssa_p (cfun))
8650 update_ssa (TODO_update_ssa_no_phi);
8651
8652 return true;
8653}
8654
8655/* A subroutine of expand_omp_atomic. Implement the atomic operation as:
8656
8657 GOMP_atomic_start ();
8658 *addr = rhs;
8659 GOMP_atomic_end ();
8660
8661 The result is not globally atomic, but works so long as all parallel
8662 references are within #pragma omp atomic directives. According to
8663 responses received from omp@openmp.org, appears to be within spec.
8664 Which makes sense, since that's how several other compilers handle
b8698a0f 8665 this situation as well.
726a989a
RB
8666 LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
8667 expanding. STORED_VAL is the operand of the matching
8668 GIMPLE_OMP_ATOMIC_STORE.
a509ebb5 8669
b8698a0f
L
8670 We replace
8671 GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
a509ebb5
RL
8672 loaded_val = *addr;
8673
8674 and replace
05409788 8675 GIMPLE_OMP_ATOMIC_STORE (stored_val) with
b8698a0f 8676 *addr = stored_val;
a509ebb5
RL
8677*/
8678
8679static bool
8680expand_omp_atomic_mutex (basic_block load_bb, basic_block store_bb,
8681 tree addr, tree loaded_val, tree stored_val)
8682{
726a989a 8683 gimple_stmt_iterator si;
538dd0b7 8684 gassign *stmt;
a509ebb5
RL
8685 tree t;
8686
726a989a
RB
8687 si = gsi_last_bb (load_bb);
8688 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
a509ebb5 8689
e79983f4 8690 t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
3bb06db4 8691 t = build_call_expr (t, 0);
726a989a 8692 force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
a509ebb5 8693
70f34814 8694 stmt = gimple_build_assign (loaded_val, build_simple_mem_ref (addr));
726a989a
RB
8695 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
8696 gsi_remove (&si, true);
a509ebb5 8697
726a989a
RB
8698 si = gsi_last_bb (store_bb);
8699 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
a509ebb5 8700
70f34814
RG
8701 stmt = gimple_build_assign (build_simple_mem_ref (unshare_expr (addr)),
8702 stored_val);
726a989a 8703 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
a509ebb5 8704
e79983f4 8705 t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
3bb06db4 8706 t = build_call_expr (t, 0);
726a989a
RB
8707 force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
8708 gsi_remove (&si, true);
a509ebb5
RL
8709
8710 if (gimple_in_ssa_p (cfun))
8711 update_ssa (TODO_update_ssa_no_phi);
8712 return true;
8713}
8714
b8698a0f
L
8715/* Expand an GIMPLE_OMP_ATOMIC statement. We try to expand
8716 using expand_omp_atomic_fetch_op. If it failed, we try to
a509ebb5
RL
8717 call expand_omp_atomic_pipeline, and if it fails too, the
8718 ultimate fallback is wrapping the operation in a mutex
b8698a0f
L
8719 (expand_omp_atomic_mutex). REGION is the atomic region built
8720 by build_omp_regions_1(). */
a509ebb5
RL
8721
8722static void
8723expand_omp_atomic (struct omp_region *region)
8724{
8725 basic_block load_bb = region->entry, store_bb = region->exit;
538dd0b7
DM
8726 gomp_atomic_load *load = as_a <gomp_atomic_load *> (last_stmt (load_bb));
8727 gomp_atomic_store *store = as_a <gomp_atomic_store *> (last_stmt (store_bb));
726a989a
RB
8728 tree loaded_val = gimple_omp_atomic_load_lhs (load);
8729 tree addr = gimple_omp_atomic_load_rhs (load);
8730 tree stored_val = gimple_omp_atomic_store_val (store);
a509ebb5
RL
8731 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
8732 HOST_WIDE_INT index;
8733
8734 /* Make sure the type is one of the supported sizes. */
ae7e9ddd 8735 index = tree_to_uhwi (TYPE_SIZE_UNIT (type));
a509ebb5
RL
8736 index = exact_log2 (index);
8737 if (index >= 0 && index <= 4)
8738 {
8739 unsigned int align = TYPE_ALIGN_UNIT (type);
8740
8741 /* __sync builtins require strict data alignment. */
4999c62c 8742 if (exact_log2 (align) >= index)
a509ebb5 8743 {
05409788 8744 /* Atomic load. */
20906c66
JJ
8745 if (loaded_val == stored_val
8746 && (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
8747 || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
8748 && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
05409788 8749 && expand_omp_atomic_load (load_bb, addr, loaded_val, index))
20906c66
JJ
8750 return;
8751
05409788 8752 /* Atomic store. */
20906c66
JJ
8753 if ((GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
8754 || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
8755 && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
8756 && store_bb == single_succ (load_bb)
8757 && first_stmt (store_bb) == store
05409788
RH
8758 && expand_omp_atomic_store (load_bb, addr, loaded_val,
8759 stored_val, index))
20906c66
JJ
8760 return;
8761
a509ebb5
RL
8762 /* When possible, use specialized atomic update functions. */
8763 if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
05409788
RH
8764 && store_bb == single_succ (load_bb)
8765 && expand_omp_atomic_fetch_op (load_bb, addr,
8766 loaded_val, stored_val, index))
8767 return;
a509ebb5
RL
8768
8769 /* If we don't have specialized __sync builtins, try and implement
8770 as a compare and swap loop. */
8771 if (expand_omp_atomic_pipeline (load_bb, store_bb, addr,
8772 loaded_val, stored_val, index))
8773 return;
8774 }
8775 }
8776
8777 /* The ultimate fallback is wrapping the operation in a mutex. */
8778 expand_omp_atomic_mutex (load_bb, store_bb, addr, loaded_val, stored_val);
8779}
8780
953ff289 8781
41dbbb37 8782/* Expand the GIMPLE_OMP_TARGET starting at REGION. */
acf0174b
JJ
8783
8784static void
8785expand_omp_target (struct omp_region *region)
8786{
8787 basic_block entry_bb, exit_bb, new_bb;
41dbbb37
TS
8788 struct function *child_cfun;
8789 tree child_fn, block, t;
acf0174b 8790 gimple_stmt_iterator gsi;
538dd0b7
DM
8791 gomp_target *entry_stmt;
8792 gimple stmt;
acf0174b 8793 edge e;
41dbbb37 8794 bool offloaded, data_region;
acf0174b 8795
538dd0b7 8796 entry_stmt = as_a <gomp_target *> (last_stmt (region->entry));
acf0174b 8797 new_bb = region->entry;
41dbbb37
TS
8798
8799 offloaded = is_gimple_omp_offloaded (entry_stmt);
8800 switch (gimple_omp_target_kind (entry_stmt))
8801 {
8802 case GF_OMP_TARGET_KIND_REGION:
8803 case GF_OMP_TARGET_KIND_UPDATE:
8804 case GF_OMP_TARGET_KIND_OACC_PARALLEL:
8805 case GF_OMP_TARGET_KIND_OACC_KERNELS:
8806 case GF_OMP_TARGET_KIND_OACC_UPDATE:
8807 case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
8808 data_region = false;
8809 break;
8810 case GF_OMP_TARGET_KIND_DATA:
8811 case GF_OMP_TARGET_KIND_OACC_DATA:
8812 data_region = true;
8813 break;
8814 default:
8815 gcc_unreachable ();
8816 }
8817
8818 child_fn = NULL_TREE;
8819 child_cfun = NULL;
8820 if (offloaded)
acf0174b
JJ
8821 {
8822 child_fn = gimple_omp_target_child_fn (entry_stmt);
8823 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
8824 }
8825
41dbbb37
TS
8826 /* Supported by expand_omp_taskreg, but not here. */
8827 if (child_cfun != NULL)
8828 gcc_checking_assert (!child_cfun->cfg);
8829 gcc_checking_assert (!gimple_in_ssa_p (cfun));
8830
acf0174b
JJ
8831 entry_bb = region->entry;
8832 exit_bb = region->exit;
8833
41dbbb37 8834 if (offloaded)
acf0174b
JJ
8835 {
8836 unsigned srcidx, dstidx, num;
8837
41dbbb37 8838 /* If the offloading region needs data sent from the parent
acf0174b 8839 function, then the very first statement (except possible
41dbbb37 8840 tree profile counter updates) of the offloading body
acf0174b
JJ
8841 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
8842 &.OMP_DATA_O is passed as an argument to the child function,
8843 we need to replace it with the argument as seen by the child
8844 function.
8845
8846 In most cases, this will end up being the identity assignment
41dbbb37 8847 .OMP_DATA_I = .OMP_DATA_I. However, if the offloading body had
acf0174b
JJ
8848 a function call that has been inlined, the original PARM_DECL
8849 .OMP_DATA_I may have been converted into a different local
8850 variable. In which case, we need to keep the assignment. */
41dbbb37
TS
8851 tree data_arg = gimple_omp_target_data_arg (entry_stmt);
8852 if (data_arg)
acf0174b
JJ
8853 {
8854 basic_block entry_succ_bb = single_succ (entry_bb);
8855 gimple_stmt_iterator gsi;
8856 tree arg;
8857 gimple tgtcopy_stmt = NULL;
41dbbb37 8858 tree sender = TREE_VEC_ELT (data_arg, 0);
acf0174b
JJ
8859
8860 for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
8861 {
8862 gcc_assert (!gsi_end_p (gsi));
8863 stmt = gsi_stmt (gsi);
8864 if (gimple_code (stmt) != GIMPLE_ASSIGN)
8865 continue;
8866
8867 if (gimple_num_ops (stmt) == 2)
8868 {
8869 tree arg = gimple_assign_rhs1 (stmt);
8870
8871 /* We're ignoring the subcode because we're
8872 effectively doing a STRIP_NOPS. */
8873
8874 if (TREE_CODE (arg) == ADDR_EXPR
8875 && TREE_OPERAND (arg, 0) == sender)
8876 {
8877 tgtcopy_stmt = stmt;
8878 break;
8879 }
8880 }
8881 }
8882
8883 gcc_assert (tgtcopy_stmt != NULL);
8884 arg = DECL_ARGUMENTS (child_fn);
8885
8886 gcc_assert (gimple_assign_lhs (tgtcopy_stmt) == arg);
8887 gsi_remove (&gsi, true);
8888 }
8889
8890 /* Declare local variables needed in CHILD_CFUN. */
8891 block = DECL_INITIAL (child_fn);
8892 BLOCK_VARS (block) = vec2chain (child_cfun->local_decls);
41dbbb37 8893 /* The gimplifier could record temporaries in the offloading block
acf0174b
JJ
8894 rather than in containing function's local_decls chain,
8895 which would mean cgraph missed finalizing them. Do it now. */
8896 for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
8897 if (TREE_CODE (t) == VAR_DECL
8898 && TREE_STATIC (t)
8899 && !DECL_EXTERNAL (t))
9041d2e6 8900 varpool_node::finalize_decl (t);
acf0174b
JJ
8901 DECL_SAVED_TREE (child_fn) = NULL;
8902 /* We'll create a CFG for child_fn, so no gimple body is needed. */
8903 gimple_set_body (child_fn, NULL);
8904 TREE_USED (block) = 1;
8905
8906 /* Reset DECL_CONTEXT on function arguments. */
8907 for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
8908 DECL_CONTEXT (t) = child_fn;
8909
41dbbb37 8910 /* Split ENTRY_BB at GIMPLE_*,
acf0174b
JJ
8911 so that it can be moved to the child function. */
8912 gsi = gsi_last_bb (entry_bb);
8913 stmt = gsi_stmt (gsi);
41dbbb37
TS
8914 gcc_assert (stmt
8915 && gimple_code (stmt) == gimple_code (entry_stmt));
acf0174b 8916 e = split_block (entry_bb, stmt);
b13c907a 8917 gsi_remove (&gsi, true);
acf0174b
JJ
8918 entry_bb = e->dest;
8919 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
8920
8921 /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
8922 if (exit_bb)
8923 {
8924 gsi = gsi_last_bb (exit_bb);
8925 gcc_assert (!gsi_end_p (gsi)
8926 && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
8927 stmt = gimple_build_return (NULL);
8928 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
8929 gsi_remove (&gsi, true);
8930 }
8931
41dbbb37 8932 /* Move the offloading region into CHILD_CFUN. */
acf0174b
JJ
8933
8934 block = gimple_block (entry_stmt);
8935
8936 new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
8937 if (exit_bb)
8938 single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
8939 /* When the OMP expansion process cannot guarantee an up-to-date
8940 loop tree arrange for the child function to fixup loops. */
8941 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
8942 child_cfun->x_current_loops->state |= LOOPS_NEED_FIXUP;
8943
8944 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
8945 num = vec_safe_length (child_cfun->local_decls);
8946 for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
8947 {
8948 t = (*child_cfun->local_decls)[srcidx];
8949 if (DECL_CONTEXT (t) == cfun->decl)
8950 continue;
8951 if (srcidx != dstidx)
8952 (*child_cfun->local_decls)[dstidx] = t;
8953 dstidx++;
8954 }
8955 if (dstidx != num)
8956 vec_safe_truncate (child_cfun->local_decls, dstidx);
8957
8958 /* Inform the callgraph about the new function. */
8959 DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
d52f5295 8960 cgraph_node::add_new_function (child_fn, true);
acf0174b 8961
844b0125 8962#ifdef ENABLE_OFFLOADING
ec6fe917
IV
8963 /* Add the new function to the offload table. */
8964 vec_safe_push (offload_funcs, child_fn);
844b0125 8965#endif
ec6fe917 8966
acf0174b
JJ
8967 /* Fix the callgraph edges for child_cfun. Those for cfun will be
8968 fixed in a following pass. */
8969 push_cfun (child_cfun);
3dafb85c 8970 cgraph_edge::rebuild_edges ();
acf0174b 8971
844b0125 8972#ifdef ENABLE_OFFLOADING
1f6be682
IV
8973 /* Prevent IPA from removing child_fn as unreachable, since there are no
8974 refs from the parent function to child_fn in offload LTO mode. */
844b0125 8975 struct cgraph_node *node = cgraph_node::get (child_fn);
1f6be682 8976 node->mark_force_output ();
844b0125 8977#endif
1f6be682 8978
acf0174b
JJ
8979 /* Some EH regions might become dead, see PR34608. If
8980 pass_cleanup_cfg isn't the first pass to happen with the
8981 new child, these dead EH edges might cause problems.
8982 Clean them up now. */
8983 if (flag_exceptions)
8984 {
8985 basic_block bb;
8986 bool changed = false;
8987
11cd3bed 8988 FOR_EACH_BB_FN (bb, cfun)
acf0174b
JJ
8989 changed |= gimple_purge_dead_eh_edges (bb);
8990 if (changed)
8991 cleanup_tree_cfg ();
8992 }
8993 pop_cfun ();
8994 }
8995
41dbbb37 8996 /* Emit a library call to launch the offloading region, or do data
acf0174b
JJ
8997 transfers. */
8998 tree t1, t2, t3, t4, device, cond, c, clauses;
8999 enum built_in_function start_ix;
9000 location_t clause_loc;
9001
41dbbb37
TS
9002 switch (gimple_omp_target_kind (entry_stmt))
9003 {
9004 case GF_OMP_TARGET_KIND_REGION:
9005 start_ix = BUILT_IN_GOMP_TARGET;
9006 break;
9007 case GF_OMP_TARGET_KIND_DATA:
9008 start_ix = BUILT_IN_GOMP_TARGET_DATA;
9009 break;
9010 case GF_OMP_TARGET_KIND_UPDATE:
9011 start_ix = BUILT_IN_GOMP_TARGET_UPDATE;
9012 break;
9013 case GF_OMP_TARGET_KIND_OACC_PARALLEL:
9014 case GF_OMP_TARGET_KIND_OACC_KERNELS:
9015 start_ix = BUILT_IN_GOACC_PARALLEL;
9016 break;
9017 case GF_OMP_TARGET_KIND_OACC_DATA:
9018 start_ix = BUILT_IN_GOACC_DATA_START;
9019 break;
9020 case GF_OMP_TARGET_KIND_OACC_UPDATE:
9021 start_ix = BUILT_IN_GOACC_UPDATE;
9022 break;
9023 case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
9024 start_ix = BUILT_IN_GOACC_ENTER_EXIT_DATA;
9025 break;
9026 default:
9027 gcc_unreachable ();
9028 }
acf0174b 9029
41dbbb37 9030 clauses = gimple_omp_target_clauses (entry_stmt);
acf0174b 9031
41dbbb37
TS
9032 /* By default, the value of DEVICE is GOMP_DEVICE_ICV (let runtime
9033 library choose) and there is no conditional. */
acf0174b 9034 cond = NULL_TREE;
41dbbb37 9035 device = build_int_cst (integer_type_node, GOMP_DEVICE_ICV);
acf0174b
JJ
9036
9037 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
9038 if (c)
9039 cond = OMP_CLAUSE_IF_EXPR (c);
9040
9041 c = find_omp_clause (clauses, OMP_CLAUSE_DEVICE);
9042 if (c)
9043 {
41dbbb37
TS
9044 /* Even if we pass it to all library function calls, it is currently only
9045 defined/used for the OpenMP target ones. */
9046 gcc_checking_assert (start_ix == BUILT_IN_GOMP_TARGET
9047 || start_ix == BUILT_IN_GOMP_TARGET_DATA
9048 || start_ix == BUILT_IN_GOMP_TARGET_UPDATE);
9049
acf0174b
JJ
9050 device = OMP_CLAUSE_DEVICE_ID (c);
9051 clause_loc = OMP_CLAUSE_LOCATION (c);
9052 }
9053 else
9054 clause_loc = gimple_location (entry_stmt);
9055
9056 /* Ensure 'device' is of the correct type. */
9057 device = fold_convert_loc (clause_loc, integer_type_node, device);
9058
9059 /* If we found the clause 'if (cond)', build
41dbbb37 9060 (cond ? device : GOMP_DEVICE_HOST_FALLBACK). */
acf0174b
JJ
9061 if (cond)
9062 {
9063 cond = gimple_boolify (cond);
9064
9065 basic_block cond_bb, then_bb, else_bb;
9066 edge e;
9067 tree tmp_var;
9068
b731b390 9069 tmp_var = create_tmp_var (TREE_TYPE (device));
41dbbb37 9070 if (offloaded)
c4d281b2 9071 e = split_block_after_labels (new_bb);
41dbbb37 9072 else
acf0174b
JJ
9073 {
9074 gsi = gsi_last_bb (new_bb);
9075 gsi_prev (&gsi);
9076 e = split_block (new_bb, gsi_stmt (gsi));
9077 }
acf0174b
JJ
9078 cond_bb = e->src;
9079 new_bb = e->dest;
9080 remove_edge (e);
9081
9082 then_bb = create_empty_bb (cond_bb);
9083 else_bb = create_empty_bb (then_bb);
9084 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
9085 set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
9086
9087 stmt = gimple_build_cond_empty (cond);
9088 gsi = gsi_last_bb (cond_bb);
9089 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
9090
9091 gsi = gsi_start_bb (then_bb);
9092 stmt = gimple_build_assign (tmp_var, device);
9093 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
9094
9095 gsi = gsi_start_bb (else_bb);
9096 stmt = gimple_build_assign (tmp_var,
41dbbb37
TS
9097 build_int_cst (integer_type_node,
9098 GOMP_DEVICE_HOST_FALLBACK));
acf0174b
JJ
9099 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
9100
9101 make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
9102 make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
726338f4
RB
9103 add_bb_to_loop (then_bb, cond_bb->loop_father);
9104 add_bb_to_loop (else_bb, cond_bb->loop_father);
acf0174b
JJ
9105 make_edge (then_bb, new_bb, EDGE_FALLTHRU);
9106 make_edge (else_bb, new_bb, EDGE_FALLTHRU);
9107
9108 device = tmp_var;
9109 }
9110
9111 gsi = gsi_last_bb (new_bb);
9112 t = gimple_omp_target_data_arg (entry_stmt);
9113 if (t == NULL)
9114 {
9115 t1 = size_zero_node;
9116 t2 = build_zero_cst (ptr_type_node);
9117 t3 = t2;
9118 t4 = t2;
9119 }
9120 else
9121 {
9122 t1 = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (TREE_VEC_ELT (t, 1))));
9123 t1 = size_binop (PLUS_EXPR, t1, size_int (1));
9124 t2 = build_fold_addr_expr (TREE_VEC_ELT (t, 0));
9125 t3 = build_fold_addr_expr (TREE_VEC_ELT (t, 1));
9126 t4 = build_fold_addr_expr (TREE_VEC_ELT (t, 2));
9127 }
9128
9129 gimple g;
41dbbb37 9130 /* The maximum number used by any start_ix, without varargs. */
9410d9b2
JJ
9131 auto_vec<tree, 11> args;
9132 args.quick_push (device);
41dbbb37 9133 if (offloaded)
9410d9b2 9134 args.quick_push (build_fold_addr_expr (child_fn));
128b26dc
TS
9135 switch (start_ix)
9136 {
9137 case BUILT_IN_GOMP_TARGET:
9138 case BUILT_IN_GOMP_TARGET_DATA:
9139 case BUILT_IN_GOMP_TARGET_UPDATE:
9140 /* This const void * is part of the current ABI, but we're not actually
9141 using it. */
9410d9b2 9142 args.quick_push (build_zero_cst (ptr_type_node));
128b26dc
TS
9143 break;
9144 case BUILT_IN_GOACC_DATA_START:
9145 case BUILT_IN_GOACC_ENTER_EXIT_DATA:
9146 case BUILT_IN_GOACC_PARALLEL:
9147 case BUILT_IN_GOACC_UPDATE:
9148 break;
9149 default:
9150 gcc_unreachable ();
9151 }
9410d9b2
JJ
9152 args.quick_push (t1);
9153 args.quick_push (t2);
9154 args.quick_push (t3);
9155 args.quick_push (t4);
41dbbb37
TS
9156 switch (start_ix)
9157 {
9158 case BUILT_IN_GOACC_DATA_START:
9159 case BUILT_IN_GOMP_TARGET:
9160 case BUILT_IN_GOMP_TARGET_DATA:
9161 case BUILT_IN_GOMP_TARGET_UPDATE:
9162 break;
9163 case BUILT_IN_GOACC_PARALLEL:
9164 {
9165 tree t_num_gangs, t_num_workers, t_vector_length;
9166
9167 /* Default values for num_gangs, num_workers, and vector_length. */
9168 t_num_gangs = t_num_workers = t_vector_length
9169 = fold_convert_loc (gimple_location (entry_stmt),
9170 integer_type_node, integer_one_node);
9171 /* ..., but if present, use the value specified by the respective
9172 clause, making sure that are of the correct type. */
9173 c = find_omp_clause (clauses, OMP_CLAUSE_NUM_GANGS);
9174 if (c)
9175 t_num_gangs = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
9176 integer_type_node,
9177 OMP_CLAUSE_NUM_GANGS_EXPR (c));
9178 c = find_omp_clause (clauses, OMP_CLAUSE_NUM_WORKERS);
9179 if (c)
9180 t_num_workers = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
9181 integer_type_node,
9182 OMP_CLAUSE_NUM_WORKERS_EXPR (c));
9183 c = find_omp_clause (clauses, OMP_CLAUSE_VECTOR_LENGTH);
9184 if (c)
9185 t_vector_length = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
9186 integer_type_node,
9187 OMP_CLAUSE_VECTOR_LENGTH_EXPR (c));
9410d9b2
JJ
9188 args.quick_push (t_num_gangs);
9189 args.quick_push (t_num_workers);
9190 args.quick_push (t_vector_length);
41dbbb37
TS
9191 }
9192 /* FALLTHRU */
9193 case BUILT_IN_GOACC_ENTER_EXIT_DATA:
9194 case BUILT_IN_GOACC_UPDATE:
9195 {
9196 tree t_async;
9197 int t_wait_idx;
9198
9199 /* Default values for t_async. */
9200 t_async = fold_convert_loc (gimple_location (entry_stmt),
9201 integer_type_node,
9202 build_int_cst (integer_type_node,
9203 GOMP_ASYNC_SYNC));
9204 /* ..., but if present, use the value specified by the respective
9205 clause, making sure that is of the correct type. */
9206 c = find_omp_clause (clauses, OMP_CLAUSE_ASYNC);
9207 if (c)
9208 t_async = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
9209 integer_type_node,
9210 OMP_CLAUSE_ASYNC_EXPR (c));
9211
9410d9b2 9212 args.quick_push (t_async);
41dbbb37 9213 /* Save the index, and... */
9410d9b2 9214 t_wait_idx = args.length ();
41dbbb37 9215 /* ... push a default value. */
9410d9b2
JJ
9216 args.quick_push (fold_convert_loc (gimple_location (entry_stmt),
9217 integer_type_node,
9218 integer_zero_node));
41dbbb37
TS
9219 c = find_omp_clause (clauses, OMP_CLAUSE_WAIT);
9220 if (c)
9221 {
9222 int n = 0;
9223
9224 for (; c; c = OMP_CLAUSE_CHAIN (c))
9225 {
9226 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_WAIT)
9227 {
9410d9b2
JJ
9228 args.safe_push (fold_convert_loc (OMP_CLAUSE_LOCATION (c),
9229 integer_type_node,
9230 OMP_CLAUSE_WAIT_EXPR (c)));
41dbbb37
TS
9231 n++;
9232 }
9233 }
9234
9235 /* Now that we know the number, replace the default value. */
9410d9b2
JJ
9236 args.ordered_remove (t_wait_idx);
9237 args.quick_insert (t_wait_idx,
9238 fold_convert_loc (gimple_location (entry_stmt),
9239 integer_type_node,
9240 build_int_cst (integer_type_node, n)));
41dbbb37
TS
9241 }
9242 }
9243 break;
9244 default:
9245 gcc_unreachable ();
acf0174b 9246 }
41dbbb37 9247
9410d9b2 9248 g = gimple_build_call_vec (builtin_decl_explicit (start_ix), args);
acf0174b
JJ
9249 gimple_set_location (g, gimple_location (entry_stmt));
9250 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
41dbbb37 9251 if (!offloaded)
acf0174b
JJ
9252 {
9253 g = gsi_stmt (gsi);
9254 gcc_assert (g && gimple_code (g) == GIMPLE_OMP_TARGET);
9255 gsi_remove (&gsi, true);
9256 }
41dbbb37
TS
9257 if (data_region
9258 && region->exit)
acf0174b
JJ
9259 {
9260 gsi = gsi_last_bb (region->exit);
9261 g = gsi_stmt (gsi);
9262 gcc_assert (g && gimple_code (g) == GIMPLE_OMP_RETURN);
9263 gsi_remove (&gsi, true);
9264 }
9265}
9266
9267
9268/* Expand the parallel region tree rooted at REGION. Expansion
9269 proceeds in depth-first order. Innermost regions are expanded
9270 first. This way, parallel regions that require a new function to
726a989a 9271 be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
50674e96
DN
9272 internal dependencies in their body. */
9273
9274static void
9275expand_omp (struct omp_region *region)
9276{
9277 while (region)
9278 {
b357f682 9279 location_t saved_location;
acf0174b 9280 gimple inner_stmt = NULL;
b357f682 9281
068e1875
ZD
9282 /* First, determine whether this is a combined parallel+workshare
9283 region. */
726a989a 9284 if (region->type == GIMPLE_OMP_PARALLEL)
068e1875
ZD
9285 determine_parallel_type (region);
9286
acf0174b
JJ
9287 if (region->type == GIMPLE_OMP_FOR
9288 && gimple_omp_for_combined_p (last_stmt (region->entry)))
9289 inner_stmt = last_stmt (region->inner->entry);
9290
50674e96
DN
9291 if (region->inner)
9292 expand_omp (region->inner);
9293
b357f682 9294 saved_location = input_location;
726a989a
RB
9295 if (gimple_has_location (last_stmt (region->entry)))
9296 input_location = gimple_location (last_stmt (region->entry));
b357f682 9297
777f7f9a 9298 switch (region->type)
50674e96 9299 {
726a989a
RB
9300 case GIMPLE_OMP_PARALLEL:
9301 case GIMPLE_OMP_TASK:
a68ab351
JJ
9302 expand_omp_taskreg (region);
9303 break;
9304
726a989a 9305 case GIMPLE_OMP_FOR:
acf0174b 9306 expand_omp_for (region, inner_stmt);
777f7f9a 9307 break;
50674e96 9308
726a989a 9309 case GIMPLE_OMP_SECTIONS:
777f7f9a
RH
9310 expand_omp_sections (region);
9311 break;
50674e96 9312
726a989a 9313 case GIMPLE_OMP_SECTION:
777f7f9a 9314 /* Individual omp sections are handled together with their
726a989a 9315 parent GIMPLE_OMP_SECTIONS region. */
777f7f9a 9316 break;
50674e96 9317
726a989a 9318 case GIMPLE_OMP_SINGLE:
777f7f9a
RH
9319 expand_omp_single (region);
9320 break;
50674e96 9321
726a989a 9322 case GIMPLE_OMP_MASTER:
acf0174b 9323 case GIMPLE_OMP_TASKGROUP:
726a989a
RB
9324 case GIMPLE_OMP_ORDERED:
9325 case GIMPLE_OMP_CRITICAL:
acf0174b 9326 case GIMPLE_OMP_TEAMS:
777f7f9a
RH
9327 expand_omp_synch (region);
9328 break;
50674e96 9329
726a989a 9330 case GIMPLE_OMP_ATOMIC_LOAD:
a509ebb5
RL
9331 expand_omp_atomic (region);
9332 break;
9333
acf0174b
JJ
9334 case GIMPLE_OMP_TARGET:
9335 expand_omp_target (region);
9336 break;
9337
777f7f9a
RH
9338 default:
9339 gcc_unreachable ();
9340 }
8d9c1aec 9341
b357f682 9342 input_location = saved_location;
50674e96
DN
9343 region = region->next;
9344 }
9345}
9346
9347
9348/* Helper for build_omp_regions. Scan the dominator tree starting at
5f40b3cb
ZD
9349 block BB. PARENT is the region that contains BB. If SINGLE_TREE is
9350 true, the function ends once a single tree is built (otherwise, whole
9351 forest of OMP constructs may be built). */
50674e96
DN
9352
9353static void
5f40b3cb
ZD
9354build_omp_regions_1 (basic_block bb, struct omp_region *parent,
9355 bool single_tree)
50674e96 9356{
726a989a
RB
9357 gimple_stmt_iterator gsi;
9358 gimple stmt;
50674e96
DN
9359 basic_block son;
9360
726a989a
RB
9361 gsi = gsi_last_bb (bb);
9362 if (!gsi_end_p (gsi) && is_gimple_omp (gsi_stmt (gsi)))
50674e96
DN
9363 {
9364 struct omp_region *region;
726a989a 9365 enum gimple_code code;
50674e96 9366
726a989a
RB
9367 stmt = gsi_stmt (gsi);
9368 code = gimple_code (stmt);
9369 if (code == GIMPLE_OMP_RETURN)
50674e96
DN
9370 {
9371 /* STMT is the return point out of region PARENT. Mark it
9372 as the exit point and make PARENT the immediately
9373 enclosing region. */
9374 gcc_assert (parent);
9375 region = parent;
777f7f9a 9376 region->exit = bb;
50674e96 9377 parent = parent->outer;
50674e96 9378 }
726a989a 9379 else if (code == GIMPLE_OMP_ATOMIC_STORE)
a509ebb5 9380 {
726a989a
RB
9381 /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
9382 GIMPLE_OMP_RETURN, but matches with
9383 GIMPLE_OMP_ATOMIC_LOAD. */
a509ebb5 9384 gcc_assert (parent);
726a989a 9385 gcc_assert (parent->type == GIMPLE_OMP_ATOMIC_LOAD);
a509ebb5
RL
9386 region = parent;
9387 region->exit = bb;
9388 parent = parent->outer;
9389 }
726a989a 9390 else if (code == GIMPLE_OMP_CONTINUE)
777f7f9a
RH
9391 {
9392 gcc_assert (parent);
9393 parent->cont = bb;
9394 }
726a989a 9395 else if (code == GIMPLE_OMP_SECTIONS_SWITCH)
e5c95afe 9396 {
726a989a
RB
9397 /* GIMPLE_OMP_SECTIONS_SWITCH is part of
9398 GIMPLE_OMP_SECTIONS, and we do nothing for it. */
e5c95afe 9399 }
50674e96
DN
9400 else
9401 {
777f7f9a 9402 region = new_omp_region (bb, code, parent);
41dbbb37
TS
9403 /* Otherwise... */
9404 if (code == GIMPLE_OMP_TARGET)
9405 {
9406 switch (gimple_omp_target_kind (stmt))
9407 {
9408 case GF_OMP_TARGET_KIND_REGION:
9409 case GF_OMP_TARGET_KIND_DATA:
9410 case GF_OMP_TARGET_KIND_OACC_PARALLEL:
9411 case GF_OMP_TARGET_KIND_OACC_KERNELS:
9412 case GF_OMP_TARGET_KIND_OACC_DATA:
9413 break;
9414 case GF_OMP_TARGET_KIND_UPDATE:
9415 case GF_OMP_TARGET_KIND_OACC_UPDATE:
9416 case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
9417 /* ..., other than for those stand-alone directives... */
9418 region = NULL;
9419 break;
9420 default:
9421 gcc_unreachable ();
9422 }
9423 }
9424 /* ..., this directive becomes the parent for a new region. */
9425 if (region)
9426 parent = region;
50674e96 9427 }
50674e96
DN
9428 }
9429
5f40b3cb
ZD
9430 if (single_tree && !parent)
9431 return;
9432
50674e96
DN
9433 for (son = first_dom_son (CDI_DOMINATORS, bb);
9434 son;
9435 son = next_dom_son (CDI_DOMINATORS, son))
5f40b3cb
ZD
9436 build_omp_regions_1 (son, parent, single_tree);
9437}
9438
9439/* Builds the tree of OMP regions rooted at ROOT, storing it to
9440 root_omp_region. */
9441
9442static void
9443build_omp_regions_root (basic_block root)
9444{
9445 gcc_assert (root_omp_region == NULL);
9446 build_omp_regions_1 (root, NULL, true);
9447 gcc_assert (root_omp_region != NULL);
50674e96
DN
9448}
9449
5f40b3cb
ZD
9450/* Expands omp construct (and its subconstructs) starting in HEAD. */
9451
9452void
9453omp_expand_local (basic_block head)
9454{
9455 build_omp_regions_root (head);
9456 if (dump_file && (dump_flags & TDF_DETAILS))
9457 {
9458 fprintf (dump_file, "\nOMP region tree\n\n");
9459 dump_omp_region (dump_file, root_omp_region, 0);
9460 fprintf (dump_file, "\n");
9461 }
9462
9463 remove_exit_barriers (root_omp_region);
9464 expand_omp (root_omp_region);
9465
9466 free_omp_regions ();
9467}
50674e96
DN
9468
9469/* Scan the CFG and build a tree of OMP regions. Return the root of
9470 the OMP region tree. */
9471
9472static void
9473build_omp_regions (void)
9474{
777f7f9a 9475 gcc_assert (root_omp_region == NULL);
50674e96 9476 calculate_dominance_info (CDI_DOMINATORS);
fefa31b5 9477 build_omp_regions_1 (ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, false);
50674e96
DN
9478}
9479
50674e96
DN
9480/* Main entry point for expanding OMP-GIMPLE into runtime calls. */
9481
c2924966 9482static unsigned int
50674e96
DN
9483execute_expand_omp (void)
9484{
9485 build_omp_regions ();
9486
777f7f9a
RH
9487 if (!root_omp_region)
9488 return 0;
50674e96 9489
777f7f9a
RH
9490 if (dump_file)
9491 {
9492 fprintf (dump_file, "\nOMP region tree\n\n");
9493 dump_omp_region (dump_file, root_omp_region, 0);
9494 fprintf (dump_file, "\n");
50674e96 9495 }
777f7f9a
RH
9496
9497 remove_exit_barriers (root_omp_region);
9498
9499 expand_omp (root_omp_region);
9500
777f7f9a
RH
9501 cleanup_tree_cfg ();
9502
9503 free_omp_regions ();
9504
c2924966 9505 return 0;
50674e96
DN
9506}
9507
917948d3
ZD
9508/* OMP expansion -- the default pass, run before creation of SSA form. */
9509
27a4cd48
DM
9510namespace {
9511
9512const pass_data pass_data_expand_omp =
9513{
9514 GIMPLE_PASS, /* type */
9515 "ompexp", /* name */
9516 OPTGROUP_NONE, /* optinfo_flags */
27a4cd48
DM
9517 TV_NONE, /* tv_id */
9518 PROP_gimple_any, /* properties_required */
18751894 9519 PROP_gimple_eomp, /* properties_provided */
27a4cd48
DM
9520 0, /* properties_destroyed */
9521 0, /* todo_flags_start */
9522 0, /* todo_flags_finish */
50674e96 9523};
27a4cd48
DM
9524
9525class pass_expand_omp : public gimple_opt_pass
9526{
9527public:
c3284718
RS
9528 pass_expand_omp (gcc::context *ctxt)
9529 : gimple_opt_pass (pass_data_expand_omp, ctxt)
27a4cd48
DM
9530 {}
9531
9532 /* opt_pass methods: */
18751894 9533 virtual unsigned int execute (function *)
1a3d085c 9534 {
41dbbb37
TS
9535 bool gate = ((flag_cilkplus != 0 || flag_openacc != 0 || flag_openmp != 0
9536 || flag_openmp_simd != 0)
9537 && !seen_error ());
1a3d085c 9538
18751894 9539 /* This pass always runs, to provide PROP_gimple_eomp.
41dbbb37 9540 But often, there is nothing to do. */
18751894
TV
9541 if (!gate)
9542 return 0;
9543
9544 return execute_expand_omp ();
9545 }
27a4cd48
DM
9546
9547}; // class pass_expand_omp
9548
9549} // anon namespace
9550
9551gimple_opt_pass *
9552make_pass_expand_omp (gcc::context *ctxt)
9553{
9554 return new pass_expand_omp (ctxt);
9555}
18751894
TV
9556
9557namespace {
9558
9559const pass_data pass_data_expand_omp_ssa =
9560{
9561 GIMPLE_PASS, /* type */
9562 "ompexpssa", /* name */
9563 OPTGROUP_NONE, /* optinfo_flags */
9564 TV_NONE, /* tv_id */
9565 PROP_cfg | PROP_ssa, /* properties_required */
9566 PROP_gimple_eomp, /* properties_provided */
9567 0, /* properties_destroyed */
9568 0, /* todo_flags_start */
9569 TODO_cleanup_cfg | TODO_rebuild_alias, /* todo_flags_finish */
9570};
9571
9572class pass_expand_omp_ssa : public gimple_opt_pass
9573{
9574public:
9575 pass_expand_omp_ssa (gcc::context *ctxt)
9576 : gimple_opt_pass (pass_data_expand_omp_ssa, ctxt)
9577 {}
9578
9579 /* opt_pass methods: */
9580 virtual bool gate (function *fun)
9581 {
9582 return !(fun->curr_properties & PROP_gimple_eomp);
9583 }
9584 virtual unsigned int execute (function *) { return execute_expand_omp (); }
9585
9586}; // class pass_expand_omp_ssa
9587
9588} // anon namespace
9589
9590gimple_opt_pass *
9591make_pass_expand_omp_ssa (gcc::context *ctxt)
9592{
9593 return new pass_expand_omp_ssa (ctxt);
9594}
50674e96 9595\f
41dbbb37
TS
9596/* Routines to lower OMP directives into OMP-GIMPLE. */
9597
9598/* Helper function to preform, potentially COMPLEX_TYPE, operation and
9599 convert it to gimple. */
9600static void
9601oacc_gimple_assign (tree dest, tree_code op, tree src, gimple_seq *seq)
9602{
9603 gimple stmt;
9604
9605 if (TREE_CODE (TREE_TYPE (dest)) != COMPLEX_TYPE)
9606 {
9607 stmt = gimple_build_assign (dest, op, dest, src);
9608 gimple_seq_add_stmt (seq, stmt);
9609 return;
9610 }
9611
9612 tree t = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
9613 tree rdest = fold_build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (dest)), dest);
9614 gimplify_assign (t, rdest, seq);
9615 rdest = t;
9616
9617 t = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
9618 tree idest = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (dest)), dest);
9619 gimplify_assign (t, idest, seq);
9620 idest = t;
9621
9622 t = create_tmp_var (TREE_TYPE (TREE_TYPE (src)));
9623 tree rsrc = fold_build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (src)), src);
9624 gimplify_assign (t, rsrc, seq);
9625 rsrc = t;
9626
9627 t = create_tmp_var (TREE_TYPE (TREE_TYPE (src)));
9628 tree isrc = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (src)), src);
9629 gimplify_assign (t, isrc, seq);
9630 isrc = t;
9631
9632 tree r = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
9633 tree i = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
9634 tree result;
9635
9636 if (op == PLUS_EXPR)
9637 {
9638 stmt = gimple_build_assign (r, op, rdest, rsrc);
9639 gimple_seq_add_stmt (seq, stmt);
9640
9641 stmt = gimple_build_assign (i, op, idest, isrc);
9642 gimple_seq_add_stmt (seq, stmt);
9643 }
9644 else if (op == MULT_EXPR)
9645 {
9646 /* Let x = a + ib = dest, y = c + id = src.
9647 x * y = (ac - bd) + i(ad + bc) */
9648 tree ac = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
9649 tree bd = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
9650 tree ad = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
9651 tree bc = create_tmp_var (TREE_TYPE (TREE_TYPE (dest)));
9652
9653 stmt = gimple_build_assign (ac, MULT_EXPR, rdest, rsrc);
9654 gimple_seq_add_stmt (seq, stmt);
9655
9656 stmt = gimple_build_assign (bd, MULT_EXPR, idest, isrc);
9657 gimple_seq_add_stmt (seq, stmt);
9658
9659 stmt = gimple_build_assign (r, MINUS_EXPR, ac, bd);
9660 gimple_seq_add_stmt (seq, stmt);
9661
9662 stmt = gimple_build_assign (ad, MULT_EXPR, rdest, isrc);
9663 gimple_seq_add_stmt (seq, stmt);
9664
9665 stmt = gimple_build_assign (bd, MULT_EXPR, idest, rsrc);
9666 gimple_seq_add_stmt (seq, stmt);
9667
9668 stmt = gimple_build_assign (i, PLUS_EXPR, ad, bc);
9669 gimple_seq_add_stmt (seq, stmt);
9670 }
9671 else
9672 gcc_unreachable ();
9673
9674 result = build2 (COMPLEX_EXPR, TREE_TYPE (dest), r, i);
9675 gimplify_assign (dest, result, seq);
9676}
9677
9678/* Helper function to initialize local data for the reduction arrays.
9679 The reduction arrays need to be placed inside the calling function
9680 for accelerators, or else the host won't be able to preform the final
9681 reduction. */
9682
9683static void
9684oacc_initialize_reduction_data (tree clauses, tree nthreads,
9685 gimple_seq *stmt_seqp, omp_context *ctx)
9686{
9687 tree c, t, oc;
9688 gimple stmt;
9689 omp_context *octx;
9690
9691 /* Find the innermost OpenACC parallel context. */
9692 if (gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
9693 && (gimple_omp_target_kind (ctx->stmt)
9694 == GF_OMP_TARGET_KIND_OACC_PARALLEL))
9695 octx = ctx;
9696 else
9697 octx = ctx->outer;
9698 gcc_checking_assert (gimple_code (octx->stmt) == GIMPLE_OMP_TARGET
9699 && (gimple_omp_target_kind (octx->stmt)
9700 == GF_OMP_TARGET_KIND_OACC_PARALLEL));
9701
9702 /* Extract the clauses. */
9703 oc = gimple_omp_target_clauses (octx->stmt);
9704
9705 /* Find the last outer clause. */
9706 for (; oc && OMP_CLAUSE_CHAIN (oc); oc = OMP_CLAUSE_CHAIN (oc))
9707 ;
9708
9709 /* Allocate arrays for each reduction variable. */
9710 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
9711 {
9712 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
9713 continue;
9714
9715 tree var = OMP_CLAUSE_DECL (c);
9716 tree type = get_base_type (var);
9717 tree array = lookup_oacc_reduction (oacc_get_reduction_array_id (var),
9718 ctx);
9719 tree size, call;
9720
9721 /* Calculate size of the reduction array. */
9722 t = create_tmp_var (TREE_TYPE (nthreads));
9723 stmt = gimple_build_assign (t, MULT_EXPR, nthreads,
9724 fold_convert (TREE_TYPE (nthreads),
9725 TYPE_SIZE_UNIT (type)));
9726 gimple_seq_add_stmt (stmt_seqp, stmt);
9727
9728 size = create_tmp_var (sizetype);
9729 gimplify_assign (size, fold_build1 (NOP_EXPR, sizetype, t), stmt_seqp);
9730
9731 /* Now allocate memory for it. */
9732 call = unshare_expr (builtin_decl_explicit (BUILT_IN_ALLOCA));
9733 stmt = gimple_build_call (call, 1, size);
9734 gimple_call_set_lhs (stmt, array);
9735 gimple_seq_add_stmt (stmt_seqp, stmt);
9736
9737 /* Map this array into the accelerator. */
9738
9739 /* Add the reduction array to the list of clauses. */
9740 tree x = array;
9741 t = build_omp_clause (gimple_location (ctx->stmt), OMP_CLAUSE_MAP);
9742 OMP_CLAUSE_SET_MAP_KIND (t, GOMP_MAP_FORCE_FROM);
9743 OMP_CLAUSE_DECL (t) = x;
9744 OMP_CLAUSE_CHAIN (t) = NULL;
9745 if (oc)
9746 OMP_CLAUSE_CHAIN (oc) = t;
9747 else
9748 gimple_omp_target_set_clauses (as_a <gomp_target *> (octx->stmt), t);
9749 OMP_CLAUSE_SIZE (t) = size;
9750 oc = t;
9751 }
9752}
9753
9754/* Helper function to process the array of partial reductions. Nthreads
9755 indicates the number of threads. Unfortunately, GOACC_GET_NUM_THREADS
9756 cannot be used here, because nthreads on the host may be different than
9757 on the accelerator. */
9758
9759static void
9760oacc_finalize_reduction_data (tree clauses, tree nthreads,
9761 gimple_seq *stmt_seqp, omp_context *ctx)
9762{
9763 tree c, x, var, array, loop_header, loop_body, loop_exit, type;
9764 gimple stmt;
9765
9766 /* Create for loop.
9767
9768 let var = the original reduction variable
9769 let array = reduction variable array
9770
9771 for (i = 0; i < nthreads; i++)
9772 var op= array[i]
9773 */
9774
9775 loop_header = create_artificial_label (UNKNOWN_LOCATION);
9776 loop_body = create_artificial_label (UNKNOWN_LOCATION);
9777 loop_exit = create_artificial_label (UNKNOWN_LOCATION);
9778
9779 /* Create and initialize an index variable. */
9780 tree ix = create_tmp_var (sizetype);
9781 gimplify_assign (ix, fold_build1 (NOP_EXPR, sizetype, integer_zero_node),
9782 stmt_seqp);
9783
9784 /* Insert the loop header label here. */
9785 gimple_seq_add_stmt (stmt_seqp, gimple_build_label (loop_header));
9786
9787 /* Exit loop if ix >= nthreads. */
9788 x = create_tmp_var (sizetype);
9789 gimplify_assign (x, fold_build1 (NOP_EXPR, sizetype, nthreads), stmt_seqp);
9790 stmt = gimple_build_cond (GE_EXPR, ix, x, loop_exit, loop_body);
9791 gimple_seq_add_stmt (stmt_seqp, stmt);
9792
9793 /* Insert the loop body label here. */
9794 gimple_seq_add_stmt (stmt_seqp, gimple_build_label (loop_body));
9795
9796 /* Collapse each reduction array, one element at a time. */
9797 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
9798 {
9799 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
9800 continue;
9801
9802 tree_code reduction_code = OMP_CLAUSE_REDUCTION_CODE (c);
9803
9804 /* reduction(-:var) sums up the partial results, so it acts
9805 identically to reduction(+:var). */
9806 if (reduction_code == MINUS_EXPR)
9807 reduction_code = PLUS_EXPR;
9808
9809 /* Set up reduction variable var. */
9810 var = OMP_CLAUSE_DECL (c);
9811 type = get_base_type (var);
9812 array = lookup_oacc_reduction (oacc_get_reduction_array_id
9813 (OMP_CLAUSE_DECL (c)), ctx);
9814
9815 /* Calculate the array offset. */
9816 tree offset = create_tmp_var (sizetype);
9817 gimplify_assign (offset, TYPE_SIZE_UNIT (type), stmt_seqp);
9818 stmt = gimple_build_assign (offset, MULT_EXPR, offset, ix);
9819 gimple_seq_add_stmt (stmt_seqp, stmt);
9820
9821 tree ptr = create_tmp_var (TREE_TYPE (array));
9822 stmt = gimple_build_assign (ptr, POINTER_PLUS_EXPR, array, offset);
9823 gimple_seq_add_stmt (stmt_seqp, stmt);
9824
9825 /* Extract array[ix] into mem. */
9826 tree mem = create_tmp_var (type);
9827 gimplify_assign (mem, build_simple_mem_ref (ptr), stmt_seqp);
9828
9829 /* Find the original reduction variable. */
9830 if (is_reference (var))
9831 var = build_simple_mem_ref (var);
9832
9833 tree t = create_tmp_var (type);
9834
9835 x = lang_hooks.decls.omp_clause_assign_op (c, t, var);
9836 gimplify_and_add (unshare_expr(x), stmt_seqp);
9837
9838 /* var = var op mem */
9839 switch (OMP_CLAUSE_REDUCTION_CODE (c))
9840 {
9841 case TRUTH_ANDIF_EXPR:
9842 case TRUTH_ORIF_EXPR:
9843 t = fold_build2 (OMP_CLAUSE_REDUCTION_CODE (c), integer_type_node,
9844 t, mem);
9845 gimplify_and_add (t, stmt_seqp);
9846 break;
9847 default:
9848 /* The lhs isn't a gimple_reg when var is COMPLEX_TYPE. */
9849 oacc_gimple_assign (t, OMP_CLAUSE_REDUCTION_CODE (c), mem,
9850 stmt_seqp);
9851 }
9852
9853 t = fold_build1 (NOP_EXPR, TREE_TYPE (var), t);
9854 x = lang_hooks.decls.omp_clause_assign_op (c, var, t);
9855 gimplify_and_add (unshare_expr(x), stmt_seqp);
9856 }
9857
9858 /* Increment the induction variable. */
9859 tree one = fold_build1 (NOP_EXPR, sizetype, integer_one_node);
9860 stmt = gimple_build_assign (ix, PLUS_EXPR, ix, one);
9861 gimple_seq_add_stmt (stmt_seqp, stmt);
9862
9863 /* Go back to the top of the loop. */
9864 gimple_seq_add_stmt (stmt_seqp, gimple_build_goto (loop_header));
9865
9866 /* Place the loop exit label here. */
9867 gimple_seq_add_stmt (stmt_seqp, gimple_build_label (loop_exit));
9868}
9869
9870/* Scan through all of the gimple stmts searching for an OMP_FOR_EXPR, and
9871 scan that for reductions. */
9872
9873static void
9874oacc_process_reduction_data (gimple_seq *body, gimple_seq *in_stmt_seqp,
9875 gimple_seq *out_stmt_seqp, omp_context *ctx)
9876{
9877 gimple_stmt_iterator gsi;
9878 gimple_seq inner = NULL;
9879
9880 /* A collapse clause may have inserted a new bind block. */
9881 gsi = gsi_start (*body);
9882 while (!gsi_end_p (gsi))
9883 {
9884 gimple stmt = gsi_stmt (gsi);
9885 if (gbind *bind_stmt = dyn_cast <gbind *> (stmt))
9886 {
9887 inner = gimple_bind_body (bind_stmt);
9888 body = &inner;
9889 gsi = gsi_start (*body);
9890 }
9891 else if (dyn_cast <gomp_for *> (stmt))
9892 break;
9893 else
9894 gsi_next (&gsi);
9895 }
9896
9897 for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
9898 {
9899 tree clauses, nthreads, t, c, acc_device, acc_device_host, call,
9900 enter, exit;
9901 bool reduction_found = false;
9902
9903 gimple stmt = gsi_stmt (gsi);
9904
9905 switch (gimple_code (stmt))
9906 {
9907 case GIMPLE_OMP_FOR:
9908 clauses = gimple_omp_for_clauses (stmt);
9909
9910 /* Search for a reduction clause. */
9911 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
9912 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
9913 {
9914 reduction_found = true;
9915 break;
9916 }
9917
9918 if (!reduction_found)
9919 break;
9920
9921 ctx = maybe_lookup_ctx (stmt);
9922 t = NULL_TREE;
9923
9924 /* Extract the number of threads. */
9925 nthreads = create_tmp_var (sizetype);
9926 t = oacc_max_threads (ctx);
9927 gimplify_assign (nthreads, t, in_stmt_seqp);
9928
9929 /* Determine if this is kernel will be executed on the host. */
9930 call = builtin_decl_explicit (BUILT_IN_ACC_GET_DEVICE_TYPE);
9931 acc_device = create_tmp_var (integer_type_node, ".acc_device_type");
9932 stmt = gimple_build_call (call, 0);
9933 gimple_call_set_lhs (stmt, acc_device);
9934 gimple_seq_add_stmt (in_stmt_seqp, stmt);
9935
9936 /* Set nthreads = 1 for ACC_DEVICE_TYPE=host. */
9937 acc_device_host = create_tmp_var (integer_type_node,
9938 ".acc_device_host");
9939 gimplify_assign (acc_device_host,
9940 build_int_cst (integer_type_node,
9941 GOMP_DEVICE_HOST),
9942 in_stmt_seqp);
9943
9944 enter = create_artificial_label (UNKNOWN_LOCATION);
9945 exit = create_artificial_label (UNKNOWN_LOCATION);
9946
9947 stmt = gimple_build_cond (EQ_EXPR, acc_device, acc_device_host,
9948 enter, exit);
9949 gimple_seq_add_stmt (in_stmt_seqp, stmt);
9950 gimple_seq_add_stmt (in_stmt_seqp, gimple_build_label (enter));
9951 gimplify_assign (nthreads, fold_build1 (NOP_EXPR, sizetype,
9952 integer_one_node),
9953 in_stmt_seqp);
9954 gimple_seq_add_stmt (in_stmt_seqp, gimple_build_label (exit));
9955
9956 /* Also, set nthreads = 1 for ACC_DEVICE_TYPE=host_nonshm. */
9957 gimplify_assign (acc_device_host,
9958 build_int_cst (integer_type_node,
9959 GOMP_DEVICE_HOST_NONSHM),
9960 in_stmt_seqp);
9961
9962 enter = create_artificial_label (UNKNOWN_LOCATION);
9963 exit = create_artificial_label (UNKNOWN_LOCATION);
9964
9965 stmt = gimple_build_cond (EQ_EXPR, acc_device, acc_device_host,
9966 enter, exit);
9967 gimple_seq_add_stmt (in_stmt_seqp, stmt);
9968 gimple_seq_add_stmt (in_stmt_seqp, gimple_build_label (enter));
9969 gimplify_assign (nthreads, fold_build1 (NOP_EXPR, sizetype,
9970 integer_one_node),
9971 in_stmt_seqp);
9972 gimple_seq_add_stmt (in_stmt_seqp, gimple_build_label (exit));
9973
9974 oacc_initialize_reduction_data (clauses, nthreads, in_stmt_seqp,
9975 ctx);
9976 oacc_finalize_reduction_data (clauses, nthreads, out_stmt_seqp, ctx);
9977 break;
9978 default:
9979 // Scan for other directives which support reduction here.
9980 break;
9981 }
9982 }
9983}
50674e96 9984
acf0174b
JJ
9985/* If ctx is a worksharing context inside of a cancellable parallel
9986 region and it isn't nowait, add lhs to its GIMPLE_OMP_RETURN
9987 and conditional branch to parallel's cancel_label to handle
9988 cancellation in the implicit barrier. */
9989
9990static void
9991maybe_add_implicit_barrier_cancel (omp_context *ctx, gimple_seq *body)
9992{
9993 gimple omp_return = gimple_seq_last_stmt (*body);
9994 gcc_assert (gimple_code (omp_return) == GIMPLE_OMP_RETURN);
9995 if (gimple_omp_return_nowait_p (omp_return))
9996 return;
9997 if (ctx->outer
9998 && gimple_code (ctx->outer->stmt) == GIMPLE_OMP_PARALLEL
9999 && ctx->outer->cancellable)
10000 {
dd2fc525
JJ
10001 tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
10002 tree c_bool_type = TREE_TYPE (TREE_TYPE (fndecl));
b731b390 10003 tree lhs = create_tmp_var (c_bool_type);
acf0174b
JJ
10004 gimple_omp_return_set_lhs (omp_return, lhs);
10005 tree fallthru_label = create_artificial_label (UNKNOWN_LOCATION);
dd2fc525
JJ
10006 gimple g = gimple_build_cond (NE_EXPR, lhs,
10007 fold_convert (c_bool_type,
10008 boolean_false_node),
acf0174b
JJ
10009 ctx->outer->cancel_label, fallthru_label);
10010 gimple_seq_add_stmt (body, g);
10011 gimple_seq_add_stmt (body, gimple_build_label (fallthru_label));
10012 }
10013}
10014
726a989a
RB
10015/* Lower the OpenMP sections directive in the current statement in GSI_P.
10016 CTX is the enclosing OMP context for the current statement. */
50674e96
DN
10017
10018static void
726a989a 10019lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
50674e96 10020{
726a989a
RB
10021 tree block, control;
10022 gimple_stmt_iterator tgsi;
538dd0b7
DM
10023 gomp_sections *stmt;
10024 gimple t;
10025 gbind *new_stmt, *bind;
355a7673 10026 gimple_seq ilist, dlist, olist, new_body;
50674e96 10027
538dd0b7 10028 stmt = as_a <gomp_sections *> (gsi_stmt (*gsi_p));
50674e96 10029
45852dcc 10030 push_gimplify_context ();
50674e96
DN
10031
10032 dlist = NULL;
10033 ilist = NULL;
726a989a 10034 lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
acf0174b 10035 &ilist, &dlist, ctx, NULL);
50674e96 10036
355a7673
MM
10037 new_body = gimple_omp_body (stmt);
10038 gimple_omp_set_body (stmt, NULL);
10039 tgsi = gsi_start (new_body);
10040 for (; !gsi_end_p (tgsi); gsi_next (&tgsi))
50674e96
DN
10041 {
10042 omp_context *sctx;
726a989a 10043 gimple sec_start;
50674e96 10044
726a989a 10045 sec_start = gsi_stmt (tgsi);
50674e96
DN
10046 sctx = maybe_lookup_ctx (sec_start);
10047 gcc_assert (sctx);
10048
355a7673
MM
10049 lower_omp (gimple_omp_body_ptr (sec_start), sctx);
10050 gsi_insert_seq_after (&tgsi, gimple_omp_body (sec_start),
10051 GSI_CONTINUE_LINKING);
726a989a 10052 gimple_omp_set_body (sec_start, NULL);
50674e96 10053
355a7673 10054 if (gsi_one_before_end_p (tgsi))
50674e96 10055 {
726a989a
RB
10056 gimple_seq l = NULL;
10057 lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
50674e96 10058 &l, ctx);
355a7673 10059 gsi_insert_seq_after (&tgsi, l, GSI_CONTINUE_LINKING);
726a989a 10060 gimple_omp_section_set_last (sec_start);
50674e96 10061 }
b8698a0f 10062
355a7673
MM
10063 gsi_insert_after (&tgsi, gimple_build_omp_return (false),
10064 GSI_CONTINUE_LINKING);
50674e96 10065 }
953ff289
DN
10066
10067 block = make_node (BLOCK);
355a7673 10068 bind = gimple_build_bind (NULL, new_body, block);
953ff289 10069
726a989a
RB
10070 olist = NULL;
10071 lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
50674e96 10072
b357f682 10073 block = make_node (BLOCK);
726a989a 10074 new_stmt = gimple_build_bind (NULL, NULL, block);
355a7673 10075 gsi_replace (gsi_p, new_stmt, true);
50674e96 10076
b357f682 10077 pop_gimplify_context (new_stmt);
726a989a
RB
10078 gimple_bind_append_vars (new_stmt, ctx->block_vars);
10079 BLOCK_VARS (block) = gimple_bind_vars (bind);
b357f682
JJ
10080 if (BLOCK_VARS (block))
10081 TREE_USED (block) = 1;
10082
726a989a
RB
10083 new_body = NULL;
10084 gimple_seq_add_seq (&new_body, ilist);
10085 gimple_seq_add_stmt (&new_body, stmt);
10086 gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
10087 gimple_seq_add_stmt (&new_body, bind);
777f7f9a 10088
e5c95afe 10089 control = create_tmp_var (unsigned_type_node, ".section");
726a989a
RB
10090 t = gimple_build_omp_continue (control, control);
10091 gimple_omp_sections_set_control (stmt, control);
10092 gimple_seq_add_stmt (&new_body, t);
777f7f9a 10093
726a989a 10094 gimple_seq_add_seq (&new_body, olist);
acf0174b
JJ
10095 if (ctx->cancellable)
10096 gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
726a989a 10097 gimple_seq_add_seq (&new_body, dlist);
50674e96 10098
726a989a 10099 new_body = maybe_catch_exception (new_body);
4a31b7ee 10100
726a989a
RB
10101 t = gimple_build_omp_return
10102 (!!find_omp_clause (gimple_omp_sections_clauses (stmt),
10103 OMP_CLAUSE_NOWAIT));
10104 gimple_seq_add_stmt (&new_body, t);
acf0174b 10105 maybe_add_implicit_barrier_cancel (ctx, &new_body);
777f7f9a 10106
726a989a 10107 gimple_bind_set_body (new_stmt, new_body);
953ff289
DN
10108}
10109
10110
50674e96 10111/* A subroutine of lower_omp_single. Expand the simple form of
726a989a 10112 a GIMPLE_OMP_SINGLE, without a copyprivate clause:
953ff289
DN
10113
10114 if (GOMP_single_start ())
10115 BODY;
10116 [ GOMP_barrier (); ] -> unless 'nowait' is present.
50674e96
DN
10117
10118 FIXME. It may be better to delay expanding the logic of this until
10119 pass_expand_omp. The expanded logic may make the job more difficult
10120 to a synchronization analysis pass. */
953ff289
DN
10121
10122static void
538dd0b7 10123lower_omp_single_simple (gomp_single *single_stmt, gimple_seq *pre_p)
953ff289 10124{
c2255bc4
AH
10125 location_t loc = gimple_location (single_stmt);
10126 tree tlabel = create_artificial_label (loc);
10127 tree flabel = create_artificial_label (loc);
726a989a
RB
10128 gimple call, cond;
10129 tree lhs, decl;
10130
e79983f4 10131 decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START);
b731b390 10132 lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)));
726a989a
RB
10133 call = gimple_build_call (decl, 0);
10134 gimple_call_set_lhs (call, lhs);
10135 gimple_seq_add_stmt (pre_p, call);
10136
10137 cond = gimple_build_cond (EQ_EXPR, lhs,
db3927fb
AH
10138 fold_convert_loc (loc, TREE_TYPE (lhs),
10139 boolean_true_node),
726a989a
RB
10140 tlabel, flabel);
10141 gimple_seq_add_stmt (pre_p, cond);
10142 gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
10143 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
10144 gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
953ff289
DN
10145}
10146
50674e96
DN
10147
10148/* A subroutine of lower_omp_single. Expand the simple form of
726a989a 10149 a GIMPLE_OMP_SINGLE, with a copyprivate clause:
953ff289
DN
10150
10151 #pragma omp single copyprivate (a, b, c)
10152
10153 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
10154
10155 {
10156 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
10157 {
10158 BODY;
10159 copyout.a = a;
10160 copyout.b = b;
10161 copyout.c = c;
10162 GOMP_single_copy_end (&copyout);
10163 }
10164 else
10165 {
10166 a = copyout_p->a;
10167 b = copyout_p->b;
10168 c = copyout_p->c;
10169 }
10170 GOMP_barrier ();
10171 }
50674e96
DN
10172
10173 FIXME. It may be better to delay expanding the logic of this until
10174 pass_expand_omp. The expanded logic may make the job more difficult
10175 to a synchronization analysis pass. */
953ff289
DN
10176
10177static void
538dd0b7
DM
10178lower_omp_single_copy (gomp_single *single_stmt, gimple_seq *pre_p,
10179 omp_context *ctx)
953ff289 10180{
e79983f4 10181 tree ptr_type, t, l0, l1, l2, bfn_decl;
726a989a 10182 gimple_seq copyin_seq;
c2255bc4 10183 location_t loc = gimple_location (single_stmt);
953ff289
DN
10184
10185 ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
10186
10187 ptr_type = build_pointer_type (ctx->record_type);
10188 ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
10189
c2255bc4
AH
10190 l0 = create_artificial_label (loc);
10191 l1 = create_artificial_label (loc);
10192 l2 = create_artificial_label (loc);
953ff289 10193
e79983f4
MM
10194 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START);
10195 t = build_call_expr_loc (loc, bfn_decl, 0);
db3927fb 10196 t = fold_convert_loc (loc, ptr_type, t);
726a989a 10197 gimplify_assign (ctx->receiver_decl, t, pre_p);
953ff289
DN
10198
10199 t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
10200 build_int_cst (ptr_type, 0));
10201 t = build3 (COND_EXPR, void_type_node, t,
10202 build_and_jump (&l0), build_and_jump (&l1));
10203 gimplify_and_add (t, pre_p);
10204
726a989a 10205 gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
953ff289 10206
726a989a 10207 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
953ff289
DN
10208
10209 copyin_seq = NULL;
726a989a 10210 lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
953ff289
DN
10211 &copyin_seq, ctx);
10212
db3927fb 10213 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
e79983f4
MM
10214 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END);
10215 t = build_call_expr_loc (loc, bfn_decl, 1, t);
953ff289
DN
10216 gimplify_and_add (t, pre_p);
10217
10218 t = build_and_jump (&l2);
10219 gimplify_and_add (t, pre_p);
10220
726a989a 10221 gimple_seq_add_stmt (pre_p, gimple_build_label (l1));
953ff289 10222
726a989a 10223 gimple_seq_add_seq (pre_p, copyin_seq);
953ff289 10224
726a989a 10225 gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
953ff289
DN
10226}
10227
50674e96 10228
953ff289
DN
10229/* Expand code for an OpenMP single directive. */
10230
10231static void
726a989a 10232lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
953ff289 10233{
726a989a 10234 tree block;
538dd0b7
DM
10235 gimple t;
10236 gomp_single *single_stmt = as_a <gomp_single *> (gsi_stmt (*gsi_p));
10237 gbind *bind;
acf0174b 10238 gimple_seq bind_body, bind_body_tail = NULL, dlist;
953ff289 10239
45852dcc 10240 push_gimplify_context ();
953ff289 10241
355a7673
MM
10242 block = make_node (BLOCK);
10243 bind = gimple_build_bind (NULL, NULL, block);
10244 gsi_replace (gsi_p, bind, true);
726a989a 10245 bind_body = NULL;
355a7673 10246 dlist = NULL;
726a989a 10247 lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
acf0174b 10248 &bind_body, &dlist, ctx, NULL);
355a7673 10249 lower_omp (gimple_omp_body_ptr (single_stmt), ctx);
953ff289 10250
726a989a 10251 gimple_seq_add_stmt (&bind_body, single_stmt);
953ff289
DN
10252
10253 if (ctx->record_type)
726a989a 10254 lower_omp_single_copy (single_stmt, &bind_body, ctx);
953ff289 10255 else
726a989a
RB
10256 lower_omp_single_simple (single_stmt, &bind_body);
10257
10258 gimple_omp_set_body (single_stmt, NULL);
953ff289 10259
726a989a 10260 gimple_seq_add_seq (&bind_body, dlist);
777f7f9a 10261
726a989a 10262 bind_body = maybe_catch_exception (bind_body);
777f7f9a 10263
b8698a0f 10264 t = gimple_build_omp_return
726a989a
RB
10265 (!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
10266 OMP_CLAUSE_NOWAIT));
acf0174b
JJ
10267 gimple_seq_add_stmt (&bind_body_tail, t);
10268 maybe_add_implicit_barrier_cancel (ctx, &bind_body_tail);
10269 if (ctx->record_type)
10270 {
10271 gimple_stmt_iterator gsi = gsi_start (bind_body_tail);
10272 tree clobber = build_constructor (ctx->record_type, NULL);
10273 TREE_THIS_VOLATILE (clobber) = 1;
10274 gsi_insert_after (&gsi, gimple_build_assign (ctx->sender_decl,
10275 clobber), GSI_SAME_STMT);
10276 }
10277 gimple_seq_add_seq (&bind_body, bind_body_tail);
355a7673 10278 gimple_bind_set_body (bind, bind_body);
777f7f9a 10279
953ff289 10280 pop_gimplify_context (bind);
50674e96 10281
726a989a
RB
10282 gimple_bind_append_vars (bind, ctx->block_vars);
10283 BLOCK_VARS (block) = ctx->block_vars;
b357f682
JJ
10284 if (BLOCK_VARS (block))
10285 TREE_USED (block) = 1;
953ff289
DN
10286}
10287
50674e96 10288
953ff289
DN
10289/* Expand code for an OpenMP master directive. */
10290
10291static void
726a989a 10292lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
953ff289 10293{
e79983f4 10294 tree block, lab = NULL, x, bfn_decl;
538dd0b7
DM
10295 gimple stmt = gsi_stmt (*gsi_p);
10296 gbind *bind;
db3927fb 10297 location_t loc = gimple_location (stmt);
726a989a 10298 gimple_seq tseq;
953ff289 10299
45852dcc 10300 push_gimplify_context ();
953ff289
DN
10301
10302 block = make_node (BLOCK);
355a7673
MM
10303 bind = gimple_build_bind (NULL, NULL, block);
10304 gsi_replace (gsi_p, bind, true);
10305 gimple_bind_add_stmt (bind, stmt);
777f7f9a 10306
e79983f4
MM
10307 bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
10308 x = build_call_expr_loc (loc, bfn_decl, 0);
953ff289
DN
10309 x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
10310 x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
726a989a
RB
10311 tseq = NULL;
10312 gimplify_and_add (x, &tseq);
10313 gimple_bind_add_seq (bind, tseq);
953ff289 10314
355a7673 10315 lower_omp (gimple_omp_body_ptr (stmt), ctx);
726a989a
RB
10316 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
10317 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
10318 gimple_omp_set_body (stmt, NULL);
953ff289 10319
726a989a 10320 gimple_bind_add_stmt (bind, gimple_build_label (lab));
777f7f9a 10321
726a989a 10322 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
777f7f9a 10323
953ff289 10324 pop_gimplify_context (bind);
50674e96 10325
726a989a
RB
10326 gimple_bind_append_vars (bind, ctx->block_vars);
10327 BLOCK_VARS (block) = ctx->block_vars;
953ff289
DN
10328}
10329
50674e96 10330
acf0174b
JJ
10331/* Expand code for an OpenMP taskgroup directive. */
10332
10333static void
10334lower_omp_taskgroup (gimple_stmt_iterator *gsi_p, omp_context *ctx)
10335{
538dd0b7
DM
10336 gimple stmt = gsi_stmt (*gsi_p);
10337 gcall *x;
10338 gbind *bind;
acf0174b
JJ
10339 tree block = make_node (BLOCK);
10340
10341 bind = gimple_build_bind (NULL, NULL, block);
10342 gsi_replace (gsi_p, bind, true);
10343 gimple_bind_add_stmt (bind, stmt);
10344
10345 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_START),
10346 0);
10347 gimple_bind_add_stmt (bind, x);
10348
10349 lower_omp (gimple_omp_body_ptr (stmt), ctx);
10350 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
10351 gimple_omp_set_body (stmt, NULL);
10352
10353 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
10354
10355 gimple_bind_append_vars (bind, ctx->block_vars);
10356 BLOCK_VARS (block) = ctx->block_vars;
10357}
10358
10359
953ff289
DN
10360/* Expand code for an OpenMP ordered directive. */
10361
10362static void
726a989a 10363lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
953ff289 10364{
726a989a 10365 tree block;
538dd0b7
DM
10366 gimple stmt = gsi_stmt (*gsi_p);
10367 gcall *x;
10368 gbind *bind;
953ff289 10369
45852dcc 10370 push_gimplify_context ();
953ff289
DN
10371
10372 block = make_node (BLOCK);
355a7673
MM
10373 bind = gimple_build_bind (NULL, NULL, block);
10374 gsi_replace (gsi_p, bind, true);
10375 gimple_bind_add_stmt (bind, stmt);
777f7f9a 10376
e79983f4
MM
10377 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
10378 0);
726a989a 10379 gimple_bind_add_stmt (bind, x);
953ff289 10380
355a7673 10381 lower_omp (gimple_omp_body_ptr (stmt), ctx);
726a989a
RB
10382 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
10383 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
10384 gimple_omp_set_body (stmt, NULL);
953ff289 10385
e79983f4 10386 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END), 0);
726a989a 10387 gimple_bind_add_stmt (bind, x);
777f7f9a 10388
726a989a 10389 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
777f7f9a 10390
953ff289 10391 pop_gimplify_context (bind);
50674e96 10392
726a989a
RB
10393 gimple_bind_append_vars (bind, ctx->block_vars);
10394 BLOCK_VARS (block) = gimple_bind_vars (bind);
953ff289
DN
10395}
10396
953ff289 10397
726a989a 10398/* Gimplify a GIMPLE_OMP_CRITICAL statement. This is a relatively simple
953ff289
DN
10399 substitution of a couple of function calls. But in the NAMED case,
10400 requires that languages coordinate a symbol name. It is therefore
10401 best put here in common code. */
10402
de144fb2 10403static GTY(()) hash_map<tree, tree> *critical_name_mutexes;
953ff289
DN
10404
10405static void
726a989a 10406lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
953ff289 10407{
726a989a
RB
10408 tree block;
10409 tree name, lock, unlock;
538dd0b7
DM
10410 gomp_critical *stmt = as_a <gomp_critical *> (gsi_stmt (*gsi_p));
10411 gbind *bind;
db3927fb 10412 location_t loc = gimple_location (stmt);
726a989a 10413 gimple_seq tbody;
953ff289 10414
726a989a 10415 name = gimple_omp_critical_name (stmt);
953ff289
DN
10416 if (name)
10417 {
5039610b 10418 tree decl;
953ff289
DN
10419
10420 if (!critical_name_mutexes)
de144fb2 10421 critical_name_mutexes = hash_map<tree, tree>::create_ggc (10);
953ff289 10422
de144fb2 10423 tree *n = critical_name_mutexes->get (name);
953ff289
DN
10424 if (n == NULL)
10425 {
10426 char *new_str;
10427
b731b390 10428 decl = create_tmp_var_raw (ptr_type_node);
953ff289
DN
10429
10430 new_str = ACONCAT ((".gomp_critical_user_",
10431 IDENTIFIER_POINTER (name), NULL));
10432 DECL_NAME (decl) = get_identifier (new_str);
10433 TREE_PUBLIC (decl) = 1;
10434 TREE_STATIC (decl) = 1;
10435 DECL_COMMON (decl) = 1;
10436 DECL_ARTIFICIAL (decl) = 1;
10437 DECL_IGNORED_P (decl) = 1;
1f6be682 10438
9041d2e6 10439 varpool_node::finalize_decl (decl);
953ff289 10440
de144fb2 10441 critical_name_mutexes->put (name, decl);
953ff289
DN
10442 }
10443 else
de144fb2 10444 decl = *n;
953ff289 10445
41dbbb37 10446 /* If '#pragma omp critical' is inside offloaded region or
476ff787
AT
10447 inside function marked as offloadable, the symbol must be
10448 marked as offloadable too. */
10449 omp_context *octx;
10450 if (cgraph_node::get (current_function_decl)->offloadable)
10451 varpool_node::get_create (decl)->offloadable = 1;
10452 else
10453 for (octx = ctx->outer; octx; octx = octx->outer)
41dbbb37 10454 if (is_gimple_omp_offloaded (octx->stmt))
476ff787
AT
10455 {
10456 varpool_node::get_create (decl)->offloadable = 1;
10457 break;
10458 }
10459
e79983f4 10460 lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START);
db3927fb 10461 lock = build_call_expr_loc (loc, lock, 1, build_fold_addr_expr_loc (loc, decl));
953ff289 10462
e79983f4 10463 unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END);
db3927fb
AH
10464 unlock = build_call_expr_loc (loc, unlock, 1,
10465 build_fold_addr_expr_loc (loc, decl));
953ff289
DN
10466 }
10467 else
10468 {
e79983f4 10469 lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START);
db3927fb 10470 lock = build_call_expr_loc (loc, lock, 0);
953ff289 10471
e79983f4 10472 unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END);
db3927fb 10473 unlock = build_call_expr_loc (loc, unlock, 0);
953ff289
DN
10474 }
10475
45852dcc 10476 push_gimplify_context ();
953ff289
DN
10477
10478 block = make_node (BLOCK);
355a7673
MM
10479 bind = gimple_build_bind (NULL, NULL, block);
10480 gsi_replace (gsi_p, bind, true);
10481 gimple_bind_add_stmt (bind, stmt);
777f7f9a 10482
726a989a
RB
10483 tbody = gimple_bind_body (bind);
10484 gimplify_and_add (lock, &tbody);
10485 gimple_bind_set_body (bind, tbody);
953ff289 10486
355a7673 10487 lower_omp (gimple_omp_body_ptr (stmt), ctx);
726a989a
RB
10488 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
10489 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
10490 gimple_omp_set_body (stmt, NULL);
953ff289 10491
726a989a
RB
10492 tbody = gimple_bind_body (bind);
10493 gimplify_and_add (unlock, &tbody);
10494 gimple_bind_set_body (bind, tbody);
777f7f9a 10495
726a989a 10496 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
953ff289
DN
10497
10498 pop_gimplify_context (bind);
726a989a
RB
10499 gimple_bind_append_vars (bind, ctx->block_vars);
10500 BLOCK_VARS (block) = gimple_bind_vars (bind);
50674e96
DN
10501}
10502
10503
10504/* A subroutine of lower_omp_for. Generate code to emit the predicate
10505 for a lastprivate clause. Given a loop control predicate of (V
10506 cond N2), we gate the clause on (!(V cond N2)). The lowered form
3d55c64b
JJ
10507 is appended to *DLIST, iterator initialization is appended to
10508 *BODY_P. */
50674e96
DN
10509
10510static void
726a989a
RB
10511lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
10512 gimple_seq *dlist, struct omp_context *ctx)
50674e96 10513{
726a989a 10514 tree clauses, cond, vinit;
50674e96 10515 enum tree_code cond_code;
726a989a 10516 gimple_seq stmts;
b8698a0f 10517
a68ab351 10518 cond_code = fd->loop.cond_code;
50674e96
DN
10519 cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
10520
10521 /* When possible, use a strict equality expression. This can let VRP
10522 type optimizations deduce the value and remove a copy. */
9541ffee 10523 if (tree_fits_shwi_p (fd->loop.step))
50674e96 10524 {
eb1ce453 10525 HOST_WIDE_INT step = tree_to_shwi (fd->loop.step);
50674e96
DN
10526 if (step == 1 || step == -1)
10527 cond_code = EQ_EXPR;
10528 }
10529
41b37d5e
JJ
10530 tree n2 = fd->loop.n2;
10531 if (fd->collapse > 1
10532 && TREE_CODE (n2) != INTEGER_CST
10533 && gimple_omp_for_combined_into_p (fd->for_stmt)
10534 && gimple_code (ctx->outer->stmt) == GIMPLE_OMP_FOR)
10535 {
10536 gomp_for *gfor = as_a <gomp_for *> (ctx->outer->stmt);
10537 if (gimple_omp_for_kind (gfor) == GF_OMP_FOR_KIND_FOR)
10538 {
10539 struct omp_for_data outer_fd;
10540 extract_omp_for_data (gfor, &outer_fd, NULL);
10541 n2 = fold_convert (TREE_TYPE (n2), outer_fd.loop.n2);
10542 }
10543 }
10544 cond = build2 (cond_code, boolean_type_node, fd->loop.v, n2);
50674e96 10545
726a989a 10546 clauses = gimple_omp_for_clauses (fd->for_stmt);
3d55c64b
JJ
10547 stmts = NULL;
10548 lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
726a989a 10549 if (!gimple_seq_empty_p (stmts))
3d55c64b 10550 {
726a989a 10551 gimple_seq_add_seq (&stmts, *dlist);
a68ab351 10552 *dlist = stmts;
3d55c64b
JJ
10553
10554 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
a68ab351 10555 vinit = fd->loop.n1;
3d55c64b 10556 if (cond_code == EQ_EXPR
9541ffee 10557 && tree_fits_shwi_p (fd->loop.n2)
a68ab351
JJ
10558 && ! integer_zerop (fd->loop.n2))
10559 vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
74bf76ed
JJ
10560 else
10561 vinit = unshare_expr (vinit);
3d55c64b
JJ
10562
10563 /* Initialize the iterator variable, so that threads that don't execute
10564 any iterations don't execute the lastprivate clauses by accident. */
726a989a 10565 gimplify_assign (fd->loop.v, vinit, body_p);
3d55c64b 10566 }
50674e96
DN
10567}
10568
10569
41dbbb37 10570/* Lower code for an OMP loop directive. */
50674e96
DN
10571
10572static void
726a989a 10573lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
50674e96 10574{
726a989a 10575 tree *rhs_p, block;
acf0174b 10576 struct omp_for_data fd, *fdp = NULL;
538dd0b7
DM
10577 gomp_for *stmt = as_a <gomp_for *> (gsi_stmt (*gsi_p));
10578 gbind *new_stmt;
0f900dfa 10579 gimple_seq omp_for_body, body, dlist;
726a989a 10580 size_t i;
50674e96 10581
45852dcc 10582 push_gimplify_context ();
50674e96 10583
355a7673 10584 lower_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
50674e96 10585
b357f682 10586 block = make_node (BLOCK);
726a989a 10587 new_stmt = gimple_build_bind (NULL, NULL, block);
355a7673
MM
10588 /* Replace at gsi right away, so that 'stmt' is no member
10589 of a sequence anymore as we're going to add to to a different
10590 one below. */
10591 gsi_replace (gsi_p, new_stmt, true);
b357f682 10592
50674e96
DN
10593 /* Move declaration of temporaries in the loop body before we make
10594 it go away. */
726a989a
RB
10595 omp_for_body = gimple_omp_body (stmt);
10596 if (!gimple_seq_empty_p (omp_for_body)
10597 && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
10598 {
538dd0b7
DM
10599 gbind *inner_bind
10600 = as_a <gbind *> (gimple_seq_first_stmt (omp_for_body));
c74559df 10601 tree vars = gimple_bind_vars (inner_bind);
726a989a 10602 gimple_bind_append_vars (new_stmt, vars);
c74559df
JJ
10603 /* bind_vars/BLOCK_VARS are being moved to new_stmt/block, don't
10604 keep them on the inner_bind and it's block. */
10605 gimple_bind_set_vars (inner_bind, NULL_TREE);
10606 if (gimple_bind_block (inner_bind))
10607 BLOCK_VARS (gimple_bind_block (inner_bind)) = NULL_TREE;
726a989a 10608 }
50674e96 10609
acf0174b
JJ
10610 if (gimple_omp_for_combined_into_p (stmt))
10611 {
10612 extract_omp_for_data (stmt, &fd, NULL);
10613 fdp = &fd;
10614
10615 /* We need two temporaries with fd.loop.v type (istart/iend)
10616 and then (fd.collapse - 1) temporaries with the same
10617 type for count2 ... countN-1 vars if not constant. */
10618 size_t count = 2;
10619 tree type = fd.iter_type;
10620 if (fd.collapse > 1
10621 && TREE_CODE (fd.loop.n2) != INTEGER_CST)
10622 count += fd.collapse - 1;
10623 bool parallel_for = gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR;
10624 tree outerc = NULL, *pc = gimple_omp_for_clauses_ptr (stmt);
10625 tree clauses = *pc;
10626 if (parallel_for)
10627 outerc
10628 = find_omp_clause (gimple_omp_parallel_clauses (ctx->outer->stmt),
10629 OMP_CLAUSE__LOOPTEMP_);
10630 for (i = 0; i < count; i++)
10631 {
10632 tree temp;
10633 if (parallel_for)
10634 {
10635 gcc_assert (outerc);
10636 temp = lookup_decl (OMP_CLAUSE_DECL (outerc), ctx->outer);
10637 outerc = find_omp_clause (OMP_CLAUSE_CHAIN (outerc),
10638 OMP_CLAUSE__LOOPTEMP_);
10639 }
10640 else
f014c653 10641 {
b731b390 10642 temp = create_tmp_var (type);
f014c653
JJ
10643 insert_decl_map (&ctx->outer->cb, temp, temp);
10644 }
acf0174b
JJ
10645 *pc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__LOOPTEMP_);
10646 OMP_CLAUSE_DECL (*pc) = temp;
10647 pc = &OMP_CLAUSE_CHAIN (*pc);
10648 }
10649 *pc = clauses;
10650 }
10651
726a989a 10652 /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR. */
50674e96 10653 dlist = NULL;
726a989a 10654 body = NULL;
acf0174b
JJ
10655 lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx,
10656 fdp);
726a989a 10657 gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
50674e96 10658
74bf76ed
JJ
10659 lower_omp (gimple_omp_body_ptr (stmt), ctx);
10660
50674e96
DN
10661 /* Lower the header expressions. At this point, we can assume that
10662 the header is of the form:
10663
10664 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
10665
10666 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
10667 using the .omp_data_s mapping, if needed. */
726a989a 10668 for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
a68ab351 10669 {
726a989a 10670 rhs_p = gimple_omp_for_initial_ptr (stmt, i);
a68ab351 10671 if (!is_gimple_min_invariant (*rhs_p))
726a989a 10672 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
a68ab351 10673
726a989a 10674 rhs_p = gimple_omp_for_final_ptr (stmt, i);
a68ab351 10675 if (!is_gimple_min_invariant (*rhs_p))
726a989a 10676 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
a68ab351 10677
726a989a 10678 rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
a68ab351 10679 if (!is_gimple_min_invariant (*rhs_p))
726a989a 10680 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
a68ab351 10681 }
50674e96
DN
10682
10683 /* Once lowered, extract the bounds and clauses. */
a68ab351 10684 extract_omp_for_data (stmt, &fd, NULL);
50674e96 10685
726a989a 10686 lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
50674e96 10687
726a989a
RB
10688 gimple_seq_add_stmt (&body, stmt);
10689 gimple_seq_add_seq (&body, gimple_omp_body (stmt));
777f7f9a 10690
726a989a
RB
10691 gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
10692 fd.loop.v));
777f7f9a 10693
50674e96 10694 /* After the loop, add exit clauses. */
726a989a 10695 lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, ctx);
acf0174b
JJ
10696
10697 if (ctx->cancellable)
10698 gimple_seq_add_stmt (&body, gimple_build_label (ctx->cancel_label));
10699
726a989a 10700 gimple_seq_add_seq (&body, dlist);
50674e96 10701
726a989a 10702 body = maybe_catch_exception (body);
4a31b7ee 10703
777f7f9a 10704 /* Region exit marker goes at the end of the loop body. */
726a989a 10705 gimple_seq_add_stmt (&body, gimple_build_omp_return (fd.have_nowait));
acf0174b 10706 maybe_add_implicit_barrier_cancel (ctx, &body);
b357f682 10707 pop_gimplify_context (new_stmt);
726a989a
RB
10708
10709 gimple_bind_append_vars (new_stmt, ctx->block_vars);
10710 BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
b357f682
JJ
10711 if (BLOCK_VARS (block))
10712 TREE_USED (block) = 1;
50674e96 10713
726a989a
RB
10714 gimple_bind_set_body (new_stmt, body);
10715 gimple_omp_set_body (stmt, NULL);
10716 gimple_omp_for_set_pre_body (stmt, NULL);
953ff289
DN
10717}
10718
b8698a0f 10719/* Callback for walk_stmts. Check if the current statement only contains
e0246869 10720 GIMPLE_OMP_FOR or GIMPLE_OMP_SECTIONS. */
69f1837b
JJ
10721
10722static tree
726a989a
RB
10723check_combined_parallel (gimple_stmt_iterator *gsi_p,
10724 bool *handled_ops_p,
10725 struct walk_stmt_info *wi)
69f1837b 10726{
d3bfe4de 10727 int *info = (int *) wi->info;
726a989a 10728 gimple stmt = gsi_stmt (*gsi_p);
69f1837b 10729
726a989a
RB
10730 *handled_ops_p = true;
10731 switch (gimple_code (stmt))
69f1837b 10732 {
726a989a
RB
10733 WALK_SUBSTMTS;
10734
10735 case GIMPLE_OMP_FOR:
10736 case GIMPLE_OMP_SECTIONS:
69f1837b
JJ
10737 *info = *info == 0 ? 1 : -1;
10738 break;
10739 default:
10740 *info = -1;
10741 break;
10742 }
10743 return NULL;
10744}
50674e96 10745
a68ab351
JJ
10746struct omp_taskcopy_context
10747{
10748 /* This field must be at the beginning, as we do "inheritance": Some
10749 callback functions for tree-inline.c (e.g., omp_copy_decl)
10750 receive a copy_body_data pointer that is up-casted to an
10751 omp_context pointer. */
10752 copy_body_data cb;
10753 omp_context *ctx;
10754};
10755
10756static tree
10757task_copyfn_copy_decl (tree var, copy_body_data *cb)
10758{
10759 struct omp_taskcopy_context *tcctx = (struct omp_taskcopy_context *) cb;
10760
10761 if (splay_tree_lookup (tcctx->ctx->sfield_map, (splay_tree_key) var))
b731b390 10762 return create_tmp_var (TREE_TYPE (var));
a68ab351
JJ
10763
10764 return var;
10765}
10766
10767static tree
10768task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
10769{
10770 tree name, new_fields = NULL, type, f;
10771
10772 type = lang_hooks.types.make_type (RECORD_TYPE);
10773 name = DECL_NAME (TYPE_NAME (orig_type));
c2255bc4
AH
10774 name = build_decl (gimple_location (tcctx->ctx->stmt),
10775 TYPE_DECL, name, type);
a68ab351
JJ
10776 TYPE_NAME (type) = name;
10777
10778 for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
10779 {
10780 tree new_f = copy_node (f);
10781 DECL_CONTEXT (new_f) = type;
10782 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
10783 TREE_CHAIN (new_f) = new_fields;
726a989a
RB
10784 walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
10785 walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
10786 walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
10787 &tcctx->cb, NULL);
a68ab351 10788 new_fields = new_f;
b787e7a2 10789 tcctx->cb.decl_map->put (f, new_f);
a68ab351
JJ
10790 }
10791 TYPE_FIELDS (type) = nreverse (new_fields);
10792 layout_type (type);
10793 return type;
10794}
10795
10796/* Create task copyfn. */
10797
10798static void
538dd0b7 10799create_task_copyfn (gomp_task *task_stmt, omp_context *ctx)
a68ab351
JJ
10800{
10801 struct function *child_cfun;
10802 tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
10803 tree record_type, srecord_type, bind, list;
10804 bool record_needs_remap = false, srecord_needs_remap = false;
10805 splay_tree_node n;
10806 struct omp_taskcopy_context tcctx;
db3927fb 10807 location_t loc = gimple_location (task_stmt);
a68ab351 10808
726a989a 10809 child_fn = gimple_omp_task_copy_fn (task_stmt);
a68ab351
JJ
10810 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
10811 gcc_assert (child_cfun->cfg == NULL);
a68ab351
JJ
10812 DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();
10813
10814 /* Reset DECL_CONTEXT on function arguments. */
910ad8de 10815 for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
a68ab351
JJ
10816 DECL_CONTEXT (t) = child_fn;
10817
10818 /* Populate the function. */
45852dcc 10819 push_gimplify_context ();
af16bc76 10820 push_cfun (child_cfun);
a68ab351
JJ
10821
10822 bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
10823 TREE_SIDE_EFFECTS (bind) = 1;
10824 list = NULL;
10825 DECL_SAVED_TREE (child_fn) = bind;
726a989a 10826 DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);
a68ab351
JJ
10827
10828 /* Remap src and dst argument types if needed. */
10829 record_type = ctx->record_type;
10830 srecord_type = ctx->srecord_type;
910ad8de 10831 for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
a68ab351
JJ
10832 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
10833 {
10834 record_needs_remap = true;
10835 break;
10836 }
910ad8de 10837 for (f = TYPE_FIELDS (srecord_type); f ; f = DECL_CHAIN (f))
a68ab351
JJ
10838 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
10839 {
10840 srecord_needs_remap = true;
10841 break;
10842 }
10843
10844 if (record_needs_remap || srecord_needs_remap)
10845 {
10846 memset (&tcctx, '\0', sizeof (tcctx));
10847 tcctx.cb.src_fn = ctx->cb.src_fn;
10848 tcctx.cb.dst_fn = child_fn;
d52f5295 10849 tcctx.cb.src_node = cgraph_node::get (tcctx.cb.src_fn);
fe660d7b 10850 gcc_checking_assert (tcctx.cb.src_node);
a68ab351
JJ
10851 tcctx.cb.dst_node = tcctx.cb.src_node;
10852 tcctx.cb.src_cfun = ctx->cb.src_cfun;
10853 tcctx.cb.copy_decl = task_copyfn_copy_decl;
1d65f45c 10854 tcctx.cb.eh_lp_nr = 0;
a68ab351 10855 tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
b787e7a2 10856 tcctx.cb.decl_map = new hash_map<tree, tree>;
a68ab351
JJ
10857 tcctx.ctx = ctx;
10858
10859 if (record_needs_remap)
10860 record_type = task_copyfn_remap_type (&tcctx, record_type);
10861 if (srecord_needs_remap)
10862 srecord_type = task_copyfn_remap_type (&tcctx, srecord_type);
10863 }
10864 else
10865 tcctx.cb.decl_map = NULL;
10866
a68ab351
JJ
10867 arg = DECL_ARGUMENTS (child_fn);
10868 TREE_TYPE (arg) = build_pointer_type (record_type);
910ad8de 10869 sarg = DECL_CHAIN (arg);
a68ab351
JJ
10870 TREE_TYPE (sarg) = build_pointer_type (srecord_type);
10871
10872 /* First pass: initialize temporaries used in record_type and srecord_type
10873 sizes and field offsets. */
10874 if (tcctx.cb.decl_map)
726a989a 10875 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
a68ab351
JJ
10876 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
10877 {
10878 tree *p;
10879
10880 decl = OMP_CLAUSE_DECL (c);
b787e7a2 10881 p = tcctx.cb.decl_map->get (decl);
a68ab351
JJ
10882 if (p == NULL)
10883 continue;
10884 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
10885 sf = (tree) n->value;
b787e7a2 10886 sf = *tcctx.cb.decl_map->get (sf);
70f34814 10887 src = build_simple_mem_ref_loc (loc, sarg);
a9a58711 10888 src = omp_build_component_ref (src, sf);
726a989a 10889 t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
a68ab351
JJ
10890 append_to_statement_list (t, &list);
10891 }
10892
10893 /* Second pass: copy shared var pointers and copy construct non-VLA
10894 firstprivate vars. */
726a989a 10895 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
a68ab351
JJ
10896 switch (OMP_CLAUSE_CODE (c))
10897 {
10898 case OMP_CLAUSE_SHARED:
10899 decl = OMP_CLAUSE_DECL (c);
10900 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
10901 if (n == NULL)
10902 break;
10903 f = (tree) n->value;
10904 if (tcctx.cb.decl_map)
b787e7a2 10905 f = *tcctx.cb.decl_map->get (f);
a68ab351
JJ
10906 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
10907 sf = (tree) n->value;
10908 if (tcctx.cb.decl_map)
b787e7a2 10909 sf = *tcctx.cb.decl_map->get (sf);
70f34814 10910 src = build_simple_mem_ref_loc (loc, sarg);
a9a58711 10911 src = omp_build_component_ref (src, sf);
70f34814 10912 dst = build_simple_mem_ref_loc (loc, arg);
a9a58711 10913 dst = omp_build_component_ref (dst, f);
726a989a 10914 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
a68ab351
JJ
10915 append_to_statement_list (t, &list);
10916 break;
10917 case OMP_CLAUSE_FIRSTPRIVATE:
10918 decl = OMP_CLAUSE_DECL (c);
10919 if (is_variable_sized (decl))
10920 break;
10921 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
10922 if (n == NULL)
10923 break;
10924 f = (tree) n->value;
10925 if (tcctx.cb.decl_map)
b787e7a2 10926 f = *tcctx.cb.decl_map->get (f);
a68ab351
JJ
10927 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
10928 if (n != NULL)
10929 {
10930 sf = (tree) n->value;
10931 if (tcctx.cb.decl_map)
b787e7a2 10932 sf = *tcctx.cb.decl_map->get (sf);
70f34814 10933 src = build_simple_mem_ref_loc (loc, sarg);
a9a58711 10934 src = omp_build_component_ref (src, sf);
a68ab351 10935 if (use_pointer_for_field (decl, NULL) || is_reference (decl))
70f34814 10936 src = build_simple_mem_ref_loc (loc, src);
a68ab351
JJ
10937 }
10938 else
10939 src = decl;
70f34814 10940 dst = build_simple_mem_ref_loc (loc, arg);
a9a58711 10941 dst = omp_build_component_ref (dst, f);
a68ab351
JJ
10942 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
10943 append_to_statement_list (t, &list);
10944 break;
10945 case OMP_CLAUSE_PRIVATE:
10946 if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c))
10947 break;
10948 decl = OMP_CLAUSE_DECL (c);
10949 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
10950 f = (tree) n->value;
10951 if (tcctx.cb.decl_map)
b787e7a2 10952 f = *tcctx.cb.decl_map->get (f);
a68ab351
JJ
10953 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
10954 if (n != NULL)
10955 {
10956 sf = (tree) n->value;
10957 if (tcctx.cb.decl_map)
b787e7a2 10958 sf = *tcctx.cb.decl_map->get (sf);
70f34814 10959 src = build_simple_mem_ref_loc (loc, sarg);
a9a58711 10960 src = omp_build_component_ref (src, sf);
a68ab351 10961 if (use_pointer_for_field (decl, NULL))
70f34814 10962 src = build_simple_mem_ref_loc (loc, src);
a68ab351
JJ
10963 }
10964 else
10965 src = decl;
70f34814 10966 dst = build_simple_mem_ref_loc (loc, arg);
a9a58711 10967 dst = omp_build_component_ref (dst, f);
726a989a 10968 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
a68ab351
JJ
10969 append_to_statement_list (t, &list);
10970 break;
10971 default:
10972 break;
10973 }
10974
10975 /* Last pass: handle VLA firstprivates. */
10976 if (tcctx.cb.decl_map)
726a989a 10977 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
a68ab351
JJ
10978 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
10979 {
10980 tree ind, ptr, df;
10981
10982 decl = OMP_CLAUSE_DECL (c);
10983 if (!is_variable_sized (decl))
10984 continue;
10985 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
10986 if (n == NULL)
10987 continue;
10988 f = (tree) n->value;
b787e7a2 10989 f = *tcctx.cb.decl_map->get (f);
a68ab351
JJ
10990 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
10991 ind = DECL_VALUE_EXPR (decl);
10992 gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
10993 gcc_assert (DECL_P (TREE_OPERAND (ind, 0)));
10994 n = splay_tree_lookup (ctx->sfield_map,
10995 (splay_tree_key) TREE_OPERAND (ind, 0));
10996 sf = (tree) n->value;
b787e7a2 10997 sf = *tcctx.cb.decl_map->get (sf);
70f34814 10998 src = build_simple_mem_ref_loc (loc, sarg);
a9a58711 10999 src = omp_build_component_ref (src, sf);
70f34814
RG
11000 src = build_simple_mem_ref_loc (loc, src);
11001 dst = build_simple_mem_ref_loc (loc, arg);
a9a58711 11002 dst = omp_build_component_ref (dst, f);
a68ab351
JJ
11003 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
11004 append_to_statement_list (t, &list);
11005 n = splay_tree_lookup (ctx->field_map,
11006 (splay_tree_key) TREE_OPERAND (ind, 0));
11007 df = (tree) n->value;
b787e7a2 11008 df = *tcctx.cb.decl_map->get (df);
70f34814 11009 ptr = build_simple_mem_ref_loc (loc, arg);
a9a58711 11010 ptr = omp_build_component_ref (ptr, df);
726a989a 11011 t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
db3927fb 11012 build_fold_addr_expr_loc (loc, dst));
a68ab351
JJ
11013 append_to_statement_list (t, &list);
11014 }
11015
11016 t = build1 (RETURN_EXPR, void_type_node, NULL);
11017 append_to_statement_list (t, &list);
11018
11019 if (tcctx.cb.decl_map)
b787e7a2 11020 delete tcctx.cb.decl_map;
a68ab351
JJ
11021 pop_gimplify_context (NULL);
11022 BIND_EXPR_BODY (bind) = list;
11023 pop_cfun ();
a68ab351
JJ
11024}
11025
acf0174b
JJ
11026static void
11027lower_depend_clauses (gimple stmt, gimple_seq *iseq, gimple_seq *oseq)
11028{
11029 tree c, clauses;
11030 gimple g;
11031 size_t n_in = 0, n_out = 0, idx = 2, i;
11032
11033 clauses = find_omp_clause (gimple_omp_task_clauses (stmt),
11034 OMP_CLAUSE_DEPEND);
11035 gcc_assert (clauses);
11036 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
11037 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
11038 switch (OMP_CLAUSE_DEPEND_KIND (c))
11039 {
11040 case OMP_CLAUSE_DEPEND_IN:
11041 n_in++;
11042 break;
11043 case OMP_CLAUSE_DEPEND_OUT:
11044 case OMP_CLAUSE_DEPEND_INOUT:
11045 n_out++;
11046 break;
11047 default:
11048 gcc_unreachable ();
11049 }
11050 tree type = build_array_type_nelts (ptr_type_node, n_in + n_out + 2);
b731b390 11051 tree array = create_tmp_var (type);
acf0174b
JJ
11052 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
11053 NULL_TREE);
11054 g = gimple_build_assign (r, build_int_cst (ptr_type_node, n_in + n_out));
11055 gimple_seq_add_stmt (iseq, g);
11056 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
11057 NULL_TREE);
11058 g = gimple_build_assign (r, build_int_cst (ptr_type_node, n_out));
11059 gimple_seq_add_stmt (iseq, g);
11060 for (i = 0; i < 2; i++)
11061 {
11062 if ((i ? n_in : n_out) == 0)
11063 continue;
11064 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
11065 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
11066 && ((OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_IN) ^ i))
11067 {
11068 tree t = OMP_CLAUSE_DECL (c);
11069 t = fold_convert (ptr_type_node, t);
11070 gimplify_expr (&t, iseq, NULL, is_gimple_val, fb_rvalue);
11071 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (idx++),
11072 NULL_TREE, NULL_TREE);
11073 g = gimple_build_assign (r, t);
11074 gimple_seq_add_stmt (iseq, g);
11075 }
11076 }
11077 tree *p = gimple_omp_task_clauses_ptr (stmt);
11078 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
11079 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
11080 OMP_CLAUSE_CHAIN (c) = *p;
11081 *p = c;
11082 tree clobber = build_constructor (type, NULL);
11083 TREE_THIS_VOLATILE (clobber) = 1;
11084 g = gimple_build_assign (array, clobber);
11085 gimple_seq_add_stmt (oseq, g);
11086}
11087
726a989a
RB
11088/* Lower the OpenMP parallel or task directive in the current statement
11089 in GSI_P. CTX holds context information for the directive. */
50674e96
DN
11090
11091static void
726a989a 11092lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
50674e96 11093{
726a989a
RB
11094 tree clauses;
11095 tree child_fn, t;
11096 gimple stmt = gsi_stmt (*gsi_p);
538dd0b7 11097 gbind *par_bind, *bind, *dep_bind = NULL;
acf0174b 11098 gimple_seq par_body, olist, ilist, par_olist, par_rlist, par_ilist, new_body;
db3927fb 11099 location_t loc = gimple_location (stmt);
50674e96 11100
726a989a 11101 clauses = gimple_omp_taskreg_clauses (stmt);
538dd0b7
DM
11102 par_bind
11103 = as_a <gbind *> (gimple_seq_first_stmt (gimple_omp_body (stmt)));
726a989a 11104 par_body = gimple_bind_body (par_bind);
50674e96 11105 child_fn = ctx->cb.dst_fn;
726a989a
RB
11106 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
11107 && !gimple_omp_parallel_combined_p (stmt))
69f1837b
JJ
11108 {
11109 struct walk_stmt_info wi;
11110 int ws_num = 0;
11111
11112 memset (&wi, 0, sizeof (wi));
69f1837b
JJ
11113 wi.info = &ws_num;
11114 wi.val_only = true;
726a989a 11115 walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
69f1837b 11116 if (ws_num == 1)
726a989a 11117 gimple_omp_parallel_set_combined_p (stmt, true);
69f1837b 11118 }
acf0174b
JJ
11119 gimple_seq dep_ilist = NULL;
11120 gimple_seq dep_olist = NULL;
11121 if (gimple_code (stmt) == GIMPLE_OMP_TASK
11122 && find_omp_clause (clauses, OMP_CLAUSE_DEPEND))
11123 {
45852dcc 11124 push_gimplify_context ();
acf0174b
JJ
11125 dep_bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
11126 lower_depend_clauses (stmt, &dep_ilist, &dep_olist);
11127 }
11128
a68ab351 11129 if (ctx->srecord_type)
538dd0b7 11130 create_task_copyfn (as_a <gomp_task *> (stmt), ctx);
50674e96 11131
45852dcc 11132 push_gimplify_context ();
50674e96 11133
726a989a
RB
11134 par_olist = NULL;
11135 par_ilist = NULL;
acf0174b
JJ
11136 par_rlist = NULL;
11137 lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx, NULL);
355a7673 11138 lower_omp (&par_body, ctx);
726a989a 11139 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
acf0174b 11140 lower_reduction_clauses (clauses, &par_rlist, ctx);
50674e96
DN
11141
11142 /* Declare all the variables created by mapping and the variables
11143 declared in the scope of the parallel body. */
11144 record_vars_into (ctx->block_vars, child_fn);
726a989a 11145 record_vars_into (gimple_bind_vars (par_bind), child_fn);
50674e96
DN
11146
11147 if (ctx->record_type)
11148 {
a68ab351
JJ
11149 ctx->sender_decl
11150 = create_tmp_var (ctx->srecord_type ? ctx->srecord_type
11151 : ctx->record_type, ".omp_data_o");
cd3f04c8 11152 DECL_NAMELESS (ctx->sender_decl) = 1;
628c189e 11153 TREE_ADDRESSABLE (ctx->sender_decl) = 1;
726a989a 11154 gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
50674e96
DN
11155 }
11156
726a989a
RB
11157 olist = NULL;
11158 ilist = NULL;
50674e96
DN
11159 lower_send_clauses (clauses, &ilist, &olist, ctx);
11160 lower_send_shared_vars (&ilist, &olist, ctx);
11161
acf0174b
JJ
11162 if (ctx->record_type)
11163 {
11164 tree clobber = build_constructor (TREE_TYPE (ctx->sender_decl), NULL);
11165 TREE_THIS_VOLATILE (clobber) = 1;
11166 gimple_seq_add_stmt (&olist, gimple_build_assign (ctx->sender_decl,
11167 clobber));
11168 }
11169
50674e96 11170 /* Once all the expansions are done, sequence all the different
726a989a 11171 fragments inside gimple_omp_body. */
50674e96 11172
726a989a 11173 new_body = NULL;
50674e96
DN
11174
11175 if (ctx->record_type)
11176 {
db3927fb 11177 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
018b899b 11178 /* fixup_child_record_type might have changed receiver_decl's type. */
db3927fb 11179 t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
726a989a
RB
11180 gimple_seq_add_stmt (&new_body,
11181 gimple_build_assign (ctx->receiver_decl, t));
50674e96
DN
11182 }
11183
726a989a
RB
11184 gimple_seq_add_seq (&new_body, par_ilist);
11185 gimple_seq_add_seq (&new_body, par_body);
acf0174b
JJ
11186 gimple_seq_add_seq (&new_body, par_rlist);
11187 if (ctx->cancellable)
11188 gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
726a989a
RB
11189 gimple_seq_add_seq (&new_body, par_olist);
11190 new_body = maybe_catch_exception (new_body);
b37dddbc
JJ
11191 if (gimple_code (stmt) == GIMPLE_OMP_TASK)
11192 gimple_seq_add_stmt (&new_body,
11193 gimple_build_omp_continue (integer_zero_node,
11194 integer_zero_node));
726a989a
RB
11195 gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
11196 gimple_omp_set_body (stmt, new_body);
50674e96 11197
726a989a 11198 bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
acf0174b
JJ
11199 gsi_replace (gsi_p, dep_bind ? dep_bind : bind, true);
11200 gimple_bind_add_seq (bind, ilist);
11201 gimple_bind_add_stmt (bind, stmt);
11202 gimple_bind_add_seq (bind, olist);
11203
11204 pop_gimplify_context (NULL);
11205
11206 if (dep_bind)
11207 {
11208 gimple_bind_add_seq (dep_bind, dep_ilist);
11209 gimple_bind_add_stmt (dep_bind, bind);
11210 gimple_bind_add_seq (dep_bind, dep_olist);
11211 pop_gimplify_context (dep_bind);
11212 }
11213}
11214
41dbbb37 11215/* Lower the GIMPLE_OMP_TARGET in the current statement
acf0174b
JJ
11216 in GSI_P. CTX holds context information for the directive. */
11217
11218static void
11219lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
11220{
11221 tree clauses;
11222 tree child_fn, t, c;
538dd0b7 11223 gomp_target *stmt = as_a <gomp_target *> (gsi_stmt (*gsi_p));
41dbbb37
TS
11224 gbind *tgt_bind, *bind;
11225 gimple_seq tgt_body, olist, ilist, orlist, irlist, new_body;
acf0174b 11226 location_t loc = gimple_location (stmt);
41dbbb37 11227 bool offloaded, data_region;
acf0174b
JJ
11228 unsigned int map_cnt = 0;
11229
41dbbb37
TS
11230 offloaded = is_gimple_omp_offloaded (stmt);
11231 switch (gimple_omp_target_kind (stmt))
11232 {
11233 case GF_OMP_TARGET_KIND_REGION:
11234 case GF_OMP_TARGET_KIND_UPDATE:
11235 case GF_OMP_TARGET_KIND_OACC_PARALLEL:
11236 case GF_OMP_TARGET_KIND_OACC_KERNELS:
11237 case GF_OMP_TARGET_KIND_OACC_UPDATE:
11238 case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
11239 data_region = false;
11240 break;
11241 case GF_OMP_TARGET_KIND_DATA:
11242 case GF_OMP_TARGET_KIND_OACC_DATA:
11243 data_region = true;
11244 break;
11245 default:
11246 gcc_unreachable ();
11247 }
11248
acf0174b 11249 clauses = gimple_omp_target_clauses (stmt);
41dbbb37
TS
11250
11251 tgt_bind = NULL;
11252 tgt_body = NULL;
11253 if (offloaded)
acf0174b 11254 {
538dd0b7 11255 tgt_bind = gimple_seq_first_stmt_as_a_bind (gimple_omp_body (stmt));
acf0174b
JJ
11256 tgt_body = gimple_bind_body (tgt_bind);
11257 }
41dbbb37 11258 else if (data_region)
acf0174b
JJ
11259 tgt_body = gimple_omp_body (stmt);
11260 child_fn = ctx->cb.dst_fn;
11261
45852dcc 11262 push_gimplify_context ();
acf0174b 11263
41dbbb37
TS
11264 irlist = NULL;
11265 orlist = NULL;
11266 if (offloaded
11267 && is_gimple_omp_oacc (stmt))
11268 oacc_process_reduction_data (&tgt_body, &irlist, &orlist, ctx);
11269
acf0174b
JJ
11270 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
11271 switch (OMP_CLAUSE_CODE (c))
11272 {
11273 tree var, x;
11274
11275 default:
11276 break;
11277 case OMP_CLAUSE_MAP:
41dbbb37
TS
11278#ifdef ENABLE_CHECKING
11279 /* First check what we're prepared to handle in the following. */
11280 switch (OMP_CLAUSE_MAP_KIND (c))
11281 {
11282 case GOMP_MAP_ALLOC:
11283 case GOMP_MAP_TO:
11284 case GOMP_MAP_FROM:
11285 case GOMP_MAP_TOFROM:
11286 case GOMP_MAP_POINTER:
11287 case GOMP_MAP_TO_PSET:
11288 break;
11289 case GOMP_MAP_FORCE_ALLOC:
11290 case GOMP_MAP_FORCE_TO:
11291 case GOMP_MAP_FORCE_FROM:
11292 case GOMP_MAP_FORCE_TOFROM:
11293 case GOMP_MAP_FORCE_PRESENT:
11294 case GOMP_MAP_FORCE_DEALLOC:
11295 case GOMP_MAP_FORCE_DEVICEPTR:
11296 gcc_assert (is_gimple_omp_oacc (stmt));
11297 break;
11298 default:
11299 gcc_unreachable ();
11300 }
11301#endif
11302 /* FALLTHRU */
acf0174b
JJ
11303 case OMP_CLAUSE_TO:
11304 case OMP_CLAUSE_FROM:
11305 var = OMP_CLAUSE_DECL (c);
11306 if (!DECL_P (var))
11307 {
11308 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
11309 || !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
11310 map_cnt++;
11311 continue;
11312 }
11313
11314 if (DECL_SIZE (var)
11315 && TREE_CODE (DECL_SIZE (var)) != INTEGER_CST)
11316 {
11317 tree var2 = DECL_VALUE_EXPR (var);
11318 gcc_assert (TREE_CODE (var2) == INDIRECT_REF);
11319 var2 = TREE_OPERAND (var2, 0);
11320 gcc_assert (DECL_P (var2));
11321 var = var2;
11322 }
11323
11324 if (!maybe_lookup_field (var, ctx))
11325 continue;
11326
41dbbb37 11327 if (offloaded)
acf0174b
JJ
11328 {
11329 x = build_receiver_ref (var, true, ctx);
11330 tree new_var = lookup_decl (var, ctx);
41dbbb37 11331 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
acf0174b
JJ
11332 && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
11333 && TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
11334 x = build_simple_mem_ref (x);
11335 SET_DECL_VALUE_EXPR (new_var, x);
11336 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
11337 }
11338 map_cnt++;
11339 }
11340
41dbbb37 11341 if (offloaded)
acf0174b
JJ
11342 {
11343 target_nesting_level++;
11344 lower_omp (&tgt_body, ctx);
11345 target_nesting_level--;
11346 }
41dbbb37 11347 else if (data_region)
acf0174b
JJ
11348 lower_omp (&tgt_body, ctx);
11349
41dbbb37 11350 if (offloaded)
acf0174b
JJ
11351 {
11352 /* Declare all the variables created by mapping and the variables
11353 declared in the scope of the target body. */
11354 record_vars_into (ctx->block_vars, child_fn);
11355 record_vars_into (gimple_bind_vars (tgt_bind), child_fn);
11356 }
11357
11358 olist = NULL;
11359 ilist = NULL;
11360 if (ctx->record_type)
11361 {
11362 ctx->sender_decl
11363 = create_tmp_var (ctx->record_type, ".omp_data_arr");
11364 DECL_NAMELESS (ctx->sender_decl) = 1;
11365 TREE_ADDRESSABLE (ctx->sender_decl) = 1;
11366 t = make_tree_vec (3);
11367 TREE_VEC_ELT (t, 0) = ctx->sender_decl;
11368 TREE_VEC_ELT (t, 1)
11369 = create_tmp_var (build_array_type_nelts (size_type_node, map_cnt),
11370 ".omp_data_sizes");
11371 DECL_NAMELESS (TREE_VEC_ELT (t, 1)) = 1;
11372 TREE_ADDRESSABLE (TREE_VEC_ELT (t, 1)) = 1;
11373 TREE_STATIC (TREE_VEC_ELT (t, 1)) = 1;
41dbbb37
TS
11374 tree tkind_type;
11375 int talign_shift;
11376 if (is_gimple_omp_oacc (stmt))
11377 {
11378 tkind_type = short_unsigned_type_node;
11379 talign_shift = 8;
11380 }
11381 else
11382 {
11383 tkind_type = unsigned_char_type_node;
11384 talign_shift = 3;
11385 }
acf0174b 11386 TREE_VEC_ELT (t, 2)
41dbbb37 11387 = create_tmp_var (build_array_type_nelts (tkind_type, map_cnt),
acf0174b
JJ
11388 ".omp_data_kinds");
11389 DECL_NAMELESS (TREE_VEC_ELT (t, 2)) = 1;
11390 TREE_ADDRESSABLE (TREE_VEC_ELT (t, 2)) = 1;
11391 TREE_STATIC (TREE_VEC_ELT (t, 2)) = 1;
11392 gimple_omp_target_set_data_arg (stmt, t);
11393
11394 vec<constructor_elt, va_gc> *vsize;
11395 vec<constructor_elt, va_gc> *vkind;
11396 vec_alloc (vsize, map_cnt);
11397 vec_alloc (vkind, map_cnt);
11398 unsigned int map_idx = 0;
11399
11400 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
11401 switch (OMP_CLAUSE_CODE (c))
11402 {
11403 tree ovar, nc;
11404
11405 default:
11406 break;
11407 case OMP_CLAUSE_MAP:
11408 case OMP_CLAUSE_TO:
11409 case OMP_CLAUSE_FROM:
11410 nc = c;
11411 ovar = OMP_CLAUSE_DECL (c);
11412 if (!DECL_P (ovar))
11413 {
11414 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
11415 && OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
11416 {
11417 gcc_checking_assert (OMP_CLAUSE_DECL (OMP_CLAUSE_CHAIN (c))
11418 == get_base_address (ovar));
11419 nc = OMP_CLAUSE_CHAIN (c);
11420 ovar = OMP_CLAUSE_DECL (nc);
11421 }
11422 else
11423 {
11424 tree x = build_sender_ref (ovar, ctx);
11425 tree v
11426 = build_fold_addr_expr_with_type (ovar, ptr_type_node);
11427 gimplify_assign (x, v, &ilist);
11428 nc = NULL_TREE;
11429 }
11430 }
11431 else
11432 {
11433 if (DECL_SIZE (ovar)
11434 && TREE_CODE (DECL_SIZE (ovar)) != INTEGER_CST)
11435 {
11436 tree ovar2 = DECL_VALUE_EXPR (ovar);
11437 gcc_assert (TREE_CODE (ovar2) == INDIRECT_REF);
11438 ovar2 = TREE_OPERAND (ovar2, 0);
11439 gcc_assert (DECL_P (ovar2));
11440 ovar = ovar2;
11441 }
11442 if (!maybe_lookup_field (ovar, ctx))
11443 continue;
11444 }
11445
0fe81a0f
JJ
11446 unsigned int talign = TYPE_ALIGN_UNIT (TREE_TYPE (ovar));
11447 if (DECL_P (ovar) && DECL_ALIGN_UNIT (ovar) > talign)
11448 talign = DECL_ALIGN_UNIT (ovar);
acf0174b
JJ
11449 if (nc)
11450 {
11451 tree var = lookup_decl_in_outer_ctx (ovar, ctx);
11452 tree x = build_sender_ref (ovar, ctx);
41dbbb37
TS
11453 if (maybe_lookup_oacc_reduction (var, ctx))
11454 {
11455 gcc_checking_assert (offloaded
11456 && is_gimple_omp_oacc (stmt));
11457 gimplify_assign (x, var, &ilist);
11458 }
11459 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
11460 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
11461 && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
11462 && TREE_CODE (TREE_TYPE (ovar)) == ARRAY_TYPE)
acf0174b 11463 {
41dbbb37 11464 gcc_assert (offloaded);
acf0174b 11465 tree avar
b731b390 11466 = create_tmp_var (TREE_TYPE (TREE_TYPE (x)));
acf0174b
JJ
11467 mark_addressable (avar);
11468 gimplify_assign (avar, build_fold_addr_expr (var), &ilist);
0fe81a0f 11469 talign = DECL_ALIGN_UNIT (avar);
acf0174b
JJ
11470 avar = build_fold_addr_expr (avar);
11471 gimplify_assign (x, avar, &ilist);
11472 }
11473 else if (is_gimple_reg (var))
11474 {
41dbbb37 11475 gcc_assert (offloaded);
b731b390 11476 tree avar = create_tmp_var (TREE_TYPE (var));
acf0174b 11477 mark_addressable (avar);
41dbbb37
TS
11478 enum gomp_map_kind map_kind = OMP_CLAUSE_MAP_KIND (c);
11479 if (GOMP_MAP_COPY_TO_P (map_kind)
11480 || map_kind == GOMP_MAP_POINTER
11481 || map_kind == GOMP_MAP_TO_PSET
11482 || map_kind == GOMP_MAP_FORCE_DEVICEPTR)
acf0174b
JJ
11483 gimplify_assign (avar, var, &ilist);
11484 avar = build_fold_addr_expr (avar);
11485 gimplify_assign (x, avar, &ilist);
41dbbb37
TS
11486 if ((GOMP_MAP_COPY_FROM_P (map_kind)
11487 || map_kind == GOMP_MAP_FORCE_DEVICEPTR)
acf0174b
JJ
11488 && !TYPE_READONLY (TREE_TYPE (var)))
11489 {
11490 x = build_sender_ref (ovar, ctx);
11491 x = build_simple_mem_ref (x);
11492 gimplify_assign (var, x, &olist);
11493 }
11494 }
11495 else
11496 {
11497 var = build_fold_addr_expr (var);
11498 gimplify_assign (x, var, &ilist);
11499 }
11500 }
11501 tree s = OMP_CLAUSE_SIZE (c);
11502 if (s == NULL_TREE)
11503 s = TYPE_SIZE_UNIT (TREE_TYPE (ovar));
11504 s = fold_convert (size_type_node, s);
11505 tree purpose = size_int (map_idx++);
11506 CONSTRUCTOR_APPEND_ELT (vsize, purpose, s);
11507 if (TREE_CODE (s) != INTEGER_CST)
11508 TREE_STATIC (TREE_VEC_ELT (t, 1)) = 0;
11509
41dbbb37 11510 unsigned HOST_WIDE_INT tkind;
acf0174b
JJ
11511 switch (OMP_CLAUSE_CODE (c))
11512 {
11513 case OMP_CLAUSE_MAP:
11514 tkind = OMP_CLAUSE_MAP_KIND (c);
11515 break;
11516 case OMP_CLAUSE_TO:
41dbbb37 11517 tkind = GOMP_MAP_TO;
acf0174b
JJ
11518 break;
11519 case OMP_CLAUSE_FROM:
41dbbb37 11520 tkind = GOMP_MAP_FROM;
acf0174b
JJ
11521 break;
11522 default:
11523 gcc_unreachable ();
11524 }
41dbbb37
TS
11525 gcc_checking_assert (tkind
11526 < (HOST_WIDE_INT_C (1U) << talign_shift));
acf0174b 11527 talign = ceil_log2 (talign);
41dbbb37
TS
11528 tkind |= talign << talign_shift;
11529 gcc_checking_assert (tkind
11530 <= tree_to_uhwi (TYPE_MAX_VALUE (tkind_type)));
acf0174b 11531 CONSTRUCTOR_APPEND_ELT (vkind, purpose,
41dbbb37 11532 build_int_cstu (tkind_type, tkind));
acf0174b
JJ
11533 if (nc && nc != c)
11534 c = nc;
11535 }
11536
11537 gcc_assert (map_idx == map_cnt);
11538
11539 DECL_INITIAL (TREE_VEC_ELT (t, 1))
11540 = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 1)), vsize);
11541 DECL_INITIAL (TREE_VEC_ELT (t, 2))
11542 = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 2)), vkind);
11543 if (!TREE_STATIC (TREE_VEC_ELT (t, 1)))
11544 {
11545 gimple_seq initlist = NULL;
11546 force_gimple_operand (build1 (DECL_EXPR, void_type_node,
11547 TREE_VEC_ELT (t, 1)),
11548 &initlist, true, NULL_TREE);
11549 gimple_seq_add_seq (&ilist, initlist);
bae729a2
TS
11550
11551 tree clobber = build_constructor (TREE_TYPE (TREE_VEC_ELT (t, 1)),
11552 NULL);
11553 TREE_THIS_VOLATILE (clobber) = 1;
11554 gimple_seq_add_stmt (&olist,
11555 gimple_build_assign (TREE_VEC_ELT (t, 1),
11556 clobber));
acf0174b
JJ
11557 }
11558
11559 tree clobber = build_constructor (ctx->record_type, NULL);
11560 TREE_THIS_VOLATILE (clobber) = 1;
11561 gimple_seq_add_stmt (&olist, gimple_build_assign (ctx->sender_decl,
11562 clobber));
11563 }
11564
11565 /* Once all the expansions are done, sequence all the different
11566 fragments inside gimple_omp_body. */
11567
11568 new_body = NULL;
11569
41dbbb37
TS
11570 if (offloaded
11571 && ctx->record_type)
acf0174b
JJ
11572 {
11573 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
11574 /* fixup_child_record_type might have changed receiver_decl's type. */
11575 t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
11576 gimple_seq_add_stmt (&new_body,
11577 gimple_build_assign (ctx->receiver_decl, t));
11578 }
11579
41dbbb37 11580 if (offloaded)
acf0174b
JJ
11581 {
11582 gimple_seq_add_seq (&new_body, tgt_body);
11583 new_body = maybe_catch_exception (new_body);
11584 }
41dbbb37 11585 else if (data_region)
acf0174b 11586 new_body = tgt_body;
41dbbb37 11587 if (offloaded || data_region)
acf0174b
JJ
11588 {
11589 gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
11590 gimple_omp_set_body (stmt, new_body);
11591 }
11592
11593 bind = gimple_build_bind (NULL, NULL,
11594 tgt_bind ? gimple_bind_block (tgt_bind)
11595 : NULL_TREE);
726a989a 11596 gsi_replace (gsi_p, bind, true);
41dbbb37 11597 gimple_bind_add_seq (bind, irlist);
355a7673
MM
11598 gimple_bind_add_seq (bind, ilist);
11599 gimple_bind_add_stmt (bind, stmt);
11600 gimple_bind_add_seq (bind, olist);
41dbbb37 11601 gimple_bind_add_seq (bind, orlist);
50674e96 11602
726a989a 11603 pop_gimplify_context (NULL);
50674e96
DN
11604}
11605
acf0174b
JJ
11606/* Expand code for an OpenMP teams directive. */
11607
11608static void
11609lower_omp_teams (gimple_stmt_iterator *gsi_p, omp_context *ctx)
11610{
538dd0b7 11611 gomp_teams *teams_stmt = as_a <gomp_teams *> (gsi_stmt (*gsi_p));
45852dcc 11612 push_gimplify_context ();
acf0174b
JJ
11613
11614 tree block = make_node (BLOCK);
538dd0b7 11615 gbind *bind = gimple_build_bind (NULL, NULL, block);
acf0174b
JJ
11616 gsi_replace (gsi_p, bind, true);
11617 gimple_seq bind_body = NULL;
11618 gimple_seq dlist = NULL;
11619 gimple_seq olist = NULL;
11620
11621 tree num_teams = find_omp_clause (gimple_omp_teams_clauses (teams_stmt),
11622 OMP_CLAUSE_NUM_TEAMS);
11623 if (num_teams == NULL_TREE)
11624 num_teams = build_int_cst (unsigned_type_node, 0);
11625 else
11626 {
11627 num_teams = OMP_CLAUSE_NUM_TEAMS_EXPR (num_teams);
11628 num_teams = fold_convert (unsigned_type_node, num_teams);
11629 gimplify_expr (&num_teams, &bind_body, NULL, is_gimple_val, fb_rvalue);
11630 }
11631 tree thread_limit = find_omp_clause (gimple_omp_teams_clauses (teams_stmt),
11632 OMP_CLAUSE_THREAD_LIMIT);
11633 if (thread_limit == NULL_TREE)
11634 thread_limit = build_int_cst (unsigned_type_node, 0);
11635 else
11636 {
11637 thread_limit = OMP_CLAUSE_THREAD_LIMIT_EXPR (thread_limit);
11638 thread_limit = fold_convert (unsigned_type_node, thread_limit);
11639 gimplify_expr (&thread_limit, &bind_body, NULL, is_gimple_val,
11640 fb_rvalue);
11641 }
11642
11643 lower_rec_input_clauses (gimple_omp_teams_clauses (teams_stmt),
11644 &bind_body, &dlist, ctx, NULL);
11645 lower_omp (gimple_omp_body_ptr (teams_stmt), ctx);
11646 lower_reduction_clauses (gimple_omp_teams_clauses (teams_stmt), &olist, ctx);
11647 gimple_seq_add_stmt (&bind_body, teams_stmt);
11648
11649 location_t loc = gimple_location (teams_stmt);
11650 tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TEAMS);
11651 gimple call = gimple_build_call (decl, 2, num_teams, thread_limit);
11652 gimple_set_location (call, loc);
11653 gimple_seq_add_stmt (&bind_body, call);
11654
11655 gimple_seq_add_seq (&bind_body, gimple_omp_body (teams_stmt));
11656 gimple_omp_set_body (teams_stmt, NULL);
11657 gimple_seq_add_seq (&bind_body, olist);
11658 gimple_seq_add_seq (&bind_body, dlist);
11659 gimple_seq_add_stmt (&bind_body, gimple_build_omp_return (true));
11660 gimple_bind_set_body (bind, bind_body);
11661
11662 pop_gimplify_context (bind);
11663
11664 gimple_bind_append_vars (bind, ctx->block_vars);
11665 BLOCK_VARS (block) = ctx->block_vars;
11666 if (BLOCK_VARS (block))
11667 TREE_USED (block) = 1;
11668}
11669
11670
d0fb20be 11671/* Callback for lower_omp_1. Return non-NULL if *tp needs to be
726a989a 11672 regimplified. If DATA is non-NULL, lower_omp_1 is outside
41dbbb37 11673 of OMP context, but with task_shared_vars set. */
75a4c3c1
AP
11674
11675static tree
726a989a
RB
11676lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
11677 void *data)
75a4c3c1 11678{
d0fb20be 11679 tree t = *tp;
75a4c3c1 11680
d0fb20be 11681 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
726a989a 11682 if (TREE_CODE (t) == VAR_DECL && data == NULL && DECL_HAS_VALUE_EXPR_P (t))
b826efd9
JJ
11683 return t;
11684
11685 if (task_shared_vars
11686 && DECL_P (t)
11687 && bitmap_bit_p (task_shared_vars, DECL_UID (t)))
d0fb20be 11688 return t;
75a4c3c1 11689
d0fb20be
JJ
11690 /* If a global variable has been privatized, TREE_CONSTANT on
11691 ADDR_EXPR might be wrong. */
726a989a 11692 if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
d0fb20be 11693 recompute_tree_invariant_for_addr_expr (t);
75a4c3c1 11694
d0fb20be
JJ
11695 *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
11696 return NULL_TREE;
75a4c3c1 11697}
50674e96 11698
d0fb20be 11699static void
726a989a 11700lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
953ff289 11701{
726a989a
RB
11702 gimple stmt = gsi_stmt (*gsi_p);
11703 struct walk_stmt_info wi;
538dd0b7 11704 gcall *call_stmt;
953ff289 11705
726a989a
RB
11706 if (gimple_has_location (stmt))
11707 input_location = gimple_location (stmt);
d0fb20be 11708
726a989a
RB
11709 if (task_shared_vars)
11710 memset (&wi, '\0', sizeof (wi));
d0fb20be 11711
50674e96 11712 /* If we have issued syntax errors, avoid doing any heavy lifting.
41dbbb37 11713 Just replace the OMP directives with a NOP to avoid
50674e96 11714 confusing RTL expansion. */
1da2ed5f 11715 if (seen_error () && is_gimple_omp (stmt))
50674e96 11716 {
726a989a 11717 gsi_replace (gsi_p, gimple_build_nop (), true);
d0fb20be 11718 return;
50674e96
DN
11719 }
11720
726a989a 11721 switch (gimple_code (stmt))
953ff289 11722 {
726a989a 11723 case GIMPLE_COND:
538dd0b7
DM
11724 {
11725 gcond *cond_stmt = as_a <gcond *> (stmt);
11726 if ((ctx || task_shared_vars)
11727 && (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
11728 lower_omp_regimplify_p,
11729 ctx ? NULL : &wi, NULL)
11730 || walk_tree (gimple_cond_rhs_ptr (cond_stmt),
11731 lower_omp_regimplify_p,
11732 ctx ? NULL : &wi, NULL)))
11733 gimple_regimplify_operands (cond_stmt, gsi_p);
11734 }
d0fb20be 11735 break;
726a989a 11736 case GIMPLE_CATCH:
538dd0b7 11737 lower_omp (gimple_catch_handler_ptr (as_a <gcatch *> (stmt)), ctx);
d0fb20be 11738 break;
726a989a 11739 case GIMPLE_EH_FILTER:
355a7673 11740 lower_omp (gimple_eh_filter_failure_ptr (stmt), ctx);
d0fb20be 11741 break;
726a989a 11742 case GIMPLE_TRY:
355a7673
MM
11743 lower_omp (gimple_try_eval_ptr (stmt), ctx);
11744 lower_omp (gimple_try_cleanup_ptr (stmt), ctx);
d0fb20be 11745 break;
d88513ea 11746 case GIMPLE_TRANSACTION:
538dd0b7
DM
11747 lower_omp (gimple_transaction_body_ptr (
11748 as_a <gtransaction *> (stmt)),
11749 ctx);
d88513ea 11750 break;
726a989a 11751 case GIMPLE_BIND:
538dd0b7 11752 lower_omp (gimple_bind_body_ptr (as_a <gbind *> (stmt)), ctx);
d0fb20be 11753 break;
726a989a
RB
11754 case GIMPLE_OMP_PARALLEL:
11755 case GIMPLE_OMP_TASK:
11756 ctx = maybe_lookup_ctx (stmt);
acf0174b
JJ
11757 gcc_assert (ctx);
11758 if (ctx->cancellable)
11759 ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
726a989a 11760 lower_omp_taskreg (gsi_p, ctx);
d0fb20be 11761 break;
726a989a
RB
11762 case GIMPLE_OMP_FOR:
11763 ctx = maybe_lookup_ctx (stmt);
953ff289 11764 gcc_assert (ctx);
acf0174b
JJ
11765 if (ctx->cancellable)
11766 ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
726a989a 11767 lower_omp_for (gsi_p, ctx);
953ff289 11768 break;
726a989a
RB
11769 case GIMPLE_OMP_SECTIONS:
11770 ctx = maybe_lookup_ctx (stmt);
953ff289 11771 gcc_assert (ctx);
acf0174b
JJ
11772 if (ctx->cancellable)
11773 ctx->cancel_label = create_artificial_label (UNKNOWN_LOCATION);
726a989a 11774 lower_omp_sections (gsi_p, ctx);
953ff289 11775 break;
726a989a
RB
11776 case GIMPLE_OMP_SINGLE:
11777 ctx = maybe_lookup_ctx (stmt);
953ff289 11778 gcc_assert (ctx);
726a989a 11779 lower_omp_single (gsi_p, ctx);
953ff289 11780 break;
726a989a
RB
11781 case GIMPLE_OMP_MASTER:
11782 ctx = maybe_lookup_ctx (stmt);
953ff289 11783 gcc_assert (ctx);
726a989a 11784 lower_omp_master (gsi_p, ctx);
953ff289 11785 break;
acf0174b
JJ
11786 case GIMPLE_OMP_TASKGROUP:
11787 ctx = maybe_lookup_ctx (stmt);
11788 gcc_assert (ctx);
11789 lower_omp_taskgroup (gsi_p, ctx);
11790 break;
726a989a
RB
11791 case GIMPLE_OMP_ORDERED:
11792 ctx = maybe_lookup_ctx (stmt);
953ff289 11793 gcc_assert (ctx);
726a989a 11794 lower_omp_ordered (gsi_p, ctx);
953ff289 11795 break;
726a989a
RB
11796 case GIMPLE_OMP_CRITICAL:
11797 ctx = maybe_lookup_ctx (stmt);
953ff289 11798 gcc_assert (ctx);
726a989a
RB
11799 lower_omp_critical (gsi_p, ctx);
11800 break;
11801 case GIMPLE_OMP_ATOMIC_LOAD:
11802 if ((ctx || task_shared_vars)
538dd0b7
DM
11803 && walk_tree (gimple_omp_atomic_load_rhs_ptr (
11804 as_a <gomp_atomic_load *> (stmt)),
726a989a
RB
11805 lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
11806 gimple_regimplify_operands (stmt, gsi_p);
953ff289 11807 break;
acf0174b
JJ
11808 case GIMPLE_OMP_TARGET:
11809 ctx = maybe_lookup_ctx (stmt);
11810 gcc_assert (ctx);
11811 lower_omp_target (gsi_p, ctx);
11812 break;
11813 case GIMPLE_OMP_TEAMS:
11814 ctx = maybe_lookup_ctx (stmt);
11815 gcc_assert (ctx);
11816 lower_omp_teams (gsi_p, ctx);
11817 break;
11818 case GIMPLE_CALL:
11819 tree fndecl;
538dd0b7
DM
11820 call_stmt = as_a <gcall *> (stmt);
11821 fndecl = gimple_call_fndecl (call_stmt);
acf0174b
JJ
11822 if (fndecl
11823 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
11824 switch (DECL_FUNCTION_CODE (fndecl))
11825 {
11826 case BUILT_IN_GOMP_BARRIER:
11827 if (ctx == NULL)
11828 break;
11829 /* FALLTHRU */
11830 case BUILT_IN_GOMP_CANCEL:
11831 case BUILT_IN_GOMP_CANCELLATION_POINT:
11832 omp_context *cctx;
11833 cctx = ctx;
11834 if (gimple_code (cctx->stmt) == GIMPLE_OMP_SECTION)
11835 cctx = cctx->outer;
538dd0b7 11836 gcc_assert (gimple_call_lhs (call_stmt) == NULL_TREE);
acf0174b
JJ
11837 if (!cctx->cancellable)
11838 {
11839 if (DECL_FUNCTION_CODE (fndecl)
11840 == BUILT_IN_GOMP_CANCELLATION_POINT)
11841 {
11842 stmt = gimple_build_nop ();
11843 gsi_replace (gsi_p, stmt, false);
11844 }
11845 break;
11846 }
acf0174b
JJ
11847 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER)
11848 {
11849 fndecl = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER_CANCEL);
538dd0b7
DM
11850 gimple_call_set_fndecl (call_stmt, fndecl);
11851 gimple_call_set_fntype (call_stmt, TREE_TYPE (fndecl));
acf0174b 11852 }
dd2fc525 11853 tree lhs;
b731b390 11854 lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (fndecl)));
538dd0b7 11855 gimple_call_set_lhs (call_stmt, lhs);
acf0174b
JJ
11856 tree fallthru_label;
11857 fallthru_label = create_artificial_label (UNKNOWN_LOCATION);
11858 gimple g;
11859 g = gimple_build_label (fallthru_label);
11860 gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
dd2fc525
JJ
11861 g = gimple_build_cond (NE_EXPR, lhs,
11862 fold_convert (TREE_TYPE (lhs),
11863 boolean_false_node),
acf0174b
JJ
11864 cctx->cancel_label, fallthru_label);
11865 gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
11866 break;
11867 default:
11868 break;
11869 }
11870 /* FALLTHRU */
d0fb20be 11871 default:
a68ab351 11872 if ((ctx || task_shared_vars)
726a989a
RB
11873 && walk_gimple_op (stmt, lower_omp_regimplify_p,
11874 ctx ? NULL : &wi))
47519a14
JJ
11875 {
11876 /* Just remove clobbers, this should happen only if we have
11877 "privatized" local addressable variables in SIMD regions,
11878 the clobber isn't needed in that case and gimplifying address
11879 of the ARRAY_REF into a pointer and creating MEM_REF based
11880 clobber would create worse code than we get with the clobber
11881 dropped. */
11882 if (gimple_clobber_p (stmt))
11883 {
11884 gsi_replace (gsi_p, gimple_build_nop (), true);
11885 break;
11886 }
11887 gimple_regimplify_operands (stmt, gsi_p);
11888 }
953ff289 11889 break;
953ff289 11890 }
953ff289
DN
11891}
11892
11893static void
355a7673 11894lower_omp (gimple_seq *body, omp_context *ctx)
953ff289 11895{
b357f682 11896 location_t saved_location = input_location;
355a7673
MM
11897 gimple_stmt_iterator gsi;
11898 for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
726a989a 11899 lower_omp_1 (&gsi, ctx);
41dbbb37
TS
11900 /* During gimplification, we haven't folded statments inside offloading
11901 regions (gimplify.c:maybe_fold_stmt); do that now. */
acf0174b
JJ
11902 if (target_nesting_level)
11903 for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
11904 fold_stmt (&gsi);
b357f682 11905 input_location = saved_location;
953ff289
DN
11906}
11907\f
11908/* Main entry point. */
11909
c2924966 11910static unsigned int
953ff289
DN
11911execute_lower_omp (void)
11912{
726a989a 11913 gimple_seq body;
5771c391
JJ
11914 int i;
11915 omp_context *ctx;
726a989a 11916
535b544a 11917 /* This pass always runs, to provide PROP_gimple_lomp.
41dbbb37
TS
11918 But often, there is nothing to do. */
11919 if (flag_cilkplus == 0 && flag_openacc == 0 && flag_openmp == 0
11920 && flag_openmp_simd == 0)
535b544a
SB
11921 return 0;
11922
953ff289
DN
11923 all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
11924 delete_omp_context);
11925
726a989a 11926 body = gimple_body (current_function_decl);
26127932 11927 scan_omp (&body, NULL);
a68ab351 11928 gcc_assert (taskreg_nesting_level == 0);
5771c391
JJ
11929 FOR_EACH_VEC_ELT (taskreg_contexts, i, ctx)
11930 finish_taskreg_scan (ctx);
11931 taskreg_contexts.release ();
953ff289
DN
11932
11933 if (all_contexts->root)
a68ab351
JJ
11934 {
11935 if (task_shared_vars)
45852dcc 11936 push_gimplify_context ();
355a7673 11937 lower_omp (&body, NULL);
a68ab351
JJ
11938 if (task_shared_vars)
11939 pop_gimplify_context (NULL);
11940 }
953ff289 11941
50674e96
DN
11942 if (all_contexts)
11943 {
11944 splay_tree_delete (all_contexts);
11945 all_contexts = NULL;
11946 }
a68ab351 11947 BITMAP_FREE (task_shared_vars);
c2924966 11948 return 0;
953ff289
DN
11949}
11950
27a4cd48
DM
11951namespace {
11952
11953const pass_data pass_data_lower_omp =
11954{
11955 GIMPLE_PASS, /* type */
11956 "omplower", /* name */
11957 OPTGROUP_NONE, /* optinfo_flags */
27a4cd48
DM
11958 TV_NONE, /* tv_id */
11959 PROP_gimple_any, /* properties_required */
11960 PROP_gimple_lomp, /* properties_provided */
11961 0, /* properties_destroyed */
11962 0, /* todo_flags_start */
11963 0, /* todo_flags_finish */
953ff289 11964};
27a4cd48
DM
11965
11966class pass_lower_omp : public gimple_opt_pass
11967{
11968public:
c3284718
RS
11969 pass_lower_omp (gcc::context *ctxt)
11970 : gimple_opt_pass (pass_data_lower_omp, ctxt)
27a4cd48
DM
11971 {}
11972
11973 /* opt_pass methods: */
be55bfe6 11974 virtual unsigned int execute (function *) { return execute_lower_omp (); }
27a4cd48
DM
11975
11976}; // class pass_lower_omp
11977
11978} // anon namespace
11979
11980gimple_opt_pass *
11981make_pass_lower_omp (gcc::context *ctxt)
11982{
11983 return new pass_lower_omp (ctxt);
11984}
953ff289 11985\f
41dbbb37 11986/* The following is a utility to diagnose structured block violations.
777f7f9a
RH
11987 It is not part of the "omplower" pass, as that's invoked too late. It
11988 should be invoked by the respective front ends after gimplification. */
953ff289
DN
11989
11990static splay_tree all_labels;
11991
11992/* Check for mismatched contexts and generate an error if needed. Return
11993 true if an error is detected. */
11994
11995static bool
726a989a
RB
11996diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
11997 gimple branch_ctx, gimple label_ctx)
953ff289 11998{
41dbbb37
TS
11999 gcc_checking_assert (!branch_ctx || is_gimple_omp (branch_ctx));
12000 gcc_checking_assert (!label_ctx || is_gimple_omp (label_ctx));
12001
726a989a 12002 if (label_ctx == branch_ctx)
953ff289
DN
12003 return false;
12004
41dbbb37
TS
12005 const char* kind = NULL;
12006
12007 if (flag_cilkplus)
12008 {
12009 if ((branch_ctx
12010 && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
12011 && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
12012 || (label_ctx
12013 && gimple_code (label_ctx) == GIMPLE_OMP_FOR
12014 && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
12015 kind = "Cilk Plus";
12016 }
12017 if (flag_openacc)
12018 {
12019 if ((branch_ctx && is_gimple_omp_oacc (branch_ctx))
12020 || (label_ctx && is_gimple_omp_oacc (label_ctx)))
12021 {
12022 gcc_checking_assert (kind == NULL);
12023 kind = "OpenACC";
12024 }
12025 }
12026 if (kind == NULL)
12027 {
12028 gcc_checking_assert (flag_openmp);
12029 kind = "OpenMP";
12030 }
b8698a0f 12031
726a989a
RB
12032 /*
12033 Previously we kept track of the label's entire context in diagnose_sb_[12]
12034 so we could traverse it and issue a correct "exit" or "enter" error
12035 message upon a structured block violation.
12036
12037 We built the context by building a list with tree_cons'ing, but there is
12038 no easy counterpart in gimple tuples. It seems like far too much work
12039 for issuing exit/enter error messages. If someone really misses the
12040 distinct error message... patches welcome.
12041 */
b8698a0f 12042
726a989a 12043#if 0
953ff289 12044 /* Try to avoid confusing the user by producing and error message
fa10beec 12045 with correct "exit" or "enter" verbiage. We prefer "exit"
953ff289
DN
12046 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
12047 if (branch_ctx == NULL)
12048 exit_p = false;
12049 else
12050 {
12051 while (label_ctx)
12052 {
12053 if (TREE_VALUE (label_ctx) == branch_ctx)
12054 {
12055 exit_p = false;
12056 break;
12057 }
12058 label_ctx = TREE_CHAIN (label_ctx);
12059 }
12060 }
12061
12062 if (exit_p)
41dbbb37 12063 error ("invalid exit from %s structured block", kind);
953ff289 12064 else
41dbbb37 12065 error ("invalid entry to %s structured block", kind);
726a989a 12066#endif
953ff289 12067
726a989a
RB
12068 /* If it's obvious we have an invalid entry, be specific about the error. */
12069 if (branch_ctx == NULL)
41dbbb37 12070 error ("invalid entry to %s structured block", kind);
726a989a 12071 else
c02065fc
AH
12072 {
12073 /* Otherwise, be vague and lazy, but efficient. */
41dbbb37 12074 error ("invalid branch to/from %s structured block", kind);
c02065fc 12075 }
726a989a
RB
12076
12077 gsi_replace (gsi_p, gimple_build_nop (), false);
953ff289
DN
12078 return true;
12079}
12080
41dbbb37 12081/* Pass 1: Create a minimal tree of structured blocks, and record
726a989a 12082 where each label is found. */
953ff289
DN
12083
12084static tree
726a989a
RB
12085diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
12086 struct walk_stmt_info *wi)
953ff289 12087{
726a989a
RB
12088 gimple context = (gimple) wi->info;
12089 gimple inner_context;
12090 gimple stmt = gsi_stmt (*gsi_p);
953ff289 12091
726a989a
RB
12092 *handled_ops_p = true;
12093
41dbbb37 12094 switch (gimple_code (stmt))
953ff289 12095 {
726a989a 12096 WALK_SUBSTMTS;
b8698a0f 12097
726a989a
RB
12098 case GIMPLE_OMP_PARALLEL:
12099 case GIMPLE_OMP_TASK:
12100 case GIMPLE_OMP_SECTIONS:
12101 case GIMPLE_OMP_SINGLE:
12102 case GIMPLE_OMP_SECTION:
12103 case GIMPLE_OMP_MASTER:
12104 case GIMPLE_OMP_ORDERED:
12105 case GIMPLE_OMP_CRITICAL:
acf0174b
JJ
12106 case GIMPLE_OMP_TARGET:
12107 case GIMPLE_OMP_TEAMS:
12108 case GIMPLE_OMP_TASKGROUP:
726a989a
RB
12109 /* The minimal context here is just the current OMP construct. */
12110 inner_context = stmt;
953ff289 12111 wi->info = inner_context;
726a989a 12112 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
953ff289
DN
12113 wi->info = context;
12114 break;
12115
726a989a
RB
12116 case GIMPLE_OMP_FOR:
12117 inner_context = stmt;
953ff289 12118 wi->info = inner_context;
726a989a
RB
12119 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
12120 walk them. */
12121 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
12122 diagnose_sb_1, NULL, wi);
12123 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
953ff289
DN
12124 wi->info = context;
12125 break;
12126
726a989a 12127 case GIMPLE_LABEL:
538dd0b7
DM
12128 splay_tree_insert (all_labels,
12129 (splay_tree_key) gimple_label_label (
12130 as_a <glabel *> (stmt)),
953ff289
DN
12131 (splay_tree_value) context);
12132 break;
12133
12134 default:
12135 break;
12136 }
12137
12138 return NULL_TREE;
12139}
12140
12141/* Pass 2: Check each branch and see if its context differs from that of
12142 the destination label's context. */
12143
12144static tree
726a989a
RB
12145diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
12146 struct walk_stmt_info *wi)
953ff289 12147{
726a989a 12148 gimple context = (gimple) wi->info;
953ff289 12149 splay_tree_node n;
726a989a 12150 gimple stmt = gsi_stmt (*gsi_p);
953ff289 12151
726a989a
RB
12152 *handled_ops_p = true;
12153
12154 switch (gimple_code (stmt))
953ff289 12155 {
726a989a
RB
12156 WALK_SUBSTMTS;
12157
12158 case GIMPLE_OMP_PARALLEL:
12159 case GIMPLE_OMP_TASK:
12160 case GIMPLE_OMP_SECTIONS:
12161 case GIMPLE_OMP_SINGLE:
12162 case GIMPLE_OMP_SECTION:
12163 case GIMPLE_OMP_MASTER:
12164 case GIMPLE_OMP_ORDERED:
12165 case GIMPLE_OMP_CRITICAL:
acf0174b
JJ
12166 case GIMPLE_OMP_TARGET:
12167 case GIMPLE_OMP_TEAMS:
12168 case GIMPLE_OMP_TASKGROUP:
726a989a 12169 wi->info = stmt;
355a7673 12170 walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
953ff289
DN
12171 wi->info = context;
12172 break;
12173
726a989a
RB
12174 case GIMPLE_OMP_FOR:
12175 wi->info = stmt;
12176 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
12177 walk them. */
355a7673
MM
12178 walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt),
12179 diagnose_sb_2, NULL, wi);
12180 walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
953ff289
DN
12181 wi->info = context;
12182 break;
12183
ca50f84a
L
12184 case GIMPLE_COND:
12185 {
538dd0b7
DM
12186 gcond *cond_stmt = as_a <gcond *> (stmt);
12187 tree lab = gimple_cond_true_label (cond_stmt);
ca50f84a
L
12188 if (lab)
12189 {
12190 n = splay_tree_lookup (all_labels,
12191 (splay_tree_key) lab);
12192 diagnose_sb_0 (gsi_p, context,
12193 n ? (gimple) n->value : NULL);
12194 }
538dd0b7 12195 lab = gimple_cond_false_label (cond_stmt);
ca50f84a
L
12196 if (lab)
12197 {
12198 n = splay_tree_lookup (all_labels,
12199 (splay_tree_key) lab);
12200 diagnose_sb_0 (gsi_p, context,
12201 n ? (gimple) n->value : NULL);
12202 }
12203 }
12204 break;
12205
726a989a 12206 case GIMPLE_GOTO:
953ff289 12207 {
726a989a 12208 tree lab = gimple_goto_dest (stmt);
953ff289
DN
12209 if (TREE_CODE (lab) != LABEL_DECL)
12210 break;
12211
12212 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
726a989a 12213 diagnose_sb_0 (gsi_p, context, n ? (gimple) n->value : NULL);
953ff289
DN
12214 }
12215 break;
12216
726a989a 12217 case GIMPLE_SWITCH:
953ff289 12218 {
538dd0b7 12219 gswitch *switch_stmt = as_a <gswitch *> (stmt);
726a989a 12220 unsigned int i;
538dd0b7 12221 for (i = 0; i < gimple_switch_num_labels (switch_stmt); ++i)
953ff289 12222 {
538dd0b7 12223 tree lab = CASE_LABEL (gimple_switch_label (switch_stmt, i));
953ff289 12224 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
726a989a 12225 if (n && diagnose_sb_0 (gsi_p, context, (gimple) n->value))
953ff289
DN
12226 break;
12227 }
12228 }
12229 break;
12230
726a989a
RB
12231 case GIMPLE_RETURN:
12232 diagnose_sb_0 (gsi_p, context, NULL);
953ff289
DN
12233 break;
12234
12235 default:
12236 break;
12237 }
12238
12239 return NULL_TREE;
12240}
12241
41dbbb37
TS
12242/* Called from tree-cfg.c::make_edges to create cfg edges for all relevant
12243 GIMPLE_* codes. */
0645c1a2 12244bool
09b22f48
JJ
12245make_gimple_omp_edges (basic_block bb, struct omp_region **region,
12246 int *region_idx)
0645c1a2
AM
12247{
12248 gimple last = last_stmt (bb);
12249 enum gimple_code code = gimple_code (last);
12250 struct omp_region *cur_region = *region;
12251 bool fallthru = false;
12252
12253 switch (code)
12254 {
12255 case GIMPLE_OMP_PARALLEL:
12256 case GIMPLE_OMP_TASK:
12257 case GIMPLE_OMP_FOR:
12258 case GIMPLE_OMP_SINGLE:
12259 case GIMPLE_OMP_TEAMS:
12260 case GIMPLE_OMP_MASTER:
12261 case GIMPLE_OMP_TASKGROUP:
12262 case GIMPLE_OMP_ORDERED:
12263 case GIMPLE_OMP_CRITICAL:
12264 case GIMPLE_OMP_SECTION:
12265 cur_region = new_omp_region (bb, code, cur_region);
12266 fallthru = true;
12267 break;
12268
12269 case GIMPLE_OMP_TARGET:
12270 cur_region = new_omp_region (bb, code, cur_region);
12271 fallthru = true;
41dbbb37
TS
12272 switch (gimple_omp_target_kind (last))
12273 {
12274 case GF_OMP_TARGET_KIND_REGION:
12275 case GF_OMP_TARGET_KIND_DATA:
12276 case GF_OMP_TARGET_KIND_OACC_PARALLEL:
12277 case GF_OMP_TARGET_KIND_OACC_KERNELS:
12278 case GF_OMP_TARGET_KIND_OACC_DATA:
12279 break;
12280 case GF_OMP_TARGET_KIND_UPDATE:
12281 case GF_OMP_TARGET_KIND_OACC_UPDATE:
12282 case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
12283 cur_region = cur_region->outer;
12284 break;
12285 default:
12286 gcc_unreachable ();
12287 }
0645c1a2
AM
12288 break;
12289
12290 case GIMPLE_OMP_SECTIONS:
12291 cur_region = new_omp_region (bb, code, cur_region);
12292 fallthru = true;
12293 break;
12294
12295 case GIMPLE_OMP_SECTIONS_SWITCH:
12296 fallthru = false;
12297 break;
12298
12299 case GIMPLE_OMP_ATOMIC_LOAD:
12300 case GIMPLE_OMP_ATOMIC_STORE:
12301 fallthru = true;
12302 break;
12303
12304 case GIMPLE_OMP_RETURN:
12305 /* In the case of a GIMPLE_OMP_SECTION, the edge will go
12306 somewhere other than the next block. This will be
12307 created later. */
12308 cur_region->exit = bb;
b37dddbc
JJ
12309 if (cur_region->type == GIMPLE_OMP_TASK)
12310 /* Add an edge corresponding to not scheduling the task
12311 immediately. */
12312 make_edge (cur_region->entry, bb, EDGE_ABNORMAL);
0645c1a2
AM
12313 fallthru = cur_region->type != GIMPLE_OMP_SECTION;
12314 cur_region = cur_region->outer;
12315 break;
12316
12317 case GIMPLE_OMP_CONTINUE:
12318 cur_region->cont = bb;
12319 switch (cur_region->type)
12320 {
12321 case GIMPLE_OMP_FOR:
12322 /* Mark all GIMPLE_OMP_FOR and GIMPLE_OMP_CONTINUE
12323 succs edges as abnormal to prevent splitting
12324 them. */
12325 single_succ_edge (cur_region->entry)->flags |= EDGE_ABNORMAL;
12326 /* Make the loopback edge. */
12327 make_edge (bb, single_succ (cur_region->entry),
12328 EDGE_ABNORMAL);
12329
12330 /* Create an edge from GIMPLE_OMP_FOR to exit, which
12331 corresponds to the case that the body of the loop
12332 is not executed at all. */
12333 make_edge (cur_region->entry, bb->next_bb, EDGE_ABNORMAL);
12334 make_edge (bb, bb->next_bb, EDGE_FALLTHRU | EDGE_ABNORMAL);
12335 fallthru = false;
12336 break;
12337
12338 case GIMPLE_OMP_SECTIONS:
12339 /* Wire up the edges into and out of the nested sections. */
12340 {
12341 basic_block switch_bb = single_succ (cur_region->entry);
12342
12343 struct omp_region *i;
12344 for (i = cur_region->inner; i ; i = i->next)
12345 {
12346 gcc_assert (i->type == GIMPLE_OMP_SECTION);
12347 make_edge (switch_bb, i->entry, 0);
12348 make_edge (i->exit, bb, EDGE_FALLTHRU);
12349 }
12350
12351 /* Make the loopback edge to the block with
12352 GIMPLE_OMP_SECTIONS_SWITCH. */
12353 make_edge (bb, switch_bb, 0);
12354
12355 /* Make the edge from the switch to exit. */
12356 make_edge (switch_bb, bb->next_bb, 0);
12357 fallthru = false;
12358 }
12359 break;
12360
b37dddbc
JJ
12361 case GIMPLE_OMP_TASK:
12362 fallthru = true;
12363 break;
12364
0645c1a2
AM
12365 default:
12366 gcc_unreachable ();
12367 }
12368 break;
12369
12370 default:
12371 gcc_unreachable ();
12372 }
12373
12374 if (*region != cur_region)
09b22f48
JJ
12375 {
12376 *region = cur_region;
12377 if (cur_region)
12378 *region_idx = cur_region->entry->index;
12379 else
12380 *region_idx = 0;
12381 }
0645c1a2
AM
12382
12383 return fallthru;
12384}
12385
a406865a
RG
12386static unsigned int
12387diagnose_omp_structured_block_errors (void)
953ff289 12388{
953ff289 12389 struct walk_stmt_info wi;
a406865a 12390 gimple_seq body = gimple_body (current_function_decl);
953ff289
DN
12391
12392 all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
12393
12394 memset (&wi, 0, sizeof (wi));
726a989a 12395 walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);
953ff289
DN
12396
12397 memset (&wi, 0, sizeof (wi));
953ff289 12398 wi.want_locations = true;
355a7673
MM
12399 walk_gimple_seq_mod (&body, diagnose_sb_2, NULL, &wi);
12400
12401 gimple_set_body (current_function_decl, body);
953ff289
DN
12402
12403 splay_tree_delete (all_labels);
12404 all_labels = NULL;
12405
a406865a 12406 return 0;
953ff289
DN
12407}
12408
27a4cd48
DM
12409namespace {
12410
12411const pass_data pass_data_diagnose_omp_blocks =
12412{
12413 GIMPLE_PASS, /* type */
12414 "*diagnose_omp_blocks", /* name */
12415 OPTGROUP_NONE, /* optinfo_flags */
27a4cd48
DM
12416 TV_NONE, /* tv_id */
12417 PROP_gimple_any, /* properties_required */
12418 0, /* properties_provided */
12419 0, /* properties_destroyed */
12420 0, /* todo_flags_start */
12421 0, /* todo_flags_finish */
a406865a
RG
12422};
12423
27a4cd48
DM
12424class pass_diagnose_omp_blocks : public gimple_opt_pass
12425{
12426public:
c3284718
RS
12427 pass_diagnose_omp_blocks (gcc::context *ctxt)
12428 : gimple_opt_pass (pass_data_diagnose_omp_blocks, ctxt)
27a4cd48
DM
12429 {}
12430
12431 /* opt_pass methods: */
41dbbb37
TS
12432 virtual bool gate (function *)
12433 {
12434 return flag_cilkplus || flag_openacc || flag_openmp;
12435 }
be55bfe6
TS
12436 virtual unsigned int execute (function *)
12437 {
12438 return diagnose_omp_structured_block_errors ();
12439 }
27a4cd48
DM
12440
12441}; // class pass_diagnose_omp_blocks
12442
12443} // anon namespace
12444
12445gimple_opt_pass *
12446make_pass_diagnose_omp_blocks (gcc::context *ctxt)
12447{
12448 return new pass_diagnose_omp_blocks (ctxt);
12449}
0136f8f0
AH
12450\f
12451/* SIMD clone supporting code. */
12452
12453/* Allocate a fresh `simd_clone' and return it. NARGS is the number
12454 of arguments to reserve space for. */
12455
12456static struct cgraph_simd_clone *
12457simd_clone_struct_alloc (int nargs)
12458{
12459 struct cgraph_simd_clone *clone_info;
12460 size_t len = (sizeof (struct cgraph_simd_clone)
12461 + nargs * sizeof (struct cgraph_simd_clone_arg));
12462 clone_info = (struct cgraph_simd_clone *)
b3bb0eb9 12463 ggc_internal_cleared_alloc (len);
0136f8f0
AH
12464 return clone_info;
12465}
12466
12467/* Make a copy of the `struct cgraph_simd_clone' in FROM to TO. */
12468
12469static inline void
12470simd_clone_struct_copy (struct cgraph_simd_clone *to,
12471 struct cgraph_simd_clone *from)
12472{
12473 memcpy (to, from, (sizeof (struct cgraph_simd_clone)
92d05580
JJ
12474 + ((from->nargs - from->inbranch)
12475 * sizeof (struct cgraph_simd_clone_arg))));
0136f8f0
AH
12476}
12477
12478/* Return vector of parameter types of function FNDECL. This uses
12479 TYPE_ARG_TYPES if available, otherwise falls back to types of
12480 DECL_ARGUMENTS types. */
12481
12482vec<tree>
12483simd_clone_vector_of_formal_parm_types (tree fndecl)
12484{
12485 if (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
12486 return ipa_get_vector_of_formal_parm_types (TREE_TYPE (fndecl));
12487 vec<tree> args = ipa_get_vector_of_formal_parms (fndecl);
12488 unsigned int i;
12489 tree arg;
12490 FOR_EACH_VEC_ELT (args, i, arg)
12491 args[i] = TREE_TYPE (args[i]);
12492 return args;
12493}
12494
12495/* Given a simd function in NODE, extract the simd specific
12496 information from the OMP clauses passed in CLAUSES, and return
12497 the struct cgraph_simd_clone * if it should be cloned. *INBRANCH_SPECIFIED
12498 is set to TRUE if the `inbranch' or `notinbranch' clause specified,
12499 otherwise set to FALSE. */
12500
12501static struct cgraph_simd_clone *
12502simd_clone_clauses_extract (struct cgraph_node *node, tree clauses,
12503 bool *inbranch_specified)
12504{
12505 vec<tree> args = simd_clone_vector_of_formal_parm_types (node->decl);
12506 tree t;
12507 int n;
12508 *inbranch_specified = false;
12509
12510 n = args.length ();
12511 if (n > 0 && args.last () == void_type_node)
12512 n--;
12513
12514 /* To distinguish from an OpenMP simd clone, Cilk Plus functions to
12515 be cloned have a distinctive artificial label in addition to "omp
12516 declare simd". */
12517 bool cilk_clone
b72271b9 12518 = (flag_cilkplus
41958c28 12519 && lookup_attribute ("cilk simd function",
0136f8f0
AH
12520 DECL_ATTRIBUTES (node->decl)));
12521
12522 /* Allocate one more than needed just in case this is an in-branch
12523 clone which will require a mask argument. */
12524 struct cgraph_simd_clone *clone_info = simd_clone_struct_alloc (n + 1);
12525 clone_info->nargs = n;
12526 clone_info->cilk_elemental = cilk_clone;
12527
12528 if (!clauses)
12529 {
12530 args.release ();
12531 return clone_info;
12532 }
12533 clauses = TREE_VALUE (clauses);
12534 if (!clauses || TREE_CODE (clauses) != OMP_CLAUSE)
12535 return clone_info;
12536
12537 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
12538 {
12539 switch (OMP_CLAUSE_CODE (t))
12540 {
12541 case OMP_CLAUSE_INBRANCH:
12542 clone_info->inbranch = 1;
12543 *inbranch_specified = true;
12544 break;
12545 case OMP_CLAUSE_NOTINBRANCH:
12546 clone_info->inbranch = 0;
12547 *inbranch_specified = true;
12548 break;
12549 case OMP_CLAUSE_SIMDLEN:
12550 clone_info->simdlen
12551 = TREE_INT_CST_LOW (OMP_CLAUSE_SIMDLEN_EXPR (t));
12552 break;
12553 case OMP_CLAUSE_LINEAR:
12554 {
12555 tree decl = OMP_CLAUSE_DECL (t);
12556 tree step = OMP_CLAUSE_LINEAR_STEP (t);
12557 int argno = TREE_INT_CST_LOW (decl);
12558 if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (t))
12559 {
12560 clone_info->args[argno].arg_type
12561 = SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP;
12562 clone_info->args[argno].linear_step = tree_to_shwi (step);
12563 gcc_assert (clone_info->args[argno].linear_step >= 0
12564 && clone_info->args[argno].linear_step < n);
12565 }
12566 else
12567 {
12568 if (POINTER_TYPE_P (args[argno]))
12569 step = fold_convert (ssizetype, step);
12570 if (!tree_fits_shwi_p (step))
12571 {
12572 warning_at (OMP_CLAUSE_LOCATION (t), 0,
12573 "ignoring large linear step");
12574 args.release ();
12575 return NULL;
12576 }
12577 else if (integer_zerop (step))
12578 {
12579 warning_at (OMP_CLAUSE_LOCATION (t), 0,
12580 "ignoring zero linear step");
12581 args.release ();
12582 return NULL;
12583 }
12584 else
12585 {
12586 clone_info->args[argno].arg_type
12587 = SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP;
12588 clone_info->args[argno].linear_step = tree_to_shwi (step);
12589 }
12590 }
12591 break;
12592 }
12593 case OMP_CLAUSE_UNIFORM:
12594 {
12595 tree decl = OMP_CLAUSE_DECL (t);
12596 int argno = tree_to_uhwi (decl);
12597 clone_info->args[argno].arg_type
12598 = SIMD_CLONE_ARG_TYPE_UNIFORM;
12599 break;
12600 }
12601 case OMP_CLAUSE_ALIGNED:
12602 {
12603 tree decl = OMP_CLAUSE_DECL (t);
12604 int argno = tree_to_uhwi (decl);
12605 clone_info->args[argno].alignment
12606 = TREE_INT_CST_LOW (OMP_CLAUSE_ALIGNED_ALIGNMENT (t));
12607 break;
12608 }
12609 default:
12610 break;
12611 }
12612 }
12613 args.release ();
12614 return clone_info;
12615}
12616
12617/* Given a SIMD clone in NODE, calculate the characteristic data
12618 type and return the coresponding type. The characteristic data
12619 type is computed as described in the Intel Vector ABI. */
12620
12621static tree
12622simd_clone_compute_base_data_type (struct cgraph_node *node,
12623 struct cgraph_simd_clone *clone_info)
12624{
12625 tree type = integer_type_node;
12626 tree fndecl = node->decl;
12627
12628 /* a) For non-void function, the characteristic data type is the
12629 return type. */
12630 if (TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE)
12631 type = TREE_TYPE (TREE_TYPE (fndecl));
12632
12633 /* b) If the function has any non-uniform, non-linear parameters,
12634 then the characteristic data type is the type of the first
12635 such parameter. */
12636 else
12637 {
12638 vec<tree> map = simd_clone_vector_of_formal_parm_types (fndecl);
12639 for (unsigned int i = 0; i < clone_info->nargs; ++i)
12640 if (clone_info->args[i].arg_type == SIMD_CLONE_ARG_TYPE_VECTOR)
12641 {
12642 type = map[i];
12643 break;
12644 }
12645 map.release ();
12646 }
12647
12648 /* c) If the characteristic data type determined by a) or b) above
12649 is struct, union, or class type which is pass-by-value (except
12650 for the type that maps to the built-in complex data type), the
12651 characteristic data type is int. */
12652 if (RECORD_OR_UNION_TYPE_P (type)
12653 && !aggregate_value_p (type, NULL)
12654 && TREE_CODE (type) != COMPLEX_TYPE)
12655 return integer_type_node;
12656
12657 /* d) If none of the above three classes is applicable, the
12658 characteristic data type is int. */
12659
12660 return type;
12661
12662 /* e) For Intel Xeon Phi native and offload compilation, if the
12663 resulting characteristic data type is 8-bit or 16-bit integer
12664 data type, the characteristic data type is int. */
12665 /* Well, we don't handle Xeon Phi yet. */
12666}
12667
12668static tree
12669simd_clone_mangle (struct cgraph_node *node,
12670 struct cgraph_simd_clone *clone_info)
12671{
12672 char vecsize_mangle = clone_info->vecsize_mangle;
12673 char mask = clone_info->inbranch ? 'M' : 'N';
12674 unsigned int simdlen = clone_info->simdlen;
12675 unsigned int n;
12676 pretty_printer pp;
12677
12678 gcc_assert (vecsize_mangle && simdlen);
12679
12680 pp_string (&pp, "_ZGV");
12681 pp_character (&pp, vecsize_mangle);
12682 pp_character (&pp, mask);
12683 pp_decimal_int (&pp, simdlen);
12684
12685 for (n = 0; n < clone_info->nargs; ++n)
12686 {
12687 struct cgraph_simd_clone_arg arg = clone_info->args[n];
12688
12689 if (arg.arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM)
12690 pp_character (&pp, 'u');
12691 else if (arg.arg_type == SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP)
12692 {
12693 gcc_assert (arg.linear_step != 0);
12694 pp_character (&pp, 'l');
12695 if (arg.linear_step > 1)
12696 pp_unsigned_wide_integer (&pp, arg.linear_step);
12697 else if (arg.linear_step < 0)
12698 {
12699 pp_character (&pp, 'n');
12700 pp_unsigned_wide_integer (&pp, (-(unsigned HOST_WIDE_INT)
12701 arg.linear_step));
12702 }
12703 }
12704 else if (arg.arg_type == SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP)
12705 {
12706 pp_character (&pp, 's');
12707 pp_unsigned_wide_integer (&pp, arg.linear_step);
12708 }
12709 else
12710 pp_character (&pp, 'v');
12711 if (arg.alignment)
12712 {
12713 pp_character (&pp, 'a');
12714 pp_decimal_int (&pp, arg.alignment);
12715 }
12716 }
12717
12718 pp_underscore (&pp);
4cd76837
JJ
12719 const char *str = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl));
12720 if (*str == '*')
12721 ++str;
12722 pp_string (&pp, str);
12723 str = pp_formatted_text (&pp);
0136f8f0
AH
12724
12725 /* If there already is a SIMD clone with the same mangled name, don't
12726 add another one. This can happen e.g. for
12727 #pragma omp declare simd
12728 #pragma omp declare simd simdlen(8)
12729 int foo (int, int);
12730 if the simdlen is assumed to be 8 for the first one, etc. */
12731 for (struct cgraph_node *clone = node->simd_clones; clone;
12732 clone = clone->simdclone->next_clone)
12733 if (strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (clone->decl)),
12734 str) == 0)
12735 return NULL_TREE;
12736
12737 return get_identifier (str);
12738}
12739
12740/* Create a simd clone of OLD_NODE and return it. */
12741
12742static struct cgraph_node *
12743simd_clone_create (struct cgraph_node *old_node)
12744{
12745 struct cgraph_node *new_node;
12746 if (old_node->definition)
e06f9964 12747 {
d52f5295 12748 if (!old_node->has_gimple_body_p ())
e06f9964 12749 return NULL;
d52f5295
ML
12750 old_node->get_body ();
12751 new_node = old_node->create_version_clone_with_body (vNULL, NULL, NULL,
12752 false, NULL, NULL,
12753 "simdclone");
e06f9964 12754 }
0136f8f0
AH
12755 else
12756 {
12757 tree old_decl = old_node->decl;
12758 tree new_decl = copy_node (old_node->decl);
12759 DECL_NAME (new_decl) = clone_function_name (old_decl, "simdclone");
12760 SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
12761 SET_DECL_RTL (new_decl, NULL);
12762 DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
12763 DECL_STATIC_DESTRUCTOR (new_decl) = 0;
d52f5295 12764 new_node = old_node->create_version_clone (new_decl, vNULL, NULL);
3dafb85c 12765 symtab->call_cgraph_insertion_hooks (new_node);
0136f8f0
AH
12766 }
12767 if (new_node == NULL)
12768 return new_node;
12769
12770 TREE_PUBLIC (new_node->decl) = TREE_PUBLIC (old_node->decl);
12771
12772 /* The function cgraph_function_versioning () will force the new
12773 symbol local. Undo this, and inherit external visability from
12774 the old node. */
12775 new_node->local.local = old_node->local.local;
12776 new_node->externally_visible = old_node->externally_visible;
12777
12778 return new_node;
12779}
12780
12781/* Adjust the return type of the given function to its appropriate
12782 vector counterpart. Returns a simd array to be used throughout the
12783 function as a return value. */
12784
12785static tree
12786simd_clone_adjust_return_type (struct cgraph_node *node)
12787{
12788 tree fndecl = node->decl;
12789 tree orig_rettype = TREE_TYPE (TREE_TYPE (fndecl));
12790 unsigned int veclen;
12791 tree t;
12792
12793 /* Adjust the function return type. */
12794 if (orig_rettype == void_type_node)
12795 return NULL_TREE;
12796 TREE_TYPE (fndecl) = build_distinct_type_copy (TREE_TYPE (fndecl));
1c4967b9
JJ
12797 t = TREE_TYPE (TREE_TYPE (fndecl));
12798 if (INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
0136f8f0
AH
12799 veclen = node->simdclone->vecsize_int;
12800 else
12801 veclen = node->simdclone->vecsize_float;
1c4967b9 12802 veclen /= GET_MODE_BITSIZE (TYPE_MODE (t));
0136f8f0
AH
12803 if (veclen > node->simdclone->simdlen)
12804 veclen = node->simdclone->simdlen;
1c4967b9
JJ
12805 if (POINTER_TYPE_P (t))
12806 t = pointer_sized_int_node;
0136f8f0 12807 if (veclen == node->simdclone->simdlen)
1c4967b9 12808 t = build_vector_type (t, node->simdclone->simdlen);
0136f8f0
AH
12809 else
12810 {
1c4967b9 12811 t = build_vector_type (t, veclen);
0136f8f0 12812 t = build_array_type_nelts (t, node->simdclone->simdlen / veclen);
0136f8f0 12813 }
1c4967b9 12814 TREE_TYPE (TREE_TYPE (fndecl)) = t;
0136f8f0
AH
12815 if (!node->definition)
12816 return NULL_TREE;
12817
12818 t = DECL_RESULT (fndecl);
12819 /* Adjust the DECL_RESULT. */
12820 gcc_assert (TREE_TYPE (t) != void_type_node);
12821 TREE_TYPE (t) = TREE_TYPE (TREE_TYPE (fndecl));
12822 relayout_decl (t);
12823
12824 tree atype = build_array_type_nelts (orig_rettype,
12825 node->simdclone->simdlen);
12826 if (veclen != node->simdclone->simdlen)
12827 return build1 (VIEW_CONVERT_EXPR, atype, t);
12828
12829 /* Set up a SIMD array to use as the return value. */
12830 tree retval = create_tmp_var_raw (atype, "retval");
12831 gimple_add_tmp_var (retval);
12832 return retval;
12833}
12834
12835/* Each vector argument has a corresponding array to be used locally
12836 as part of the eventual loop. Create such temporary array and
12837 return it.
12838
12839 PREFIX is the prefix to be used for the temporary.
12840
12841 TYPE is the inner element type.
12842
12843 SIMDLEN is the number of elements. */
12844
12845static tree
12846create_tmp_simd_array (const char *prefix, tree type, int simdlen)
12847{
12848 tree atype = build_array_type_nelts (type, simdlen);
12849 tree avar = create_tmp_var_raw (atype, prefix);
12850 gimple_add_tmp_var (avar);
12851 return avar;
12852}
12853
12854/* Modify the function argument types to their corresponding vector
12855 counterparts if appropriate. Also, create one array for each simd
12856 argument to be used locally when using the function arguments as
12857 part of the loop.
12858
12859 NODE is the function whose arguments are to be adjusted.
12860
12861 Returns an adjustment vector that will be filled describing how the
12862 argument types will be adjusted. */
12863
12864static ipa_parm_adjustment_vec
12865simd_clone_adjust_argument_types (struct cgraph_node *node)
12866{
12867 vec<tree> args;
12868 ipa_parm_adjustment_vec adjustments;
12869
12870 if (node->definition)
12871 args = ipa_get_vector_of_formal_parms (node->decl);
12872 else
12873 args = simd_clone_vector_of_formal_parm_types (node->decl);
12874 adjustments.create (args.length ());
12875 unsigned i, j, veclen;
12876 struct ipa_parm_adjustment adj;
12877 for (i = 0; i < node->simdclone->nargs; ++i)
12878 {
12879 memset (&adj, 0, sizeof (adj));
12880 tree parm = args[i];
12881 tree parm_type = node->definition ? TREE_TYPE (parm) : parm;
12882 adj.base_index = i;
12883 adj.base = parm;
12884
12885 node->simdclone->args[i].orig_arg = node->definition ? parm : NULL_TREE;
12886 node->simdclone->args[i].orig_type = parm_type;
12887
12888 if (node->simdclone->args[i].arg_type != SIMD_CLONE_ARG_TYPE_VECTOR)
12889 {
12890 /* No adjustment necessary for scalar arguments. */
12891 adj.op = IPA_PARM_OP_COPY;
12892 }
12893 else
12894 {
12895 if (INTEGRAL_TYPE_P (parm_type) || POINTER_TYPE_P (parm_type))
12896 veclen = node->simdclone->vecsize_int;
12897 else
12898 veclen = node->simdclone->vecsize_float;
12899 veclen /= GET_MODE_BITSIZE (TYPE_MODE (parm_type));
12900 if (veclen > node->simdclone->simdlen)
12901 veclen = node->simdclone->simdlen;
12902 adj.arg_prefix = "simd";
1c4967b9
JJ
12903 if (POINTER_TYPE_P (parm_type))
12904 adj.type = build_vector_type (pointer_sized_int_node, veclen);
12905 else
12906 adj.type = build_vector_type (parm_type, veclen);
0136f8f0
AH
12907 node->simdclone->args[i].vector_type = adj.type;
12908 for (j = veclen; j < node->simdclone->simdlen; j += veclen)
12909 {
12910 adjustments.safe_push (adj);
12911 if (j == veclen)
12912 {
12913 memset (&adj, 0, sizeof (adj));
12914 adj.op = IPA_PARM_OP_NEW;
12915 adj.arg_prefix = "simd";
12916 adj.base_index = i;
12917 adj.type = node->simdclone->args[i].vector_type;
12918 }
12919 }
12920
12921 if (node->definition)
12922 node->simdclone->args[i].simd_array
12923 = create_tmp_simd_array (IDENTIFIER_POINTER (DECL_NAME (parm)),
12924 parm_type, node->simdclone->simdlen);
12925 }
12926 adjustments.safe_push (adj);
12927 }
12928
12929 if (node->simdclone->inbranch)
12930 {
12931 tree base_type
12932 = simd_clone_compute_base_data_type (node->simdclone->origin,
12933 node->simdclone);
12934
12935 memset (&adj, 0, sizeof (adj));
12936 adj.op = IPA_PARM_OP_NEW;
12937 adj.arg_prefix = "mask";
12938
12939 adj.base_index = i;
12940 if (INTEGRAL_TYPE_P (base_type) || POINTER_TYPE_P (base_type))
12941 veclen = node->simdclone->vecsize_int;
12942 else
12943 veclen = node->simdclone->vecsize_float;
12944 veclen /= GET_MODE_BITSIZE (TYPE_MODE (base_type));
12945 if (veclen > node->simdclone->simdlen)
12946 veclen = node->simdclone->simdlen;
1c4967b9
JJ
12947 if (POINTER_TYPE_P (base_type))
12948 adj.type = build_vector_type (pointer_sized_int_node, veclen);
12949 else
12950 adj.type = build_vector_type (base_type, veclen);
0136f8f0
AH
12951 adjustments.safe_push (adj);
12952
12953 for (j = veclen; j < node->simdclone->simdlen; j += veclen)
12954 adjustments.safe_push (adj);
12955
12956 /* We have previously allocated one extra entry for the mask. Use
12957 it and fill it. */
12958 struct cgraph_simd_clone *sc = node->simdclone;
12959 sc->nargs++;
12960 if (node->definition)
12961 {
12962 sc->args[i].orig_arg
12963 = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL, base_type);
12964 sc->args[i].simd_array
12965 = create_tmp_simd_array ("mask", base_type, sc->simdlen);
12966 }
12967 sc->args[i].orig_type = base_type;
12968 sc->args[i].arg_type = SIMD_CLONE_ARG_TYPE_MASK;
12969 }
12970
12971 if (node->definition)
12972 ipa_modify_formal_parameters (node->decl, adjustments);
12973 else
12974 {
12975 tree new_arg_types = NULL_TREE, new_reversed;
12976 bool last_parm_void = false;
12977 if (args.length () > 0 && args.last () == void_type_node)
12978 last_parm_void = true;
12979
12980 gcc_assert (TYPE_ARG_TYPES (TREE_TYPE (node->decl)));
12981 j = adjustments.length ();
12982 for (i = 0; i < j; i++)
12983 {
12984 struct ipa_parm_adjustment *adj = &adjustments[i];
12985 tree ptype;
12986 if (adj->op == IPA_PARM_OP_COPY)
12987 ptype = args[adj->base_index];
12988 else
12989 ptype = adj->type;
12990 new_arg_types = tree_cons (NULL_TREE, ptype, new_arg_types);
12991 }
12992 new_reversed = nreverse (new_arg_types);
12993 if (last_parm_void)
12994 {
12995 if (new_reversed)
12996 TREE_CHAIN (new_arg_types) = void_list_node;
12997 else
12998 new_reversed = void_list_node;
12999 }
13000
13001 tree new_type = build_distinct_type_copy (TREE_TYPE (node->decl));
13002 TYPE_ARG_TYPES (new_type) = new_reversed;
13003 TREE_TYPE (node->decl) = new_type;
13004
13005 adjustments.release ();
13006 }
13007 args.release ();
13008 return adjustments;
13009}
13010
13011/* Initialize and copy the function arguments in NODE to their
13012 corresponding local simd arrays. Returns a fresh gimple_seq with
13013 the instruction sequence generated. */
13014
13015static gimple_seq
13016simd_clone_init_simd_arrays (struct cgraph_node *node,
13017 ipa_parm_adjustment_vec adjustments)
13018{
13019 gimple_seq seq = NULL;
13020 unsigned i = 0, j = 0, k;
13021
13022 for (tree arg = DECL_ARGUMENTS (node->decl);
13023 arg;
13024 arg = DECL_CHAIN (arg), i++, j++)
13025 {
13026 if (adjustments[j].op == IPA_PARM_OP_COPY)
13027 continue;
13028
13029 node->simdclone->args[i].vector_arg = arg;
13030
13031 tree array = node->simdclone->args[i].simd_array;
13032 if (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg)) == node->simdclone->simdlen)
13033 {
13034 tree ptype = build_pointer_type (TREE_TYPE (TREE_TYPE (array)));
13035 tree ptr = build_fold_addr_expr (array);
13036 tree t = build2 (MEM_REF, TREE_TYPE (arg), ptr,
13037 build_int_cst (ptype, 0));
13038 t = build2 (MODIFY_EXPR, TREE_TYPE (t), t, arg);
13039 gimplify_and_add (t, &seq);
13040 }
13041 else
13042 {
13043 unsigned int simdlen = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg));
13044 tree ptype = build_pointer_type (TREE_TYPE (TREE_TYPE (array)));
13045 for (k = 0; k < node->simdclone->simdlen; k += simdlen)
13046 {
13047 tree ptr = build_fold_addr_expr (array);
13048 int elemsize;
13049 if (k)
13050 {
13051 arg = DECL_CHAIN (arg);
13052 j++;
13053 }
13054 elemsize
13055 = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))));
13056 tree t = build2 (MEM_REF, TREE_TYPE (arg), ptr,
13057 build_int_cst (ptype, k * elemsize));
13058 t = build2 (MODIFY_EXPR, TREE_TYPE (t), t, arg);
13059 gimplify_and_add (t, &seq);
13060 }
13061 }
13062 }
13063 return seq;
13064}
13065
13066/* Callback info for ipa_simd_modify_stmt_ops below. */
13067
13068struct modify_stmt_info {
13069 ipa_parm_adjustment_vec adjustments;
13070 gimple stmt;
13071 /* True if the parent statement was modified by
13072 ipa_simd_modify_stmt_ops. */
13073 bool modified;
13074};
13075
13076/* Callback for walk_gimple_op.
13077
13078 Adjust operands from a given statement as specified in the
13079 adjustments vector in the callback data. */
13080
13081static tree
13082ipa_simd_modify_stmt_ops (tree *tp, int *walk_subtrees, void *data)
13083{
13084 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
2044a4c3
JJ
13085 struct modify_stmt_info *info = (struct modify_stmt_info *) wi->info;
13086 tree *orig_tp = tp;
13087 if (TREE_CODE (*tp) == ADDR_EXPR)
13088 tp = &TREE_OPERAND (*tp, 0);
13089 struct ipa_parm_adjustment *cand = NULL;
13090 if (TREE_CODE (*tp) == PARM_DECL)
13091 cand = ipa_get_adjustment_candidate (&tp, NULL, info->adjustments, true);
13092 else
0136f8f0 13093 {
0136f8f0
AH
13094 if (TYPE_P (*tp))
13095 *walk_subtrees = 0;
0136f8f0 13096 }
0136f8f0 13097
2044a4c3
JJ
13098 tree repl = NULL_TREE;
13099 if (cand)
13100 repl = unshare_expr (cand->new_decl);
13101 else
0136f8f0 13102 {
2044a4c3
JJ
13103 if (tp != orig_tp)
13104 {
13105 *walk_subtrees = 0;
13106 bool modified = info->modified;
13107 info->modified = false;
13108 walk_tree (tp, ipa_simd_modify_stmt_ops, wi, wi->pset);
13109 if (!info->modified)
13110 {
13111 info->modified = modified;
13112 return NULL_TREE;
13113 }
13114 info->modified = modified;
13115 repl = *tp;
13116 }
13117 else
13118 return NULL_TREE;
0136f8f0 13119 }
2044a4c3
JJ
13120
13121 if (tp != orig_tp)
0136f8f0 13122 {
2044a4c3 13123 repl = build_fold_addr_expr (repl);
932b6d61
JJ
13124 gimple stmt;
13125 if (is_gimple_debug (info->stmt))
13126 {
13127 tree vexpr = make_node (DEBUG_EXPR_DECL);
13128 stmt = gimple_build_debug_source_bind (vexpr, repl, NULL);
13129 DECL_ARTIFICIAL (vexpr) = 1;
13130 TREE_TYPE (vexpr) = TREE_TYPE (repl);
13131 DECL_MODE (vexpr) = TYPE_MODE (TREE_TYPE (repl));
13132 repl = vexpr;
13133 }
13134 else
13135 {
b731b390 13136 stmt = gimple_build_assign (make_ssa_name (TREE_TYPE (repl)), repl);
932b6d61
JJ
13137 repl = gimple_assign_lhs (stmt);
13138 }
2044a4c3 13139 gimple_stmt_iterator gsi = gsi_for_stmt (info->stmt);
0136f8f0 13140 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
2044a4c3 13141 *orig_tp = repl;
0136f8f0 13142 }
2044a4c3 13143 else if (!useless_type_conversion_p (TREE_TYPE (*tp), TREE_TYPE (repl)))
0136f8f0
AH
13144 {
13145 tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*tp), repl);
13146 *tp = vce;
13147 }
13148 else
13149 *tp = repl;
13150
13151 info->modified = true;
0136f8f0
AH
13152 return NULL_TREE;
13153}
13154
13155/* Traverse the function body and perform all modifications as
13156 described in ADJUSTMENTS. At function return, ADJUSTMENTS will be
13157 modified such that the replacement/reduction value will now be an
13158 offset into the corresponding simd_array.
13159
13160 This function will replace all function argument uses with their
13161 corresponding simd array elements, and ajust the return values
13162 accordingly. */
13163
13164static void
13165ipa_simd_modify_function_body (struct cgraph_node *node,
13166 ipa_parm_adjustment_vec adjustments,
13167 tree retval_array, tree iter)
13168{
13169 basic_block bb;
2044a4c3 13170 unsigned int i, j, l;
0136f8f0
AH
13171
13172 /* Re-use the adjustments array, but this time use it to replace
13173 every function argument use to an offset into the corresponding
13174 simd_array. */
13175 for (i = 0, j = 0; i < node->simdclone->nargs; ++i, ++j)
13176 {
13177 if (!node->simdclone->args[i].vector_arg)
13178 continue;
13179
13180 tree basetype = TREE_TYPE (node->simdclone->args[i].orig_arg);
13181 tree vectype = TREE_TYPE (node->simdclone->args[i].vector_arg);
13182 adjustments[j].new_decl
13183 = build4 (ARRAY_REF,
13184 basetype,
13185 node->simdclone->args[i].simd_array,
13186 iter,
13187 NULL_TREE, NULL_TREE);
13188 if (adjustments[j].op == IPA_PARM_OP_NONE
13189 && TYPE_VECTOR_SUBPARTS (vectype) < node->simdclone->simdlen)
13190 j += node->simdclone->simdlen / TYPE_VECTOR_SUBPARTS (vectype) - 1;
13191 }
13192
2044a4c3
JJ
13193 l = adjustments.length ();
13194 for (i = 1; i < num_ssa_names; i++)
13195 {
13196 tree name = ssa_name (i);
13197 if (name
13198 && SSA_NAME_VAR (name)
13199 && TREE_CODE (SSA_NAME_VAR (name)) == PARM_DECL)
13200 {
13201 for (j = 0; j < l; j++)
13202 if (SSA_NAME_VAR (name) == adjustments[j].base
13203 && adjustments[j].new_decl)
13204 {
13205 tree base_var;
13206 if (adjustments[j].new_ssa_base == NULL_TREE)
13207 {
13208 base_var
13209 = copy_var_decl (adjustments[j].base,
13210 DECL_NAME (adjustments[j].base),
13211 TREE_TYPE (adjustments[j].base));
13212 adjustments[j].new_ssa_base = base_var;
13213 }
13214 else
13215 base_var = adjustments[j].new_ssa_base;
13216 if (SSA_NAME_IS_DEFAULT_DEF (name))
13217 {
13218 bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
13219 gimple_stmt_iterator gsi = gsi_after_labels (bb);
13220 tree new_decl = unshare_expr (adjustments[j].new_decl);
13221 set_ssa_default_def (cfun, adjustments[j].base, NULL_TREE);
13222 SET_SSA_NAME_VAR_OR_IDENTIFIER (name, base_var);
13223 SSA_NAME_IS_DEFAULT_DEF (name) = 0;
13224 gimple stmt = gimple_build_assign (name, new_decl);
13225 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
13226 }
13227 else
13228 SET_SSA_NAME_VAR_OR_IDENTIFIER (name, base_var);
13229 }
13230 }
13231 }
13232
0136f8f0
AH
13233 struct modify_stmt_info info;
13234 info.adjustments = adjustments;
13235
13236 FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
13237 {
13238 gimple_stmt_iterator gsi;
13239
13240 gsi = gsi_start_bb (bb);
13241 while (!gsi_end_p (gsi))
13242 {
13243 gimple stmt = gsi_stmt (gsi);
13244 info.stmt = stmt;
13245 struct walk_stmt_info wi;
13246
13247 memset (&wi, 0, sizeof (wi));
13248 info.modified = false;
13249 wi.info = &info;
13250 walk_gimple_op (stmt, ipa_simd_modify_stmt_ops, &wi);
13251
538dd0b7 13252 if (greturn *return_stmt = dyn_cast <greturn *> (stmt))
0136f8f0 13253 {
538dd0b7 13254 tree retval = gimple_return_retval (return_stmt);
0136f8f0
AH
13255 if (!retval)
13256 {
13257 gsi_remove (&gsi, true);
13258 continue;
13259 }
13260
13261 /* Replace `return foo' with `retval_array[iter] = foo'. */
13262 tree ref = build4 (ARRAY_REF, TREE_TYPE (retval),
13263 retval_array, iter, NULL, NULL);
13264 stmt = gimple_build_assign (ref, retval);
13265 gsi_replace (&gsi, stmt, true);
13266 info.modified = true;
13267 }
13268
13269 if (info.modified)
13270 {
13271 update_stmt (stmt);
13272 if (maybe_clean_eh_stmt (stmt))
13273 gimple_purge_dead_eh_edges (gimple_bb (stmt));
13274 }
13275 gsi_next (&gsi);
13276 }
13277 }
13278}
13279
13280/* Adjust the argument types in NODE to their appropriate vector
13281 counterparts. */
13282
13283static void
13284simd_clone_adjust (struct cgraph_node *node)
13285{
13286 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
13287
13288 targetm.simd_clone.adjust (node);
13289
13290 tree retval = simd_clone_adjust_return_type (node);
13291 ipa_parm_adjustment_vec adjustments
13292 = simd_clone_adjust_argument_types (node);
13293
13294 push_gimplify_context ();
13295
13296 gimple_seq seq = simd_clone_init_simd_arrays (node, adjustments);
13297
13298 /* Adjust all uses of vector arguments accordingly. Adjust all
13299 return values accordingly. */
13300 tree iter = create_tmp_var (unsigned_type_node, "iter");
b731b390
JJ
13301 tree iter1 = make_ssa_name (iter);
13302 tree iter2 = make_ssa_name (iter);
0136f8f0
AH
13303 ipa_simd_modify_function_body (node, adjustments, retval, iter1);
13304
13305 /* Initialize the iteration variable. */
13306 basic_block entry_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
13307 basic_block body_bb = split_block_after_labels (entry_bb)->dest;
13308 gimple_stmt_iterator gsi = gsi_after_labels (entry_bb);
13309 /* Insert the SIMD array and iv initialization at function
13310 entry. */
13311 gsi_insert_seq_before (&gsi, seq, GSI_NEW_STMT);
13312
13313 pop_gimplify_context (NULL);
13314
13315 /* Create a new BB right before the original exit BB, to hold the
13316 iteration increment and the condition/branch. */
13317 basic_block orig_exit = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), 0)->src;
13318 basic_block incr_bb = create_empty_bb (orig_exit);
33d9078a 13319 add_bb_to_loop (incr_bb, body_bb->loop_father);
0136f8f0
AH
13320 /* The succ of orig_exit was EXIT_BLOCK_PTR_FOR_FN (cfun), with an empty
13321 flag. Set it now to be a FALLTHRU_EDGE. */
13322 gcc_assert (EDGE_COUNT (orig_exit->succs) == 1);
13323 EDGE_SUCC (orig_exit, 0)->flags |= EDGE_FALLTHRU;
13324 for (unsigned i = 0;
13325 i < EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds); ++i)
13326 {
13327 edge e = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), i);
13328 redirect_edge_succ (e, incr_bb);
13329 }
13330 edge e = make_edge (incr_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
13331 e->probability = REG_BR_PROB_BASE;
13332 gsi = gsi_last_bb (incr_bb);
0d0e4a03
JJ
13333 gimple g = gimple_build_assign (iter2, PLUS_EXPR, iter1,
13334 build_int_cst (unsigned_type_node, 1));
0136f8f0
AH
13335 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
13336
13337 /* Mostly annotate the loop for the vectorizer (the rest is done below). */
13338 struct loop *loop = alloc_loop ();
b15b5979 13339 cfun->has_force_vectorize_loops = true;
0136f8f0 13340 loop->safelen = node->simdclone->simdlen;
b15b5979 13341 loop->force_vectorize = true;
0136f8f0 13342 loop->header = body_bb;
0136f8f0
AH
13343
13344 /* Branch around the body if the mask applies. */
13345 if (node->simdclone->inbranch)
13346 {
13347 gimple_stmt_iterator gsi = gsi_last_bb (loop->header);
13348 tree mask_array
13349 = node->simdclone->args[node->simdclone->nargs - 1].simd_array;
b731b390 13350 tree mask = make_ssa_name (TREE_TYPE (TREE_TYPE (mask_array)));
0136f8f0
AH
13351 tree aref = build4 (ARRAY_REF,
13352 TREE_TYPE (TREE_TYPE (mask_array)),
13353 mask_array, iter1,
13354 NULL, NULL);
13355 g = gimple_build_assign (mask, aref);
13356 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
13357 int bitsize = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (aref)));
13358 if (!INTEGRAL_TYPE_P (TREE_TYPE (aref)))
13359 {
13360 aref = build1 (VIEW_CONVERT_EXPR,
13361 build_nonstandard_integer_type (bitsize, 0), mask);
b731b390 13362 mask = make_ssa_name (TREE_TYPE (aref));
0136f8f0
AH
13363 g = gimple_build_assign (mask, aref);
13364 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
13365 }
13366
13367 g = gimple_build_cond (EQ_EXPR, mask, build_zero_cst (TREE_TYPE (mask)),
13368 NULL, NULL);
13369 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
13370 make_edge (loop->header, incr_bb, EDGE_TRUE_VALUE);
13371 FALLTHRU_EDGE (loop->header)->flags = EDGE_FALSE_VALUE;
13372 }
13373
13374 /* Generate the condition. */
13375 g = gimple_build_cond (LT_EXPR,
13376 iter2,
13377 build_int_cst (unsigned_type_node,
13378 node->simdclone->simdlen),
13379 NULL, NULL);
13380 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
13381 e = split_block (incr_bb, gsi_stmt (gsi));
13382 basic_block latch_bb = e->dest;
33d9078a 13383 basic_block new_exit_bb;
c4d281b2 13384 new_exit_bb = split_block_after_labels (latch_bb)->dest;
0136f8f0
AH
13385 loop->latch = latch_bb;
13386
13387 redirect_edge_succ (FALLTHRU_EDGE (latch_bb), body_bb);
13388
13389 make_edge (incr_bb, new_exit_bb, EDGE_FALSE_VALUE);
13390 /* The successor of incr_bb is already pointing to latch_bb; just
13391 change the flags.
13392 make_edge (incr_bb, latch_bb, EDGE_TRUE_VALUE); */
13393 FALLTHRU_EDGE (incr_bb)->flags = EDGE_TRUE_VALUE;
13394
538dd0b7 13395 gphi *phi = create_phi_node (iter1, body_bb);
0136f8f0
AH
13396 edge preheader_edge = find_edge (entry_bb, body_bb);
13397 edge latch_edge = single_succ_edge (latch_bb);
13398 add_phi_arg (phi, build_zero_cst (unsigned_type_node), preheader_edge,
13399 UNKNOWN_LOCATION);
13400 add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
13401
13402 /* Generate the new return. */
13403 gsi = gsi_last_bb (new_exit_bb);
13404 if (retval
13405 && TREE_CODE (retval) == VIEW_CONVERT_EXPR
13406 && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
13407 retval = TREE_OPERAND (retval, 0);
13408 else if (retval)
13409 {
13410 retval = build1 (VIEW_CONVERT_EXPR,
13411 TREE_TYPE (TREE_TYPE (node->decl)),
13412 retval);
13413 retval = force_gimple_operand_gsi (&gsi, retval, true, NULL,
13414 false, GSI_CONTINUE_LINKING);
13415 }
13416 g = gimple_build_return (retval);
13417 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
13418
13419 /* Handle aligned clauses by replacing default defs of the aligned
13420 uniform args with __builtin_assume_aligned (arg_N(D), alignment)
13421 lhs. Handle linear by adding PHIs. */
13422 for (unsigned i = 0; i < node->simdclone->nargs; i++)
13423 if (node->simdclone->args[i].alignment
13424 && node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM
13425 && (node->simdclone->args[i].alignment
13426 & (node->simdclone->args[i].alignment - 1)) == 0
13427 && TREE_CODE (TREE_TYPE (node->simdclone->args[i].orig_arg))
13428 == POINTER_TYPE)
13429 {
13430 unsigned int alignment = node->simdclone->args[i].alignment;
13431 tree orig_arg = node->simdclone->args[i].orig_arg;
13432 tree def = ssa_default_def (cfun, orig_arg);
ab04b46e 13433 if (def && !has_zero_uses (def))
0136f8f0
AH
13434 {
13435 tree fn = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
13436 gimple_seq seq = NULL;
13437 bool need_cvt = false;
538dd0b7 13438 gcall *call
0136f8f0
AH
13439 = gimple_build_call (fn, 2, def, size_int (alignment));
13440 g = call;
13441 if (!useless_type_conversion_p (TREE_TYPE (orig_arg),
13442 ptr_type_node))
13443 need_cvt = true;
b731b390 13444 tree t = make_ssa_name (need_cvt ? ptr_type_node : orig_arg);
0136f8f0
AH
13445 gimple_call_set_lhs (g, t);
13446 gimple_seq_add_stmt_without_update (&seq, g);
13447 if (need_cvt)
13448 {
b731b390 13449 t = make_ssa_name (orig_arg);
0d0e4a03 13450 g = gimple_build_assign (t, NOP_EXPR, gimple_call_lhs (g));
0136f8f0
AH
13451 gimple_seq_add_stmt_without_update (&seq, g);
13452 }
13453 gsi_insert_seq_on_edge_immediate
13454 (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);
13455
13456 entry_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
13457 int freq = compute_call_stmt_bb_frequency (current_function_decl,
13458 entry_bb);
d52f5295
ML
13459 node->create_edge (cgraph_node::get_create (fn),
13460 call, entry_bb->count, freq);
0136f8f0
AH
13461
13462 imm_use_iterator iter;
13463 use_operand_p use_p;
13464 gimple use_stmt;
13465 tree repl = gimple_get_lhs (g);
13466 FOR_EACH_IMM_USE_STMT (use_stmt, iter, def)
13467 if (is_gimple_debug (use_stmt) || use_stmt == call)
13468 continue;
13469 else
13470 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
13471 SET_USE (use_p, repl);
13472 }
13473 }
13474 else if (node->simdclone->args[i].arg_type
13475 == SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP)
13476 {
13477 tree orig_arg = node->simdclone->args[i].orig_arg;
13478 tree def = ssa_default_def (cfun, orig_arg);
13479 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
13480 || POINTER_TYPE_P (TREE_TYPE (orig_arg)));
ab04b46e 13481 if (def && !has_zero_uses (def))
0136f8f0 13482 {
b731b390
JJ
13483 iter1 = make_ssa_name (orig_arg);
13484 iter2 = make_ssa_name (orig_arg);
0136f8f0
AH
13485 phi = create_phi_node (iter1, body_bb);
13486 add_phi_arg (phi, def, preheader_edge, UNKNOWN_LOCATION);
13487 add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
13488 enum tree_code code = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
13489 ? PLUS_EXPR : POINTER_PLUS_EXPR;
13490 tree addtype = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
13491 ? TREE_TYPE (orig_arg) : sizetype;
13492 tree addcst
13493 = build_int_cst (addtype, node->simdclone->args[i].linear_step);
0d0e4a03 13494 g = gimple_build_assign (iter2, code, iter1, addcst);
0136f8f0
AH
13495 gsi = gsi_last_bb (incr_bb);
13496 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
13497
13498 imm_use_iterator iter;
13499 use_operand_p use_p;
13500 gimple use_stmt;
13501 FOR_EACH_IMM_USE_STMT (use_stmt, iter, def)
13502 if (use_stmt == phi)
13503 continue;
13504 else
13505 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
13506 SET_USE (use_p, iter1);
13507 }
13508 }
13509
13510 calculate_dominance_info (CDI_DOMINATORS);
13511 add_loop (loop, loop->header->loop_father);
13512 update_ssa (TODO_update_ssa);
13513
13514 pop_cfun ();
13515}
13516
13517/* If the function in NODE is tagged as an elemental SIMD function,
13518 create the appropriate SIMD clones. */
13519
13520static void
13521expand_simd_clones (struct cgraph_node *node)
13522{
0136f8f0
AH
13523 tree attr = lookup_attribute ("omp declare simd",
13524 DECL_ATTRIBUTES (node->decl));
e06f9964
JJ
13525 if (attr == NULL_TREE
13526 || node->global.inlined_to
13527 || lookup_attribute ("noclone", DECL_ATTRIBUTES (node->decl)))
0136f8f0 13528 return;
e06f9964 13529
0136f8f0
AH
13530 /* Ignore
13531 #pragma omp declare simd
13532 extern int foo ();
13533 in C, there we don't know the argument types at all. */
13534 if (!node->definition
13535 && TYPE_ARG_TYPES (TREE_TYPE (node->decl)) == NULL_TREE)
13536 return;
13537
13538 do
13539 {
13540 /* Start with parsing the "omp declare simd" attribute(s). */
13541 bool inbranch_clause_specified;
13542 struct cgraph_simd_clone *clone_info
13543 = simd_clone_clauses_extract (node, TREE_VALUE (attr),
13544 &inbranch_clause_specified);
13545 if (clone_info == NULL)
13546 continue;
13547
13548 int orig_simdlen = clone_info->simdlen;
13549 tree base_type = simd_clone_compute_base_data_type (node, clone_info);
13550 /* The target can return 0 (no simd clones should be created),
13551 1 (just one ISA of simd clones should be created) or higher
13552 count of ISA variants. In that case, clone_info is initialized
13553 for the first ISA variant. */
13554 int count
13555 = targetm.simd_clone.compute_vecsize_and_simdlen (node, clone_info,
13556 base_type, 0);
13557 if (count == 0)
13558 continue;
13559
13560 /* Loop over all COUNT ISA variants, and if !INBRANCH_CLAUSE_SPECIFIED,
13561 also create one inbranch and one !inbranch clone of it. */
13562 for (int i = 0; i < count * 2; i++)
13563 {
13564 struct cgraph_simd_clone *clone = clone_info;
13565 if (inbranch_clause_specified && (i & 1) != 0)
13566 continue;
13567
13568 if (i != 0)
13569 {
13570 clone = simd_clone_struct_alloc (clone_info->nargs
0136f8f0
AH
13571 + ((i & 1) != 0));
13572 simd_clone_struct_copy (clone, clone_info);
13573 /* Undo changes targetm.simd_clone.compute_vecsize_and_simdlen
13574 and simd_clone_adjust_argument_types did to the first
13575 clone's info. */
13576 clone->nargs -= clone_info->inbranch;
13577 clone->simdlen = orig_simdlen;
13578 /* And call the target hook again to get the right ISA. */
13579 targetm.simd_clone.compute_vecsize_and_simdlen (node, clone,
13580 base_type,
13581 i / 2);
13582 if ((i & 1) != 0)
13583 clone->inbranch = 1;
13584 }
13585
13586 /* simd_clone_mangle might fail if such a clone has been created
13587 already. */
13588 tree id = simd_clone_mangle (node, clone);
13589 if (id == NULL_TREE)
13590 continue;
13591
13592 /* Only when we are sure we want to create the clone actually
13593 clone the function (or definitions) or create another
13594 extern FUNCTION_DECL (for prototypes without definitions). */
13595 struct cgraph_node *n = simd_clone_create (node);
13596 if (n == NULL)
13597 continue;
13598
13599 n->simdclone = clone;
13600 clone->origin = node;
13601 clone->next_clone = NULL;
13602 if (node->simd_clones == NULL)
13603 {
13604 clone->prev_clone = n;
13605 node->simd_clones = n;
13606 }
13607 else
13608 {
13609 clone->prev_clone = node->simd_clones->simdclone->prev_clone;
13610 clone->prev_clone->simdclone->next_clone = n;
13611 node->simd_clones->simdclone->prev_clone = n;
13612 }
3dafb85c 13613 symtab->change_decl_assembler_name (n->decl, id);
0136f8f0
AH
13614 /* And finally adjust the return type, parameters and for
13615 definitions also function body. */
13616 if (node->definition)
13617 simd_clone_adjust (n);
13618 else
13619 {
13620 simd_clone_adjust_return_type (n);
13621 simd_clone_adjust_argument_types (n);
13622 }
13623 }
13624 }
13625 while ((attr = lookup_attribute ("omp declare simd", TREE_CHAIN (attr))));
13626}
13627
13628/* Entry point for IPA simd clone creation pass. */
13629
13630static unsigned int
13631ipa_omp_simd_clone (void)
13632{
13633 struct cgraph_node *node;
13634 FOR_EACH_FUNCTION (node)
13635 expand_simd_clones (node);
13636 return 0;
13637}
13638
13639namespace {
13640
13641const pass_data pass_data_omp_simd_clone =
13642{
13643 SIMPLE_IPA_PASS, /* type */
13644 "simdclone", /* name */
13645 OPTGROUP_NONE, /* optinfo_flags */
0136f8f0
AH
13646 TV_NONE, /* tv_id */
13647 ( PROP_ssa | PROP_cfg ), /* properties_required */
13648 0, /* properties_provided */
13649 0, /* properties_destroyed */
13650 0, /* todo_flags_start */
13651 0, /* todo_flags_finish */
13652};
13653
13654class pass_omp_simd_clone : public simple_ipa_opt_pass
13655{
13656public:
13657 pass_omp_simd_clone(gcc::context *ctxt)
13658 : simple_ipa_opt_pass(pass_data_omp_simd_clone, ctxt)
13659 {}
13660
13661 /* opt_pass methods: */
1a3d085c 13662 virtual bool gate (function *);
be55bfe6 13663 virtual unsigned int execute (function *) { return ipa_omp_simd_clone (); }
0136f8f0
AH
13664};
13665
1a3d085c
TS
13666bool
13667pass_omp_simd_clone::gate (function *)
13668{
13669 return ((flag_openmp || flag_openmp_simd
13670 || flag_cilkplus
13671 || (in_lto_p && !flag_wpa))
13672 && (targetm.simd_clone.compute_vecsize_and_simdlen != NULL));
13673}
13674
0136f8f0
AH
13675} // anon namespace
13676
13677simple_ipa_opt_pass *
13678make_pass_omp_simd_clone (gcc::context *ctxt)
13679{
13680 return new pass_omp_simd_clone (ctxt);
13681}
27a4cd48 13682
ec6fe917
IV
13683/* Helper function for omp_finish_file routine. Takes decls from V_DECLS and
13684 adds their addresses and sizes to constructor-vector V_CTOR. */
13685static void
13686add_decls_addresses_to_decl_constructor (vec<tree, va_gc> *v_decls,
13687 vec<constructor_elt, va_gc> *v_ctor)
13688{
13689 unsigned len = vec_safe_length (v_decls);
13690 for (unsigned i = 0; i < len; i++)
13691 {
13692 tree it = (*v_decls)[i];
13693 bool is_function = TREE_CODE (it) != VAR_DECL;
13694
13695 CONSTRUCTOR_APPEND_ELT (v_ctor, NULL_TREE, build_fold_addr_expr (it));
13696 if (!is_function)
13697 CONSTRUCTOR_APPEND_ELT (v_ctor, NULL_TREE,
13698 fold_convert (const_ptr_type_node,
13699 DECL_SIZE_UNIT (it)));
13700 }
13701}
13702
13703/* Create new symbols containing (address, size) pairs for global variables,
13704 marked with "omp declare target" attribute, as well as addresses for the
41dbbb37 13705 functions, which are outlined offloading regions. */
ec6fe917
IV
13706void
13707omp_finish_file (void)
13708{
13709 unsigned num_funcs = vec_safe_length (offload_funcs);
13710 unsigned num_vars = vec_safe_length (offload_vars);
13711
13712 if (num_funcs == 0 && num_vars == 0)
13713 return;
13714
13715 if (targetm_common.have_named_sections)
13716 {
13717 vec<constructor_elt, va_gc> *v_f, *v_v;
13718 vec_alloc (v_f, num_funcs);
13719 vec_alloc (v_v, num_vars * 2);
13720
13721 add_decls_addresses_to_decl_constructor (offload_funcs, v_f);
13722 add_decls_addresses_to_decl_constructor (offload_vars, v_v);
13723
13724 tree vars_decl_type = build_array_type_nelts (pointer_sized_int_node,
13725 num_vars * 2);
13726 tree funcs_decl_type = build_array_type_nelts (pointer_sized_int_node,
13727 num_funcs);
13728 TYPE_ALIGN (vars_decl_type) = TYPE_ALIGN (pointer_sized_int_node);
13729 TYPE_ALIGN (funcs_decl_type) = TYPE_ALIGN (pointer_sized_int_node);
13730 tree ctor_v = build_constructor (vars_decl_type, v_v);
13731 tree ctor_f = build_constructor (funcs_decl_type, v_f);
13732 TREE_CONSTANT (ctor_v) = TREE_CONSTANT (ctor_f) = 1;
13733 TREE_STATIC (ctor_v) = TREE_STATIC (ctor_f) = 1;
13734 tree funcs_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
13735 get_identifier (".offload_func_table"),
13736 funcs_decl_type);
13737 tree vars_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
13738 get_identifier (".offload_var_table"),
13739 vars_decl_type);
13740 TREE_STATIC (funcs_decl) = TREE_STATIC (vars_decl) = 1;
13741 /* Do not align tables more than TYPE_ALIGN (pointer_sized_int_node),
13742 otherwise a joint table in a binary will contain padding between
13743 tables from multiple object files. */
13744 DECL_USER_ALIGN (funcs_decl) = DECL_USER_ALIGN (vars_decl) = 1;
13745 DECL_ALIGN (funcs_decl) = TYPE_ALIGN (funcs_decl_type);
13746 DECL_ALIGN (vars_decl) = TYPE_ALIGN (vars_decl_type);
13747 DECL_INITIAL (funcs_decl) = ctor_f;
13748 DECL_INITIAL (vars_decl) = ctor_v;
13749 set_decl_section_name (funcs_decl, OFFLOAD_FUNC_TABLE_SECTION_NAME);
13750 set_decl_section_name (vars_decl, OFFLOAD_VAR_TABLE_SECTION_NAME);
13751
13752 varpool_node::finalize_decl (vars_decl);
13753 varpool_node::finalize_decl (funcs_decl);
844b0125 13754 }
ec6fe917
IV
13755 else
13756 {
13757 for (unsigned i = 0; i < num_funcs; i++)
13758 {
13759 tree it = (*offload_funcs)[i];
13760 targetm.record_offload_symbol (it);
13761 }
13762 for (unsigned i = 0; i < num_vars; i++)
13763 {
13764 tree it = (*offload_vars)[i];
13765 targetm.record_offload_symbol (it);
13766 }
13767 }
13768}
13769
953ff289 13770#include "gt-omp-low.h"