1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2021 Free Software Foundation, Inc.
4 Major work done by Sebastian Pop <s.pop@laposte.net>,
5 Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "backend.h"
27 #include "target.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "memmodel.h"
31 #include "tm_p.h"
32 #include "gimple.h"
33 #include "gimple-predict.h"
34 #include "tree-pass.h" /* FIXME: only for PROP_gimple_any */
35 #include "ssa.h"
36 #include "cgraph.h"
37 #include "tree-pretty-print.h"
38 #include "diagnostic-core.h"
39 #include "alias.h"
40 #include "fold-const.h"
41 #include "calls.h"
42 #include "varasm.h"
43 #include "stmt.h"
44 #include "expr.h"
45 #include "gimple-fold.h"
46 #include "tree-eh.h"
47 #include "gimplify.h"
48 #include "gimple-iterator.h"
49 #include "stor-layout.h"
50 #include "print-tree.h"
51 #include "tree-iterator.h"
52 #include "tree-inline.h"
53 #include "langhooks.h"
54 #include "tree-cfg.h"
55 #include "tree-ssa.h"
56 #include "omp-general.h"
57 #include "omp-low.h"
58 #include "gimple-low.h"
59 #include "gomp-constants.h"
60 #include "splay-tree.h"
61 #include "gimple-walk.h"
62 #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
63 #include "builtins.h"
64 #include "stringpool.h"
65 #include "attribs.h"
66 #include "asan.h"
67 #include "dbgcnt.h"
68 #include "omp-offload.h"
69 #include "context.h"
70 #include "tree-nested.h"
71
72 /* Hash set of poisoned variables in a bind expr. */
73 static hash_set<tree> *asan_poisoned_variables = NULL;
74
75 enum gimplify_omp_var_data
76 {
77 GOVD_SEEN = 0x000001,
78 GOVD_EXPLICIT = 0x000002,
79 GOVD_SHARED = 0x000004,
80 GOVD_PRIVATE = 0x000008,
81 GOVD_FIRSTPRIVATE = 0x000010,
82 GOVD_LASTPRIVATE = 0x000020,
83 GOVD_REDUCTION = 0x000040,
84 GOVD_LOCAL = 0x00080,
85 GOVD_MAP = 0x000100,
86 GOVD_DEBUG_PRIVATE = 0x000200,
87 GOVD_PRIVATE_OUTER_REF = 0x000400,
88 GOVD_LINEAR = 0x000800,
89 GOVD_ALIGNED = 0x001000,
90
91 /* Flag for GOVD_MAP: don't copy back. */
92 GOVD_MAP_TO_ONLY = 0x002000,
93
94 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
95 GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 0x004000,
96
97 GOVD_MAP_0LEN_ARRAY = 0x008000,
98
99 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
100 GOVD_MAP_ALWAYS_TO = 0x010000,
101
102 /* Flag for shared vars that are or might be stored to in the region. */
103 GOVD_WRITTEN = 0x020000,
104
105 /* Flag for GOVD_MAP, if it is a forced mapping. */
106 GOVD_MAP_FORCE = 0x040000,
107
108 /* Flag for GOVD_MAP: must be present already. */
109 GOVD_MAP_FORCE_PRESENT = 0x080000,
110
111 /* Flag for GOVD_MAP: only allocate. */
112 GOVD_MAP_ALLOC_ONLY = 0x100000,
113
114 /* Flag for GOVD_MAP: only copy back. */
115 GOVD_MAP_FROM_ONLY = 0x200000,
116
117 GOVD_NONTEMPORAL = 0x400000,
118
119 /* Flag for GOVD_LASTPRIVATE: conditional modifier. */
120 GOVD_LASTPRIVATE_CONDITIONAL = 0x800000,
121
122 GOVD_CONDTEMP = 0x1000000,
123
124 /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause. */
125 GOVD_REDUCTION_INSCAN = 0x2000000,
126
127 /* Flag for GOVD_MAP: (struct) vars that have pointer attachments for
128 fields. */
129 GOVD_MAP_HAS_ATTACHMENTS = 8388608,
130
131 GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
132 | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
133 | GOVD_LOCAL)
134 };
135
136
137 enum omp_region_type
138 {
139 ORT_WORKSHARE = 0x00,
140 ORT_TASKGROUP = 0x01,
141 ORT_SIMD = 0x04,
142
143 ORT_PARALLEL = 0x08,
144 ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1,
145
146 ORT_TASK = 0x10,
147 ORT_UNTIED_TASK = ORT_TASK | 1,
148 ORT_TASKLOOP = ORT_TASK | 2,
149 ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2,
150
151 ORT_TEAMS = 0x20,
152 ORT_COMBINED_TEAMS = ORT_TEAMS | 1,
153 ORT_HOST_TEAMS = ORT_TEAMS | 2,
154 ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2,
155
156 /* Data region. */
157 ORT_TARGET_DATA = 0x40,
158
159 /* Data region with offloading. */
160 ORT_TARGET = 0x80,
161 ORT_COMBINED_TARGET = ORT_TARGET | 1,
162 ORT_IMPLICIT_TARGET = ORT_TARGET | 2,
163
164 /* OpenACC variants. */
165 ORT_ACC = 0x100, /* A generic OpenACC region. */
166 ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */
167 ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */
168 ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 2, /* Kernels construct. */
169 ORT_ACC_SERIAL = ORT_ACC | ORT_TARGET | 4, /* Serial construct. */
170 ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2, /* Host data. */
171
172 /* Dummy OpenMP region, used to disable expansion of
173 DECL_VALUE_EXPRs in taskloop pre body. */
174 ORT_NONE = 0x200
175 };
176
177 /* Gimplify hashtable helper. */
178
179 struct gimplify_hasher : free_ptr_hash <elt_t>
180 {
181 static inline hashval_t hash (const elt_t *);
182 static inline bool equal (const elt_t *, const elt_t *);
183 };
184
185 struct gimplify_ctx
186 {
187 struct gimplify_ctx *prev_context;
188
189 vec<gbind *> bind_expr_stack;
190 tree temps;
191 gimple_seq conditional_cleanups;
192 tree exit_label;
193 tree return_temp;
194
195 vec<tree> case_labels;
196 hash_set<tree> *live_switch_vars;
197 /* The formal temporary table. Should this be persistent? */
198 hash_table<gimplify_hasher> *temp_htab;
199
200 int conditions;
201 unsigned into_ssa : 1;
202 unsigned allow_rhs_cond_expr : 1;
203 unsigned in_cleanup_point_expr : 1;
204 unsigned keep_stack : 1;
205 unsigned save_stack : 1;
206 unsigned in_switch_expr : 1;
207 };
208
209 enum gimplify_defaultmap_kind
210 {
211 GDMK_SCALAR,
212 GDMK_AGGREGATE,
213 GDMK_ALLOCATABLE,
214 GDMK_POINTER
215 };
216
217 struct gimplify_omp_ctx
218 {
219 struct gimplify_omp_ctx *outer_context;
220 splay_tree variables;
221 hash_set<tree> *privatized_types;
222 tree clauses;
223 /* Iteration variables in an OMP_FOR. */
224 vec<tree> loop_iter_var;
225 location_t location;
226 enum omp_clause_default_kind default_kind;
227 enum omp_region_type region_type;
228 enum tree_code code;
229 bool combined_loop;
230 bool distribute;
231 bool target_firstprivatize_array_bases;
232 bool add_safelen1;
233 bool order_concurrent;
234 bool has_depend;
235 bool in_for_exprs;
236 int defaultmap[4];
237 };
238
239 static struct gimplify_ctx *gimplify_ctxp;
240 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
241 static bool in_omp_construct;
242
243 /* Forward declaration. */
244 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
245 static hash_map<tree, tree> *oacc_declare_returns;
246 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
247 bool (*) (tree), fallback_t, bool);
248
249 /* Shorter alias name for the above function for use in gimplify.c
250 only. */
251
252 static inline void
gimplify_seq_add_stmt(gimple_seq * seq_p,gimple * gs)253 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
254 {
255 gimple_seq_add_stmt_without_update (seq_p, gs);
256 }
257
258 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
259 NULL, a new sequence is allocated. This function is
260 similar to gimple_seq_add_seq, but does not scan the operands.
261 During gimplification, we need to manipulate statement sequences
262 before the def/use vectors have been constructed. */
263
264 static void
gimplify_seq_add_seq(gimple_seq * dst_p,gimple_seq src)265 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
266 {
267 gimple_stmt_iterator si;
268
269 if (src == NULL)
270 return;
271
272 si = gsi_last (*dst_p);
273 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
274 }
275
276
277 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
278 and popping gimplify contexts. */
279
280 static struct gimplify_ctx *ctx_pool = NULL;
281
282 /* Return a gimplify context struct from the pool. */
283
284 static inline struct gimplify_ctx *
ctx_alloc(void)285 ctx_alloc (void)
286 {
287 struct gimplify_ctx * c = ctx_pool;
288
289 if (c)
290 ctx_pool = c->prev_context;
291 else
292 c = XNEW (struct gimplify_ctx);
293
294 memset (c, '\0', sizeof (*c));
295 return c;
296 }
297
298 /* Put gimplify context C back into the pool. */
299
300 static inline void
ctx_free(struct gimplify_ctx * c)301 ctx_free (struct gimplify_ctx *c)
302 {
303 c->prev_context = ctx_pool;
304 ctx_pool = c;
305 }
306
307 /* Free allocated ctx stack memory. */
308
309 void
free_gimplify_stack(void)310 free_gimplify_stack (void)
311 {
312 struct gimplify_ctx *c;
313
314 while ((c = ctx_pool))
315 {
316 ctx_pool = c->prev_context;
317 free (c);
318 }
319 }
320
321
322 /* Set up a context for the gimplifier. */
323
324 void
push_gimplify_context(bool in_ssa,bool rhs_cond_ok)325 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
326 {
327 struct gimplify_ctx *c = ctx_alloc ();
328
329 c->prev_context = gimplify_ctxp;
330 gimplify_ctxp = c;
331 gimplify_ctxp->into_ssa = in_ssa;
332 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
333 }
334
335 /* Tear down a context for the gimplifier. If BODY is non-null, then
336 put the temporaries into the outer BIND_EXPR. Otherwise, put them
337 in the local_decls.
338
339 BODY is not a sequence, but the first tuple in a sequence. */
340
341 void
pop_gimplify_context(gimple * body)342 pop_gimplify_context (gimple *body)
343 {
344 struct gimplify_ctx *c = gimplify_ctxp;
345
346 gcc_assert (c
347 && (!c->bind_expr_stack.exists ()
348 || c->bind_expr_stack.is_empty ()));
349 c->bind_expr_stack.release ();
350 gimplify_ctxp = c->prev_context;
351
352 if (body)
353 declare_vars (c->temps, body, false);
354 else
355 record_vars (c->temps);
356
357 delete c->temp_htab;
358 c->temp_htab = NULL;
359 ctx_free (c);
360 }
361
362 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
363
364 static void
gimple_push_bind_expr(gbind * bind_stmt)365 gimple_push_bind_expr (gbind *bind_stmt)
366 {
367 gimplify_ctxp->bind_expr_stack.reserve (8);
368 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
369 }
370
371 /* Pop the first element off the stack of bindings. */
372
373 static void
gimple_pop_bind_expr(void)374 gimple_pop_bind_expr (void)
375 {
376 gimplify_ctxp->bind_expr_stack.pop ();
377 }
378
379 /* Return the first element of the stack of bindings. */
380
381 gbind *
gimple_current_bind_expr(void)382 gimple_current_bind_expr (void)
383 {
384 return gimplify_ctxp->bind_expr_stack.last ();
385 }
386
387 /* Return the stack of bindings created during gimplification. */
388
389 vec<gbind *>
gimple_bind_expr_stack(void)390 gimple_bind_expr_stack (void)
391 {
392 return gimplify_ctxp->bind_expr_stack;
393 }
394
395 /* Return true iff there is a COND_EXPR between us and the innermost
396 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
397
398 static bool
gimple_conditional_context(void)399 gimple_conditional_context (void)
400 {
401 return gimplify_ctxp->conditions > 0;
402 }
403
404 /* Note that we've entered a COND_EXPR. */
405
406 static void
gimple_push_condition(void)407 gimple_push_condition (void)
408 {
409 #ifdef ENABLE_GIMPLE_CHECKING
410 if (gimplify_ctxp->conditions == 0)
411 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
412 #endif
413 ++(gimplify_ctxp->conditions);
414 }
415
416 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
417 now, add any conditional cleanups we've seen to the prequeue. */
418
419 static void
gimple_pop_condition(gimple_seq * pre_p)420 gimple_pop_condition (gimple_seq *pre_p)
421 {
422 int conds = --(gimplify_ctxp->conditions);
423
424 gcc_assert (conds >= 0);
425 if (conds == 0)
426 {
427 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
428 gimplify_ctxp->conditional_cleanups = NULL;
429 }
430 }
431
432 /* A stable comparison routine for use with splay trees and DECLs. */
433
434 static int
splay_tree_compare_decl_uid(splay_tree_key xa,splay_tree_key xb)435 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
436 {
437 tree a = (tree) xa;
438 tree b = (tree) xb;
439
440 return DECL_UID (a) - DECL_UID (b);
441 }
442
443 /* Create a new omp construct that deals with variable remapping. */
444
445 static struct gimplify_omp_ctx *
new_omp_context(enum omp_region_type region_type)446 new_omp_context (enum omp_region_type region_type)
447 {
448 struct gimplify_omp_ctx *c;
449
450 c = XCNEW (struct gimplify_omp_ctx);
451 c->outer_context = gimplify_omp_ctxp;
452 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
453 c->privatized_types = new hash_set<tree>;
454 c->location = input_location;
455 c->region_type = region_type;
456 if ((region_type & ORT_TASK) == 0)
457 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
458 else
459 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
460 c->defaultmap[GDMK_SCALAR] = GOVD_MAP;
461 c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
462 c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
463 c->defaultmap[GDMK_POINTER] = GOVD_MAP;
464
465 return c;
466 }
467
468 /* Destroy an omp construct that deals with variable remapping. */
469
470 static void
delete_omp_context(struct gimplify_omp_ctx * c)471 delete_omp_context (struct gimplify_omp_ctx *c)
472 {
473 splay_tree_delete (c->variables);
474 delete c->privatized_types;
475 c->loop_iter_var.release ();
476 XDELETE (c);
477 }
478
479 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
480 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
481
482 /* Both gimplify the statement T and append it to *SEQ_P. This function
483 behaves exactly as gimplify_stmt, but you don't have to pass T as a
484 reference. */
485
486 void
gimplify_and_add(tree t,gimple_seq * seq_p)487 gimplify_and_add (tree t, gimple_seq *seq_p)
488 {
489 gimplify_stmt (&t, seq_p);
490 }
491
492 /* Gimplify statement T into sequence *SEQ_P, and return the first
493 tuple in the sequence of generated tuples for this statement.
494 Return NULL if gimplifying T produced no tuples. */
495
496 static gimple *
gimplify_and_return_first(tree t,gimple_seq * seq_p)497 gimplify_and_return_first (tree t, gimple_seq *seq_p)
498 {
499 gimple_stmt_iterator last = gsi_last (*seq_p);
500
501 gimplify_and_add (t, seq_p);
502
503 if (!gsi_end_p (last))
504 {
505 gsi_next (&last);
506 return gsi_stmt (last);
507 }
508 else
509 return gimple_seq_first_stmt (*seq_p);
510 }
511
512 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
513 LHS, or for a call argument. */
514
515 static bool
is_gimple_mem_rhs(tree t)516 is_gimple_mem_rhs (tree t)
517 {
518 /* If we're dealing with a renamable type, either source or dest must be
519 a renamed variable. */
520 if (is_gimple_reg_type (TREE_TYPE (t)))
521 return is_gimple_val (t);
522 else
523 return is_gimple_val (t) || is_gimple_lvalue (t);
524 }
525
526 /* Return true if T is a CALL_EXPR or an expression that can be
527 assigned to a temporary. Note that this predicate should only be
528 used during gimplification. See the rationale for this in
529 gimplify_modify_expr. */
530
531 static bool
is_gimple_reg_rhs_or_call(tree t)532 is_gimple_reg_rhs_or_call (tree t)
533 {
534 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
535 || TREE_CODE (t) == CALL_EXPR);
536 }
537
538 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
539 this predicate should only be used during gimplification. See the
540 rationale for this in gimplify_modify_expr. */
541
542 static bool
is_gimple_mem_rhs_or_call(tree t)543 is_gimple_mem_rhs_or_call (tree t)
544 {
545 /* If we're dealing with a renamable type, either source or dest must be
546 a renamed variable. */
547 if (is_gimple_reg_type (TREE_TYPE (t)))
548 return is_gimple_val (t);
549 else
550 return (is_gimple_val (t)
551 || is_gimple_lvalue (t)
552 || TREE_CLOBBER_P (t)
553 || TREE_CODE (t) == CALL_EXPR);
554 }
555
556 /* Create a temporary with a name derived from VAL. Subroutine of
557 lookup_tmp_var; nobody else should call this function. */
558
559 static inline tree
create_tmp_from_val(tree val)560 create_tmp_from_val (tree val)
561 {
562 /* Drop all qualifiers and address-space information from the value type. */
563 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
564 tree var = create_tmp_var (type, get_name (val));
565 return var;
566 }
567
568 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
569 an existing expression temporary. */
570
571 static tree
lookup_tmp_var(tree val,bool is_formal)572 lookup_tmp_var (tree val, bool is_formal)
573 {
574 tree ret;
575
576 /* If not optimizing, never really reuse a temporary. local-alloc
577 won't allocate any variable that is used in more than one basic
578 block, which means it will go into memory, causing much extra
579 work in reload and final and poorer code generation, outweighing
580 the extra memory allocation here. */
581 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
582 ret = create_tmp_from_val (val);
583 else
584 {
585 elt_t elt, *elt_p;
586 elt_t **slot;
587
588 elt.val = val;
589 if (!gimplify_ctxp->temp_htab)
590 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
591 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
592 if (*slot == NULL)
593 {
594 elt_p = XNEW (elt_t);
595 elt_p->val = val;
596 elt_p->temp = ret = create_tmp_from_val (val);
597 *slot = elt_p;
598 }
599 else
600 {
601 elt_p = *slot;
602 ret = elt_p->temp;
603 }
604 }
605
606 return ret;
607 }
608
609 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
610
611 static tree
internal_get_tmp_var(tree val,gimple_seq * pre_p,gimple_seq * post_p,bool is_formal,bool allow_ssa)612 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
613 bool is_formal, bool allow_ssa)
614 {
615 tree t, mod;
616
617 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
618 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
619 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
620 fb_rvalue);
621
622 if (allow_ssa
623 && gimplify_ctxp->into_ssa
624 && is_gimple_reg_type (TREE_TYPE (val)))
625 {
626 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
627 if (! gimple_in_ssa_p (cfun))
628 {
629 const char *name = get_name (val);
630 if (name)
631 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
632 }
633 }
634 else
635 t = lookup_tmp_var (val, is_formal);
636
637 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
638
639 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
640
641 /* gimplify_modify_expr might want to reduce this further. */
642 gimplify_and_add (mod, pre_p);
643 ggc_free (mod);
644
645 return t;
646 }
647
648 /* Return a formal temporary variable initialized with VAL. PRE_P is as
649 in gimplify_expr. Only use this function if:
650
651 1) The value of the unfactored expression represented by VAL will not
652 change between the initialization and use of the temporary, and
653 2) The temporary will not be otherwise modified.
654
655 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
656 and #2 means it is inappropriate for && temps.
657
658 For other cases, use get_initialized_tmp_var instead. */
659
660 tree
get_formal_tmp_var(tree val,gimple_seq * pre_p)661 get_formal_tmp_var (tree val, gimple_seq *pre_p)
662 {
663 return internal_get_tmp_var (val, pre_p, NULL, true, true);
664 }
665
666 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
667 are as in gimplify_expr. */
668
669 tree
get_initialized_tmp_var(tree val,gimple_seq * pre_p,gimple_seq * post_p,bool allow_ssa)670 get_initialized_tmp_var (tree val, gimple_seq *pre_p,
671 gimple_seq *post_p /* = NULL */,
672 bool allow_ssa /* = true */)
673 {
674 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
675 }
676
677 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
678 generate debug info for them; otherwise don't. */
679
680 void
declare_vars(tree vars,gimple * gs,bool debug_info)681 declare_vars (tree vars, gimple *gs, bool debug_info)
682 {
683 tree last = vars;
684 if (last)
685 {
686 tree temps, block;
687
688 gbind *scope = as_a <gbind *> (gs);
689
690 temps = nreverse (last);
691
692 block = gimple_bind_block (scope);
693 gcc_assert (!block || TREE_CODE (block) == BLOCK);
694 if (!block || !debug_info)
695 {
696 DECL_CHAIN (last) = gimple_bind_vars (scope);
697 gimple_bind_set_vars (scope, temps);
698 }
699 else
700 {
701 /* We need to attach the nodes both to the BIND_EXPR and to its
702 associated BLOCK for debugging purposes. The key point here
703 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
704 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
705 if (BLOCK_VARS (block))
706 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
707 else
708 {
709 gimple_bind_set_vars (scope,
710 chainon (gimple_bind_vars (scope), temps));
711 BLOCK_VARS (block) = temps;
712 }
713 }
714 }
715 }
716
717 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
718 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
719 no such upper bound can be obtained. */
720
721 static void
force_constant_size(tree var)722 force_constant_size (tree var)
723 {
724 /* The only attempt we make is by querying the maximum size of objects
725 of the variable's type. */
726
727 HOST_WIDE_INT max_size;
728
729 gcc_assert (VAR_P (var));
730
731 max_size = max_int_size_in_bytes (TREE_TYPE (var));
732
733 gcc_assert (max_size >= 0);
734
735 DECL_SIZE_UNIT (var)
736 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
737 DECL_SIZE (var)
738 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
739 }
740
741 /* Push the temporary variable TMP into the current binding. */
742
743 void
gimple_add_tmp_var_fn(struct function * fn,tree tmp)744 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
745 {
746 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
747
748 /* Later processing assumes that the object size is constant, which might
749 not be true at this point. Force the use of a constant upper bound in
750 this case. */
751 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
752 force_constant_size (tmp);
753
754 DECL_CONTEXT (tmp) = fn->decl;
755 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
756
757 record_vars_into (tmp, fn->decl);
758 }
759
760 /* Push the temporary variable TMP into the current binding. */
761
762 void
gimple_add_tmp_var(tree tmp)763 gimple_add_tmp_var (tree tmp)
764 {
765 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
766
767 /* Later processing assumes that the object size is constant, which might
768 not be true at this point. Force the use of a constant upper bound in
769 this case. */
770 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
771 force_constant_size (tmp);
772
773 DECL_CONTEXT (tmp) = current_function_decl;
774 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
775
776 if (gimplify_ctxp)
777 {
778 DECL_CHAIN (tmp) = gimplify_ctxp->temps;
779 gimplify_ctxp->temps = tmp;
780
781 /* Mark temporaries local within the nearest enclosing parallel. */
782 if (gimplify_omp_ctxp)
783 {
784 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
785 int flag = GOVD_LOCAL | GOVD_SEEN;
786 while (ctx
787 && (ctx->region_type == ORT_WORKSHARE
788 || ctx->region_type == ORT_TASKGROUP
789 || ctx->region_type == ORT_SIMD
790 || ctx->region_type == ORT_ACC))
791 {
792 if (ctx->region_type == ORT_SIMD
793 && TREE_ADDRESSABLE (tmp)
794 && !TREE_STATIC (tmp))
795 {
796 if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
797 ctx->add_safelen1 = true;
798 else if (ctx->in_for_exprs)
799 flag = GOVD_PRIVATE;
800 else
801 flag = GOVD_PRIVATE | GOVD_SEEN;
802 break;
803 }
804 ctx = ctx->outer_context;
805 }
806 if (ctx)
807 omp_add_variable (ctx, tmp, flag);
808 }
809 }
810 else if (cfun)
811 record_vars (tmp);
812 else
813 {
814 gimple_seq body_seq;
815
816 /* This case is for nested functions. We need to expose the locals
817 they create. */
818 body_seq = gimple_body (current_function_decl);
819 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
820 }
821 }
822
823
824
825 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
826 nodes that are referenced more than once in GENERIC functions. This is
827 necessary because gimplification (translation into GIMPLE) is performed
828 by modifying tree nodes in-place, so gimplication of a shared node in a
829 first context could generate an invalid GIMPLE form in a second context.
830
831 This is achieved with a simple mark/copy/unmark algorithm that walks the
832 GENERIC representation top-down, marks nodes with TREE_VISITED the first
833 time it encounters them, duplicates them if they already have TREE_VISITED
834 set, and finally removes the TREE_VISITED marks it has set.
835
836 The algorithm works only at the function level, i.e. it generates a GENERIC
837 representation of a function with no nodes shared within the function when
838 passed a GENERIC function (except for nodes that are allowed to be shared).
839
840 At the global level, it is also necessary to unshare tree nodes that are
841 referenced in more than one function, for the same aforementioned reason.
842 This requires some cooperation from the front-end. There are 2 strategies:
843
844 1. Manual unsharing. The front-end needs to call unshare_expr on every
845 expression that might end up being shared across functions.
846
847 2. Deep unsharing. This is an extension of regular unsharing. Instead
848 of calling unshare_expr on expressions that might be shared across
849 functions, the front-end pre-marks them with TREE_VISITED. This will
850 ensure that they are unshared on the first reference within functions
851 when the regular unsharing algorithm runs. The counterpart is that
852 this algorithm must look deeper than for manual unsharing, which is
853 specified by LANG_HOOKS_DEEP_UNSHARING.
854
855 If there are only few specific cases of node sharing across functions, it is
856 probably easier for a front-end to unshare the expressions manually. On the
857 contrary, if the expressions generated at the global level are as widespread
858 as expressions generated within functions, deep unsharing is very likely the
859 way to go. */
860
861 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
862 These nodes model computations that must be done once. If we were to
863 unshare something like SAVE_EXPR(i++), the gimplification process would
864 create wrong code. However, if DATA is non-null, it must hold a pointer
865 set that is used to unshare the subtrees of these nodes. */
866
867 static tree
mostly_copy_tree_r(tree * tp,int * walk_subtrees,void * data)868 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
869 {
870 tree t = *tp;
871 enum tree_code code = TREE_CODE (t);
872
873 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
874 copy their subtrees if we can make sure to do it only once. */
875 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
876 {
877 if (data && !((hash_set<tree> *)data)->add (t))
878 ;
879 else
880 *walk_subtrees = 0;
881 }
882
883 /* Stop at types, decls, constants like copy_tree_r. */
884 else if (TREE_CODE_CLASS (code) == tcc_type
885 || TREE_CODE_CLASS (code) == tcc_declaration
886 || TREE_CODE_CLASS (code) == tcc_constant)
887 *walk_subtrees = 0;
888
889 /* Cope with the statement expression extension. */
890 else if (code == STATEMENT_LIST)
891 ;
892
893 /* Leave the bulk of the work to copy_tree_r itself. */
894 else
895 copy_tree_r (tp, walk_subtrees, NULL);
896
897 return NULL_TREE;
898 }
899
900 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
901 If *TP has been visited already, then *TP is deeply copied by calling
902 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
903
904 static tree
copy_if_shared_r(tree * tp,int * walk_subtrees,void * data)905 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
906 {
907 tree t = *tp;
908 enum tree_code code = TREE_CODE (t);
909
910 /* Skip types, decls, and constants. But we do want to look at their
911 types and the bounds of types. Mark them as visited so we properly
912 unmark their subtrees on the unmark pass. If we've already seen them,
913 don't look down further. */
914 if (TREE_CODE_CLASS (code) == tcc_type
915 || TREE_CODE_CLASS (code) == tcc_declaration
916 || TREE_CODE_CLASS (code) == tcc_constant)
917 {
918 if (TREE_VISITED (t))
919 *walk_subtrees = 0;
920 else
921 TREE_VISITED (t) = 1;
922 }
923
924 /* If this node has been visited already, unshare it and don't look
925 any deeper. */
926 else if (TREE_VISITED (t))
927 {
928 walk_tree (tp, mostly_copy_tree_r, data, NULL);
929 *walk_subtrees = 0;
930 }
931
932 /* Otherwise, mark the node as visited and keep looking. */
933 else
934 TREE_VISITED (t) = 1;
935
936 return NULL_TREE;
937 }
938
939 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
940 copy_if_shared_r callback unmodified. */
941
942 void
copy_if_shared(tree * tp,void * data)943 copy_if_shared (tree *tp, void *data)
944 {
945 walk_tree (tp, copy_if_shared_r, data, NULL);
946 }
947
948 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
949 any nested functions. */
950
951 static void
unshare_body(tree fndecl)952 unshare_body (tree fndecl)
953 {
954 struct cgraph_node *cgn = cgraph_node::get (fndecl);
955 /* If the language requires deep unsharing, we need a pointer set to make
956 sure we don't repeatedly unshare subtrees of unshareable nodes. */
957 hash_set<tree> *visited
958 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
959
960 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
961 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
962 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
963
964 delete visited;
965
966 if (cgn)
967 for (cgn = first_nested_function (cgn); cgn;
968 cgn = next_nested_function (cgn))
969 unshare_body (cgn->decl);
970 }
971
972 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
973 Subtrees are walked until the first unvisited node is encountered. */
974
975 static tree
unmark_visited_r(tree * tp,int * walk_subtrees,void * data ATTRIBUTE_UNUSED)976 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
977 {
978 tree t = *tp;
979
980 /* If this node has been visited, unmark it and keep looking. */
981 if (TREE_VISITED (t))
982 TREE_VISITED (t) = 0;
983
984 /* Otherwise, don't look any deeper. */
985 else
986 *walk_subtrees = 0;
987
988 return NULL_TREE;
989 }
990
991 /* Unmark the visited trees rooted at *TP. */
992
993 static inline void
unmark_visited(tree * tp)994 unmark_visited (tree *tp)
995 {
996 walk_tree (tp, unmark_visited_r, NULL, NULL);
997 }
998
999 /* Likewise, but mark all trees as not visited. */
1000
1001 static void
unvisit_body(tree fndecl)1002 unvisit_body (tree fndecl)
1003 {
1004 struct cgraph_node *cgn = cgraph_node::get (fndecl);
1005
1006 unmark_visited (&DECL_SAVED_TREE (fndecl));
1007 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
1008 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
1009
1010 if (cgn)
1011 for (cgn = first_nested_function (cgn);
1012 cgn; cgn = next_nested_function (cgn))
1013 unvisit_body (cgn->decl);
1014 }
1015
1016 /* Unconditionally make an unshared copy of EXPR. This is used when using
1017 stored expressions which span multiple functions, such as BINFO_VTABLE,
1018 as the normal unsharing process can't tell that they're shared. */
1019
1020 tree
unshare_expr(tree expr)1021 unshare_expr (tree expr)
1022 {
1023 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1024 return expr;
1025 }
1026
1027 /* Worker for unshare_expr_without_location. */
1028
1029 static tree
prune_expr_location(tree * tp,int * walk_subtrees,void *)1030 prune_expr_location (tree *tp, int *walk_subtrees, void *)
1031 {
1032 if (EXPR_P (*tp))
1033 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
1034 else
1035 *walk_subtrees = 0;
1036 return NULL_TREE;
1037 }
1038
1039 /* Similar to unshare_expr but also prune all expression locations
1040 from EXPR. */
1041
1042 tree
unshare_expr_without_location(tree expr)1043 unshare_expr_without_location (tree expr)
1044 {
1045 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1046 if (EXPR_P (expr))
1047 walk_tree (&expr, prune_expr_location, NULL, NULL);
1048 return expr;
1049 }
1050
1051 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1052 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1053 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1054 EXPR is the location of the EXPR. */
1055
1056 static location_t
1057 rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION)
1058 {
1059 if (!expr)
1060 return or_else;
1061
1062 if (EXPR_HAS_LOCATION (expr))
1063 return EXPR_LOCATION (expr);
1064
1065 if (TREE_CODE (expr) != STATEMENT_LIST)
1066 return or_else;
1067
1068 tree_stmt_iterator i = tsi_start (expr);
1069
1070 bool found = false;
1071 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
1072 {
1073 found = true;
1074 tsi_next (&i);
1075 }
1076
1077 if (!found || !tsi_one_before_end_p (i))
1078 return or_else;
1079
1080 return rexpr_location (tsi_stmt (i), or_else);
1081 }
1082
1083 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1084 rexpr_location for the potential recursion. */
1085
1086 static inline bool
rexpr_has_location(tree expr)1087 rexpr_has_location (tree expr)
1088 {
1089 return rexpr_location (expr) != UNKNOWN_LOCATION;
1090 }
1091
1092
1093 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1094 contain statements and have a value. Assign its value to a temporary
1095 and give it void_type_node. Return the temporary, or NULL_TREE if
1096 WRAPPER was already void. */
1097
1098 tree
voidify_wrapper_expr(tree wrapper,tree temp)1099 voidify_wrapper_expr (tree wrapper, tree temp)
1100 {
1101 tree type = TREE_TYPE (wrapper);
1102 if (type && !VOID_TYPE_P (type))
1103 {
1104 tree *p;
1105
1106 /* Set p to point to the body of the wrapper. Loop until we find
1107 something that isn't a wrapper. */
1108 for (p = &wrapper; p && *p; )
1109 {
1110 switch (TREE_CODE (*p))
1111 {
1112 case BIND_EXPR:
1113 TREE_SIDE_EFFECTS (*p) = 1;
1114 TREE_TYPE (*p) = void_type_node;
1115 /* For a BIND_EXPR, the body is operand 1. */
1116 p = &BIND_EXPR_BODY (*p);
1117 break;
1118
1119 case CLEANUP_POINT_EXPR:
1120 case TRY_FINALLY_EXPR:
1121 case TRY_CATCH_EXPR:
1122 TREE_SIDE_EFFECTS (*p) = 1;
1123 TREE_TYPE (*p) = void_type_node;
1124 p = &TREE_OPERAND (*p, 0);
1125 break;
1126
1127 case STATEMENT_LIST:
1128 {
1129 tree_stmt_iterator i = tsi_last (*p);
1130 TREE_SIDE_EFFECTS (*p) = 1;
1131 TREE_TYPE (*p) = void_type_node;
1132 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1133 }
1134 break;
1135
1136 case COMPOUND_EXPR:
1137 /* Advance to the last statement. Set all container types to
1138 void. */
1139 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1140 {
1141 TREE_SIDE_EFFECTS (*p) = 1;
1142 TREE_TYPE (*p) = void_type_node;
1143 }
1144 break;
1145
1146 case TRANSACTION_EXPR:
1147 TREE_SIDE_EFFECTS (*p) = 1;
1148 TREE_TYPE (*p) = void_type_node;
1149 p = &TRANSACTION_EXPR_BODY (*p);
1150 break;
1151
1152 default:
1153 /* Assume that any tree upon which voidify_wrapper_expr is
1154 directly called is a wrapper, and that its body is op0. */
1155 if (p == &wrapper)
1156 {
1157 TREE_SIDE_EFFECTS (*p) = 1;
1158 TREE_TYPE (*p) = void_type_node;
1159 p = &TREE_OPERAND (*p, 0);
1160 break;
1161 }
1162 goto out;
1163 }
1164 }
1165
1166 out:
1167 if (p == NULL || IS_EMPTY_STMT (*p))
1168 temp = NULL_TREE;
1169 else if (temp)
1170 {
1171 /* The wrapper is on the RHS of an assignment that we're pushing
1172 down. */
1173 gcc_assert (TREE_CODE (temp) == INIT_EXPR
1174 || TREE_CODE (temp) == MODIFY_EXPR);
1175 TREE_OPERAND (temp, 1) = *p;
1176 *p = temp;
1177 }
1178 else
1179 {
1180 temp = create_tmp_var (type, "retval");
1181 *p = build2 (INIT_EXPR, type, temp, *p);
1182 }
1183
1184 return temp;
1185 }
1186
1187 return NULL_TREE;
1188 }
1189
1190 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1191 a temporary through which they communicate. */
1192
1193 static void
build_stack_save_restore(gcall ** save,gcall ** restore)1194 build_stack_save_restore (gcall **save, gcall **restore)
1195 {
1196 tree tmp_var;
1197
1198 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1199 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1200 gimple_call_set_lhs (*save, tmp_var);
1201
1202 *restore
1203 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1204 1, tmp_var);
1205 }
1206
1207 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1208
1209 static tree
build_asan_poison_call_expr(tree decl)1210 build_asan_poison_call_expr (tree decl)
1211 {
1212 /* Do not poison variables that have size equal to zero. */
1213 tree unit_size = DECL_SIZE_UNIT (decl);
1214 if (zerop (unit_size))
1215 return NULL_TREE;
1216
1217 tree base = build_fold_addr_expr (decl);
1218
1219 return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
1220 void_type_node, 3,
1221 build_int_cst (integer_type_node,
1222 ASAN_MARK_POISON),
1223 base, unit_size);
1224 }
1225
1226 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1227 on POISON flag, shadow memory of a DECL variable. The call will be
1228 put on location identified by IT iterator, where BEFORE flag drives
1229 position where the stmt will be put. */
1230
1231 static void
asan_poison_variable(tree decl,bool poison,gimple_stmt_iterator * it,bool before)1232 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
1233 bool before)
1234 {
1235 tree unit_size = DECL_SIZE_UNIT (decl);
1236 tree base = build_fold_addr_expr (decl);
1237
1238 /* Do not poison variables that have size equal to zero. */
1239 if (zerop (unit_size))
1240 return;
1241
1242 /* It's necessary to have all stack variables aligned to ASAN granularity
1243 bytes. */
1244 gcc_assert (!hwasan_sanitize_p () || hwasan_sanitize_stack_p ());
1245 unsigned shadow_granularity
1246 = hwasan_sanitize_p () ? HWASAN_TAG_GRANULE_SIZE : ASAN_SHADOW_GRANULARITY;
1247 if (DECL_ALIGN_UNIT (decl) <= shadow_granularity)
1248 SET_DECL_ALIGN (decl, BITS_PER_UNIT * shadow_granularity);
1249
1250 HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
1251
1252 gimple *g
1253 = gimple_build_call_internal (IFN_ASAN_MARK, 3,
1254 build_int_cst (integer_type_node, flags),
1255 base, unit_size);
1256
1257 if (before)
1258 gsi_insert_before (it, g, GSI_NEW_STMT);
1259 else
1260 gsi_insert_after (it, g, GSI_NEW_STMT);
1261 }
1262
1263 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1264 either poisons or unpoisons a DECL. Created statement is appended
1265 to SEQ_P gimple sequence. */
1266
1267 static void
asan_poison_variable(tree decl,bool poison,gimple_seq * seq_p)1268 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
1269 {
1270 gimple_stmt_iterator it = gsi_last (*seq_p);
1271 bool before = false;
1272
1273 if (gsi_end_p (it))
1274 before = true;
1275
1276 asan_poison_variable (decl, poison, &it, before);
1277 }
1278
1279 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1280
1281 static int
sort_by_decl_uid(const void * a,const void * b)1282 sort_by_decl_uid (const void *a, const void *b)
1283 {
1284 const tree *t1 = (const tree *)a;
1285 const tree *t2 = (const tree *)b;
1286
1287 int uid1 = DECL_UID (*t1);
1288 int uid2 = DECL_UID (*t2);
1289
1290 if (uid1 < uid2)
1291 return -1;
1292 else if (uid1 > uid2)
1293 return 1;
1294 else
1295 return 0;
1296 }
1297
1298 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1299 depending on POISON flag. Created statement is appended
1300 to SEQ_P gimple sequence. */
1301
1302 static void
asan_poison_variables(hash_set<tree> * variables,bool poison,gimple_seq * seq_p)1303 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
1304 {
1305 unsigned c = variables->elements ();
1306 if (c == 0)
1307 return;
1308
1309 auto_vec<tree> sorted_variables (c);
1310
1311 for (hash_set<tree>::iterator it = variables->begin ();
1312 it != variables->end (); ++it)
1313 sorted_variables.safe_push (*it);
1314
1315 sorted_variables.qsort (sort_by_decl_uid);
1316
1317 unsigned i;
1318 tree var;
1319 FOR_EACH_VEC_ELT (sorted_variables, i, var)
1320 {
1321 asan_poison_variable (var, poison, seq_p);
1322
1323 /* Add use_after_scope_memory attribute for the variable in order
1324 to prevent re-written into SSA. */
1325 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
1326 DECL_ATTRIBUTES (var)))
1327 DECL_ATTRIBUTES (var)
1328 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
1329 integer_one_node,
1330 DECL_ATTRIBUTES (var));
1331 }
1332 }
1333
1334 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1335
1336 static enum gimplify_status
gimplify_bind_expr(tree * expr_p,gimple_seq * pre_p)1337 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1338 {
1339 tree bind_expr = *expr_p;
1340 bool old_keep_stack = gimplify_ctxp->keep_stack;
1341 bool old_save_stack = gimplify_ctxp->save_stack;
1342 tree t;
1343 gbind *bind_stmt;
1344 gimple_seq body, cleanup;
1345 gcall *stack_save;
1346 location_t start_locus = 0, end_locus = 0;
1347 tree ret_clauses = NULL;
1348
1349 tree temp = voidify_wrapper_expr (bind_expr, NULL);
1350
1351 /* Mark variables seen in this bind expr. */
1352 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1353 {
1354 if (VAR_P (t))
1355 {
1356 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1357
1358 /* Mark variable as local. */
1359 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t))
1360 {
1361 if (! DECL_SEEN_IN_BIND_EXPR_P (t)
1362 || splay_tree_lookup (ctx->variables,
1363 (splay_tree_key) t) == NULL)
1364 {
1365 int flag = GOVD_LOCAL;
1366 if (ctx->region_type == ORT_SIMD
1367 && TREE_ADDRESSABLE (t)
1368 && !TREE_STATIC (t))
1369 {
1370 if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST)
1371 ctx->add_safelen1 = true;
1372 else
1373 flag = GOVD_PRIVATE;
1374 }
1375 omp_add_variable (ctx, t, flag | GOVD_SEEN);
1376 }
1377 /* Static locals inside of target construct or offloaded
1378 routines need to be "omp declare target". */
1379 if (TREE_STATIC (t))
1380 for (; ctx; ctx = ctx->outer_context)
1381 if ((ctx->region_type & ORT_TARGET) != 0)
1382 {
1383 if (!lookup_attribute ("omp declare target",
1384 DECL_ATTRIBUTES (t)))
1385 {
1386 tree id = get_identifier ("omp declare target");
1387 DECL_ATTRIBUTES (t)
1388 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
1389 varpool_node *node = varpool_node::get (t);
1390 if (node)
1391 {
1392 node->offloadable = 1;
1393 if (ENABLE_OFFLOADING && !DECL_EXTERNAL (t))
1394 {
1395 g->have_offload = true;
1396 if (!in_lto_p)
1397 vec_safe_push (offload_vars, t);
1398 }
1399 }
1400 }
1401 break;
1402 }
1403 }
1404
1405 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1406
1407 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1408 cfun->has_local_explicit_reg_vars = true;
1409 }
1410 }
1411
1412 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1413 BIND_EXPR_BLOCK (bind_expr));
1414 gimple_push_bind_expr (bind_stmt);
1415
1416 gimplify_ctxp->keep_stack = false;
1417 gimplify_ctxp->save_stack = false;
1418
1419 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1420 body = NULL;
1421 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1422 gimple_bind_set_body (bind_stmt, body);
1423
1424 /* Source location wise, the cleanup code (stack_restore and clobbers)
1425 belongs to the end of the block, so propagate what we have. The
1426 stack_save operation belongs to the beginning of block, which we can
1427 infer from the bind_expr directly if the block has no explicit
1428 assignment. */
1429 if (BIND_EXPR_BLOCK (bind_expr))
1430 {
1431 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1432 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1433 }
1434 if (start_locus == 0)
1435 start_locus = EXPR_LOCATION (bind_expr);
1436
1437 cleanup = NULL;
1438 stack_save = NULL;
1439
1440 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1441 the stack space allocated to the VLAs. */
1442 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1443 {
1444 gcall *stack_restore;
1445
1446 /* Save stack on entry and restore it on exit. Add a try_finally
1447 block to achieve this. */
1448 build_stack_save_restore (&stack_save, &stack_restore);
1449
1450 gimple_set_location (stack_save, start_locus);
1451 gimple_set_location (stack_restore, end_locus);
1452
1453 gimplify_seq_add_stmt (&cleanup, stack_restore);
1454 }
1455
1456 /* Add clobbers for all variables that go out of scope. */
1457 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1458 {
1459 if (VAR_P (t)
1460 && !is_global_var (t)
1461 && DECL_CONTEXT (t) == current_function_decl)
1462 {
1463 if (!DECL_HARD_REGISTER (t)
1464 && !TREE_THIS_VOLATILE (t)
1465 && !DECL_HAS_VALUE_EXPR_P (t)
1466 /* Only care for variables that have to be in memory. Others
1467 will be rewritten into SSA names, hence moved to the
1468 top-level. */
1469 && !is_gimple_reg (t)
1470 && flag_stack_reuse != SR_NONE)
1471 {
1472 tree clobber = build_clobber (TREE_TYPE (t));
1473 gimple *clobber_stmt;
1474 clobber_stmt = gimple_build_assign (t, clobber);
1475 gimple_set_location (clobber_stmt, end_locus);
1476 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1477 }
1478
1479 if (flag_openacc && oacc_declare_returns != NULL)
1480 {
1481 tree key = t;
1482 if (DECL_HAS_VALUE_EXPR_P (key))
1483 {
1484 key = DECL_VALUE_EXPR (key);
1485 if (TREE_CODE (key) == INDIRECT_REF)
1486 key = TREE_OPERAND (key, 0);
1487 }
1488 tree *c = oacc_declare_returns->get (key);
1489 if (c != NULL)
1490 {
1491 if (ret_clauses)
1492 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1493
1494 ret_clauses = unshare_expr (*c);
1495
1496 oacc_declare_returns->remove (key);
1497
1498 if (oacc_declare_returns->is_empty ())
1499 {
1500 delete oacc_declare_returns;
1501 oacc_declare_returns = NULL;
1502 }
1503 }
1504 }
1505 }
1506
1507 if (asan_poisoned_variables != NULL
1508 && asan_poisoned_variables->contains (t))
1509 {
1510 asan_poisoned_variables->remove (t);
1511 asan_poison_variable (t, true, &cleanup);
1512 }
1513
1514 if (gimplify_ctxp->live_switch_vars != NULL
1515 && gimplify_ctxp->live_switch_vars->contains (t))
1516 gimplify_ctxp->live_switch_vars->remove (t);
1517 }
1518
1519 if (ret_clauses)
1520 {
1521 gomp_target *stmt;
1522 gimple_stmt_iterator si = gsi_start (cleanup);
1523
1524 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1525 ret_clauses);
1526 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1527 }
1528
1529 if (cleanup)
1530 {
1531 gtry *gs;
1532 gimple_seq new_body;
1533
1534 new_body = NULL;
1535 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1536 GIMPLE_TRY_FINALLY);
1537
1538 if (stack_save)
1539 gimplify_seq_add_stmt (&new_body, stack_save);
1540 gimplify_seq_add_stmt (&new_body, gs);
1541 gimple_bind_set_body (bind_stmt, new_body);
1542 }
1543
1544 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1545 if (!gimplify_ctxp->keep_stack)
1546 gimplify_ctxp->keep_stack = old_keep_stack;
1547 gimplify_ctxp->save_stack = old_save_stack;
1548
1549 gimple_pop_bind_expr ();
1550
1551 gimplify_seq_add_stmt (pre_p, bind_stmt);
1552
1553 if (temp)
1554 {
1555 *expr_p = temp;
1556 return GS_OK;
1557 }
1558
1559 *expr_p = NULL_TREE;
1560 return GS_ALL_DONE;
1561 }
1562
1563 /* Maybe add early return predict statement to PRE_P sequence. */
1564
1565 static void
maybe_add_early_return_predict_stmt(gimple_seq * pre_p)1566 maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
1567 {
1568 /* If we are not in a conditional context, add PREDICT statement. */
1569 if (gimple_conditional_context ())
1570 {
1571 gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
1572 NOT_TAKEN);
1573 gimplify_seq_add_stmt (pre_p, predict);
1574 }
1575 }
1576
1577 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1578 GIMPLE value, it is assigned to a new temporary and the statement is
1579 re-written to return the temporary.
1580
1581 PRE_P points to the sequence where side effects that must happen before
1582 STMT should be stored. */
1583
1584 static enum gimplify_status
gimplify_return_expr(tree stmt,gimple_seq * pre_p)1585 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1586 {
1587 greturn *ret;
1588 tree ret_expr = TREE_OPERAND (stmt, 0);
1589 tree result_decl, result;
1590
1591 if (ret_expr == error_mark_node)
1592 return GS_ERROR;
1593
1594 if (!ret_expr
1595 || TREE_CODE (ret_expr) == RESULT_DECL)
1596 {
1597 maybe_add_early_return_predict_stmt (pre_p);
1598 greturn *ret = gimple_build_return (ret_expr);
1599 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1600 gimplify_seq_add_stmt (pre_p, ret);
1601 return GS_ALL_DONE;
1602 }
1603
1604 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1605 result_decl = NULL_TREE;
1606 else if (TREE_CODE (ret_expr) == COMPOUND_EXPR)
1607 {
1608 /* Used in C++ for handling EH cleanup of the return value if a local
1609 cleanup throws. Assume the front-end knows what it's doing. */
1610 result_decl = DECL_RESULT (current_function_decl);
1611 /* But crash if we end up trying to modify ret_expr below. */
1612 ret_expr = NULL_TREE;
1613 }
1614 else
1615 {
1616 result_decl = TREE_OPERAND (ret_expr, 0);
1617
1618 /* See through a return by reference. */
1619 if (TREE_CODE (result_decl) == INDIRECT_REF)
1620 result_decl = TREE_OPERAND (result_decl, 0);
1621
1622 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1623 || TREE_CODE (ret_expr) == INIT_EXPR)
1624 && TREE_CODE (result_decl) == RESULT_DECL);
1625 }
1626
1627 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1628 Recall that aggregate_value_p is FALSE for any aggregate type that is
1629 returned in registers. If we're returning values in registers, then
1630 we don't want to extend the lifetime of the RESULT_DECL, particularly
1631 across another call. In addition, for those aggregates for which
1632 hard_function_value generates a PARALLEL, we'll die during normal
1633 expansion of structure assignments; there's special code in expand_return
1634 to handle this case that does not exist in expand_expr. */
1635 if (!result_decl)
1636 result = NULL_TREE;
1637 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1638 {
1639 if (!poly_int_tree_p (DECL_SIZE (result_decl)))
1640 {
1641 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1642 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1643 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1644 should be effectively allocated by the caller, i.e. all calls to
1645 this function must be subject to the Return Slot Optimization. */
1646 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1647 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1648 }
1649 result = result_decl;
1650 }
1651 else if (gimplify_ctxp->return_temp)
1652 result = gimplify_ctxp->return_temp;
1653 else
1654 {
1655 result = create_tmp_reg (TREE_TYPE (result_decl));
1656
1657 /* ??? With complex control flow (usually involving abnormal edges),
1658 we can wind up warning about an uninitialized value for this. Due
1659 to how this variable is constructed and initialized, this is never
1660 true. Give up and never warn. */
1661 TREE_NO_WARNING (result) = 1;
1662
1663 gimplify_ctxp->return_temp = result;
1664 }
1665
1666 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1667 Then gimplify the whole thing. */
1668 if (result != result_decl)
1669 TREE_OPERAND (ret_expr, 0) = result;
1670
1671 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1672
1673 maybe_add_early_return_predict_stmt (pre_p);
1674 ret = gimple_build_return (result);
1675 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1676 gimplify_seq_add_stmt (pre_p, ret);
1677
1678 return GS_ALL_DONE;
1679 }
1680
1681 /* Gimplify a variable-length array DECL. */
1682
1683 static void
gimplify_vla_decl(tree decl,gimple_seq * seq_p)1684 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1685 {
1686 /* This is a variable-sized decl. Simplify its size and mark it
1687 for deferred expansion. */
1688 tree t, addr, ptr_type;
1689
1690 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1691 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1692
1693 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1694 if (DECL_HAS_VALUE_EXPR_P (decl))
1695 return;
1696
1697 /* All occurrences of this decl in final gimplified code will be
1698 replaced by indirection. Setting DECL_VALUE_EXPR does two
1699 things: First, it lets the rest of the gimplifier know what
1700 replacement to use. Second, it lets the debug info know
1701 where to find the value. */
1702 ptr_type = build_pointer_type (TREE_TYPE (decl));
1703 addr = create_tmp_var (ptr_type, get_name (decl));
1704 DECL_IGNORED_P (addr) = 0;
1705 t = build_fold_indirect_ref (addr);
1706 TREE_THIS_NOTRAP (t) = 1;
1707 SET_DECL_VALUE_EXPR (decl, t);
1708 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1709
1710 t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
1711 max_int_size_in_bytes (TREE_TYPE (decl)));
1712 /* The call has been built for a variable-sized object. */
1713 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1714 t = fold_convert (ptr_type, t);
1715 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1716
1717 gimplify_and_add (t, seq_p);
1718
1719 /* Record the dynamic allocation associated with DECL if requested. */
1720 if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)
1721 record_dynamic_alloc (decl);
1722 }
1723
1724 /* A helper function to be called via walk_tree. Mark all labels under *TP
1725 as being forced. To be called for DECL_INITIAL of static variables. */
1726
1727 static tree
force_labels_r(tree * tp,int * walk_subtrees,void * data ATTRIBUTE_UNUSED)1728 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1729 {
1730 if (TYPE_P (*tp))
1731 *walk_subtrees = 0;
1732 if (TREE_CODE (*tp) == LABEL_DECL)
1733 {
1734 FORCED_LABEL (*tp) = 1;
1735 cfun->has_forced_label_in_static = 1;
1736 }
1737
1738 return NULL_TREE;
1739 }
1740
1741 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1742 and initialization explicit. */
1743
1744 static enum gimplify_status
gimplify_decl_expr(tree * stmt_p,gimple_seq * seq_p)1745 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1746 {
1747 tree stmt = *stmt_p;
1748 tree decl = DECL_EXPR_DECL (stmt);
1749
1750 *stmt_p = NULL_TREE;
1751
1752 if (TREE_TYPE (decl) == error_mark_node)
1753 return GS_ERROR;
1754
1755 if ((TREE_CODE (decl) == TYPE_DECL
1756 || VAR_P (decl))
1757 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1758 {
1759 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1760 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1761 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1762 }
1763
1764 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1765 in case its size expressions contain problematic nodes like CALL_EXPR. */
1766 if (TREE_CODE (decl) == TYPE_DECL
1767 && DECL_ORIGINAL_TYPE (decl)
1768 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1769 {
1770 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1771 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1772 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1773 }
1774
1775 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1776 {
1777 tree init = DECL_INITIAL (decl);
1778 bool is_vla = false;
1779
1780 poly_uint64 size;
1781 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
1782 || (!TREE_STATIC (decl)
1783 && flag_stack_check == GENERIC_STACK_CHECK
1784 && maybe_gt (size,
1785 (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
1786 {
1787 gimplify_vla_decl (decl, seq_p);
1788 is_vla = true;
1789 }
1790
1791 if (asan_poisoned_variables
1792 && !is_vla
1793 && TREE_ADDRESSABLE (decl)
1794 && !TREE_STATIC (decl)
1795 && !DECL_HAS_VALUE_EXPR_P (decl)
1796 && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
1797 && dbg_cnt (asan_use_after_scope)
1798 && !gimplify_omp_ctxp
1799 /* GNAT introduces temporaries to hold return values of calls in
1800 initializers of variables defined in other units, so the
1801 declaration of the variable is discarded completely. We do not
1802 want to issue poison calls for such dropped variables. */
1803 && (DECL_SEEN_IN_BIND_EXPR_P (decl)
1804 || (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)))
1805 {
1806 asan_poisoned_variables->add (decl);
1807 asan_poison_variable (decl, false, seq_p);
1808 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
1809 gimplify_ctxp->live_switch_vars->add (decl);
1810 }
1811
1812 /* Some front ends do not explicitly declare all anonymous
1813 artificial variables. We compensate here by declaring the
1814 variables, though it would be better if the front ends would
1815 explicitly declare them. */
1816 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1817 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1818 gimple_add_tmp_var (decl);
1819
1820 if (init && init != error_mark_node)
1821 {
1822 if (!TREE_STATIC (decl))
1823 {
1824 DECL_INITIAL (decl) = NULL_TREE;
1825 init = build2 (INIT_EXPR, void_type_node, decl, init);
1826 gimplify_and_add (init, seq_p);
1827 ggc_free (init);
1828 }
1829 else
1830 /* We must still examine initializers for static variables
1831 as they may contain a label address. */
1832 walk_tree (&init, force_labels_r, NULL, NULL);
1833 }
1834 }
1835
1836 return GS_ALL_DONE;
1837 }
1838
1839 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1840 and replacing the LOOP_EXPR with goto, but if the loop contains an
1841 EXIT_EXPR, we need to append a label for it to jump to. */
1842
1843 static enum gimplify_status
gimplify_loop_expr(tree * expr_p,gimple_seq * pre_p)1844 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1845 {
1846 tree saved_label = gimplify_ctxp->exit_label;
1847 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1848
1849 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1850
1851 gimplify_ctxp->exit_label = NULL_TREE;
1852
1853 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1854
1855 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
1856
1857 if (gimplify_ctxp->exit_label)
1858 gimplify_seq_add_stmt (pre_p,
1859 gimple_build_label (gimplify_ctxp->exit_label));
1860
1861 gimplify_ctxp->exit_label = saved_label;
1862
1863 *expr_p = NULL;
1864 return GS_ALL_DONE;
1865 }
1866
1867 /* Gimplify a statement list onto a sequence. These may be created either
1868 by an enlightened front-end, or by shortcut_cond_expr. */
1869
1870 static enum gimplify_status
gimplify_statement_list(tree * expr_p,gimple_seq * pre_p)1871 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
1872 {
1873 tree temp = voidify_wrapper_expr (*expr_p, NULL);
1874
1875 tree_stmt_iterator i = tsi_start (*expr_p);
1876
1877 while (!tsi_end_p (i))
1878 {
1879 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
1880 tsi_delink (&i);
1881 }
1882
1883 if (temp)
1884 {
1885 *expr_p = temp;
1886 return GS_OK;
1887 }
1888
1889 return GS_ALL_DONE;
1890 }
1891
1892 /* Callback for walk_gimple_seq. */
1893
1894 static tree
warn_switch_unreachable_r(gimple_stmt_iterator * gsi_p,bool * handled_ops_p,struct walk_stmt_info * wi)1895 warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
1896 struct walk_stmt_info *wi)
1897 {
1898 gimple *stmt = gsi_stmt (*gsi_p);
1899
1900 *handled_ops_p = true;
1901 switch (gimple_code (stmt))
1902 {
1903 case GIMPLE_TRY:
1904 /* A compiler-generated cleanup or a user-written try block.
1905 If it's empty, don't dive into it--that would result in
1906 worse location info. */
1907 if (gimple_try_eval (stmt) == NULL)
1908 {
1909 wi->info = stmt;
1910 return integer_zero_node;
1911 }
1912 /* Fall through. */
1913 case GIMPLE_BIND:
1914 case GIMPLE_CATCH:
1915 case GIMPLE_EH_FILTER:
1916 case GIMPLE_TRANSACTION:
1917 /* Walk the sub-statements. */
1918 *handled_ops_p = false;
1919 break;
1920
1921 case GIMPLE_DEBUG:
1922 /* Ignore these. We may generate them before declarations that
1923 are never executed. If there's something to warn about,
1924 there will be non-debug stmts too, and we'll catch those. */
1925 break;
1926
1927 case GIMPLE_CALL:
1928 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
1929 {
1930 *handled_ops_p = false;
1931 break;
1932 }
1933 /* Fall through. */
1934 default:
1935 /* Save the first "real" statement (not a decl/lexical scope/...). */
1936 wi->info = stmt;
1937 return integer_zero_node;
1938 }
1939 return NULL_TREE;
1940 }
1941
1942 /* Possibly warn about unreachable statements between switch's controlling
1943 expression and the first case. SEQ is the body of a switch expression. */
1944
1945 static void
maybe_warn_switch_unreachable(gimple_seq seq)1946 maybe_warn_switch_unreachable (gimple_seq seq)
1947 {
1948 if (!warn_switch_unreachable
1949 /* This warning doesn't play well with Fortran when optimizations
1950 are on. */
1951 || lang_GNU_Fortran ()
1952 || seq == NULL)
1953 return;
1954
1955 struct walk_stmt_info wi;
1956 memset (&wi, 0, sizeof (wi));
1957 walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi);
1958 gimple *stmt = (gimple *) wi.info;
1959
1960 if (stmt && gimple_code (stmt) != GIMPLE_LABEL)
1961 {
1962 if (gimple_code (stmt) == GIMPLE_GOTO
1963 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
1964 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
1965 /* Don't warn for compiler-generated gotos. These occur
1966 in Duff's devices, for example. */;
1967 else
1968 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
1969 "statement will never be executed");
1970 }
1971 }
1972
1973
1974 /* A label entry that pairs label and a location. */
1975 struct label_entry
1976 {
1977 tree label;
1978 location_t loc;
1979 };
1980
1981 /* Find LABEL in vector of label entries VEC. */
1982
1983 static struct label_entry *
find_label_entry(const auto_vec<struct label_entry> * vec,tree label)1984 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
1985 {
1986 unsigned int i;
1987 struct label_entry *l;
1988
1989 FOR_EACH_VEC_ELT (*vec, i, l)
1990 if (l->label == label)
1991 return l;
1992 return NULL;
1993 }
1994
1995 /* Return true if LABEL, a LABEL_DECL, represents a case label
1996 in a vector of labels CASES. */
1997
1998 static bool
case_label_p(const vec<tree> * cases,tree label)1999 case_label_p (const vec<tree> *cases, tree label)
2000 {
2001 unsigned int i;
2002 tree l;
2003
2004 FOR_EACH_VEC_ELT (*cases, i, l)
2005 if (CASE_LABEL (l) == label)
2006 return true;
2007 return false;
2008 }
2009
2010 /* Find the last nondebug statement in a scope STMT. */
2011
2012 static gimple *
last_stmt_in_scope(gimple * stmt)2013 last_stmt_in_scope (gimple *stmt)
2014 {
2015 if (!stmt)
2016 return NULL;
2017
2018 switch (gimple_code (stmt))
2019 {
2020 case GIMPLE_BIND:
2021 {
2022 gbind *bind = as_a <gbind *> (stmt);
2023 stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
2024 return last_stmt_in_scope (stmt);
2025 }
2026
2027 case GIMPLE_TRY:
2028 {
2029 gtry *try_stmt = as_a <gtry *> (stmt);
2030 stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
2031 gimple *last_eval = last_stmt_in_scope (stmt);
2032 if (gimple_stmt_may_fallthru (last_eval)
2033 && (last_eval == NULL
2034 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
2035 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
2036 {
2037 stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
2038 return last_stmt_in_scope (stmt);
2039 }
2040 else
2041 return last_eval;
2042 }
2043
2044 case GIMPLE_DEBUG:
2045 gcc_unreachable ();
2046
2047 default:
2048 return stmt;
2049 }
2050 }
2051
2052 /* Collect interesting labels in LABELS and return the statement preceding
2053 another case label, or a user-defined label. Store a location useful
2054 to give warnings at *PREVLOC (usually the location of the returned
2055 statement or of its surrounding scope). */
2056
2057 static gimple *
collect_fallthrough_labels(gimple_stmt_iterator * gsi_p,auto_vec<struct label_entry> * labels,location_t * prevloc)2058 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
2059 auto_vec <struct label_entry> *labels,
2060 location_t *prevloc)
2061 {
2062 gimple *prev = NULL;
2063
2064 *prevloc = UNKNOWN_LOCATION;
2065 do
2066 {
2067 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
2068 {
2069 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2070 which starts on a GIMPLE_SWITCH and ends with a break label.
2071 Handle that as a single statement that can fall through. */
2072 gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
2073 gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
2074 gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
2075 if (last
2076 && gimple_code (first) == GIMPLE_SWITCH
2077 && gimple_code (last) == GIMPLE_LABEL)
2078 {
2079 tree label = gimple_label_label (as_a <glabel *> (last));
2080 if (SWITCH_BREAK_LABEL_P (label))
2081 {
2082 prev = bind;
2083 gsi_next (gsi_p);
2084 continue;
2085 }
2086 }
2087 }
2088 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
2089 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
2090 {
2091 /* Nested scope. Only look at the last statement of
2092 the innermost scope. */
2093 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
2094 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
2095 if (last)
2096 {
2097 prev = last;
2098 /* It might be a label without a location. Use the
2099 location of the scope then. */
2100 if (!gimple_has_location (prev))
2101 *prevloc = bind_loc;
2102 }
2103 gsi_next (gsi_p);
2104 continue;
2105 }
2106
2107 /* Ifs are tricky. */
2108 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
2109 {
2110 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
2111 tree false_lab = gimple_cond_false_label (cond_stmt);
2112 location_t if_loc = gimple_location (cond_stmt);
2113
2114 /* If we have e.g.
2115 if (i > 1) goto <D.2259>; else goto D;
2116 we can't do much with the else-branch. */
2117 if (!DECL_ARTIFICIAL (false_lab))
2118 break;
2119
2120 /* Go on until the false label, then one step back. */
2121 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
2122 {
2123 gimple *stmt = gsi_stmt (*gsi_p);
2124 if (gimple_code (stmt) == GIMPLE_LABEL
2125 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
2126 break;
2127 }
2128
2129 /* Not found? Oops. */
2130 if (gsi_end_p (*gsi_p))
2131 break;
2132
2133 struct label_entry l = { false_lab, if_loc };
2134 labels->safe_push (l);
2135
2136 /* Go to the last statement of the then branch. */
2137 gsi_prev (gsi_p);
2138
2139 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2140 <D.1759>:
2141 <stmt>;
2142 goto <D.1761>;
2143 <D.1760>:
2144 */
2145 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2146 && !gimple_has_location (gsi_stmt (*gsi_p)))
2147 {
2148 /* Look at the statement before, it might be
2149 attribute fallthrough, in which case don't warn. */
2150 gsi_prev (gsi_p);
2151 bool fallthru_before_dest
2152 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2153 gsi_next (gsi_p);
2154 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2155 if (!fallthru_before_dest)
2156 {
2157 struct label_entry l = { goto_dest, if_loc };
2158 labels->safe_push (l);
2159 }
2160 }
2161 /* And move back. */
2162 gsi_next (gsi_p);
2163 }
2164
2165 /* Remember the last statement. Skip labels that are of no interest
2166 to us. */
2167 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2168 {
2169 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2170 if (find_label_entry (labels, label))
2171 prev = gsi_stmt (*gsi_p);
2172 }
2173 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2174 ;
2175 else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
2176 ;
2177 else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2178 prev = gsi_stmt (*gsi_p);
2179 gsi_next (gsi_p);
2180 }
2181 while (!gsi_end_p (*gsi_p)
2182 /* Stop if we find a case or a user-defined label. */
2183 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2184 || !gimple_has_location (gsi_stmt (*gsi_p))));
2185
2186 if (prev && gimple_has_location (prev))
2187 *prevloc = gimple_location (prev);
2188 return prev;
2189 }
2190
2191 /* Return true if the switch fallthough warning should occur. LABEL is
2192 the label statement that we're falling through to. */
2193
2194 static bool
should_warn_for_implicit_fallthrough(gimple_stmt_iterator * gsi_p,tree label)2195 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2196 {
2197 gimple_stmt_iterator gsi = *gsi_p;
2198
2199 /* Don't warn if the label is marked with a "falls through" comment. */
2200 if (FALLTHROUGH_LABEL_P (label))
2201 return false;
2202
2203 /* Don't warn for non-case labels followed by a statement:
2204 case 0:
2205 foo ();
2206 label:
2207 bar ();
2208 as these are likely intentional. */
2209 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2210 {
2211 tree l;
2212 while (!gsi_end_p (gsi)
2213 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2214 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2215 && !case_label_p (&gimplify_ctxp->case_labels, l))
2216 gsi_next_nondebug (&gsi);
2217 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2218 return false;
2219 }
2220
2221 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2222 immediately breaks. */
2223 gsi = *gsi_p;
2224
2225 /* Skip all immediately following labels. */
2226 while (!gsi_end_p (gsi)
2227 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2228 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2229 gsi_next_nondebug (&gsi);
2230
2231 /* { ... something; default:; } */
2232 if (gsi_end_p (gsi)
2233 /* { ... something; default: break; } or
2234 { ... something; default: goto L; } */
2235 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2236 /* { ... something; default: return; } */
2237 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2238 return false;
2239
2240 return true;
2241 }
2242
2243 /* Callback for walk_gimple_seq. */
2244
2245 static tree
warn_implicit_fallthrough_r(gimple_stmt_iterator * gsi_p,bool * handled_ops_p,struct walk_stmt_info *)2246 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2247 struct walk_stmt_info *)
2248 {
2249 gimple *stmt = gsi_stmt (*gsi_p);
2250
2251 *handled_ops_p = true;
2252 switch (gimple_code (stmt))
2253 {
2254 case GIMPLE_TRY:
2255 case GIMPLE_BIND:
2256 case GIMPLE_CATCH:
2257 case GIMPLE_EH_FILTER:
2258 case GIMPLE_TRANSACTION:
2259 /* Walk the sub-statements. */
2260 *handled_ops_p = false;
2261 break;
2262
2263 /* Find a sequence of form:
2264
2265 GIMPLE_LABEL
2266 [...]
2267 <may fallthru stmt>
2268 GIMPLE_LABEL
2269
2270 and possibly warn. */
2271 case GIMPLE_LABEL:
2272 {
2273 /* Found a label. Skip all immediately following labels. */
2274 while (!gsi_end_p (*gsi_p)
2275 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2276 gsi_next_nondebug (gsi_p);
2277
2278 /* There might be no more statements. */
2279 if (gsi_end_p (*gsi_p))
2280 return integer_zero_node;
2281
2282 /* Vector of labels that fall through. */
2283 auto_vec <struct label_entry> labels;
2284 location_t prevloc;
2285 gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
2286
2287 /* There might be no more statements. */
2288 if (gsi_end_p (*gsi_p))
2289 return integer_zero_node;
2290
2291 gimple *next = gsi_stmt (*gsi_p);
2292 tree label;
2293 /* If what follows is a label, then we may have a fallthrough. */
2294 if (gimple_code (next) == GIMPLE_LABEL
2295 && gimple_has_location (next)
2296 && (label = gimple_label_label (as_a <glabel *> (next)))
2297 && prev != NULL)
2298 {
2299 struct label_entry *l;
2300 bool warned_p = false;
2301 auto_diagnostic_group d;
2302 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2303 /* Quiet. */;
2304 else if (gimple_code (prev) == GIMPLE_LABEL
2305 && (label = gimple_label_label (as_a <glabel *> (prev)))
2306 && (l = find_label_entry (&labels, label)))
2307 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2308 "this statement may fall through");
2309 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2310 /* Try to be clever and don't warn when the statement
2311 can't actually fall through. */
2312 && gimple_stmt_may_fallthru (prev)
2313 && prevloc != UNKNOWN_LOCATION)
2314 warned_p = warning_at (prevloc,
2315 OPT_Wimplicit_fallthrough_,
2316 "this statement may fall through");
2317 if (warned_p)
2318 inform (gimple_location (next), "here");
2319
2320 /* Mark this label as processed so as to prevent multiple
2321 warnings in nested switches. */
2322 FALLTHROUGH_LABEL_P (label) = true;
2323
2324 /* So that next warn_implicit_fallthrough_r will start looking for
2325 a new sequence starting with this label. */
2326 gsi_prev (gsi_p);
2327 }
2328 }
2329 break;
2330 default:
2331 break;
2332 }
2333 return NULL_TREE;
2334 }
2335
2336 /* Warn when a switch case falls through. */
2337
2338 static void
maybe_warn_implicit_fallthrough(gimple_seq seq)2339 maybe_warn_implicit_fallthrough (gimple_seq seq)
2340 {
2341 if (!warn_implicit_fallthrough)
2342 return;
2343
2344 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2345 if (!(lang_GNU_C ()
2346 || lang_GNU_CXX ()
2347 || lang_GNU_OBJC ()))
2348 return;
2349
2350 struct walk_stmt_info wi;
2351 memset (&wi, 0, sizeof (wi));
2352 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2353 }
2354
2355 /* Callback for walk_gimple_seq. */
2356
2357 static tree
expand_FALLTHROUGH_r(gimple_stmt_iterator * gsi_p,bool * handled_ops_p,struct walk_stmt_info * wi)2358 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2359 struct walk_stmt_info *wi)
2360 {
2361 gimple *stmt = gsi_stmt (*gsi_p);
2362
2363 *handled_ops_p = true;
2364 switch (gimple_code (stmt))
2365 {
2366 case GIMPLE_TRY:
2367 case GIMPLE_BIND:
2368 case GIMPLE_CATCH:
2369 case GIMPLE_EH_FILTER:
2370 case GIMPLE_TRANSACTION:
2371 /* Walk the sub-statements. */
2372 *handled_ops_p = false;
2373 break;
2374 case GIMPLE_CALL:
2375 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2376 {
2377 gsi_remove (gsi_p, true);
2378 if (gsi_end_p (*gsi_p))
2379 {
2380 *static_cast<location_t *>(wi->info) = gimple_location (stmt);
2381 return integer_zero_node;
2382 }
2383
2384 bool found = false;
2385 location_t loc = gimple_location (stmt);
2386
2387 gimple_stmt_iterator gsi2 = *gsi_p;
2388 stmt = gsi_stmt (gsi2);
2389 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2390 {
2391 /* Go on until the artificial label. */
2392 tree goto_dest = gimple_goto_dest (stmt);
2393 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2394 {
2395 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2396 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2397 == goto_dest)
2398 break;
2399 }
2400
2401 /* Not found? Stop. */
2402 if (gsi_end_p (gsi2))
2403 break;
2404
2405 /* Look one past it. */
2406 gsi_next (&gsi2);
2407 }
2408
2409 /* We're looking for a case label or default label here. */
2410 while (!gsi_end_p (gsi2))
2411 {
2412 stmt = gsi_stmt (gsi2);
2413 if (gimple_code (stmt) == GIMPLE_LABEL)
2414 {
2415 tree label = gimple_label_label (as_a <glabel *> (stmt));
2416 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2417 {
2418 found = true;
2419 break;
2420 }
2421 }
2422 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2423 ;
2424 else if (!is_gimple_debug (stmt))
2425 /* Anything else is not expected. */
2426 break;
2427 gsi_next (&gsi2);
2428 }
2429 if (!found)
2430 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2431 "a case label or default label");
2432 }
2433 break;
2434 default:
2435 break;
2436 }
2437 return NULL_TREE;
2438 }
2439
2440 /* Expand all FALLTHROUGH () calls in SEQ. */
2441
2442 static void
expand_FALLTHROUGH(gimple_seq * seq_p)2443 expand_FALLTHROUGH (gimple_seq *seq_p)
2444 {
2445 struct walk_stmt_info wi;
2446 location_t loc;
2447 memset (&wi, 0, sizeof (wi));
2448 wi.info = (void *) &loc;
2449 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2450 if (wi.callback_result == integer_zero_node)
2451 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2452 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2453 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2454 "a case label or default label");
2455 }
2456
2457
2458 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2459 branch to. */
2460
2461 static enum gimplify_status
gimplify_switch_expr(tree * expr_p,gimple_seq * pre_p)2462 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2463 {
2464 tree switch_expr = *expr_p;
2465 gimple_seq switch_body_seq = NULL;
2466 enum gimplify_status ret;
2467 tree index_type = TREE_TYPE (switch_expr);
2468 if (index_type == NULL_TREE)
2469 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2470
2471 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2472 fb_rvalue);
2473 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2474 return ret;
2475
2476 if (SWITCH_BODY (switch_expr))
2477 {
2478 vec<tree> labels;
2479 vec<tree> saved_labels;
2480 hash_set<tree> *saved_live_switch_vars = NULL;
2481 tree default_case = NULL_TREE;
2482 gswitch *switch_stmt;
2483
2484 /* Save old labels, get new ones from body, then restore the old
2485 labels. Save all the things from the switch body to append after. */
2486 saved_labels = gimplify_ctxp->case_labels;
2487 gimplify_ctxp->case_labels.create (8);
2488
2489 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2490 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2491 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2492 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2493 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2494 else
2495 gimplify_ctxp->live_switch_vars = NULL;
2496
2497 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2498 gimplify_ctxp->in_switch_expr = true;
2499
2500 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2501
2502 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2503 maybe_warn_switch_unreachable (switch_body_seq);
2504 maybe_warn_implicit_fallthrough (switch_body_seq);
2505 /* Only do this for the outermost GIMPLE_SWITCH. */
2506 if (!gimplify_ctxp->in_switch_expr)
2507 expand_FALLTHROUGH (&switch_body_seq);
2508
2509 labels = gimplify_ctxp->case_labels;
2510 gimplify_ctxp->case_labels = saved_labels;
2511
2512 if (gimplify_ctxp->live_switch_vars)
2513 {
2514 gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
2515 delete gimplify_ctxp->live_switch_vars;
2516 }
2517 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2518
2519 preprocess_case_label_vec_for_gimple (labels, index_type,
2520 &default_case);
2521
2522 bool add_bind = false;
2523 if (!default_case)
2524 {
2525 glabel *new_default;
2526
2527 default_case
2528 = build_case_label (NULL_TREE, NULL_TREE,
2529 create_artificial_label (UNKNOWN_LOCATION));
2530 if (old_in_switch_expr)
2531 {
2532 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2533 add_bind = true;
2534 }
2535 new_default = gimple_build_label (CASE_LABEL (default_case));
2536 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2537 }
2538 else if (old_in_switch_expr)
2539 {
2540 gimple *last = gimple_seq_last_stmt (switch_body_seq);
2541 if (last && gimple_code (last) == GIMPLE_LABEL)
2542 {
2543 tree label = gimple_label_label (as_a <glabel *> (last));
2544 if (SWITCH_BREAK_LABEL_P (label))
2545 add_bind = true;
2546 }
2547 }
2548
2549 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2550 default_case, labels);
2551 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2552 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2553 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2554 so that we can easily find the start and end of the switch
2555 statement. */
2556 if (add_bind)
2557 {
2558 gimple_seq bind_body = NULL;
2559 gimplify_seq_add_stmt (&bind_body, switch_stmt);
2560 gimple_seq_add_seq (&bind_body, switch_body_seq);
2561 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
2562 gimple_set_location (bind, EXPR_LOCATION (switch_expr));
2563 gimplify_seq_add_stmt (pre_p, bind);
2564 }
2565 else
2566 {
2567 gimplify_seq_add_stmt (pre_p, switch_stmt);
2568 gimplify_seq_add_seq (pre_p, switch_body_seq);
2569 }
2570 labels.release ();
2571 }
2572 else
2573 gcc_unreachable ();
2574
2575 return GS_ALL_DONE;
2576 }
2577
2578 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2579
2580 static enum gimplify_status
gimplify_label_expr(tree * expr_p,gimple_seq * pre_p)2581 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2582 {
2583 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2584 == current_function_decl);
2585
2586 tree label = LABEL_EXPR_LABEL (*expr_p);
2587 glabel *label_stmt = gimple_build_label (label);
2588 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2589 gimplify_seq_add_stmt (pre_p, label_stmt);
2590
2591 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2592 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2593 NOT_TAKEN));
2594 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2595 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2596 TAKEN));
2597
2598 return GS_ALL_DONE;
2599 }
2600
2601 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2602
2603 static enum gimplify_status
gimplify_case_label_expr(tree * expr_p,gimple_seq * pre_p)2604 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2605 {
2606 struct gimplify_ctx *ctxp;
2607 glabel *label_stmt;
2608
2609 /* Invalid programs can play Duff's Device type games with, for example,
2610 #pragma omp parallel. At least in the C front end, we don't
2611 detect such invalid branches until after gimplification, in the
2612 diagnose_omp_blocks pass. */
2613 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2614 if (ctxp->case_labels.exists ())
2615 break;
2616
2617 tree label = CASE_LABEL (*expr_p);
2618 label_stmt = gimple_build_label (label);
2619 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2620 ctxp->case_labels.safe_push (*expr_p);
2621 gimplify_seq_add_stmt (pre_p, label_stmt);
2622
2623 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2624 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2625 NOT_TAKEN));
2626 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2627 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2628 TAKEN));
2629
2630 return GS_ALL_DONE;
2631 }
2632
2633 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2634 if necessary. */
2635
2636 tree
build_and_jump(tree * label_p)2637 build_and_jump (tree *label_p)
2638 {
2639 if (label_p == NULL)
2640 /* If there's nowhere to jump, just fall through. */
2641 return NULL_TREE;
2642
2643 if (*label_p == NULL_TREE)
2644 {
2645 tree label = create_artificial_label (UNKNOWN_LOCATION);
2646 *label_p = label;
2647 }
2648
2649 return build1 (GOTO_EXPR, void_type_node, *label_p);
2650 }
2651
2652 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2653 This also involves building a label to jump to and communicating it to
2654 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2655
2656 static enum gimplify_status
gimplify_exit_expr(tree * expr_p)2657 gimplify_exit_expr (tree *expr_p)
2658 {
2659 tree cond = TREE_OPERAND (*expr_p, 0);
2660 tree expr;
2661
2662 expr = build_and_jump (&gimplify_ctxp->exit_label);
2663 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2664 *expr_p = expr;
2665
2666 return GS_OK;
2667 }
2668
2669 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2670 different from its canonical type, wrap the whole thing inside a
2671 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2672 type.
2673
2674 The canonical type of a COMPONENT_REF is the type of the field being
2675 referenced--unless the field is a bit-field which can be read directly
2676 in a smaller mode, in which case the canonical type is the
2677 sign-appropriate type corresponding to that mode. */
2678
2679 static void
canonicalize_component_ref(tree * expr_p)2680 canonicalize_component_ref (tree *expr_p)
2681 {
2682 tree expr = *expr_p;
2683 tree type;
2684
2685 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2686
2687 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2688 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2689 else
2690 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2691
2692 /* One could argue that all the stuff below is not necessary for
2693 the non-bitfield case and declare it a FE error if type
2694 adjustment would be needed. */
2695 if (TREE_TYPE (expr) != type)
2696 {
2697 #ifdef ENABLE_TYPES_CHECKING
2698 tree old_type = TREE_TYPE (expr);
2699 #endif
2700 int type_quals;
2701
2702 /* We need to preserve qualifiers and propagate them from
2703 operand 0. */
2704 type_quals = TYPE_QUALS (type)
2705 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2706 if (TYPE_QUALS (type) != type_quals)
2707 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2708
2709 /* Set the type of the COMPONENT_REF to the underlying type. */
2710 TREE_TYPE (expr) = type;
2711
2712 #ifdef ENABLE_TYPES_CHECKING
2713 /* It is now a FE error, if the conversion from the canonical
2714 type to the original expression type is not useless. */
2715 gcc_assert (useless_type_conversion_p (old_type, type));
2716 #endif
2717 }
2718 }
2719
2720 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2721 to foo, embed that change in the ADDR_EXPR by converting
2722 T array[U];
2723 (T *)&array
2724 ==>
2725 &array[L]
2726 where L is the lower bound. For simplicity, only do this for constant
2727 lower bound.
2728 The constraint is that the type of &array[L] is trivially convertible
2729 to T *. */
2730
2731 static void
canonicalize_addr_expr(tree * expr_p)2732 canonicalize_addr_expr (tree *expr_p)
2733 {
2734 tree expr = *expr_p;
2735 tree addr_expr = TREE_OPERAND (expr, 0);
2736 tree datype, ddatype, pddatype;
2737
2738 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2739 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2740 || TREE_CODE (addr_expr) != ADDR_EXPR)
2741 return;
2742
2743 /* The addr_expr type should be a pointer to an array. */
2744 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2745 if (TREE_CODE (datype) != ARRAY_TYPE)
2746 return;
2747
2748 /* The pointer to element type shall be trivially convertible to
2749 the expression pointer type. */
2750 ddatype = TREE_TYPE (datype);
2751 pddatype = build_pointer_type (ddatype);
2752 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2753 pddatype))
2754 return;
2755
2756 /* The lower bound and element sizes must be constant. */
2757 if (!TYPE_SIZE_UNIT (ddatype)
2758 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2759 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2760 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2761 return;
2762
2763 /* All checks succeeded. Build a new node to merge the cast. */
2764 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2765 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2766 NULL_TREE, NULL_TREE);
2767 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2768
2769 /* We can have stripped a required restrict qualifier above. */
2770 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2771 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2772 }
2773
2774 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2775 underneath as appropriate. */
2776
2777 static enum gimplify_status
gimplify_conversion(tree * expr_p)2778 gimplify_conversion (tree *expr_p)
2779 {
2780 location_t loc = EXPR_LOCATION (*expr_p);
2781 gcc_assert (CONVERT_EXPR_P (*expr_p));
2782
2783 /* Then strip away all but the outermost conversion. */
2784 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
2785
2786 /* And remove the outermost conversion if it's useless. */
2787 if (tree_ssa_useless_type_conversion (*expr_p))
2788 *expr_p = TREE_OPERAND (*expr_p, 0);
2789
2790 /* If we still have a conversion at the toplevel,
2791 then canonicalize some constructs. */
2792 if (CONVERT_EXPR_P (*expr_p))
2793 {
2794 tree sub = TREE_OPERAND (*expr_p, 0);
2795
2796 /* If a NOP conversion is changing the type of a COMPONENT_REF
2797 expression, then canonicalize its type now in order to expose more
2798 redundant conversions. */
2799 if (TREE_CODE (sub) == COMPONENT_REF)
2800 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
2801
2802 /* If a NOP conversion is changing a pointer to array of foo
2803 to a pointer to foo, embed that change in the ADDR_EXPR. */
2804 else if (TREE_CODE (sub) == ADDR_EXPR)
2805 canonicalize_addr_expr (expr_p);
2806 }
2807
2808 /* If we have a conversion to a non-register type force the
2809 use of a VIEW_CONVERT_EXPR instead. */
2810 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
2811 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
2812 TREE_OPERAND (*expr_p, 0));
2813
2814 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2815 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
2816 TREE_SET_CODE (*expr_p, NOP_EXPR);
2817
2818 return GS_OK;
2819 }
2820
2821 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2822 DECL_VALUE_EXPR, and it's worth re-examining things. */
2823
2824 static enum gimplify_status
gimplify_var_or_parm_decl(tree * expr_p)2825 gimplify_var_or_parm_decl (tree *expr_p)
2826 {
2827 tree decl = *expr_p;
2828
2829 /* ??? If this is a local variable, and it has not been seen in any
2830 outer BIND_EXPR, then it's probably the result of a duplicate
2831 declaration, for which we've already issued an error. It would
2832 be really nice if the front end wouldn't leak these at all.
2833 Currently the only known culprit is C++ destructors, as seen
2834 in g++.old-deja/g++.jason/binding.C. */
2835 if (VAR_P (decl)
2836 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
2837 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
2838 && decl_function_context (decl) == current_function_decl)
2839 {
2840 gcc_assert (seen_error ());
2841 return GS_ERROR;
2842 }
2843
2844 /* When within an OMP context, notice uses of variables. */
2845 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
2846 return GS_ALL_DONE;
2847
2848 /* If the decl is an alias for another expression, substitute it now. */
2849 if (DECL_HAS_VALUE_EXPR_P (decl))
2850 {
2851 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
2852 return GS_OK;
2853 }
2854
2855 return GS_ALL_DONE;
2856 }
2857
2858 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2859
2860 static void
recalculate_side_effects(tree t)2861 recalculate_side_effects (tree t)
2862 {
2863 enum tree_code code = TREE_CODE (t);
2864 int len = TREE_OPERAND_LENGTH (t);
2865 int i;
2866
2867 switch (TREE_CODE_CLASS (code))
2868 {
2869 case tcc_expression:
2870 switch (code)
2871 {
2872 case INIT_EXPR:
2873 case MODIFY_EXPR:
2874 case VA_ARG_EXPR:
2875 case PREDECREMENT_EXPR:
2876 case PREINCREMENT_EXPR:
2877 case POSTDECREMENT_EXPR:
2878 case POSTINCREMENT_EXPR:
2879 /* All of these have side-effects, no matter what their
2880 operands are. */
2881 return;
2882
2883 default:
2884 break;
2885 }
2886 /* Fall through. */
2887
2888 case tcc_comparison: /* a comparison expression */
2889 case tcc_unary: /* a unary arithmetic expression */
2890 case tcc_binary: /* a binary arithmetic expression */
2891 case tcc_reference: /* a reference */
2892 case tcc_vl_exp: /* a function call */
2893 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
2894 for (i = 0; i < len; ++i)
2895 {
2896 tree op = TREE_OPERAND (t, i);
2897 if (op && TREE_SIDE_EFFECTS (op))
2898 TREE_SIDE_EFFECTS (t) = 1;
2899 }
2900 break;
2901
2902 case tcc_constant:
2903 /* No side-effects. */
2904 return;
2905
2906 default:
2907 gcc_unreachable ();
2908 }
2909 }
2910
2911 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
2912 node *EXPR_P.
2913
2914 compound_lval
2915 : min_lval '[' val ']'
2916 | min_lval '.' ID
2917 | compound_lval '[' val ']'
2918 | compound_lval '.' ID
2919
2920 This is not part of the original SIMPLE definition, which separates
2921 array and member references, but it seems reasonable to handle them
2922 together. Also, this way we don't run into problems with union
2923 aliasing; gcc requires that for accesses through a union to alias, the
2924 union reference must be explicit, which was not always the case when we
2925 were splitting up array and member refs.
2926
2927 PRE_P points to the sequence where side effects that must happen before
2928 *EXPR_P should be stored.
2929
2930 POST_P points to the sequence where side effects that must happen after
2931 *EXPR_P should be stored. */
2932
2933 static enum gimplify_status
gimplify_compound_lval(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p,fallback_t fallback)2934 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2935 fallback_t fallback)
2936 {
2937 tree *p;
2938 enum gimplify_status ret = GS_ALL_DONE, tret;
2939 int i;
2940 location_t loc = EXPR_LOCATION (*expr_p);
2941 tree expr = *expr_p;
2942
2943 /* Create a stack of the subexpressions so later we can walk them in
2944 order from inner to outer. */
2945 auto_vec<tree, 10> expr_stack;
2946
2947 /* We can handle anything that get_inner_reference can deal with. */
2948 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
2949 {
2950 restart:
2951 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
2952 if (TREE_CODE (*p) == INDIRECT_REF)
2953 *p = fold_indirect_ref_loc (loc, *p);
2954
2955 if (handled_component_p (*p))
2956 ;
2957 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
2958 additional COMPONENT_REFs. */
2959 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
2960 && gimplify_var_or_parm_decl (p) == GS_OK)
2961 goto restart;
2962 else
2963 break;
2964
2965 expr_stack.safe_push (*p);
2966 }
2967
2968 gcc_assert (expr_stack.length ());
2969
2970 /* Now EXPR_STACK is a stack of pointers to all the refs we've
2971 walked through and P points to the innermost expression.
2972
2973 Java requires that we elaborated nodes in source order. That
2974 means we must gimplify the inner expression followed by each of
2975 the indices, in order. But we can't gimplify the inner
2976 expression until we deal with any variable bounds, sizes, or
2977 positions in order to deal with PLACEHOLDER_EXPRs.
2978
2979 So we do this in three steps. First we deal with the annotations
2980 for any variables in the components, then we gimplify the base,
2981 then we gimplify any indices, from left to right. */
2982 for (i = expr_stack.length () - 1; i >= 0; i--)
2983 {
2984 tree t = expr_stack[i];
2985
2986 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2987 {
2988 /* Gimplify the low bound and element type size and put them into
2989 the ARRAY_REF. If these values are set, they have already been
2990 gimplified. */
2991 if (TREE_OPERAND (t, 2) == NULL_TREE)
2992 {
2993 tree low = unshare_expr (array_ref_low_bound (t));
2994 if (!is_gimple_min_invariant (low))
2995 {
2996 TREE_OPERAND (t, 2) = low;
2997 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2998 post_p, is_gimple_reg,
2999 fb_rvalue);
3000 ret = MIN (ret, tret);
3001 }
3002 }
3003 else
3004 {
3005 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3006 is_gimple_reg, fb_rvalue);
3007 ret = MIN (ret, tret);
3008 }
3009
3010 if (TREE_OPERAND (t, 3) == NULL_TREE)
3011 {
3012 tree elmt_size = array_ref_element_size (t);
3013 if (!is_gimple_min_invariant (elmt_size))
3014 {
3015 elmt_size = unshare_expr (elmt_size);
3016 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
3017 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
3018
3019 /* Divide the element size by the alignment of the element
3020 type (above). */
3021 elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR,
3022 elmt_size, factor);
3023
3024 TREE_OPERAND (t, 3) = elmt_size;
3025 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
3026 post_p, is_gimple_reg,
3027 fb_rvalue);
3028 ret = MIN (ret, tret);
3029 }
3030 }
3031 else
3032 {
3033 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
3034 is_gimple_reg, fb_rvalue);
3035 ret = MIN (ret, tret);
3036 }
3037 }
3038 else if (TREE_CODE (t) == COMPONENT_REF)
3039 {
3040 /* Set the field offset into T and gimplify it. */
3041 if (TREE_OPERAND (t, 2) == NULL_TREE)
3042 {
3043 tree offset = component_ref_field_offset (t);
3044 if (!is_gimple_min_invariant (offset))
3045 {
3046 offset = unshare_expr (offset);
3047 tree field = TREE_OPERAND (t, 1);
3048 tree factor
3049 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
3050
3051 /* Divide the offset by its alignment. */
3052 offset = size_binop_loc (loc, EXACT_DIV_EXPR,
3053 offset, factor);
3054
3055 TREE_OPERAND (t, 2) = offset;
3056 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
3057 post_p, is_gimple_reg,
3058 fb_rvalue);
3059 ret = MIN (ret, tret);
3060 }
3061 }
3062 else
3063 {
3064 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3065 is_gimple_reg, fb_rvalue);
3066 ret = MIN (ret, tret);
3067 }
3068 }
3069 }
3070
3071 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3072 so as to match the min_lval predicate. Failure to do so may result
3073 in the creation of large aggregate temporaries. */
3074 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
3075 fallback | fb_lvalue);
3076 ret = MIN (ret, tret);
3077
3078 /* And finally, the indices and operands of ARRAY_REF. During this
3079 loop we also remove any useless conversions. */
3080 for (; expr_stack.length () > 0; )
3081 {
3082 tree t = expr_stack.pop ();
3083
3084 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3085 {
3086 /* Gimplify the dimension. */
3087 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
3088 {
3089 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
3090 is_gimple_val, fb_rvalue);
3091 ret = MIN (ret, tret);
3092 }
3093 }
3094
3095 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
3096
3097 /* The innermost expression P may have originally had
3098 TREE_SIDE_EFFECTS set which would have caused all the outer
3099 expressions in *EXPR_P leading to P to also have had
3100 TREE_SIDE_EFFECTS set. */
3101 recalculate_side_effects (t);
3102 }
3103
3104 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3105 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
3106 {
3107 canonicalize_component_ref (expr_p);
3108 }
3109
3110 expr_stack.release ();
3111
3112 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
3113
3114 return ret;
3115 }
3116
3117 /* Gimplify the self modifying expression pointed to by EXPR_P
3118 (++, --, +=, -=).
3119
3120 PRE_P points to the list where side effects that must happen before
3121 *EXPR_P should be stored.
3122
3123 POST_P points to the list where side effects that must happen after
3124 *EXPR_P should be stored.
3125
3126 WANT_VALUE is nonzero iff we want to use the value of this expression
3127 in another expression.
3128
3129 ARITH_TYPE is the type the computation should be performed in. */
3130
3131 enum gimplify_status
gimplify_self_mod_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p,bool want_value,tree arith_type)3132 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3133 bool want_value, tree arith_type)
3134 {
3135 enum tree_code code;
3136 tree lhs, lvalue, rhs, t1;
3137 gimple_seq post = NULL, *orig_post_p = post_p;
3138 bool postfix;
3139 enum tree_code arith_code;
3140 enum gimplify_status ret;
3141 location_t loc = EXPR_LOCATION (*expr_p);
3142
3143 code = TREE_CODE (*expr_p);
3144
3145 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3146 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3147
3148 /* Prefix or postfix? */
3149 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3150 /* Faster to treat as prefix if result is not used. */
3151 postfix = want_value;
3152 else
3153 postfix = false;
3154
3155 /* For postfix, make sure the inner expression's post side effects
3156 are executed after side effects from this expression. */
3157 if (postfix)
3158 post_p = &post;
3159
3160 /* Add or subtract? */
3161 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3162 arith_code = PLUS_EXPR;
3163 else
3164 arith_code = MINUS_EXPR;
3165
3166 /* Gimplify the LHS into a GIMPLE lvalue. */
3167 lvalue = TREE_OPERAND (*expr_p, 0);
3168 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3169 if (ret == GS_ERROR)
3170 return ret;
3171
3172 /* Extract the operands to the arithmetic operation. */
3173 lhs = lvalue;
3174 rhs = TREE_OPERAND (*expr_p, 1);
3175
3176 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3177 that as the result value and in the postqueue operation. */
3178 if (postfix)
3179 {
3180 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3181 if (ret == GS_ERROR)
3182 return ret;
3183
3184 lhs = get_initialized_tmp_var (lhs, pre_p);
3185 }
3186
3187 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3188 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3189 {
3190 rhs = convert_to_ptrofftype_loc (loc, rhs);
3191 if (arith_code == MINUS_EXPR)
3192 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3193 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3194 }
3195 else
3196 t1 = fold_convert (TREE_TYPE (*expr_p),
3197 fold_build2 (arith_code, arith_type,
3198 fold_convert (arith_type, lhs),
3199 fold_convert (arith_type, rhs)));
3200
3201 if (postfix)
3202 {
3203 gimplify_assign (lvalue, t1, pre_p);
3204 gimplify_seq_add_seq (orig_post_p, post);
3205 *expr_p = lhs;
3206 return GS_ALL_DONE;
3207 }
3208 else
3209 {
3210 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3211 return GS_OK;
3212 }
3213 }
3214
3215 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3216
3217 static void
maybe_with_size_expr(tree * expr_p)3218 maybe_with_size_expr (tree *expr_p)
3219 {
3220 tree expr = *expr_p;
3221 tree type = TREE_TYPE (expr);
3222 tree size;
3223
3224 /* If we've already wrapped this or the type is error_mark_node, we can't do
3225 anything. */
3226 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3227 || type == error_mark_node)
3228 return;
3229
3230 /* If the size isn't known or is a constant, we have nothing to do. */
3231 size = TYPE_SIZE_UNIT (type);
3232 if (!size || poly_int_tree_p (size))
3233 return;
3234
3235 /* Otherwise, make a WITH_SIZE_EXPR. */
3236 size = unshare_expr (size);
3237 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3238 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3239 }
3240
3241 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3242 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3243 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3244 gimplified to an SSA name. */
3245
3246 enum gimplify_status
gimplify_arg(tree * arg_p,gimple_seq * pre_p,location_t call_location,bool allow_ssa)3247 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3248 bool allow_ssa)
3249 {
3250 bool (*test) (tree);
3251 fallback_t fb;
3252
3253 /* In general, we allow lvalues for function arguments to avoid
3254 extra overhead of copying large aggregates out of even larger
3255 aggregates into temporaries only to copy the temporaries to
3256 the argument list. Make optimizers happy by pulling out to
3257 temporaries those types that fit in registers. */
3258 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3259 test = is_gimple_val, fb = fb_rvalue;
3260 else
3261 {
3262 test = is_gimple_lvalue, fb = fb_either;
3263 /* Also strip a TARGET_EXPR that would force an extra copy. */
3264 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3265 {
3266 tree init = TARGET_EXPR_INITIAL (*arg_p);
3267 if (init
3268 && !VOID_TYPE_P (TREE_TYPE (init)))
3269 *arg_p = init;
3270 }
3271 }
3272
3273 /* If this is a variable sized type, we must remember the size. */
3274 maybe_with_size_expr (arg_p);
3275
3276 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3277 /* Make sure arguments have the same location as the function call
3278 itself. */
3279 protected_set_expr_location (*arg_p, call_location);
3280
3281 /* There is a sequence point before a function call. Side effects in
3282 the argument list must occur before the actual call. So, when
3283 gimplifying arguments, force gimplify_expr to use an internal
3284 post queue which is then appended to the end of PRE_P. */
3285 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3286 }
3287
3288 /* Don't fold inside offloading or taskreg regions: it can break code by
3289 adding decl references that weren't in the source. We'll do it during
3290 omplower pass instead. */
3291
3292 static bool
maybe_fold_stmt(gimple_stmt_iterator * gsi)3293 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3294 {
3295 struct gimplify_omp_ctx *ctx;
3296 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3297 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3298 return false;
3299 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3300 return false;
3301 /* Delay folding of builtins until the IL is in consistent state
3302 so the diagnostic machinery can do a better job. */
3303 if (gimple_call_builtin_p (gsi_stmt (*gsi)))
3304 return false;
3305 return fold_stmt (gsi);
3306 }
3307
3308 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3309 WANT_VALUE is true if the result of the call is desired. */
3310
3311 static enum gimplify_status
gimplify_call_expr(tree * expr_p,gimple_seq * pre_p,bool want_value)3312 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3313 {
3314 tree fndecl, parms, p, fnptrtype;
3315 enum gimplify_status ret;
3316 int i, nargs;
3317 gcall *call;
3318 bool builtin_va_start_p = false;
3319 location_t loc = EXPR_LOCATION (*expr_p);
3320
3321 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3322
3323 /* For reliable diagnostics during inlining, it is necessary that
3324 every call_expr be annotated with file and line. */
3325 if (! EXPR_HAS_LOCATION (*expr_p))
3326 SET_EXPR_LOCATION (*expr_p, input_location);
3327
3328 /* Gimplify internal functions created in the FEs. */
3329 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3330 {
3331 if (want_value)
3332 return GS_ALL_DONE;
3333
3334 nargs = call_expr_nargs (*expr_p);
3335 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3336 auto_vec<tree> vargs (nargs);
3337
3338 for (i = 0; i < nargs; i++)
3339 {
3340 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3341 EXPR_LOCATION (*expr_p));
3342 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3343 }
3344
3345 gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3346 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3347 gimplify_seq_add_stmt (pre_p, call);
3348 return GS_ALL_DONE;
3349 }
3350
3351 /* This may be a call to a builtin function.
3352
3353 Builtin function calls may be transformed into different
3354 (and more efficient) builtin function calls under certain
3355 circumstances. Unfortunately, gimplification can muck things
3356 up enough that the builtin expanders are not aware that certain
3357 transformations are still valid.
3358
3359 So we attempt transformation/gimplification of the call before
3360 we gimplify the CALL_EXPR. At this time we do not manage to
3361 transform all calls in the same manner as the expanders do, but
3362 we do transform most of them. */
3363 fndecl = get_callee_fndecl (*expr_p);
3364 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3365 switch (DECL_FUNCTION_CODE (fndecl))
3366 {
3367 CASE_BUILT_IN_ALLOCA:
3368 /* If the call has been built for a variable-sized object, then we
3369 want to restore the stack level when the enclosing BIND_EXPR is
3370 exited to reclaim the allocated space; otherwise, we precisely
3371 need to do the opposite and preserve the latest stack level. */
3372 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3373 gimplify_ctxp->save_stack = true;
3374 else
3375 gimplify_ctxp->keep_stack = true;
3376 break;
3377
3378 case BUILT_IN_VA_START:
3379 {
3380 builtin_va_start_p = TRUE;
3381 if (call_expr_nargs (*expr_p) < 2)
3382 {
3383 error ("too few arguments to function %<va_start%>");
3384 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3385 return GS_OK;
3386 }
3387
3388 if (fold_builtin_next_arg (*expr_p, true))
3389 {
3390 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3391 return GS_OK;
3392 }
3393 break;
3394 }
3395
3396 case BUILT_IN_EH_RETURN:
3397 cfun->calls_eh_return = true;
3398 break;
3399
3400 case BUILT_IN_CLEAR_PADDING:
3401 if (call_expr_nargs (*expr_p) == 1)
3402 {
3403 /* Remember the original type of the argument in an internal
3404 dummy second argument, as in GIMPLE pointer conversions are
3405 useless. */
3406 p = CALL_EXPR_ARG (*expr_p, 0);
3407 *expr_p
3408 = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p,
3409 build_zero_cst (TREE_TYPE (p)));
3410 return GS_OK;
3411 }
3412 break;
3413
3414 default:
3415 ;
3416 }
3417 if (fndecl && fndecl_built_in_p (fndecl))
3418 {
3419 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3420 if (new_tree && new_tree != *expr_p)
3421 {
3422 /* There was a transformation of this call which computes the
3423 same value, but in a more efficient way. Return and try
3424 again. */
3425 *expr_p = new_tree;
3426 return GS_OK;
3427 }
3428 }
3429
3430 /* Remember the original function pointer type. */
3431 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3432
3433 if (flag_openmp
3434 && fndecl
3435 && cfun
3436 && (cfun->curr_properties & PROP_gimple_any) == 0)
3437 {
3438 tree variant = omp_resolve_declare_variant (fndecl);
3439 if (variant != fndecl)
3440 CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
3441 }
3442
3443 /* There is a sequence point before the call, so any side effects in
3444 the calling expression must occur before the actual call. Force
3445 gimplify_expr to use an internal post queue. */
3446 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3447 is_gimple_call_addr, fb_rvalue);
3448
3449 nargs = call_expr_nargs (*expr_p);
3450
3451 /* Get argument types for verification. */
3452 fndecl = get_callee_fndecl (*expr_p);
3453 parms = NULL_TREE;
3454 if (fndecl)
3455 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3456 else
3457 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3458
3459 if (fndecl && DECL_ARGUMENTS (fndecl))
3460 p = DECL_ARGUMENTS (fndecl);
3461 else if (parms)
3462 p = parms;
3463 else
3464 p = NULL_TREE;
3465 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3466 ;
3467
3468 /* If the last argument is __builtin_va_arg_pack () and it is not
3469 passed as a named argument, decrease the number of CALL_EXPR
3470 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3471 if (!p
3472 && i < nargs
3473 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3474 {
3475 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3476 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3477
3478 if (last_arg_fndecl
3479 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3480 {
3481 tree call = *expr_p;
3482
3483 --nargs;
3484 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3485 CALL_EXPR_FN (call),
3486 nargs, CALL_EXPR_ARGP (call));
3487
3488 /* Copy all CALL_EXPR flags, location and block, except
3489 CALL_EXPR_VA_ARG_PACK flag. */
3490 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3491 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3492 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3493 = CALL_EXPR_RETURN_SLOT_OPT (call);
3494 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3495 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3496
3497 /* Set CALL_EXPR_VA_ARG_PACK. */
3498 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3499 }
3500 }
3501
3502 /* If the call returns twice then after building the CFG the call
3503 argument computations will no longer dominate the call because
3504 we add an abnormal incoming edge to the call. So do not use SSA
3505 vars there. */
3506 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3507
3508 /* Gimplify the function arguments. */
3509 if (nargs > 0)
3510 {
3511 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3512 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3513 PUSH_ARGS_REVERSED ? i-- : i++)
3514 {
3515 enum gimplify_status t;
3516
3517 /* Avoid gimplifying the second argument to va_start, which needs to
3518 be the plain PARM_DECL. */
3519 if ((i != 1) || !builtin_va_start_p)
3520 {
3521 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3522 EXPR_LOCATION (*expr_p), ! returns_twice);
3523
3524 if (t == GS_ERROR)
3525 ret = GS_ERROR;
3526 }
3527 }
3528 }
3529
3530 /* Gimplify the static chain. */
3531 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3532 {
3533 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3534 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3535 else
3536 {
3537 enum gimplify_status t;
3538 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3539 EXPR_LOCATION (*expr_p), ! returns_twice);
3540 if (t == GS_ERROR)
3541 ret = GS_ERROR;
3542 }
3543 }
3544
3545 /* Verify the function result. */
3546 if (want_value && fndecl
3547 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3548 {
3549 error_at (loc, "using result of function returning %<void%>");
3550 ret = GS_ERROR;
3551 }
3552
3553 /* Try this again in case gimplification exposed something. */
3554 if (ret != GS_ERROR)
3555 {
3556 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3557
3558 if (new_tree && new_tree != *expr_p)
3559 {
3560 /* There was a transformation of this call which computes the
3561 same value, but in a more efficient way. Return and try
3562 again. */
3563 *expr_p = new_tree;
3564 return GS_OK;
3565 }
3566 }
3567 else
3568 {
3569 *expr_p = error_mark_node;
3570 return GS_ERROR;
3571 }
3572
3573 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3574 decl. This allows us to eliminate redundant or useless
3575 calls to "const" functions. */
3576 if (TREE_CODE (*expr_p) == CALL_EXPR)
3577 {
3578 int flags = call_expr_flags (*expr_p);
3579 if (flags & (ECF_CONST | ECF_PURE)
3580 /* An infinite loop is considered a side effect. */
3581 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3582 TREE_SIDE_EFFECTS (*expr_p) = 0;
3583 }
3584
3585 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3586 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3587 form and delegate the creation of a GIMPLE_CALL to
3588 gimplify_modify_expr. This is always possible because when
3589 WANT_VALUE is true, the caller wants the result of this call into
3590 a temporary, which means that we will emit an INIT_EXPR in
3591 internal_get_tmp_var which will then be handled by
3592 gimplify_modify_expr. */
3593 if (!want_value)
3594 {
3595 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3596 have to do is replicate it as a GIMPLE_CALL tuple. */
3597 gimple_stmt_iterator gsi;
3598 call = gimple_build_call_from_tree (*expr_p, fnptrtype);
3599 notice_special_calls (call);
3600 gimplify_seq_add_stmt (pre_p, call);
3601 gsi = gsi_last (*pre_p);
3602 maybe_fold_stmt (&gsi);
3603 *expr_p = NULL_TREE;
3604 }
3605 else
3606 /* Remember the original function type. */
3607 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3608 CALL_EXPR_FN (*expr_p));
3609
3610 return ret;
3611 }
3612
3613 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3614 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3615
3616 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3617 condition is true or false, respectively. If null, we should generate
3618 our own to skip over the evaluation of this specific expression.
3619
3620 LOCUS is the source location of the COND_EXPR.
3621
3622 This function is the tree equivalent of do_jump.
3623
3624 shortcut_cond_r should only be called by shortcut_cond_expr. */
3625
3626 static tree
shortcut_cond_r(tree pred,tree * true_label_p,tree * false_label_p,location_t locus)3627 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3628 location_t locus)
3629 {
3630 tree local_label = NULL_TREE;
3631 tree t, expr = NULL;
3632
3633 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3634 retain the shortcut semantics. Just insert the gotos here;
3635 shortcut_cond_expr will append the real blocks later. */
3636 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3637 {
3638 location_t new_locus;
3639
3640 /* Turn if (a && b) into
3641
3642 if (a); else goto no;
3643 if (b) goto yes; else goto no;
3644 (no:) */
3645
3646 if (false_label_p == NULL)
3647 false_label_p = &local_label;
3648
3649 /* Keep the original source location on the first 'if'. */
3650 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3651 append_to_statement_list (t, &expr);
3652
3653 /* Set the source location of the && on the second 'if'. */
3654 new_locus = rexpr_location (pred, locus);
3655 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3656 new_locus);
3657 append_to_statement_list (t, &expr);
3658 }
3659 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3660 {
3661 location_t new_locus;
3662
3663 /* Turn if (a || b) into
3664
3665 if (a) goto yes;
3666 if (b) goto yes; else goto no;
3667 (yes:) */
3668
3669 if (true_label_p == NULL)
3670 true_label_p = &local_label;
3671
3672 /* Keep the original source location on the first 'if'. */
3673 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3674 append_to_statement_list (t, &expr);
3675
3676 /* Set the source location of the || on the second 'if'. */
3677 new_locus = rexpr_location (pred, locus);
3678 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3679 new_locus);
3680 append_to_statement_list (t, &expr);
3681 }
3682 else if (TREE_CODE (pred) == COND_EXPR
3683 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3684 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3685 {
3686 location_t new_locus;
3687
3688 /* As long as we're messing with gotos, turn if (a ? b : c) into
3689 if (a)
3690 if (b) goto yes; else goto no;
3691 else
3692 if (c) goto yes; else goto no;
3693
3694 Don't do this if one of the arms has void type, which can happen
3695 in C++ when the arm is throw. */
3696
3697 /* Keep the original source location on the first 'if'. Set the source
3698 location of the ? on the second 'if'. */
3699 new_locus = rexpr_location (pred, locus);
3700 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3701 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3702 false_label_p, locus),
3703 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3704 false_label_p, new_locus));
3705 }
3706 else
3707 {
3708 expr = build3 (COND_EXPR, void_type_node, pred,
3709 build_and_jump (true_label_p),
3710 build_and_jump (false_label_p));
3711 SET_EXPR_LOCATION (expr, locus);
3712 }
3713
3714 if (local_label)
3715 {
3716 t = build1 (LABEL_EXPR, void_type_node, local_label);
3717 append_to_statement_list (t, &expr);
3718 }
3719
3720 return expr;
3721 }
3722
3723 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3724 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3725 statement, if it is the last one. Otherwise, return NULL. */
3726
3727 static tree
find_goto(tree expr)3728 find_goto (tree expr)
3729 {
3730 if (!expr)
3731 return NULL_TREE;
3732
3733 if (TREE_CODE (expr) == GOTO_EXPR)
3734 return expr;
3735
3736 if (TREE_CODE (expr) != STATEMENT_LIST)
3737 return NULL_TREE;
3738
3739 tree_stmt_iterator i = tsi_start (expr);
3740
3741 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
3742 tsi_next (&i);
3743
3744 if (!tsi_one_before_end_p (i))
3745 return NULL_TREE;
3746
3747 return find_goto (tsi_stmt (i));
3748 }
3749
3750 /* Same as find_goto, except that it returns NULL if the destination
3751 is not a LABEL_DECL. */
3752
3753 static inline tree
find_goto_label(tree expr)3754 find_goto_label (tree expr)
3755 {
3756 tree dest = find_goto (expr);
3757 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
3758 return dest;
3759 return NULL_TREE;
3760 }
3761
3762 /* Given a conditional expression EXPR with short-circuit boolean
3763 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3764 predicate apart into the equivalent sequence of conditionals. */
3765
3766 static tree
shortcut_cond_expr(tree expr)3767 shortcut_cond_expr (tree expr)
3768 {
3769 tree pred = TREE_OPERAND (expr, 0);
3770 tree then_ = TREE_OPERAND (expr, 1);
3771 tree else_ = TREE_OPERAND (expr, 2);
3772 tree true_label, false_label, end_label, t;
3773 tree *true_label_p;
3774 tree *false_label_p;
3775 bool emit_end, emit_false, jump_over_else;
3776 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3777 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3778
3779 /* First do simple transformations. */
3780 if (!else_se)
3781 {
3782 /* If there is no 'else', turn
3783 if (a && b) then c
3784 into
3785 if (a) if (b) then c. */
3786 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3787 {
3788 /* Keep the original source location on the first 'if'. */
3789 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3790 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3791 /* Set the source location of the && on the second 'if'. */
3792 if (rexpr_has_location (pred))
3793 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3794 then_ = shortcut_cond_expr (expr);
3795 then_se = then_ && TREE_SIDE_EFFECTS (then_);
3796 pred = TREE_OPERAND (pred, 0);
3797 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
3798 SET_EXPR_LOCATION (expr, locus);
3799 }
3800 }
3801
3802 if (!then_se)
3803 {
3804 /* If there is no 'then', turn
3805 if (a || b); else d
3806 into
3807 if (a); else if (b); else d. */
3808 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3809 {
3810 /* Keep the original source location on the first 'if'. */
3811 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3812 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3813 /* Set the source location of the || on the second 'if'. */
3814 if (rexpr_has_location (pred))
3815 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3816 else_ = shortcut_cond_expr (expr);
3817 else_se = else_ && TREE_SIDE_EFFECTS (else_);
3818 pred = TREE_OPERAND (pred, 0);
3819 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
3820 SET_EXPR_LOCATION (expr, locus);
3821 }
3822 }
3823
3824 /* If we're done, great. */
3825 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
3826 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
3827 return expr;
3828
3829 /* Otherwise we need to mess with gotos. Change
3830 if (a) c; else d;
3831 to
3832 if (a); else goto no;
3833 c; goto end;
3834 no: d; end:
3835 and recursively gimplify the condition. */
3836
3837 true_label = false_label = end_label = NULL_TREE;
3838
3839 /* If our arms just jump somewhere, hijack those labels so we don't
3840 generate jumps to jumps. */
3841
3842 if (tree then_goto = find_goto_label (then_))
3843 {
3844 true_label = GOTO_DESTINATION (then_goto);
3845 then_ = NULL;
3846 then_se = false;
3847 }
3848
3849 if (tree else_goto = find_goto_label (else_))
3850 {
3851 false_label = GOTO_DESTINATION (else_goto);
3852 else_ = NULL;
3853 else_se = false;
3854 }
3855
3856 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3857 if (true_label)
3858 true_label_p = &true_label;
3859 else
3860 true_label_p = NULL;
3861
3862 /* The 'else' branch also needs a label if it contains interesting code. */
3863 if (false_label || else_se)
3864 false_label_p = &false_label;
3865 else
3866 false_label_p = NULL;
3867
3868 /* If there was nothing else in our arms, just forward the label(s). */
3869 if (!then_se && !else_se)
3870 return shortcut_cond_r (pred, true_label_p, false_label_p,
3871 EXPR_LOC_OR_LOC (expr, input_location));
3872
3873 /* If our last subexpression already has a terminal label, reuse it. */
3874 if (else_se)
3875 t = expr_last (else_);
3876 else if (then_se)
3877 t = expr_last (then_);
3878 else
3879 t = NULL;
3880 if (t && TREE_CODE (t) == LABEL_EXPR)
3881 end_label = LABEL_EXPR_LABEL (t);
3882
3883 /* If we don't care about jumping to the 'else' branch, jump to the end
3884 if the condition is false. */
3885 if (!false_label_p)
3886 false_label_p = &end_label;
3887
3888 /* We only want to emit these labels if we aren't hijacking them. */
3889 emit_end = (end_label == NULL_TREE);
3890 emit_false = (false_label == NULL_TREE);
3891
3892 /* We only emit the jump over the else clause if we have to--if the
3893 then clause may fall through. Otherwise we can wind up with a
3894 useless jump and a useless label at the end of gimplified code,
3895 which will cause us to think that this conditional as a whole
3896 falls through even if it doesn't. If we then inline a function
3897 which ends with such a condition, that can cause us to issue an
3898 inappropriate warning about control reaching the end of a
3899 non-void function. */
3900 jump_over_else = block_may_fallthru (then_);
3901
3902 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
3903 EXPR_LOC_OR_LOC (expr, input_location));
3904
3905 expr = NULL;
3906 append_to_statement_list (pred, &expr);
3907
3908 append_to_statement_list (then_, &expr);
3909 if (else_se)
3910 {
3911 if (jump_over_else)
3912 {
3913 tree last = expr_last (expr);
3914 t = build_and_jump (&end_label);
3915 if (rexpr_has_location (last))
3916 SET_EXPR_LOCATION (t, rexpr_location (last));
3917 append_to_statement_list (t, &expr);
3918 }
3919 if (emit_false)
3920 {
3921 t = build1 (LABEL_EXPR, void_type_node, false_label);
3922 append_to_statement_list (t, &expr);
3923 }
3924 append_to_statement_list (else_, &expr);
3925 }
3926 if (emit_end && end_label)
3927 {
3928 t = build1 (LABEL_EXPR, void_type_node, end_label);
3929 append_to_statement_list (t, &expr);
3930 }
3931
3932 return expr;
3933 }
3934
3935 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
3936
3937 tree
gimple_boolify(tree expr)3938 gimple_boolify (tree expr)
3939 {
3940 tree type = TREE_TYPE (expr);
3941 location_t loc = EXPR_LOCATION (expr);
3942
3943 if (TREE_CODE (expr) == NE_EXPR
3944 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
3945 && integer_zerop (TREE_OPERAND (expr, 1)))
3946 {
3947 tree call = TREE_OPERAND (expr, 0);
3948 tree fn = get_callee_fndecl (call);
3949
3950 /* For __builtin_expect ((long) (x), y) recurse into x as well
3951 if x is truth_value_p. */
3952 if (fn
3953 && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
3954 && call_expr_nargs (call) == 2)
3955 {
3956 tree arg = CALL_EXPR_ARG (call, 0);
3957 if (arg)
3958 {
3959 if (TREE_CODE (arg) == NOP_EXPR
3960 && TREE_TYPE (arg) == TREE_TYPE (call))
3961 arg = TREE_OPERAND (arg, 0);
3962 if (truth_value_p (TREE_CODE (arg)))
3963 {
3964 arg = gimple_boolify (arg);
3965 CALL_EXPR_ARG (call, 0)
3966 = fold_convert_loc (loc, TREE_TYPE (call), arg);
3967 }
3968 }
3969 }
3970 }
3971
3972 switch (TREE_CODE (expr))
3973 {
3974 case TRUTH_AND_EXPR:
3975 case TRUTH_OR_EXPR:
3976 case TRUTH_XOR_EXPR:
3977 case TRUTH_ANDIF_EXPR:
3978 case TRUTH_ORIF_EXPR:
3979 /* Also boolify the arguments of truth exprs. */
3980 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
3981 /* FALLTHRU */
3982
3983 case TRUTH_NOT_EXPR:
3984 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3985
3986 /* These expressions always produce boolean results. */
3987 if (TREE_CODE (type) != BOOLEAN_TYPE)
3988 TREE_TYPE (expr) = boolean_type_node;
3989 return expr;
3990
3991 case ANNOTATE_EXPR:
3992 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
3993 {
3994 case annot_expr_ivdep_kind:
3995 case annot_expr_unroll_kind:
3996 case annot_expr_no_vector_kind:
3997 case annot_expr_vector_kind:
3998 case annot_expr_parallel_kind:
3999 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4000 if (TREE_CODE (type) != BOOLEAN_TYPE)
4001 TREE_TYPE (expr) = boolean_type_node;
4002 return expr;
4003 default:
4004 gcc_unreachable ();
4005 }
4006
4007 default:
4008 if (COMPARISON_CLASS_P (expr))
4009 {
4010 /* There expressions always prduce boolean results. */
4011 if (TREE_CODE (type) != BOOLEAN_TYPE)
4012 TREE_TYPE (expr) = boolean_type_node;
4013 return expr;
4014 }
4015 /* Other expressions that get here must have boolean values, but
4016 might need to be converted to the appropriate mode. */
4017 if (TREE_CODE (type) == BOOLEAN_TYPE)
4018 return expr;
4019 return fold_convert_loc (loc, boolean_type_node, expr);
4020 }
4021 }
4022
4023 /* Given a conditional expression *EXPR_P without side effects, gimplify
4024 its operands. New statements are inserted to PRE_P. */
4025
4026 static enum gimplify_status
gimplify_pure_cond_expr(tree * expr_p,gimple_seq * pre_p)4027 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
4028 {
4029 tree expr = *expr_p, cond;
4030 enum gimplify_status ret, tret;
4031 enum tree_code code;
4032
4033 cond = gimple_boolify (COND_EXPR_COND (expr));
4034
4035 /* We need to handle && and || specially, as their gimplification
4036 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4037 code = TREE_CODE (cond);
4038 if (code == TRUTH_ANDIF_EXPR)
4039 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
4040 else if (code == TRUTH_ORIF_EXPR)
4041 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
4042 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
4043 COND_EXPR_COND (*expr_p) = cond;
4044
4045 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
4046 is_gimple_val, fb_rvalue);
4047 ret = MIN (ret, tret);
4048 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
4049 is_gimple_val, fb_rvalue);
4050
4051 return MIN (ret, tret);
4052 }
4053
4054 /* Return true if evaluating EXPR could trap.
4055 EXPR is GENERIC, while tree_could_trap_p can be called
4056 only on GIMPLE. */
4057
4058 bool
generic_expr_could_trap_p(tree expr)4059 generic_expr_could_trap_p (tree expr)
4060 {
4061 unsigned i, n;
4062
4063 if (!expr || is_gimple_val (expr))
4064 return false;
4065
4066 if (!EXPR_P (expr) || tree_could_trap_p (expr))
4067 return true;
4068
4069 n = TREE_OPERAND_LENGTH (expr);
4070 for (i = 0; i < n; i++)
4071 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
4072 return true;
4073
4074 return false;
4075 }
4076
4077 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4078 into
4079
4080 if (p) if (p)
4081 t1 = a; a;
4082 else or else
4083 t1 = b; b;
4084 t1;
4085
4086 The second form is used when *EXPR_P is of type void.
4087
4088 PRE_P points to the list where side effects that must happen before
4089 *EXPR_P should be stored. */
4090
4091 static enum gimplify_status
gimplify_cond_expr(tree * expr_p,gimple_seq * pre_p,fallback_t fallback)4092 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
4093 {
4094 tree expr = *expr_p;
4095 tree type = TREE_TYPE (expr);
4096 location_t loc = EXPR_LOCATION (expr);
4097 tree tmp, arm1, arm2;
4098 enum gimplify_status ret;
4099 tree label_true, label_false, label_cont;
4100 bool have_then_clause_p, have_else_clause_p;
4101 gcond *cond_stmt;
4102 enum tree_code pred_code;
4103 gimple_seq seq = NULL;
4104
4105 /* If this COND_EXPR has a value, copy the values into a temporary within
4106 the arms. */
4107 if (!VOID_TYPE_P (type))
4108 {
4109 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
4110 tree result;
4111
4112 /* If either an rvalue is ok or we do not require an lvalue, create the
4113 temporary. But we cannot do that if the type is addressable. */
4114 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
4115 && !TREE_ADDRESSABLE (type))
4116 {
4117 if (gimplify_ctxp->allow_rhs_cond_expr
4118 /* If either branch has side effects or could trap, it can't be
4119 evaluated unconditionally. */
4120 && !TREE_SIDE_EFFECTS (then_)
4121 && !generic_expr_could_trap_p (then_)
4122 && !TREE_SIDE_EFFECTS (else_)
4123 && !generic_expr_could_trap_p (else_))
4124 return gimplify_pure_cond_expr (expr_p, pre_p);
4125
4126 tmp = create_tmp_var (type, "iftmp");
4127 result = tmp;
4128 }
4129
4130 /* Otherwise, only create and copy references to the values. */
4131 else
4132 {
4133 type = build_pointer_type (type);
4134
4135 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4136 then_ = build_fold_addr_expr_loc (loc, then_);
4137
4138 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4139 else_ = build_fold_addr_expr_loc (loc, else_);
4140
4141 expr
4142 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
4143
4144 tmp = create_tmp_var (type, "iftmp");
4145 result = build_simple_mem_ref_loc (loc, tmp);
4146 }
4147
4148 /* Build the new then clause, `tmp = then_;'. But don't build the
4149 assignment if the value is void; in C++ it can be if it's a throw. */
4150 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4151 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
4152
4153 /* Similarly, build the new else clause, `tmp = else_;'. */
4154 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4155 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
4156
4157 TREE_TYPE (expr) = void_type_node;
4158 recalculate_side_effects (expr);
4159
4160 /* Move the COND_EXPR to the prequeue. */
4161 gimplify_stmt (&expr, pre_p);
4162
4163 *expr_p = result;
4164 return GS_ALL_DONE;
4165 }
4166
4167 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4168 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4169 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4170 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4171
4172 /* Make sure the condition has BOOLEAN_TYPE. */
4173 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4174
4175 /* Break apart && and || conditions. */
4176 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4177 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4178 {
4179 expr = shortcut_cond_expr (expr);
4180
4181 if (expr != *expr_p)
4182 {
4183 *expr_p = expr;
4184
4185 /* We can't rely on gimplify_expr to re-gimplify the expanded
4186 form properly, as cleanups might cause the target labels to be
4187 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4188 set up a conditional context. */
4189 gimple_push_condition ();
4190 gimplify_stmt (expr_p, &seq);
4191 gimple_pop_condition (pre_p);
4192 gimple_seq_add_seq (pre_p, seq);
4193
4194 return GS_ALL_DONE;
4195 }
4196 }
4197
4198 /* Now do the normal gimplification. */
4199
4200 /* Gimplify condition. */
4201 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
4202 is_gimple_condexpr_for_cond, fb_rvalue);
4203 if (ret == GS_ERROR)
4204 return GS_ERROR;
4205 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4206
4207 gimple_push_condition ();
4208
4209 have_then_clause_p = have_else_clause_p = false;
4210 label_true = find_goto_label (TREE_OPERAND (expr, 1));
4211 if (label_true
4212 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4213 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4214 have different locations, otherwise we end up with incorrect
4215 location information on the branches. */
4216 && (optimize
4217 || !EXPR_HAS_LOCATION (expr)
4218 || !rexpr_has_location (label_true)
4219 || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4220 {
4221 have_then_clause_p = true;
4222 label_true = GOTO_DESTINATION (label_true);
4223 }
4224 else
4225 label_true = create_artificial_label (UNKNOWN_LOCATION);
4226 label_false = find_goto_label (TREE_OPERAND (expr, 2));
4227 if (label_false
4228 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4229 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4230 have different locations, otherwise we end up with incorrect
4231 location information on the branches. */
4232 && (optimize
4233 || !EXPR_HAS_LOCATION (expr)
4234 || !rexpr_has_location (label_false)
4235 || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4236 {
4237 have_else_clause_p = true;
4238 label_false = GOTO_DESTINATION (label_false);
4239 }
4240 else
4241 label_false = create_artificial_label (UNKNOWN_LOCATION);
4242
4243 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4244 &arm2);
4245 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4246 label_false);
4247 gimple_set_no_warning (cond_stmt, TREE_NO_WARNING (COND_EXPR_COND (expr)));
4248 gimplify_seq_add_stmt (&seq, cond_stmt);
4249 gimple_stmt_iterator gsi = gsi_last (seq);
4250 maybe_fold_stmt (&gsi);
4251
4252 label_cont = NULL_TREE;
4253 if (!have_then_clause_p)
4254 {
4255 /* For if (...) {} else { code; } put label_true after
4256 the else block. */
4257 if (TREE_OPERAND (expr, 1) == NULL_TREE
4258 && !have_else_clause_p
4259 && TREE_OPERAND (expr, 2) != NULL_TREE)
4260 label_cont = label_true;
4261 else
4262 {
4263 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4264 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4265 /* For if (...) { code; } else {} or
4266 if (...) { code; } else goto label; or
4267 if (...) { code; return; } else { ... }
4268 label_cont isn't needed. */
4269 if (!have_else_clause_p
4270 && TREE_OPERAND (expr, 2) != NULL_TREE
4271 && gimple_seq_may_fallthru (seq))
4272 {
4273 gimple *g;
4274 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4275
4276 g = gimple_build_goto (label_cont);
4277
4278 /* GIMPLE_COND's are very low level; they have embedded
4279 gotos. This particular embedded goto should not be marked
4280 with the location of the original COND_EXPR, as it would
4281 correspond to the COND_EXPR's condition, not the ELSE or the
4282 THEN arms. To avoid marking it with the wrong location, flag
4283 it as "no location". */
4284 gimple_set_do_not_emit_location (g);
4285
4286 gimplify_seq_add_stmt (&seq, g);
4287 }
4288 }
4289 }
4290 if (!have_else_clause_p)
4291 {
4292 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4293 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4294 }
4295 if (label_cont)
4296 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4297
4298 gimple_pop_condition (pre_p);
4299 gimple_seq_add_seq (pre_p, seq);
4300
4301 if (ret == GS_ERROR)
4302 ; /* Do nothing. */
4303 else if (have_then_clause_p || have_else_clause_p)
4304 ret = GS_ALL_DONE;
4305 else
4306 {
4307 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4308 expr = TREE_OPERAND (expr, 0);
4309 gimplify_stmt (&expr, pre_p);
4310 }
4311
4312 *expr_p = NULL;
4313 return ret;
4314 }
4315
4316 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4317 to be marked addressable.
4318
4319 We cannot rely on such an expression being directly markable if a temporary
4320 has been created by the gimplification. In this case, we create another
4321 temporary and initialize it with a copy, which will become a store after we
4322 mark it addressable. This can happen if the front-end passed us something
4323 that it could not mark addressable yet, like a Fortran pass-by-reference
4324 parameter (int) floatvar. */
4325
4326 static void
prepare_gimple_addressable(tree * expr_p,gimple_seq * seq_p)4327 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4328 {
4329 while (handled_component_p (*expr_p))
4330 expr_p = &TREE_OPERAND (*expr_p, 0);
4331 if (is_gimple_reg (*expr_p))
4332 {
4333 /* Do not allow an SSA name as the temporary. */
4334 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
4335 DECL_NOT_GIMPLE_REG_P (var) = 1;
4336 *expr_p = var;
4337 }
4338 }
4339
4340 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4341 a call to __builtin_memcpy. */
4342
4343 static enum gimplify_status
gimplify_modify_expr_to_memcpy(tree * expr_p,tree size,bool want_value,gimple_seq * seq_p)4344 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4345 gimple_seq *seq_p)
4346 {
4347 tree t, to, to_ptr, from, from_ptr;
4348 gcall *gs;
4349 location_t loc = EXPR_LOCATION (*expr_p);
4350
4351 to = TREE_OPERAND (*expr_p, 0);
4352 from = TREE_OPERAND (*expr_p, 1);
4353
4354 /* Mark the RHS addressable. Beware that it may not be possible to do so
4355 directly if a temporary has been created by the gimplification. */
4356 prepare_gimple_addressable (&from, seq_p);
4357
4358 mark_addressable (from);
4359 from_ptr = build_fold_addr_expr_loc (loc, from);
4360 gimplify_arg (&from_ptr, seq_p, loc);
4361
4362 mark_addressable (to);
4363 to_ptr = build_fold_addr_expr_loc (loc, to);
4364 gimplify_arg (&to_ptr, seq_p, loc);
4365
4366 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4367
4368 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4369 gimple_call_set_alloca_for_var (gs, true);
4370
4371 if (want_value)
4372 {
4373 /* tmp = memcpy() */
4374 t = create_tmp_var (TREE_TYPE (to_ptr));
4375 gimple_call_set_lhs (gs, t);
4376 gimplify_seq_add_stmt (seq_p, gs);
4377
4378 *expr_p = build_simple_mem_ref (t);
4379 return GS_ALL_DONE;
4380 }
4381
4382 gimplify_seq_add_stmt (seq_p, gs);
4383 *expr_p = NULL;
4384 return GS_ALL_DONE;
4385 }
4386
4387 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4388 a call to __builtin_memset. In this case we know that the RHS is
4389 a CONSTRUCTOR with an empty element list. */
4390
4391 static enum gimplify_status
gimplify_modify_expr_to_memset(tree * expr_p,tree size,bool want_value,gimple_seq * seq_p)4392 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4393 gimple_seq *seq_p)
4394 {
4395 tree t, from, to, to_ptr;
4396 gcall *gs;
4397 location_t loc = EXPR_LOCATION (*expr_p);
4398
4399 /* Assert our assumptions, to abort instead of producing wrong code
4400 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4401 not be immediately exposed. */
4402 from = TREE_OPERAND (*expr_p, 1);
4403 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4404 from = TREE_OPERAND (from, 0);
4405
4406 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4407 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4408
4409 /* Now proceed. */
4410 to = TREE_OPERAND (*expr_p, 0);
4411
4412 to_ptr = build_fold_addr_expr_loc (loc, to);
4413 gimplify_arg (&to_ptr, seq_p, loc);
4414 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4415
4416 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4417
4418 if (want_value)
4419 {
4420 /* tmp = memset() */
4421 t = create_tmp_var (TREE_TYPE (to_ptr));
4422 gimple_call_set_lhs (gs, t);
4423 gimplify_seq_add_stmt (seq_p, gs);
4424
4425 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4426 return GS_ALL_DONE;
4427 }
4428
4429 gimplify_seq_add_stmt (seq_p, gs);
4430 *expr_p = NULL;
4431 return GS_ALL_DONE;
4432 }
4433
4434 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4435 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4436 assignment. Return non-null if we detect a potential overlap. */
4437
4438 struct gimplify_init_ctor_preeval_data
4439 {
4440 /* The base decl of the lhs object. May be NULL, in which case we
4441 have to assume the lhs is indirect. */
4442 tree lhs_base_decl;
4443
4444 /* The alias set of the lhs object. */
4445 alias_set_type lhs_alias_set;
4446 };
4447
4448 static tree
gimplify_init_ctor_preeval_1(tree * tp,int * walk_subtrees,void * xdata)4449 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4450 {
4451 struct gimplify_init_ctor_preeval_data *data
4452 = (struct gimplify_init_ctor_preeval_data *) xdata;
4453 tree t = *tp;
4454
4455 /* If we find the base object, obviously we have overlap. */
4456 if (data->lhs_base_decl == t)
4457 return t;
4458
4459 /* If the constructor component is indirect, determine if we have a
4460 potential overlap with the lhs. The only bits of information we
4461 have to go on at this point are addressability and alias sets. */
4462 if ((INDIRECT_REF_P (t)
4463 || TREE_CODE (t) == MEM_REF)
4464 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4465 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4466 return t;
4467
4468 /* If the constructor component is a call, determine if it can hide a
4469 potential overlap with the lhs through an INDIRECT_REF like above.
4470 ??? Ugh - this is completely broken. In fact this whole analysis
4471 doesn't look conservative. */
4472 if (TREE_CODE (t) == CALL_EXPR)
4473 {
4474 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4475
4476 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4477 if (POINTER_TYPE_P (TREE_VALUE (type))
4478 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4479 && alias_sets_conflict_p (data->lhs_alias_set,
4480 get_alias_set
4481 (TREE_TYPE (TREE_VALUE (type)))))
4482 return t;
4483 }
4484
4485 if (IS_TYPE_OR_DECL_P (t))
4486 *walk_subtrees = 0;
4487 return NULL;
4488 }
4489
4490 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4491 force values that overlap with the lhs (as described by *DATA)
4492 into temporaries. */
4493
4494 static void
gimplify_init_ctor_preeval(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p,struct gimplify_init_ctor_preeval_data * data)4495 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4496 struct gimplify_init_ctor_preeval_data *data)
4497 {
4498 enum gimplify_status one;
4499
4500 /* If the value is constant, then there's nothing to pre-evaluate. */
4501 if (TREE_CONSTANT (*expr_p))
4502 {
4503 /* Ensure it does not have side effects, it might contain a reference to
4504 the object we're initializing. */
4505 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4506 return;
4507 }
4508
4509 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4510 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4511 return;
4512
4513 /* Recurse for nested constructors. */
4514 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4515 {
4516 unsigned HOST_WIDE_INT ix;
4517 constructor_elt *ce;
4518 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4519
4520 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4521 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4522
4523 return;
4524 }
4525
4526 /* If this is a variable sized type, we must remember the size. */
4527 maybe_with_size_expr (expr_p);
4528
4529 /* Gimplify the constructor element to something appropriate for the rhs
4530 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4531 the gimplifier will consider this a store to memory. Doing this
4532 gimplification now means that we won't have to deal with complicated
4533 language-specific trees, nor trees like SAVE_EXPR that can induce
4534 exponential search behavior. */
4535 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4536 if (one == GS_ERROR)
4537 {
4538 *expr_p = NULL;
4539 return;
4540 }
4541
4542 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4543 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4544 always be true for all scalars, since is_gimple_mem_rhs insists on a
4545 temporary variable for them. */
4546 if (DECL_P (*expr_p))
4547 return;
4548
4549 /* If this is of variable size, we have no choice but to assume it doesn't
4550 overlap since we can't make a temporary for it. */
4551 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4552 return;
4553
4554 /* Otherwise, we must search for overlap ... */
4555 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4556 return;
4557
4558 /* ... and if found, force the value into a temporary. */
4559 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4560 }
4561
4562 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4563 a RANGE_EXPR in a CONSTRUCTOR for an array.
4564
4565 var = lower;
4566 loop_entry:
4567 object[var] = value;
4568 if (var == upper)
4569 goto loop_exit;
4570 var = var + 1;
4571 goto loop_entry;
4572 loop_exit:
4573
4574 We increment var _after_ the loop exit check because we might otherwise
4575 fail if upper == TYPE_MAX_VALUE (type for upper).
4576
4577 Note that we never have to deal with SAVE_EXPRs here, because this has
4578 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4579
4580 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4581 gimple_seq *, bool);
4582
4583 static void
gimplify_init_ctor_eval_range(tree object,tree lower,tree upper,tree value,tree array_elt_type,gimple_seq * pre_p,bool cleared)4584 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4585 tree value, tree array_elt_type,
4586 gimple_seq *pre_p, bool cleared)
4587 {
4588 tree loop_entry_label, loop_exit_label, fall_thru_label;
4589 tree var, var_type, cref, tmp;
4590
4591 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4592 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4593 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4594
4595 /* Create and initialize the index variable. */
4596 var_type = TREE_TYPE (upper);
4597 var = create_tmp_var (var_type);
4598 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4599
4600 /* Add the loop entry label. */
4601 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4602
4603 /* Build the reference. */
4604 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4605 var, NULL_TREE, NULL_TREE);
4606
4607 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4608 the store. Otherwise just assign value to the reference. */
4609
4610 if (TREE_CODE (value) == CONSTRUCTOR)
4611 /* NB we might have to call ourself recursively through
4612 gimplify_init_ctor_eval if the value is a constructor. */
4613 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4614 pre_p, cleared);
4615 else
4616 {
4617 if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue)
4618 != GS_ERROR)
4619 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4620 }
4621
4622 /* We exit the loop when the index var is equal to the upper bound. */
4623 gimplify_seq_add_stmt (pre_p,
4624 gimple_build_cond (EQ_EXPR, var, upper,
4625 loop_exit_label, fall_thru_label));
4626
4627 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4628
4629 /* Otherwise, increment the index var... */
4630 tmp = build2 (PLUS_EXPR, var_type, var,
4631 fold_convert (var_type, integer_one_node));
4632 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4633
4634 /* ...and jump back to the loop entry. */
4635 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4636
4637 /* Add the loop exit label. */
4638 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4639 }
4640
4641 /* Return true if FDECL is accessing a field that is zero sized. */
4642
4643 static bool
zero_sized_field_decl(const_tree fdecl)4644 zero_sized_field_decl (const_tree fdecl)
4645 {
4646 if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl)
4647 && integer_zerop (DECL_SIZE (fdecl)))
4648 return true;
4649 return false;
4650 }
4651
4652 /* Return true if TYPE is zero sized. */
4653
4654 static bool
zero_sized_type(const_tree type)4655 zero_sized_type (const_tree type)
4656 {
4657 if (AGGREGATE_TYPE_P (type) && TYPE_SIZE (type)
4658 && integer_zerop (TYPE_SIZE (type)))
4659 return true;
4660 return false;
4661 }
4662
4663 /* A subroutine of gimplify_init_constructor. Generate individual
4664 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4665 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4666 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4667 zeroed first. */
4668
4669 static void
gimplify_init_ctor_eval(tree object,vec<constructor_elt,va_gc> * elts,gimple_seq * pre_p,bool cleared)4670 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4671 gimple_seq *pre_p, bool cleared)
4672 {
4673 tree array_elt_type = NULL;
4674 unsigned HOST_WIDE_INT ix;
4675 tree purpose, value;
4676
4677 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4678 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4679
4680 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4681 {
4682 tree cref;
4683
4684 /* NULL values are created above for gimplification errors. */
4685 if (value == NULL)
4686 continue;
4687
4688 if (cleared && initializer_zerop (value))
4689 continue;
4690
4691 /* ??? Here's to hoping the front end fills in all of the indices,
4692 so we don't have to figure out what's missing ourselves. */
4693 gcc_assert (purpose);
4694
4695 /* Skip zero-sized fields, unless value has side-effects. This can
4696 happen with calls to functions returning a zero-sized type, which
4697 we shouldn't discard. As a number of downstream passes don't
4698 expect sets of zero-sized fields, we rely on the gimplification of
4699 the MODIFY_EXPR we make below to drop the assignment statement. */
4700 if (! TREE_SIDE_EFFECTS (value) && zero_sized_field_decl (purpose))
4701 continue;
4702
4703 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4704 whole range. */
4705 if (TREE_CODE (purpose) == RANGE_EXPR)
4706 {
4707 tree lower = TREE_OPERAND (purpose, 0);
4708 tree upper = TREE_OPERAND (purpose, 1);
4709
4710 /* If the lower bound is equal to upper, just treat it as if
4711 upper was the index. */
4712 if (simple_cst_equal (lower, upper))
4713 purpose = upper;
4714 else
4715 {
4716 gimplify_init_ctor_eval_range (object, lower, upper, value,
4717 array_elt_type, pre_p, cleared);
4718 continue;
4719 }
4720 }
4721
4722 if (array_elt_type)
4723 {
4724 /* Do not use bitsizetype for ARRAY_REF indices. */
4725 if (TYPE_DOMAIN (TREE_TYPE (object)))
4726 purpose
4727 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4728 purpose);
4729 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4730 purpose, NULL_TREE, NULL_TREE);
4731 }
4732 else
4733 {
4734 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4735 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4736 unshare_expr (object), purpose, NULL_TREE);
4737 }
4738
4739 if (TREE_CODE (value) == CONSTRUCTOR
4740 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4741 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4742 pre_p, cleared);
4743 else
4744 {
4745 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4746 gimplify_and_add (init, pre_p);
4747 ggc_free (init);
4748 }
4749 }
4750 }
4751
4752 /* Return the appropriate RHS predicate for this LHS. */
4753
4754 gimple_predicate
rhs_predicate_for(tree lhs)4755 rhs_predicate_for (tree lhs)
4756 {
4757 if (is_gimple_reg (lhs))
4758 return is_gimple_reg_rhs_or_call;
4759 else
4760 return is_gimple_mem_rhs_or_call;
4761 }
4762
4763 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4764 before the LHS has been gimplified. */
4765
4766 static gimple_predicate
initial_rhs_predicate_for(tree lhs)4767 initial_rhs_predicate_for (tree lhs)
4768 {
4769 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4770 return is_gimple_reg_rhs_or_call;
4771 else
4772 return is_gimple_mem_rhs_or_call;
4773 }
4774
4775 /* Gimplify a C99 compound literal expression. This just means adding
4776 the DECL_EXPR before the current statement and using its anonymous
4777 decl instead. */
4778
4779 static enum gimplify_status
gimplify_compound_literal_expr(tree * expr_p,gimple_seq * pre_p,bool (* gimple_test_f)(tree),fallback_t fallback)4780 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
4781 bool (*gimple_test_f) (tree),
4782 fallback_t fallback)
4783 {
4784 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
4785 tree decl = DECL_EXPR_DECL (decl_s);
4786 tree init = DECL_INITIAL (decl);
4787 /* Mark the decl as addressable if the compound literal
4788 expression is addressable now, otherwise it is marked too late
4789 after we gimplify the initialization expression. */
4790 if (TREE_ADDRESSABLE (*expr_p))
4791 TREE_ADDRESSABLE (decl) = 1;
4792 /* Otherwise, if we don't need an lvalue and have a literal directly
4793 substitute it. Check if it matches the gimple predicate, as
4794 otherwise we'd generate a new temporary, and we can as well just
4795 use the decl we already have. */
4796 else if (!TREE_ADDRESSABLE (decl)
4797 && !TREE_THIS_VOLATILE (decl)
4798 && init
4799 && (fallback & fb_lvalue) == 0
4800 && gimple_test_f (init))
4801 {
4802 *expr_p = init;
4803 return GS_OK;
4804 }
4805
4806 /* If the decl is not addressable, then it is being used in some
4807 expression or on the right hand side of a statement, and it can
4808 be put into a readonly data section. */
4809 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
4810 TREE_READONLY (decl) = 1;
4811
4812 /* This decl isn't mentioned in the enclosing block, so add it to the
4813 list of temps. FIXME it seems a bit of a kludge to say that
4814 anonymous artificial vars aren't pushed, but everything else is. */
4815 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
4816 gimple_add_tmp_var (decl);
4817
4818 gimplify_and_add (decl_s, pre_p);
4819 *expr_p = decl;
4820 return GS_OK;
4821 }
4822
4823 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4824 return a new CONSTRUCTOR if something changed. */
4825
4826 static tree
optimize_compound_literals_in_ctor(tree orig_ctor)4827 optimize_compound_literals_in_ctor (tree orig_ctor)
4828 {
4829 tree ctor = orig_ctor;
4830 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
4831 unsigned int idx, num = vec_safe_length (elts);
4832
4833 for (idx = 0; idx < num; idx++)
4834 {
4835 tree value = (*elts)[idx].value;
4836 tree newval = value;
4837 if (TREE_CODE (value) == CONSTRUCTOR)
4838 newval = optimize_compound_literals_in_ctor (value);
4839 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
4840 {
4841 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
4842 tree decl = DECL_EXPR_DECL (decl_s);
4843 tree init = DECL_INITIAL (decl);
4844
4845 if (!TREE_ADDRESSABLE (value)
4846 && !TREE_ADDRESSABLE (decl)
4847 && init
4848 && TREE_CODE (init) == CONSTRUCTOR)
4849 newval = optimize_compound_literals_in_ctor (init);
4850 }
4851 if (newval == value)
4852 continue;
4853
4854 if (ctor == orig_ctor)
4855 {
4856 ctor = copy_node (orig_ctor);
4857 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
4858 elts = CONSTRUCTOR_ELTS (ctor);
4859 }
4860 (*elts)[idx].value = newval;
4861 }
4862 return ctor;
4863 }
4864
4865 /* A subroutine of gimplify_modify_expr. Break out elements of a
4866 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4867
4868 Note that we still need to clear any elements that don't have explicit
4869 initializers, so if not all elements are initialized we keep the
4870 original MODIFY_EXPR, we just remove all of the constructor elements.
4871
4872 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4873 GS_ERROR if we would have to create a temporary when gimplifying
4874 this constructor. Otherwise, return GS_OK.
4875
4876 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4877
4878 static enum gimplify_status
gimplify_init_constructor(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p,bool want_value,bool notify_temp_creation)4879 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4880 bool want_value, bool notify_temp_creation)
4881 {
4882 tree object, ctor, type;
4883 enum gimplify_status ret;
4884 vec<constructor_elt, va_gc> *elts;
4885
4886 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
4887
4888 if (!notify_temp_creation)
4889 {
4890 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
4891 is_gimple_lvalue, fb_lvalue);
4892 if (ret == GS_ERROR)
4893 return ret;
4894 }
4895
4896 object = TREE_OPERAND (*expr_p, 0);
4897 ctor = TREE_OPERAND (*expr_p, 1)
4898 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
4899 type = TREE_TYPE (ctor);
4900 elts = CONSTRUCTOR_ELTS (ctor);
4901 ret = GS_ALL_DONE;
4902
4903 switch (TREE_CODE (type))
4904 {
4905 case RECORD_TYPE:
4906 case UNION_TYPE:
4907 case QUAL_UNION_TYPE:
4908 case ARRAY_TYPE:
4909 {
4910 /* Use readonly data for initializers of this or smaller size
4911 regardless of the num_nonzero_elements / num_unique_nonzero_elements
4912 ratio. */
4913 const HOST_WIDE_INT min_unique_size = 64;
4914 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
4915 is smaller than this, use readonly data. */
4916 const int unique_nonzero_ratio = 8;
4917 /* True if a single access of the object must be ensured. This is the
4918 case if the target is volatile, the type is non-addressable and more
4919 than one field need to be assigned. */
4920 const bool ensure_single_access
4921 = TREE_THIS_VOLATILE (object)
4922 && !TREE_ADDRESSABLE (type)
4923 && vec_safe_length (elts) > 1;
4924 struct gimplify_init_ctor_preeval_data preeval_data;
4925 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
4926 HOST_WIDE_INT num_unique_nonzero_elements;
4927 bool cleared, complete_p, valid_const_initializer;
4928
4929 /* Aggregate types must lower constructors to initialization of
4930 individual elements. The exception is that a CONSTRUCTOR node
4931 with no elements indicates zero-initialization of the whole. */
4932 if (vec_safe_is_empty (elts))
4933 {
4934 if (notify_temp_creation)
4935 return GS_OK;
4936 break;
4937 }
4938
4939 /* Fetch information about the constructor to direct later processing.
4940 We might want to make static versions of it in various cases, and
4941 can only do so if it known to be a valid constant initializer. */
4942 valid_const_initializer
4943 = categorize_ctor_elements (ctor, &num_nonzero_elements,
4944 &num_unique_nonzero_elements,
4945 &num_ctor_elements, &complete_p);
4946
4947 /* If a const aggregate variable is being initialized, then it
4948 should never be a lose to promote the variable to be static. */
4949 if (valid_const_initializer
4950 && num_nonzero_elements > 1
4951 && TREE_READONLY (object)
4952 && VAR_P (object)
4953 && !DECL_REGISTER (object)
4954 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))
4955 /* For ctors that have many repeated nonzero elements
4956 represented through RANGE_EXPRs, prefer initializing
4957 those through runtime loops over copies of large amounts
4958 of data from readonly data section. */
4959 && (num_unique_nonzero_elements
4960 > num_nonzero_elements / unique_nonzero_ratio
4961 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
4962 <= (unsigned HOST_WIDE_INT) min_unique_size)))
4963 {
4964 if (notify_temp_creation)
4965 return GS_ERROR;
4966
4967 DECL_INITIAL (object) = ctor;
4968 TREE_STATIC (object) = 1;
4969 if (!DECL_NAME (object))
4970 DECL_NAME (object) = create_tmp_var_name ("C");
4971 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
4972
4973 /* ??? C++ doesn't automatically append a .<number> to the
4974 assembler name, and even when it does, it looks at FE private
4975 data structures to figure out what that number should be,
4976 which are not set for this variable. I suppose this is
4977 important for local statics for inline functions, which aren't
4978 "local" in the object file sense. So in order to get a unique
4979 TU-local symbol, we must invoke the lhd version now. */
4980 lhd_set_decl_assembler_name (object);
4981
4982 *expr_p = NULL_TREE;
4983 break;
4984 }
4985
4986 /* If there are "lots" of initialized elements, even discounting
4987 those that are not address constants (and thus *must* be
4988 computed at runtime), then partition the constructor into
4989 constant and non-constant parts. Block copy the constant
4990 parts in, then generate code for the non-constant parts. */
4991 /* TODO. There's code in cp/typeck.c to do this. */
4992
4993 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
4994 /* store_constructor will ignore the clearing of variable-sized
4995 objects. Initializers for such objects must explicitly set
4996 every field that needs to be set. */
4997 cleared = false;
4998 else if (!complete_p)
4999 /* If the constructor isn't complete, clear the whole object
5000 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
5001
5002 ??? This ought not to be needed. For any element not present
5003 in the initializer, we should simply set them to zero. Except
5004 we'd need to *find* the elements that are not present, and that
5005 requires trickery to avoid quadratic compile-time behavior in
5006 large cases or excessive memory use in small cases. */
5007 cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
5008 else if (num_ctor_elements - num_nonzero_elements
5009 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
5010 && num_nonzero_elements < num_ctor_elements / 4)
5011 /* If there are "lots" of zeros, it's more efficient to clear
5012 the memory and then set the nonzero elements. */
5013 cleared = true;
5014 else if (ensure_single_access && num_nonzero_elements == 0)
5015 /* If a single access to the target must be ensured and all elements
5016 are zero, then it's optimal to clear whatever their number. */
5017 cleared = true;
5018 else
5019 cleared = false;
5020
5021 /* If there are "lots" of initialized elements, and all of them
5022 are valid address constants, then the entire initializer can
5023 be dropped to memory, and then memcpy'd out. Don't do this
5024 for sparse arrays, though, as it's more efficient to follow
5025 the standard CONSTRUCTOR behavior of memset followed by
5026 individual element initialization. Also don't do this for small
5027 all-zero initializers (which aren't big enough to merit
5028 clearing), and don't try to make bitwise copies of
5029 TREE_ADDRESSABLE types. */
5030 if (valid_const_initializer
5031 && complete_p
5032 && !(cleared || num_nonzero_elements == 0)
5033 && !TREE_ADDRESSABLE (type))
5034 {
5035 HOST_WIDE_INT size = int_size_in_bytes (type);
5036 unsigned int align;
5037
5038 /* ??? We can still get unbounded array types, at least
5039 from the C++ front end. This seems wrong, but attempt
5040 to work around it for now. */
5041 if (size < 0)
5042 {
5043 size = int_size_in_bytes (TREE_TYPE (object));
5044 if (size >= 0)
5045 TREE_TYPE (ctor) = type = TREE_TYPE (object);
5046 }
5047
5048 /* Find the maximum alignment we can assume for the object. */
5049 /* ??? Make use of DECL_OFFSET_ALIGN. */
5050 if (DECL_P (object))
5051 align = DECL_ALIGN (object);
5052 else
5053 align = TYPE_ALIGN (type);
5054
5055 /* Do a block move either if the size is so small as to make
5056 each individual move a sub-unit move on average, or if it
5057 is so large as to make individual moves inefficient. */
5058 if (size > 0
5059 && num_nonzero_elements > 1
5060 /* For ctors that have many repeated nonzero elements
5061 represented through RANGE_EXPRs, prefer initializing
5062 those through runtime loops over copies of large amounts
5063 of data from readonly data section. */
5064 && (num_unique_nonzero_elements
5065 > num_nonzero_elements / unique_nonzero_ratio
5066 || size <= min_unique_size)
5067 && (size < num_nonzero_elements
5068 || !can_move_by_pieces (size, align)))
5069 {
5070 if (notify_temp_creation)
5071 return GS_ERROR;
5072
5073 walk_tree (&ctor, force_labels_r, NULL, NULL);
5074 ctor = tree_output_constant_def (ctor);
5075 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
5076 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
5077 TREE_OPERAND (*expr_p, 1) = ctor;
5078
5079 /* This is no longer an assignment of a CONSTRUCTOR, but
5080 we still may have processing to do on the LHS. So
5081 pretend we didn't do anything here to let that happen. */
5082 return GS_UNHANDLED;
5083 }
5084 }
5085
5086 /* If a single access to the target must be ensured and there are
5087 nonzero elements or the zero elements are not assigned en masse,
5088 initialize the target from a temporary. */
5089 if (ensure_single_access && (num_nonzero_elements > 0 || !cleared))
5090 {
5091 if (notify_temp_creation)
5092 return GS_ERROR;
5093
5094 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
5095 TREE_OPERAND (*expr_p, 0) = temp;
5096 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
5097 *expr_p,
5098 build2 (MODIFY_EXPR, void_type_node,
5099 object, temp));
5100 return GS_OK;
5101 }
5102
5103 if (notify_temp_creation)
5104 return GS_OK;
5105
5106 /* If there are nonzero elements and if needed, pre-evaluate to capture
5107 elements overlapping with the lhs into temporaries. We must do this
5108 before clearing to fetch the values before they are zeroed-out. */
5109 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
5110 {
5111 preeval_data.lhs_base_decl = get_base_address (object);
5112 if (!DECL_P (preeval_data.lhs_base_decl))
5113 preeval_data.lhs_base_decl = NULL;
5114 preeval_data.lhs_alias_set = get_alias_set (object);
5115
5116 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
5117 pre_p, post_p, &preeval_data);
5118 }
5119
5120 bool ctor_has_side_effects_p
5121 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
5122
5123 if (cleared)
5124 {
5125 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5126 Note that we still have to gimplify, in order to handle the
5127 case of variable sized types. Avoid shared tree structures. */
5128 CONSTRUCTOR_ELTS (ctor) = NULL;
5129 TREE_SIDE_EFFECTS (ctor) = 0;
5130 object = unshare_expr (object);
5131 gimplify_stmt (expr_p, pre_p);
5132 }
5133
5134 /* If we have not block cleared the object, or if there are nonzero
5135 elements in the constructor, or if the constructor has side effects,
5136 add assignments to the individual scalar fields of the object. */
5137 if (!cleared
5138 || num_nonzero_elements > 0
5139 || ctor_has_side_effects_p)
5140 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
5141
5142 *expr_p = NULL_TREE;
5143 }
5144 break;
5145
5146 case COMPLEX_TYPE:
5147 {
5148 tree r, i;
5149
5150 if (notify_temp_creation)
5151 return GS_OK;
5152
5153 /* Extract the real and imaginary parts out of the ctor. */
5154 gcc_assert (elts->length () == 2);
5155 r = (*elts)[0].value;
5156 i = (*elts)[1].value;
5157 if (r == NULL || i == NULL)
5158 {
5159 tree zero = build_zero_cst (TREE_TYPE (type));
5160 if (r == NULL)
5161 r = zero;
5162 if (i == NULL)
5163 i = zero;
5164 }
5165
5166 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5167 represent creation of a complex value. */
5168 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
5169 {
5170 ctor = build_complex (type, r, i);
5171 TREE_OPERAND (*expr_p, 1) = ctor;
5172 }
5173 else
5174 {
5175 ctor = build2 (COMPLEX_EXPR, type, r, i);
5176 TREE_OPERAND (*expr_p, 1) = ctor;
5177 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
5178 pre_p,
5179 post_p,
5180 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
5181 fb_rvalue);
5182 }
5183 }
5184 break;
5185
5186 case VECTOR_TYPE:
5187 {
5188 unsigned HOST_WIDE_INT ix;
5189 constructor_elt *ce;
5190
5191 if (notify_temp_creation)
5192 return GS_OK;
5193
5194 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5195 if (TREE_CONSTANT (ctor))
5196 {
5197 bool constant_p = true;
5198 tree value;
5199
5200 /* Even when ctor is constant, it might contain non-*_CST
5201 elements, such as addresses or trapping values like
5202 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5203 in VECTOR_CST nodes. */
5204 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5205 if (!CONSTANT_CLASS_P (value))
5206 {
5207 constant_p = false;
5208 break;
5209 }
5210
5211 if (constant_p)
5212 {
5213 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5214 break;
5215 }
5216
5217 TREE_CONSTANT (ctor) = 0;
5218 }
5219
5220 /* Vector types use CONSTRUCTOR all the way through gimple
5221 compilation as a general initializer. */
5222 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5223 {
5224 enum gimplify_status tret;
5225 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5226 fb_rvalue);
5227 if (tret == GS_ERROR)
5228 ret = GS_ERROR;
5229 else if (TREE_STATIC (ctor)
5230 && !initializer_constant_valid_p (ce->value,
5231 TREE_TYPE (ce->value)))
5232 TREE_STATIC (ctor) = 0;
5233 }
5234 recompute_constructor_flags (ctor);
5235 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5236 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5237 }
5238 break;
5239
5240 default:
5241 /* So how did we get a CONSTRUCTOR for a scalar type? */
5242 gcc_unreachable ();
5243 }
5244
5245 if (ret == GS_ERROR)
5246 return GS_ERROR;
5247 /* If we have gimplified both sides of the initializer but have
5248 not emitted an assignment, do so now. */
5249 if (*expr_p)
5250 {
5251 tree lhs = TREE_OPERAND (*expr_p, 0);
5252 tree rhs = TREE_OPERAND (*expr_p, 1);
5253 if (want_value && object == lhs)
5254 lhs = unshare_expr (lhs);
5255 gassign *init = gimple_build_assign (lhs, rhs);
5256 gimplify_seq_add_stmt (pre_p, init);
5257 }
5258 if (want_value)
5259 {
5260 *expr_p = object;
5261 return GS_OK;
5262 }
5263 else
5264 {
5265 *expr_p = NULL;
5266 return GS_ALL_DONE;
5267 }
5268 }
5269
5270 /* Given a pointer value OP0, return a simplified version of an
5271 indirection through OP0, or NULL_TREE if no simplification is
5272 possible. This may only be applied to a rhs of an expression.
5273 Note that the resulting type may be different from the type pointed
5274 to in the sense that it is still compatible from the langhooks
5275 point of view. */
5276
5277 static tree
gimple_fold_indirect_ref_rhs(tree t)5278 gimple_fold_indirect_ref_rhs (tree t)
5279 {
5280 return gimple_fold_indirect_ref (t);
5281 }
5282
5283 /* Subroutine of gimplify_modify_expr to do simplifications of
5284 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5285 something changes. */
5286
5287 static enum gimplify_status
gimplify_modify_expr_rhs(tree * expr_p,tree * from_p,tree * to_p,gimple_seq * pre_p,gimple_seq * post_p,bool want_value)5288 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5289 gimple_seq *pre_p, gimple_seq *post_p,
5290 bool want_value)
5291 {
5292 enum gimplify_status ret = GS_UNHANDLED;
5293 bool changed;
5294
5295 do
5296 {
5297 changed = false;
5298 switch (TREE_CODE (*from_p))
5299 {
5300 case VAR_DECL:
5301 /* If we're assigning from a read-only variable initialized with
5302 a constructor and not volatile, do the direct assignment from
5303 the constructor, but only if the target is not volatile either
5304 since this latter assignment might end up being done on a per
5305 field basis. However, if the target is volatile and the type
5306 is aggregate and non-addressable, gimplify_init_constructor
5307 knows that it needs to ensure a single access to the target
5308 and it will return GS_OK only in this case. */
5309 if (TREE_READONLY (*from_p)
5310 && DECL_INITIAL (*from_p)
5311 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR
5312 && !TREE_THIS_VOLATILE (*from_p)
5313 && (!TREE_THIS_VOLATILE (*to_p)
5314 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p))
5315 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p)))))
5316 {
5317 tree old_from = *from_p;
5318 enum gimplify_status subret;
5319
5320 /* Move the constructor into the RHS. */
5321 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5322
5323 /* Let's see if gimplify_init_constructor will need to put
5324 it in memory. */
5325 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5326 false, true);
5327 if (subret == GS_ERROR)
5328 {
5329 /* If so, revert the change. */
5330 *from_p = old_from;
5331 }
5332 else
5333 {
5334 ret = GS_OK;
5335 changed = true;
5336 }
5337 }
5338 break;
5339 case INDIRECT_REF:
5340 {
5341 /* If we have code like
5342
5343 *(const A*)(A*)&x
5344
5345 where the type of "x" is a (possibly cv-qualified variant
5346 of "A"), treat the entire expression as identical to "x".
5347 This kind of code arises in C++ when an object is bound
5348 to a const reference, and if "x" is a TARGET_EXPR we want
5349 to take advantage of the optimization below. */
5350 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5351 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5352 if (t)
5353 {
5354 if (TREE_THIS_VOLATILE (t) != volatile_p)
5355 {
5356 if (DECL_P (t))
5357 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5358 build_fold_addr_expr (t));
5359 if (REFERENCE_CLASS_P (t))
5360 TREE_THIS_VOLATILE (t) = volatile_p;
5361 }
5362 *from_p = t;
5363 ret = GS_OK;
5364 changed = true;
5365 }
5366 break;
5367 }
5368
5369 case TARGET_EXPR:
5370 {
5371 /* If we are initializing something from a TARGET_EXPR, strip the
5372 TARGET_EXPR and initialize it directly, if possible. This can't
5373 be done if the initializer is void, since that implies that the
5374 temporary is set in some non-trivial way.
5375
5376 ??? What about code that pulls out the temp and uses it
5377 elsewhere? I think that such code never uses the TARGET_EXPR as
5378 an initializer. If I'm wrong, we'll die because the temp won't
5379 have any RTL. In that case, I guess we'll need to replace
5380 references somehow. */
5381 tree init = TARGET_EXPR_INITIAL (*from_p);
5382
5383 if (init
5384 && (TREE_CODE (*expr_p) != MODIFY_EXPR
5385 || !TARGET_EXPR_NO_ELIDE (*from_p))
5386 && !VOID_TYPE_P (TREE_TYPE (init)))
5387 {
5388 *from_p = init;
5389 ret = GS_OK;
5390 changed = true;
5391 }
5392 }
5393 break;
5394
5395 case COMPOUND_EXPR:
5396 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5397 caught. */
5398 gimplify_compound_expr (from_p, pre_p, true);
5399 ret = GS_OK;
5400 changed = true;
5401 break;
5402
5403 case CONSTRUCTOR:
5404 /* If we already made some changes, let the front end have a
5405 crack at this before we break it down. */
5406 if (ret != GS_UNHANDLED)
5407 break;
5408 /* If we're initializing from a CONSTRUCTOR, break this into
5409 individual MODIFY_EXPRs. */
5410 return gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5411 false);
5412
5413 case COND_EXPR:
5414 /* If we're assigning to a non-register type, push the assignment
5415 down into the branches. This is mandatory for ADDRESSABLE types,
5416 since we cannot generate temporaries for such, but it saves a
5417 copy in other cases as well. */
5418 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5419 {
5420 /* This code should mirror the code in gimplify_cond_expr. */
5421 enum tree_code code = TREE_CODE (*expr_p);
5422 tree cond = *from_p;
5423 tree result = *to_p;
5424
5425 ret = gimplify_expr (&result, pre_p, post_p,
5426 is_gimple_lvalue, fb_lvalue);
5427 if (ret != GS_ERROR)
5428 ret = GS_OK;
5429
5430 /* If we are going to write RESULT more than once, clear
5431 TREE_READONLY flag, otherwise we might incorrectly promote
5432 the variable to static const and initialize it at compile
5433 time in one of the branches. */
5434 if (VAR_P (result)
5435 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5436 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5437 TREE_READONLY (result) = 0;
5438 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5439 TREE_OPERAND (cond, 1)
5440 = build2 (code, void_type_node, result,
5441 TREE_OPERAND (cond, 1));
5442 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5443 TREE_OPERAND (cond, 2)
5444 = build2 (code, void_type_node, unshare_expr (result),
5445 TREE_OPERAND (cond, 2));
5446
5447 TREE_TYPE (cond) = void_type_node;
5448 recalculate_side_effects (cond);
5449
5450 if (want_value)
5451 {
5452 gimplify_and_add (cond, pre_p);
5453 *expr_p = unshare_expr (result);
5454 }
5455 else
5456 *expr_p = cond;
5457 return ret;
5458 }
5459 break;
5460
5461 case CALL_EXPR:
5462 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5463 return slot so that we don't generate a temporary. */
5464 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5465 && aggregate_value_p (*from_p, *from_p))
5466 {
5467 bool use_target;
5468
5469 if (!(rhs_predicate_for (*to_p))(*from_p))
5470 /* If we need a temporary, *to_p isn't accurate. */
5471 use_target = false;
5472 /* It's OK to use the return slot directly unless it's an NRV. */
5473 else if (TREE_CODE (*to_p) == RESULT_DECL
5474 && DECL_NAME (*to_p) == NULL_TREE
5475 && needs_to_live_in_memory (*to_p))
5476 use_target = true;
5477 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5478 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5479 /* Don't force regs into memory. */
5480 use_target = false;
5481 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5482 /* It's OK to use the target directly if it's being
5483 initialized. */
5484 use_target = true;
5485 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5486 != INTEGER_CST)
5487 /* Always use the target and thus RSO for variable-sized types.
5488 GIMPLE cannot deal with a variable-sized assignment
5489 embedded in a call statement. */
5490 use_target = true;
5491 else if (TREE_CODE (*to_p) != SSA_NAME
5492 && (!is_gimple_variable (*to_p)
5493 || needs_to_live_in_memory (*to_p)))
5494 /* Don't use the original target if it's already addressable;
5495 if its address escapes, and the called function uses the
5496 NRV optimization, a conforming program could see *to_p
5497 change before the called function returns; see c++/19317.
5498 When optimizing, the return_slot pass marks more functions
5499 as safe after we have escape info. */
5500 use_target = false;
5501 else
5502 use_target = true;
5503
5504 if (use_target)
5505 {
5506 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5507 mark_addressable (*to_p);
5508 }
5509 }
5510 break;
5511
5512 case WITH_SIZE_EXPR:
5513 /* Likewise for calls that return an aggregate of non-constant size,
5514 since we would not be able to generate a temporary at all. */
5515 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5516 {
5517 *from_p = TREE_OPERAND (*from_p, 0);
5518 /* We don't change ret in this case because the
5519 WITH_SIZE_EXPR might have been added in
5520 gimplify_modify_expr, so returning GS_OK would lead to an
5521 infinite loop. */
5522 changed = true;
5523 }
5524 break;
5525
5526 /* If we're initializing from a container, push the initialization
5527 inside it. */
5528 case CLEANUP_POINT_EXPR:
5529 case BIND_EXPR:
5530 case STATEMENT_LIST:
5531 {
5532 tree wrap = *from_p;
5533 tree t;
5534
5535 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5536 fb_lvalue);
5537 if (ret != GS_ERROR)
5538 ret = GS_OK;
5539
5540 t = voidify_wrapper_expr (wrap, *expr_p);
5541 gcc_assert (t == *expr_p);
5542
5543 if (want_value)
5544 {
5545 gimplify_and_add (wrap, pre_p);
5546 *expr_p = unshare_expr (*to_p);
5547 }
5548 else
5549 *expr_p = wrap;
5550 return GS_OK;
5551 }
5552
5553 case NOP_EXPR:
5554 /* Pull out compound literal expressions from a NOP_EXPR.
5555 Those are created in the C FE to drop qualifiers during
5556 lvalue conversion. */
5557 if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
5558 && tree_ssa_useless_type_conversion (*from_p))
5559 {
5560 *from_p = TREE_OPERAND (*from_p, 0);
5561 ret = GS_OK;
5562 changed = true;
5563 }
5564 break;
5565
5566 case COMPOUND_LITERAL_EXPR:
5567 {
5568 tree complit = TREE_OPERAND (*expr_p, 1);
5569 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5570 tree decl = DECL_EXPR_DECL (decl_s);
5571 tree init = DECL_INITIAL (decl);
5572
5573 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5574 into struct T x = { 0, 1, 2 } if the address of the
5575 compound literal has never been taken. */
5576 if (!TREE_ADDRESSABLE (complit)
5577 && !TREE_ADDRESSABLE (decl)
5578 && init)
5579 {
5580 *expr_p = copy_node (*expr_p);
5581 TREE_OPERAND (*expr_p, 1) = init;
5582 return GS_OK;
5583 }
5584 }
5585
5586 default:
5587 break;
5588 }
5589 }
5590 while (changed);
5591
5592 return ret;
5593 }
5594
5595
5596 /* Return true if T looks like a valid GIMPLE statement. */
5597
5598 static bool
is_gimple_stmt(tree t)5599 is_gimple_stmt (tree t)
5600 {
5601 const enum tree_code code = TREE_CODE (t);
5602
5603 switch (code)
5604 {
5605 case NOP_EXPR:
5606 /* The only valid NOP_EXPR is the empty statement. */
5607 return IS_EMPTY_STMT (t);
5608
5609 case BIND_EXPR:
5610 case COND_EXPR:
5611 /* These are only valid if they're void. */
5612 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5613
5614 case SWITCH_EXPR:
5615 case GOTO_EXPR:
5616 case RETURN_EXPR:
5617 case LABEL_EXPR:
5618 case CASE_LABEL_EXPR:
5619 case TRY_CATCH_EXPR:
5620 case TRY_FINALLY_EXPR:
5621 case EH_FILTER_EXPR:
5622 case CATCH_EXPR:
5623 case ASM_EXPR:
5624 case STATEMENT_LIST:
5625 case OACC_PARALLEL:
5626 case OACC_KERNELS:
5627 case OACC_SERIAL:
5628 case OACC_DATA:
5629 case OACC_HOST_DATA:
5630 case OACC_DECLARE:
5631 case OACC_UPDATE:
5632 case OACC_ENTER_DATA:
5633 case OACC_EXIT_DATA:
5634 case OACC_CACHE:
5635 case OMP_PARALLEL:
5636 case OMP_FOR:
5637 case OMP_SIMD:
5638 case OMP_DISTRIBUTE:
5639 case OMP_LOOP:
5640 case OACC_LOOP:
5641 case OMP_SCAN:
5642 case OMP_SECTIONS:
5643 case OMP_SECTION:
5644 case OMP_SINGLE:
5645 case OMP_MASTER:
5646 case OMP_TASKGROUP:
5647 case OMP_ORDERED:
5648 case OMP_CRITICAL:
5649 case OMP_TASK:
5650 case OMP_TARGET:
5651 case OMP_TARGET_DATA:
5652 case OMP_TARGET_UPDATE:
5653 case OMP_TARGET_ENTER_DATA:
5654 case OMP_TARGET_EXIT_DATA:
5655 case OMP_TASKLOOP:
5656 case OMP_TEAMS:
5657 /* These are always void. */
5658 return true;
5659
5660 case CALL_EXPR:
5661 case MODIFY_EXPR:
5662 case PREDICT_EXPR:
5663 /* These are valid regardless of their type. */
5664 return true;
5665
5666 default:
5667 return false;
5668 }
5669 }
5670
5671
5672 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5673 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
5674
5675 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5676 other, unmodified part of the complex object just before the total store.
5677 As a consequence, if the object is still uninitialized, an undefined value
5678 will be loaded into a register, which may result in a spurious exception
5679 if the register is floating-point and the value happens to be a signaling
5680 NaN for example. Then the fully-fledged complex operations lowering pass
5681 followed by a DCE pass are necessary in order to fix things up. */
5682
5683 static enum gimplify_status
gimplify_modify_expr_complex_part(tree * expr_p,gimple_seq * pre_p,bool want_value)5684 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5685 bool want_value)
5686 {
5687 enum tree_code code, ocode;
5688 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5689
5690 lhs = TREE_OPERAND (*expr_p, 0);
5691 rhs = TREE_OPERAND (*expr_p, 1);
5692 code = TREE_CODE (lhs);
5693 lhs = TREE_OPERAND (lhs, 0);
5694
5695 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5696 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5697 TREE_NO_WARNING (other) = 1;
5698 other = get_formal_tmp_var (other, pre_p);
5699
5700 realpart = code == REALPART_EXPR ? rhs : other;
5701 imagpart = code == REALPART_EXPR ? other : rhs;
5702
5703 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5704 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5705 else
5706 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5707
5708 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5709 *expr_p = (want_value) ? rhs : NULL_TREE;
5710
5711 return GS_ALL_DONE;
5712 }
5713
5714 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5715
5716 modify_expr
5717 : varname '=' rhs
5718 | '*' ID '=' rhs
5719
5720 PRE_P points to the list where side effects that must happen before
5721 *EXPR_P should be stored.
5722
5723 POST_P points to the list where side effects that must happen after
5724 *EXPR_P should be stored.
5725
5726 WANT_VALUE is nonzero iff we want to use the value of this expression
5727 in another expression. */
5728
5729 static enum gimplify_status
gimplify_modify_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p,bool want_value)5730 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5731 bool want_value)
5732 {
5733 tree *from_p = &TREE_OPERAND (*expr_p, 1);
5734 tree *to_p = &TREE_OPERAND (*expr_p, 0);
5735 enum gimplify_status ret = GS_UNHANDLED;
5736 gimple *assign;
5737 location_t loc = EXPR_LOCATION (*expr_p);
5738 gimple_stmt_iterator gsi;
5739
5740 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
5741 || TREE_CODE (*expr_p) == INIT_EXPR);
5742
5743 /* Trying to simplify a clobber using normal logic doesn't work,
5744 so handle it here. */
5745 if (TREE_CLOBBER_P (*from_p))
5746 {
5747 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5748 if (ret == GS_ERROR)
5749 return ret;
5750 gcc_assert (!want_value);
5751 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
5752 {
5753 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
5754 pre_p, post_p);
5755 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
5756 }
5757 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
5758 *expr_p = NULL;
5759 return GS_ALL_DONE;
5760 }
5761
5762 /* Insert pointer conversions required by the middle-end that are not
5763 required by the frontend. This fixes middle-end type checking for
5764 for example gcc.dg/redecl-6.c. */
5765 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
5766 {
5767 STRIP_USELESS_TYPE_CONVERSION (*from_p);
5768 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
5769 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
5770 }
5771
5772 /* See if any simplifications can be done based on what the RHS is. */
5773 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5774 want_value);
5775 if (ret != GS_UNHANDLED)
5776 return ret;
5777
5778 /* For zero sized types only gimplify the left hand side and right hand
5779 side as statements and throw away the assignment. Do this after
5780 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5781 types properly. */
5782 if (zero_sized_type (TREE_TYPE (*from_p))
5783 && !want_value
5784 /* Don't do this for calls that return addressable types, expand_call
5785 relies on those having a lhs. */
5786 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
5787 && TREE_CODE (*from_p) == CALL_EXPR))
5788 {
5789 gimplify_stmt (from_p, pre_p);
5790 gimplify_stmt (to_p, pre_p);
5791 *expr_p = NULL_TREE;
5792 return GS_ALL_DONE;
5793 }
5794
5795 /* If the value being copied is of variable width, compute the length
5796 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5797 before gimplifying any of the operands so that we can resolve any
5798 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5799 the size of the expression to be copied, not of the destination, so
5800 that is what we must do here. */
5801 maybe_with_size_expr (from_p);
5802
5803 /* As a special case, we have to temporarily allow for assignments
5804 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5805 a toplevel statement, when gimplifying the GENERIC expression
5806 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5807 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5808
5809 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5810 prevent gimplify_expr from trying to create a new temporary for
5811 foo's LHS, we tell it that it should only gimplify until it
5812 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5813 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5814 and all we need to do here is set 'a' to be its LHS. */
5815
5816 /* Gimplify the RHS first for C++17 and bug 71104. */
5817 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
5818 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
5819 if (ret == GS_ERROR)
5820 return ret;
5821
5822 /* Then gimplify the LHS. */
5823 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5824 twice we have to make sure to gimplify into non-SSA as otherwise
5825 the abnormal edge added later will make those defs not dominate
5826 their uses.
5827 ??? Technically this applies only to the registers used in the
5828 resulting non-register *TO_P. */
5829 bool saved_into_ssa = gimplify_ctxp->into_ssa;
5830 if (saved_into_ssa
5831 && TREE_CODE (*from_p) == CALL_EXPR
5832 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
5833 gimplify_ctxp->into_ssa = false;
5834 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5835 gimplify_ctxp->into_ssa = saved_into_ssa;
5836 if (ret == GS_ERROR)
5837 return ret;
5838
5839 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5840 guess for the predicate was wrong. */
5841 gimple_predicate final_pred = rhs_predicate_for (*to_p);
5842 if (final_pred != initial_pred)
5843 {
5844 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
5845 if (ret == GS_ERROR)
5846 return ret;
5847 }
5848
5849 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5850 size as argument to the call. */
5851 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5852 {
5853 tree call = TREE_OPERAND (*from_p, 0);
5854 tree vlasize = TREE_OPERAND (*from_p, 1);
5855
5856 if (TREE_CODE (call) == CALL_EXPR
5857 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
5858 {
5859 int nargs = call_expr_nargs (call);
5860 tree type = TREE_TYPE (call);
5861 tree ap = CALL_EXPR_ARG (call, 0);
5862 tree tag = CALL_EXPR_ARG (call, 1);
5863 tree aptag = CALL_EXPR_ARG (call, 2);
5864 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
5865 IFN_VA_ARG, type,
5866 nargs + 1, ap, tag,
5867 aptag, vlasize);
5868 TREE_OPERAND (*from_p, 0) = newcall;
5869 }
5870 }
5871
5872 /* Now see if the above changed *from_p to something we handle specially. */
5873 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5874 want_value);
5875 if (ret != GS_UNHANDLED)
5876 return ret;
5877
5878 /* If we've got a variable sized assignment between two lvalues (i.e. does
5879 not involve a call), then we can make things a bit more straightforward
5880 by converting the assignment to memcpy or memset. */
5881 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5882 {
5883 tree from = TREE_OPERAND (*from_p, 0);
5884 tree size = TREE_OPERAND (*from_p, 1);
5885
5886 if (TREE_CODE (from) == CONSTRUCTOR)
5887 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
5888
5889 if (is_gimple_addressable (from))
5890 {
5891 *from_p = from;
5892 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
5893 pre_p);
5894 }
5895 }
5896
5897 /* Transform partial stores to non-addressable complex variables into
5898 total stores. This allows us to use real instead of virtual operands
5899 for these variables, which improves optimization. */
5900 if ((TREE_CODE (*to_p) == REALPART_EXPR
5901 || TREE_CODE (*to_p) == IMAGPART_EXPR)
5902 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
5903 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
5904
5905 /* Try to alleviate the effects of the gimplification creating artificial
5906 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
5907 make sure not to create DECL_DEBUG_EXPR links across functions. */
5908 if (!gimplify_ctxp->into_ssa
5909 && VAR_P (*from_p)
5910 && DECL_IGNORED_P (*from_p)
5911 && DECL_P (*to_p)
5912 && !DECL_IGNORED_P (*to_p)
5913 && decl_function_context (*to_p) == current_function_decl
5914 && decl_function_context (*from_p) == current_function_decl)
5915 {
5916 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
5917 DECL_NAME (*from_p)
5918 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
5919 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
5920 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
5921 }
5922
5923 if (want_value && TREE_THIS_VOLATILE (*to_p))
5924 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
5925
5926 if (TREE_CODE (*from_p) == CALL_EXPR)
5927 {
5928 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
5929 instead of a GIMPLE_ASSIGN. */
5930 gcall *call_stmt;
5931 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
5932 {
5933 /* Gimplify internal functions created in the FEs. */
5934 int nargs = call_expr_nargs (*from_p), i;
5935 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
5936 auto_vec<tree> vargs (nargs);
5937
5938 for (i = 0; i < nargs; i++)
5939 {
5940 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
5941 EXPR_LOCATION (*from_p));
5942 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
5943 }
5944 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
5945 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
5946 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
5947 }
5948 else
5949 {
5950 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
5951 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
5952 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
5953 tree fndecl = get_callee_fndecl (*from_p);
5954 if (fndecl
5955 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
5956 && call_expr_nargs (*from_p) == 3)
5957 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
5958 CALL_EXPR_ARG (*from_p, 0),
5959 CALL_EXPR_ARG (*from_p, 1),
5960 CALL_EXPR_ARG (*from_p, 2));
5961 else
5962 {
5963 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
5964 }
5965 }
5966 notice_special_calls (call_stmt);
5967 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
5968 gimple_call_set_lhs (call_stmt, *to_p);
5969 else if (TREE_CODE (*to_p) == SSA_NAME)
5970 /* The above is somewhat premature, avoid ICEing later for a
5971 SSA name w/o a definition. We may have uses in the GIMPLE IL.
5972 ??? This doesn't make it a default-def. */
5973 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
5974
5975 assign = call_stmt;
5976 }
5977 else
5978 {
5979 assign = gimple_build_assign (*to_p, *from_p);
5980 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
5981 if (COMPARISON_CLASS_P (*from_p))
5982 gimple_set_no_warning (assign, TREE_NO_WARNING (*from_p));
5983 }
5984
5985 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
5986 {
5987 /* We should have got an SSA name from the start. */
5988 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
5989 || ! gimple_in_ssa_p (cfun));
5990 }
5991
5992 gimplify_seq_add_stmt (pre_p, assign);
5993 gsi = gsi_last (*pre_p);
5994 maybe_fold_stmt (&gsi);
5995
5996 if (want_value)
5997 {
5998 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
5999 return GS_OK;
6000 }
6001 else
6002 *expr_p = NULL;
6003
6004 return GS_ALL_DONE;
6005 }
6006
6007 /* Gimplify a comparison between two variable-sized objects. Do this
6008 with a call to BUILT_IN_MEMCMP. */
6009
6010 static enum gimplify_status
gimplify_variable_sized_compare(tree * expr_p)6011 gimplify_variable_sized_compare (tree *expr_p)
6012 {
6013 location_t loc = EXPR_LOCATION (*expr_p);
6014 tree op0 = TREE_OPERAND (*expr_p, 0);
6015 tree op1 = TREE_OPERAND (*expr_p, 1);
6016 tree t, arg, dest, src, expr;
6017
6018 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
6019 arg = unshare_expr (arg);
6020 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
6021 src = build_fold_addr_expr_loc (loc, op1);
6022 dest = build_fold_addr_expr_loc (loc, op0);
6023 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
6024 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
6025
6026 expr
6027 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
6028 SET_EXPR_LOCATION (expr, loc);
6029 *expr_p = expr;
6030
6031 return GS_OK;
6032 }
6033
6034 /* Gimplify a comparison between two aggregate objects of integral scalar
6035 mode as a comparison between the bitwise equivalent scalar values. */
6036
6037 static enum gimplify_status
gimplify_scalar_mode_aggregate_compare(tree * expr_p)6038 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
6039 {
6040 location_t loc = EXPR_LOCATION (*expr_p);
6041 tree op0 = TREE_OPERAND (*expr_p, 0);
6042 tree op1 = TREE_OPERAND (*expr_p, 1);
6043
6044 tree type = TREE_TYPE (op0);
6045 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
6046
6047 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
6048 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
6049
6050 *expr_p
6051 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
6052
6053 return GS_OK;
6054 }
6055
6056 /* Gimplify an expression sequence. This function gimplifies each
6057 expression and rewrites the original expression with the last
6058 expression of the sequence in GIMPLE form.
6059
6060 PRE_P points to the list where the side effects for all the
6061 expressions in the sequence will be emitted.
6062
6063 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6064
6065 static enum gimplify_status
gimplify_compound_expr(tree * expr_p,gimple_seq * pre_p,bool want_value)6066 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
6067 {
6068 tree t = *expr_p;
6069
6070 do
6071 {
6072 tree *sub_p = &TREE_OPERAND (t, 0);
6073
6074 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
6075 gimplify_compound_expr (sub_p, pre_p, false);
6076 else
6077 gimplify_stmt (sub_p, pre_p);
6078
6079 t = TREE_OPERAND (t, 1);
6080 }
6081 while (TREE_CODE (t) == COMPOUND_EXPR);
6082
6083 *expr_p = t;
6084 if (want_value)
6085 return GS_OK;
6086 else
6087 {
6088 gimplify_stmt (expr_p, pre_p);
6089 return GS_ALL_DONE;
6090 }
6091 }
6092
6093 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6094 gimplify. After gimplification, EXPR_P will point to a new temporary
6095 that holds the original value of the SAVE_EXPR node.
6096
6097 PRE_P points to the list where side effects that must happen before
6098 *EXPR_P should be stored. */
6099
6100 static enum gimplify_status
gimplify_save_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p)6101 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6102 {
6103 enum gimplify_status ret = GS_ALL_DONE;
6104 tree val;
6105
6106 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
6107 val = TREE_OPERAND (*expr_p, 0);
6108
6109 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6110 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
6111 {
6112 /* The operand may be a void-valued expression. It is
6113 being executed only for its side-effects. */
6114 if (TREE_TYPE (val) == void_type_node)
6115 {
6116 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
6117 is_gimple_stmt, fb_none);
6118 val = NULL;
6119 }
6120 else
6121 /* The temporary may not be an SSA name as later abnormal and EH
6122 control flow may invalidate use/def domination. When in SSA
6123 form then assume there are no such issues and SAVE_EXPRs only
6124 appear via GENERIC foldings. */
6125 val = get_initialized_tmp_var (val, pre_p, post_p,
6126 gimple_in_ssa_p (cfun));
6127
6128 TREE_OPERAND (*expr_p, 0) = val;
6129 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
6130 }
6131
6132 *expr_p = val;
6133
6134 return ret;
6135 }
6136
6137 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6138
6139 unary_expr
6140 : ...
6141 | '&' varname
6142 ...
6143
6144 PRE_P points to the list where side effects that must happen before
6145 *EXPR_P should be stored.
6146
6147 POST_P points to the list where side effects that must happen after
6148 *EXPR_P should be stored. */
6149
6150 static enum gimplify_status
gimplify_addr_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p)6151 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6152 {
6153 tree expr = *expr_p;
6154 tree op0 = TREE_OPERAND (expr, 0);
6155 enum gimplify_status ret;
6156 location_t loc = EXPR_LOCATION (*expr_p);
6157
6158 switch (TREE_CODE (op0))
6159 {
6160 case INDIRECT_REF:
6161 do_indirect_ref:
6162 /* Check if we are dealing with an expression of the form '&*ptr'.
6163 While the front end folds away '&*ptr' into 'ptr', these
6164 expressions may be generated internally by the compiler (e.g.,
6165 builtins like __builtin_va_end). */
6166 /* Caution: the silent array decomposition semantics we allow for
6167 ADDR_EXPR means we can't always discard the pair. */
6168 /* Gimplification of the ADDR_EXPR operand may drop
6169 cv-qualification conversions, so make sure we add them if
6170 needed. */
6171 {
6172 tree op00 = TREE_OPERAND (op0, 0);
6173 tree t_expr = TREE_TYPE (expr);
6174 tree t_op00 = TREE_TYPE (op00);
6175
6176 if (!useless_type_conversion_p (t_expr, t_op00))
6177 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
6178 *expr_p = op00;
6179 ret = GS_OK;
6180 }
6181 break;
6182
6183 case VIEW_CONVERT_EXPR:
6184 /* Take the address of our operand and then convert it to the type of
6185 this ADDR_EXPR.
6186
6187 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6188 all clear. The impact of this transformation is even less clear. */
6189
6190 /* If the operand is a useless conversion, look through it. Doing so
6191 guarantees that the ADDR_EXPR and its operand will remain of the
6192 same type. */
6193 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
6194 op0 = TREE_OPERAND (op0, 0);
6195
6196 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
6197 build_fold_addr_expr_loc (loc,
6198 TREE_OPERAND (op0, 0)));
6199 ret = GS_OK;
6200 break;
6201
6202 case MEM_REF:
6203 if (integer_zerop (TREE_OPERAND (op0, 1)))
6204 goto do_indirect_ref;
6205
6206 /* fall through */
6207
6208 default:
6209 /* If we see a call to a declared builtin or see its address
6210 being taken (we can unify those cases here) then we can mark
6211 the builtin for implicit generation by GCC. */
6212 if (TREE_CODE (op0) == FUNCTION_DECL
6213 && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6214 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6215 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6216
6217 /* We use fb_either here because the C frontend sometimes takes
6218 the address of a call that returns a struct; see
6219 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6220 the implied temporary explicit. */
6221
6222 /* Make the operand addressable. */
6223 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6224 is_gimple_addressable, fb_either);
6225 if (ret == GS_ERROR)
6226 break;
6227
6228 /* Then mark it. Beware that it may not be possible to do so directly
6229 if a temporary has been created by the gimplification. */
6230 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6231
6232 op0 = TREE_OPERAND (expr, 0);
6233
6234 /* For various reasons, the gimplification of the expression
6235 may have made a new INDIRECT_REF. */
6236 if (TREE_CODE (op0) == INDIRECT_REF
6237 || (TREE_CODE (op0) == MEM_REF
6238 && integer_zerop (TREE_OPERAND (op0, 1))))
6239 goto do_indirect_ref;
6240
6241 mark_addressable (TREE_OPERAND (expr, 0));
6242
6243 /* The FEs may end up building ADDR_EXPRs early on a decl with
6244 an incomplete type. Re-build ADDR_EXPRs in canonical form
6245 here. */
6246 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6247 *expr_p = build_fold_addr_expr (op0);
6248
6249 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6250 recompute_tree_invariant_for_addr_expr (*expr_p);
6251
6252 /* If we re-built the ADDR_EXPR add a conversion to the original type
6253 if required. */
6254 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6255 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6256
6257 break;
6258 }
6259
6260 return ret;
6261 }
6262
6263 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6264 value; output operands should be a gimple lvalue. */
6265
6266 static enum gimplify_status
gimplify_asm_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p)6267 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6268 {
6269 tree expr;
6270 int noutputs;
6271 const char **oconstraints;
6272 int i;
6273 tree link;
6274 const char *constraint;
6275 bool allows_mem, allows_reg, is_inout;
6276 enum gimplify_status ret, tret;
6277 gasm *stmt;
6278 vec<tree, va_gc> *inputs;
6279 vec<tree, va_gc> *outputs;
6280 vec<tree, va_gc> *clobbers;
6281 vec<tree, va_gc> *labels;
6282 tree link_next;
6283
6284 expr = *expr_p;
6285 noutputs = list_length (ASM_OUTPUTS (expr));
6286 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6287
6288 inputs = NULL;
6289 outputs = NULL;
6290 clobbers = NULL;
6291 labels = NULL;
6292
6293 ret = GS_ALL_DONE;
6294 link_next = NULL_TREE;
6295 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6296 {
6297 bool ok;
6298 size_t constraint_len;
6299
6300 link_next = TREE_CHAIN (link);
6301
6302 oconstraints[i]
6303 = constraint
6304 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6305 constraint_len = strlen (constraint);
6306 if (constraint_len == 0)
6307 continue;
6308
6309 ok = parse_output_constraint (&constraint, i, 0, 0,
6310 &allows_mem, &allows_reg, &is_inout);
6311 if (!ok)
6312 {
6313 ret = GS_ERROR;
6314 is_inout = false;
6315 }
6316
6317 /* If we can't make copies, we can only accept memory.
6318 Similarly for VLAs. */
6319 tree outtype = TREE_TYPE (TREE_VALUE (link));
6320 if (outtype != error_mark_node
6321 && (TREE_ADDRESSABLE (outtype)
6322 || !COMPLETE_TYPE_P (outtype)
6323 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
6324 {
6325 if (allows_mem)
6326 allows_reg = 0;
6327 else
6328 {
6329 error ("impossible constraint in %<asm%>");
6330 error ("non-memory output %d must stay in memory", i);
6331 return GS_ERROR;
6332 }
6333 }
6334
6335 if (!allows_reg && allows_mem)
6336 mark_addressable (TREE_VALUE (link));
6337
6338 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6339 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6340 fb_lvalue | fb_mayfail);
6341 if (tret == GS_ERROR)
6342 {
6343 error ("invalid lvalue in %<asm%> output %d", i);
6344 ret = tret;
6345 }
6346
6347 /* If the constraint does not allow memory make sure we gimplify
6348 it to a register if it is not already but its base is. This
6349 happens for complex and vector components. */
6350 if (!allows_mem)
6351 {
6352 tree op = TREE_VALUE (link);
6353 if (! is_gimple_val (op)
6354 && is_gimple_reg_type (TREE_TYPE (op))
6355 && is_gimple_reg (get_base_address (op)))
6356 {
6357 tree tem = create_tmp_reg (TREE_TYPE (op));
6358 tree ass;
6359 if (is_inout)
6360 {
6361 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6362 tem, unshare_expr (op));
6363 gimplify_and_add (ass, pre_p);
6364 }
6365 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6366 gimplify_and_add (ass, post_p);
6367
6368 TREE_VALUE (link) = tem;
6369 tret = GS_OK;
6370 }
6371 }
6372
6373 vec_safe_push (outputs, link);
6374 TREE_CHAIN (link) = NULL_TREE;
6375
6376 if (is_inout)
6377 {
6378 /* An input/output operand. To give the optimizers more
6379 flexibility, split it into separate input and output
6380 operands. */
6381 tree input;
6382 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6383 char buf[11];
6384
6385 /* Turn the in/out constraint into an output constraint. */
6386 char *p = xstrdup (constraint);
6387 p[0] = '=';
6388 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6389
6390 /* And add a matching input constraint. */
6391 if (allows_reg)
6392 {
6393 sprintf (buf, "%u", i);
6394
6395 /* If there are multiple alternatives in the constraint,
6396 handle each of them individually. Those that allow register
6397 will be replaced with operand number, the others will stay
6398 unchanged. */
6399 if (strchr (p, ',') != NULL)
6400 {
6401 size_t len = 0, buflen = strlen (buf);
6402 char *beg, *end, *str, *dst;
6403
6404 for (beg = p + 1;;)
6405 {
6406 end = strchr (beg, ',');
6407 if (end == NULL)
6408 end = strchr (beg, '\0');
6409 if ((size_t) (end - beg) < buflen)
6410 len += buflen + 1;
6411 else
6412 len += end - beg + 1;
6413 if (*end)
6414 beg = end + 1;
6415 else
6416 break;
6417 }
6418
6419 str = (char *) alloca (len);
6420 for (beg = p + 1, dst = str;;)
6421 {
6422 const char *tem;
6423 bool mem_p, reg_p, inout_p;
6424
6425 end = strchr (beg, ',');
6426 if (end)
6427 *end = '\0';
6428 beg[-1] = '=';
6429 tem = beg - 1;
6430 parse_output_constraint (&tem, i, 0, 0,
6431 &mem_p, ®_p, &inout_p);
6432 if (dst != str)
6433 *dst++ = ',';
6434 if (reg_p)
6435 {
6436 memcpy (dst, buf, buflen);
6437 dst += buflen;
6438 }
6439 else
6440 {
6441 if (end)
6442 len = end - beg;
6443 else
6444 len = strlen (beg);
6445 memcpy (dst, beg, len);
6446 dst += len;
6447 }
6448 if (end)
6449 beg = end + 1;
6450 else
6451 break;
6452 }
6453 *dst = '\0';
6454 input = build_string (dst - str, str);
6455 }
6456 else
6457 input = build_string (strlen (buf), buf);
6458 }
6459 else
6460 input = build_string (constraint_len - 1, constraint + 1);
6461
6462 free (p);
6463
6464 input = build_tree_list (build_tree_list (NULL_TREE, input),
6465 unshare_expr (TREE_VALUE (link)));
6466 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6467 }
6468 }
6469
6470 link_next = NULL_TREE;
6471 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6472 {
6473 link_next = TREE_CHAIN (link);
6474 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6475 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6476 oconstraints, &allows_mem, &allows_reg);
6477
6478 /* If we can't make copies, we can only accept memory. */
6479 tree intype = TREE_TYPE (TREE_VALUE (link));
6480 if (intype != error_mark_node
6481 && (TREE_ADDRESSABLE (intype)
6482 || !COMPLETE_TYPE_P (intype)
6483 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
6484 {
6485 if (allows_mem)
6486 allows_reg = 0;
6487 else
6488 {
6489 error ("impossible constraint in %<asm%>");
6490 error ("non-memory input %d must stay in memory", i);
6491 return GS_ERROR;
6492 }
6493 }
6494
6495 /* If the operand is a memory input, it should be an lvalue. */
6496 if (!allows_reg && allows_mem)
6497 {
6498 tree inputv = TREE_VALUE (link);
6499 STRIP_NOPS (inputv);
6500 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6501 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6502 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6503 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6504 || TREE_CODE (inputv) == MODIFY_EXPR)
6505 TREE_VALUE (link) = error_mark_node;
6506 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6507 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6508 if (tret != GS_ERROR)
6509 {
6510 /* Unlike output operands, memory inputs are not guaranteed
6511 to be lvalues by the FE, and while the expressions are
6512 marked addressable there, if it is e.g. a statement
6513 expression, temporaries in it might not end up being
6514 addressable. They might be already used in the IL and thus
6515 it is too late to make them addressable now though. */
6516 tree x = TREE_VALUE (link);
6517 while (handled_component_p (x))
6518 x = TREE_OPERAND (x, 0);
6519 if (TREE_CODE (x) == MEM_REF
6520 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6521 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6522 if ((VAR_P (x)
6523 || TREE_CODE (x) == PARM_DECL
6524 || TREE_CODE (x) == RESULT_DECL)
6525 && !TREE_ADDRESSABLE (x)
6526 && is_gimple_reg (x))
6527 {
6528 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6529 input_location), 0,
6530 "memory input %d is not directly addressable",
6531 i);
6532 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6533 }
6534 }
6535 mark_addressable (TREE_VALUE (link));
6536 if (tret == GS_ERROR)
6537 {
6538 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6539 "memory input %d is not directly addressable", i);
6540 ret = tret;
6541 }
6542 }
6543 else
6544 {
6545 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6546 is_gimple_asm_val, fb_rvalue);
6547 if (tret == GS_ERROR)
6548 ret = tret;
6549 }
6550
6551 TREE_CHAIN (link) = NULL_TREE;
6552 vec_safe_push (inputs, link);
6553 }
6554
6555 link_next = NULL_TREE;
6556 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6557 {
6558 link_next = TREE_CHAIN (link);
6559 TREE_CHAIN (link) = NULL_TREE;
6560 vec_safe_push (clobbers, link);
6561 }
6562
6563 link_next = NULL_TREE;
6564 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6565 {
6566 link_next = TREE_CHAIN (link);
6567 TREE_CHAIN (link) = NULL_TREE;
6568 vec_safe_push (labels, link);
6569 }
6570
6571 /* Do not add ASMs with errors to the gimple IL stream. */
6572 if (ret != GS_ERROR)
6573 {
6574 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6575 inputs, outputs, clobbers, labels);
6576
6577 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
6578 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6579 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
6580
6581 gimplify_seq_add_stmt (pre_p, stmt);
6582 }
6583
6584 return ret;
6585 }
6586
6587 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6588 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6589 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6590 return to this function.
6591
6592 FIXME should we complexify the prequeue handling instead? Or use flags
6593 for all the cleanups and let the optimizer tighten them up? The current
6594 code seems pretty fragile; it will break on a cleanup within any
6595 non-conditional nesting. But any such nesting would be broken, anyway;
6596 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6597 and continues out of it. We can do that at the RTL level, though, so
6598 having an optimizer to tighten up try/finally regions would be a Good
6599 Thing. */
6600
6601 static enum gimplify_status
gimplify_cleanup_point_expr(tree * expr_p,gimple_seq * pre_p)6602 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6603 {
6604 gimple_stmt_iterator iter;
6605 gimple_seq body_sequence = NULL;
6606
6607 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6608
6609 /* We only care about the number of conditions between the innermost
6610 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6611 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6612 int old_conds = gimplify_ctxp->conditions;
6613 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6614 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6615 gimplify_ctxp->conditions = 0;
6616 gimplify_ctxp->conditional_cleanups = NULL;
6617 gimplify_ctxp->in_cleanup_point_expr = true;
6618
6619 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6620
6621 gimplify_ctxp->conditions = old_conds;
6622 gimplify_ctxp->conditional_cleanups = old_cleanups;
6623 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6624
6625 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6626 {
6627 gimple *wce = gsi_stmt (iter);
6628
6629 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6630 {
6631 if (gsi_one_before_end_p (iter))
6632 {
6633 /* Note that gsi_insert_seq_before and gsi_remove do not
6634 scan operands, unlike some other sequence mutators. */
6635 if (!gimple_wce_cleanup_eh_only (wce))
6636 gsi_insert_seq_before_without_update (&iter,
6637 gimple_wce_cleanup (wce),
6638 GSI_SAME_STMT);
6639 gsi_remove (&iter, true);
6640 break;
6641 }
6642 else
6643 {
6644 gtry *gtry;
6645 gimple_seq seq;
6646 enum gimple_try_flags kind;
6647
6648 if (gimple_wce_cleanup_eh_only (wce))
6649 kind = GIMPLE_TRY_CATCH;
6650 else
6651 kind = GIMPLE_TRY_FINALLY;
6652 seq = gsi_split_seq_after (iter);
6653
6654 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6655 /* Do not use gsi_replace here, as it may scan operands.
6656 We want to do a simple structural modification only. */
6657 gsi_set_stmt (&iter, gtry);
6658 iter = gsi_start (gtry->eval);
6659 }
6660 }
6661 else
6662 gsi_next (&iter);
6663 }
6664
6665 gimplify_seq_add_seq (pre_p, body_sequence);
6666 if (temp)
6667 {
6668 *expr_p = temp;
6669 return GS_OK;
6670 }
6671 else
6672 {
6673 *expr_p = NULL;
6674 return GS_ALL_DONE;
6675 }
6676 }
6677
6678 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6679 is the cleanup action required. EH_ONLY is true if the cleanup should
6680 only be executed if an exception is thrown, not on normal exit.
6681 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6682 only valid for clobbers. */
6683
6684 static void
6685 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6686 bool force_uncond = false)
6687 {
6688 gimple *wce;
6689 gimple_seq cleanup_stmts = NULL;
6690
6691 /* Errors can result in improperly nested cleanups. Which results in
6692 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6693 if (seen_error ())
6694 return;
6695
6696 if (gimple_conditional_context ())
6697 {
6698 /* If we're in a conditional context, this is more complex. We only
6699 want to run the cleanup if we actually ran the initialization that
6700 necessitates it, but we want to run it after the end of the
6701 conditional context. So we wrap the try/finally around the
6702 condition and use a flag to determine whether or not to actually
6703 run the destructor. Thus
6704
6705 test ? f(A()) : 0
6706
6707 becomes (approximately)
6708
6709 flag = 0;
6710 try {
6711 if (test) { A::A(temp); flag = 1; val = f(temp); }
6712 else { val = 0; }
6713 } finally {
6714 if (flag) A::~A(temp);
6715 }
6716 val
6717 */
6718 if (force_uncond)
6719 {
6720 gimplify_stmt (&cleanup, &cleanup_stmts);
6721 wce = gimple_build_wce (cleanup_stmts);
6722 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6723 }
6724 else
6725 {
6726 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6727 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
6728 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
6729
6730 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
6731 gimplify_stmt (&cleanup, &cleanup_stmts);
6732 wce = gimple_build_wce (cleanup_stmts);
6733
6734 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
6735 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6736 gimplify_seq_add_stmt (pre_p, ftrue);
6737
6738 /* Because of this manipulation, and the EH edges that jump
6739 threading cannot redirect, the temporary (VAR) will appear
6740 to be used uninitialized. Don't warn. */
6741 TREE_NO_WARNING (var) = 1;
6742 }
6743 }
6744 else
6745 {
6746 gimplify_stmt (&cleanup, &cleanup_stmts);
6747 wce = gimple_build_wce (cleanup_stmts);
6748 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6749 gimplify_seq_add_stmt (pre_p, wce);
6750 }
6751 }
6752
6753 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6754
6755 static enum gimplify_status
gimplify_target_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p)6756 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6757 {
6758 tree targ = *expr_p;
6759 tree temp = TARGET_EXPR_SLOT (targ);
6760 tree init = TARGET_EXPR_INITIAL (targ);
6761 enum gimplify_status ret;
6762
6763 bool unpoison_empty_seq = false;
6764 gimple_stmt_iterator unpoison_it;
6765
6766 if (init)
6767 {
6768 tree cleanup = NULL_TREE;
6769
6770 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6771 to the temps list. Handle also variable length TARGET_EXPRs. */
6772 if (!poly_int_tree_p (DECL_SIZE (temp)))
6773 {
6774 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
6775 gimplify_type_sizes (TREE_TYPE (temp), pre_p);
6776 gimplify_vla_decl (temp, pre_p);
6777 }
6778 else
6779 {
6780 /* Save location where we need to place unpoisoning. It's possible
6781 that a variable will be converted to needs_to_live_in_memory. */
6782 unpoison_it = gsi_last (*pre_p);
6783 unpoison_empty_seq = gsi_end_p (unpoison_it);
6784
6785 gimple_add_tmp_var (temp);
6786 }
6787
6788 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6789 expression is supposed to initialize the slot. */
6790 if (VOID_TYPE_P (TREE_TYPE (init)))
6791 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6792 else
6793 {
6794 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
6795 init = init_expr;
6796 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6797 init = NULL;
6798 ggc_free (init_expr);
6799 }
6800 if (ret == GS_ERROR)
6801 {
6802 /* PR c++/28266 Make sure this is expanded only once. */
6803 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6804 return GS_ERROR;
6805 }
6806 if (init)
6807 gimplify_and_add (init, pre_p);
6808
6809 /* If needed, push the cleanup for the temp. */
6810 if (TARGET_EXPR_CLEANUP (targ))
6811 {
6812 if (CLEANUP_EH_ONLY (targ))
6813 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
6814 CLEANUP_EH_ONLY (targ), pre_p);
6815 else
6816 cleanup = TARGET_EXPR_CLEANUP (targ);
6817 }
6818
6819 /* Add a clobber for the temporary going out of scope, like
6820 gimplify_bind_expr. */
6821 if (gimplify_ctxp->in_cleanup_point_expr
6822 && needs_to_live_in_memory (temp))
6823 {
6824 if (flag_stack_reuse == SR_ALL)
6825 {
6826 tree clobber = build_clobber (TREE_TYPE (temp));
6827 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
6828 gimple_push_cleanup (temp, clobber, false, pre_p, true);
6829 }
6830 if (asan_poisoned_variables
6831 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
6832 && !TREE_STATIC (temp)
6833 && dbg_cnt (asan_use_after_scope)
6834 && !gimplify_omp_ctxp)
6835 {
6836 tree asan_cleanup = build_asan_poison_call_expr (temp);
6837 if (asan_cleanup)
6838 {
6839 if (unpoison_empty_seq)
6840 unpoison_it = gsi_start (*pre_p);
6841
6842 asan_poison_variable (temp, false, &unpoison_it,
6843 unpoison_empty_seq);
6844 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
6845 }
6846 }
6847 }
6848 if (cleanup)
6849 gimple_push_cleanup (temp, cleanup, false, pre_p);
6850
6851 /* Only expand this once. */
6852 TREE_OPERAND (targ, 3) = init;
6853 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6854 }
6855 else
6856 /* We should have expanded this before. */
6857 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
6858
6859 *expr_p = temp;
6860 return GS_OK;
6861 }
6862
6863 /* Gimplification of expression trees. */
6864
6865 /* Gimplify an expression which appears at statement context. The
6866 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
6867 NULL, a new sequence is allocated.
6868
6869 Return true if we actually added a statement to the queue. */
6870
6871 bool
gimplify_stmt(tree * stmt_p,gimple_seq * seq_p)6872 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
6873 {
6874 gimple_seq_node last;
6875
6876 last = gimple_seq_last (*seq_p);
6877 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
6878 return last != gimple_seq_last (*seq_p);
6879 }
6880
6881 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
6882 to CTX. If entries already exist, force them to be some flavor of private.
6883 If there is no enclosing parallel, do nothing. */
6884
6885 void
omp_firstprivatize_variable(struct gimplify_omp_ctx * ctx,tree decl)6886 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
6887 {
6888 splay_tree_node n;
6889
6890 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
6891 return;
6892
6893 do
6894 {
6895 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6896 if (n != NULL)
6897 {
6898 if (n->value & GOVD_SHARED)
6899 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
6900 else if (n->value & GOVD_MAP)
6901 n->value |= GOVD_MAP_TO_ONLY;
6902 else
6903 return;
6904 }
6905 else if ((ctx->region_type & ORT_TARGET) != 0)
6906 {
6907 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
6908 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6909 else
6910 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
6911 }
6912 else if (ctx->region_type != ORT_WORKSHARE
6913 && ctx->region_type != ORT_TASKGROUP
6914 && ctx->region_type != ORT_SIMD
6915 && ctx->region_type != ORT_ACC
6916 && !(ctx->region_type & ORT_TARGET_DATA))
6917 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6918
6919 ctx = ctx->outer_context;
6920 }
6921 while (ctx);
6922 }
6923
6924 /* Similarly for each of the type sizes of TYPE. */
6925
6926 static void
omp_firstprivatize_type_sizes(struct gimplify_omp_ctx * ctx,tree type)6927 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
6928 {
6929 if (type == NULL || type == error_mark_node)
6930 return;
6931 type = TYPE_MAIN_VARIANT (type);
6932
6933 if (ctx->privatized_types->add (type))
6934 return;
6935
6936 switch (TREE_CODE (type))
6937 {
6938 case INTEGER_TYPE:
6939 case ENUMERAL_TYPE:
6940 case BOOLEAN_TYPE:
6941 case REAL_TYPE:
6942 case FIXED_POINT_TYPE:
6943 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
6944 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
6945 break;
6946
6947 case ARRAY_TYPE:
6948 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6949 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
6950 break;
6951
6952 case RECORD_TYPE:
6953 case UNION_TYPE:
6954 case QUAL_UNION_TYPE:
6955 {
6956 tree field;
6957 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
6958 if (TREE_CODE (field) == FIELD_DECL)
6959 {
6960 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
6961 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
6962 }
6963 }
6964 break;
6965
6966 case POINTER_TYPE:
6967 case REFERENCE_TYPE:
6968 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6969 break;
6970
6971 default:
6972 break;
6973 }
6974
6975 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
6976 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
6977 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
6978 }
6979
6980 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
6981
6982 static void
omp_add_variable(struct gimplify_omp_ctx * ctx,tree decl,unsigned int flags)6983 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
6984 {
6985 splay_tree_node n;
6986 unsigned int nflags;
6987 tree t;
6988
6989 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
6990 return;
6991
6992 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
6993 there are constructors involved somewhere. Exception is a shared clause,
6994 there is nothing privatized in that case. */
6995 if ((flags & GOVD_SHARED) == 0
6996 && (TREE_ADDRESSABLE (TREE_TYPE (decl))
6997 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
6998 flags |= GOVD_SEEN;
6999
7000 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7001 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7002 {
7003 /* We shouldn't be re-adding the decl with the same data
7004 sharing class. */
7005 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
7006 nflags = n->value | flags;
7007 /* The only combination of data sharing classes we should see is
7008 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
7009 reduction variables to be used in data sharing clauses. */
7010 gcc_assert ((ctx->region_type & ORT_ACC) != 0
7011 || ((nflags & GOVD_DATA_SHARE_CLASS)
7012 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
7013 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
7014 n->value = nflags;
7015 return;
7016 }
7017
7018 /* When adding a variable-sized variable, we have to handle all sorts
7019 of additional bits of data: the pointer replacement variable, and
7020 the parameters of the type. */
7021 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7022 {
7023 /* Add the pointer replacement variable as PRIVATE if the variable
7024 replacement is private, else FIRSTPRIVATE since we'll need the
7025 address of the original variable either for SHARED, or for the
7026 copy into or out of the context. */
7027 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
7028 {
7029 if (flags & GOVD_MAP)
7030 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
7031 else if (flags & GOVD_PRIVATE)
7032 nflags = GOVD_PRIVATE;
7033 else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7034 && (flags & GOVD_FIRSTPRIVATE))
7035 || (ctx->region_type == ORT_TARGET_DATA
7036 && (flags & GOVD_DATA_SHARE_CLASS) == 0))
7037 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
7038 else
7039 nflags = GOVD_FIRSTPRIVATE;
7040 nflags |= flags & GOVD_SEEN;
7041 t = DECL_VALUE_EXPR (decl);
7042 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7043 t = TREE_OPERAND (t, 0);
7044 gcc_assert (DECL_P (t));
7045 omp_add_variable (ctx, t, nflags);
7046 }
7047
7048 /* Add all of the variable and type parameters (which should have
7049 been gimplified to a formal temporary) as FIRSTPRIVATE. */
7050 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
7051 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
7052 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7053
7054 /* The variable-sized variable itself is never SHARED, only some form
7055 of PRIVATE. The sharing would take place via the pointer variable
7056 which we remapped above. */
7057 if (flags & GOVD_SHARED)
7058 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
7059 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
7060
7061 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7062 alloca statement we generate for the variable, so make sure it
7063 is available. This isn't automatically needed for the SHARED
7064 case, since we won't be allocating local storage then.
7065 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7066 in this case omp_notice_variable will be called later
7067 on when it is gimplified. */
7068 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
7069 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
7070 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
7071 }
7072 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
7073 && lang_hooks.decls.omp_privatize_by_reference (decl))
7074 {
7075 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7076
7077 /* Similar to the direct variable sized case above, we'll need the
7078 size of references being privatized. */
7079 if ((flags & GOVD_SHARED) == 0)
7080 {
7081 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7082 if (t && DECL_P (t))
7083 omp_notice_variable (ctx, t, true);
7084 }
7085 }
7086
7087 if (n != NULL)
7088 n->value |= flags;
7089 else
7090 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
7091
7092 /* For reductions clauses in OpenACC loop directives, by default create a
7093 copy clause on the enclosing parallel construct for carrying back the
7094 results. */
7095 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
7096 {
7097 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
7098 while (outer_ctx)
7099 {
7100 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
7101 if (n != NULL)
7102 {
7103 /* Ignore local variables and explicitly declared clauses. */
7104 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
7105 break;
7106 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
7107 {
7108 /* According to the OpenACC spec, such a reduction variable
7109 should already have a copy map on a kernels construct,
7110 verify that here. */
7111 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
7112 && (n->value & GOVD_MAP));
7113 }
7114 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7115 {
7116 /* Remove firstprivate and make it a copy map. */
7117 n->value &= ~GOVD_FIRSTPRIVATE;
7118 n->value |= GOVD_MAP;
7119 }
7120 }
7121 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7122 {
7123 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
7124 GOVD_MAP | GOVD_SEEN);
7125 break;
7126 }
7127 outer_ctx = outer_ctx->outer_context;
7128 }
7129 }
7130 }
7131
7132 /* Notice a threadprivate variable DECL used in OMP context CTX.
7133 This just prints out diagnostics about threadprivate variable uses
7134 in untied tasks. If DECL2 is non-NULL, prevent this warning
7135 on that variable. */
7136
7137 static bool
omp_notice_threadprivate_variable(struct gimplify_omp_ctx * ctx,tree decl,tree decl2)7138 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
7139 tree decl2)
7140 {
7141 splay_tree_node n;
7142 struct gimplify_omp_ctx *octx;
7143
7144 for (octx = ctx; octx; octx = octx->outer_context)
7145 if ((octx->region_type & ORT_TARGET) != 0
7146 || octx->order_concurrent)
7147 {
7148 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
7149 if (n == NULL)
7150 {
7151 if (octx->order_concurrent)
7152 {
7153 error ("threadprivate variable %qE used in a region with"
7154 " %<order(concurrent)%> clause", DECL_NAME (decl));
7155 inform (octx->location, "enclosing region");
7156 }
7157 else
7158 {
7159 error ("threadprivate variable %qE used in target region",
7160 DECL_NAME (decl));
7161 inform (octx->location, "enclosing target region");
7162 }
7163 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
7164 }
7165 if (decl2)
7166 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
7167 }
7168
7169 if (ctx->region_type != ORT_UNTIED_TASK)
7170 return false;
7171 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7172 if (n == NULL)
7173 {
7174 error ("threadprivate variable %qE used in untied task",
7175 DECL_NAME (decl));
7176 inform (ctx->location, "enclosing task");
7177 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
7178 }
7179 if (decl2)
7180 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
7181 return false;
7182 }
7183
7184 /* Return true if global var DECL is device resident. */
7185
7186 static bool
device_resident_p(tree decl)7187 device_resident_p (tree decl)
7188 {
7189 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
7190
7191 if (!attr)
7192 return false;
7193
7194 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
7195 {
7196 tree c = TREE_VALUE (t);
7197 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
7198 return true;
7199 }
7200
7201 return false;
7202 }
7203
7204 /* Return true if DECL has an ACC DECLARE attribute. */
7205
7206 static bool
is_oacc_declared(tree decl)7207 is_oacc_declared (tree decl)
7208 {
7209 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
7210 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
7211 return declared != NULL_TREE;
7212 }
7213
7214 /* Determine outer default flags for DECL mentioned in an OMP region
7215 but not declared in an enclosing clause.
7216
7217 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7218 remapped firstprivate instead of shared. To some extent this is
7219 addressed in omp_firstprivatize_type_sizes, but not
7220 effectively. */
7221
7222 static unsigned
omp_default_clause(struct gimplify_omp_ctx * ctx,tree decl,bool in_code,unsigned flags)7223 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
7224 bool in_code, unsigned flags)
7225 {
7226 enum omp_clause_default_kind default_kind = ctx->default_kind;
7227 enum omp_clause_default_kind kind;
7228
7229 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
7230 if (ctx->region_type & ORT_TASK)
7231 {
7232 tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH);
7233
7234 /* The event-handle specified by a detach clause should always be firstprivate,
7235 regardless of the current default. */
7236 if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl)
7237 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
7238 }
7239 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7240 default_kind = kind;
7241 else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
7242 default_kind = OMP_CLAUSE_DEFAULT_SHARED;
7243
7244 switch (default_kind)
7245 {
7246 case OMP_CLAUSE_DEFAULT_NONE:
7247 {
7248 const char *rtype;
7249
7250 if (ctx->region_type & ORT_PARALLEL)
7251 rtype = "parallel";
7252 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
7253 rtype = "taskloop";
7254 else if (ctx->region_type & ORT_TASK)
7255 rtype = "task";
7256 else if (ctx->region_type & ORT_TEAMS)
7257 rtype = "teams";
7258 else
7259 gcc_unreachable ();
7260
7261 error ("%qE not specified in enclosing %qs",
7262 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7263 inform (ctx->location, "enclosing %qs", rtype);
7264 }
7265 /* FALLTHRU */
7266 case OMP_CLAUSE_DEFAULT_SHARED:
7267 flags |= GOVD_SHARED;
7268 break;
7269 case OMP_CLAUSE_DEFAULT_PRIVATE:
7270 flags |= GOVD_PRIVATE;
7271 break;
7272 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7273 flags |= GOVD_FIRSTPRIVATE;
7274 break;
7275 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7276 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7277 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7278 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7279 {
7280 omp_notice_variable (octx, decl, in_code);
7281 for (; octx; octx = octx->outer_context)
7282 {
7283 splay_tree_node n2;
7284
7285 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7286 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7287 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7288 continue;
7289 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7290 {
7291 flags |= GOVD_FIRSTPRIVATE;
7292 goto found_outer;
7293 }
7294 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7295 {
7296 flags |= GOVD_SHARED;
7297 goto found_outer;
7298 }
7299 }
7300 }
7301
7302 if (TREE_CODE (decl) == PARM_DECL
7303 || (!is_global_var (decl)
7304 && DECL_CONTEXT (decl) == current_function_decl))
7305 flags |= GOVD_FIRSTPRIVATE;
7306 else
7307 flags |= GOVD_SHARED;
7308 found_outer:
7309 break;
7310
7311 default:
7312 gcc_unreachable ();
7313 }
7314
7315 return flags;
7316 }
7317
7318
7319 /* Determine outer default flags for DECL mentioned in an OACC region
7320 but not declared in an enclosing clause. */
7321
7322 static unsigned
oacc_default_clause(struct gimplify_omp_ctx * ctx,tree decl,unsigned flags)7323 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7324 {
7325 const char *rkind;
7326 bool on_device = false;
7327 bool is_private = false;
7328 bool declared = is_oacc_declared (decl);
7329 tree type = TREE_TYPE (decl);
7330
7331 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7332 type = TREE_TYPE (type);
7333
7334 /* For Fortran COMMON blocks, only used variables in those blocks are
7335 transfered and remapped. The block itself will have a private clause to
7336 avoid transfering the data twice.
7337 The hook evaluates to false by default. For a variable in Fortran's COMMON
7338 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7339 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7340 the whole block. For C++ and Fortran, it can also be true under certain
7341 other conditions, if DECL_HAS_VALUE_EXPR. */
7342 if (RECORD_OR_UNION_TYPE_P (type))
7343 is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
7344
7345 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7346 && is_global_var (decl)
7347 && device_resident_p (decl)
7348 && !is_private)
7349 {
7350 on_device = true;
7351 flags |= GOVD_MAP_TO_ONLY;
7352 }
7353
7354 switch (ctx->region_type)
7355 {
7356 case ORT_ACC_KERNELS:
7357 rkind = "kernels";
7358
7359 if (is_private)
7360 flags |= GOVD_FIRSTPRIVATE;
7361 else if (AGGREGATE_TYPE_P (type))
7362 {
7363 /* Aggregates default to 'present_or_copy', or 'present'. */
7364 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7365 flags |= GOVD_MAP;
7366 else
7367 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7368 }
7369 else
7370 /* Scalars default to 'copy'. */
7371 flags |= GOVD_MAP | GOVD_MAP_FORCE;
7372
7373 break;
7374
7375 case ORT_ACC_PARALLEL:
7376 case ORT_ACC_SERIAL:
7377 rkind = ctx->region_type == ORT_ACC_PARALLEL ? "parallel" : "serial";
7378
7379 if (is_private)
7380 flags |= GOVD_FIRSTPRIVATE;
7381 else if (on_device || declared)
7382 flags |= GOVD_MAP;
7383 else if (AGGREGATE_TYPE_P (type))
7384 {
7385 /* Aggregates default to 'present_or_copy', or 'present'. */
7386 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7387 flags |= GOVD_MAP;
7388 else
7389 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7390 }
7391 else
7392 /* Scalars default to 'firstprivate'. */
7393 flags |= GOVD_FIRSTPRIVATE;
7394
7395 break;
7396
7397 default:
7398 gcc_unreachable ();
7399 }
7400
7401 if (DECL_ARTIFICIAL (decl))
7402 ; /* We can get compiler-generated decls, and should not complain
7403 about them. */
7404 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7405 {
7406 error ("%qE not specified in enclosing OpenACC %qs construct",
7407 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
7408 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
7409 }
7410 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7411 ; /* Handled above. */
7412 else
7413 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7414
7415 return flags;
7416 }
7417
7418 /* Record the fact that DECL was used within the OMP context CTX.
7419 IN_CODE is true when real code uses DECL, and false when we should
7420 merely emit default(none) errors. Return true if DECL is going to
7421 be remapped and thus DECL shouldn't be gimplified into its
7422 DECL_VALUE_EXPR (if any). */
7423
7424 static bool
omp_notice_variable(struct gimplify_omp_ctx * ctx,tree decl,bool in_code)7425 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7426 {
7427 splay_tree_node n;
7428 unsigned flags = in_code ? GOVD_SEEN : 0;
7429 bool ret = false, shared;
7430
7431 if (error_operand_p (decl))
7432 return false;
7433
7434 if (ctx->region_type == ORT_NONE)
7435 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7436
7437 if (is_global_var (decl))
7438 {
7439 /* Threadprivate variables are predetermined. */
7440 if (DECL_THREAD_LOCAL_P (decl))
7441 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7442
7443 if (DECL_HAS_VALUE_EXPR_P (decl))
7444 {
7445 if (ctx->region_type & ORT_ACC)
7446 /* For OpenACC, defer expansion of value to avoid transfering
7447 privatized common block data instead of im-/explicitly transfered
7448 variables which are in common blocks. */
7449 ;
7450 else
7451 {
7452 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7453
7454 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7455 return omp_notice_threadprivate_variable (ctx, decl, value);
7456 }
7457 }
7458
7459 if (gimplify_omp_ctxp->outer_context == NULL
7460 && VAR_P (decl)
7461 && oacc_get_fn_attrib (current_function_decl))
7462 {
7463 location_t loc = DECL_SOURCE_LOCATION (decl);
7464
7465 if (lookup_attribute ("omp declare target link",
7466 DECL_ATTRIBUTES (decl)))
7467 {
7468 error_at (loc,
7469 "%qE with %<link%> clause used in %<routine%> function",
7470 DECL_NAME (decl));
7471 return false;
7472 }
7473 else if (!lookup_attribute ("omp declare target",
7474 DECL_ATTRIBUTES (decl)))
7475 {
7476 error_at (loc,
7477 "%qE requires a %<declare%> directive for use "
7478 "in a %<routine%> function", DECL_NAME (decl));
7479 return false;
7480 }
7481 }
7482 }
7483
7484 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7485 if ((ctx->region_type & ORT_TARGET) != 0)
7486 {
7487 if (ctx->region_type & ORT_ACC)
7488 /* For OpenACC, as remarked above, defer expansion. */
7489 shared = false;
7490 else
7491 shared = true;
7492
7493 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7494 if (n == NULL)
7495 {
7496 unsigned nflags = flags;
7497 if ((ctx->region_type & ORT_ACC) == 0)
7498 {
7499 bool is_declare_target = false;
7500 if (is_global_var (decl)
7501 && varpool_node::get_create (decl)->offloadable)
7502 {
7503 struct gimplify_omp_ctx *octx;
7504 for (octx = ctx->outer_context;
7505 octx; octx = octx->outer_context)
7506 {
7507 n = splay_tree_lookup (octx->variables,
7508 (splay_tree_key)decl);
7509 if (n
7510 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7511 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7512 break;
7513 }
7514 is_declare_target = octx == NULL;
7515 }
7516 if (!is_declare_target)
7517 {
7518 int gdmk;
7519 enum omp_clause_defaultmap_kind kind;
7520 if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7521 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7522 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7523 == POINTER_TYPE)))
7524 gdmk = GDMK_POINTER;
7525 else if (lang_hooks.decls.omp_scalar_p (decl))
7526 gdmk = GDMK_SCALAR;
7527 else
7528 gdmk = GDMK_AGGREGATE;
7529 kind = lang_hooks.decls.omp_predetermined_mapping (decl);
7530 if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
7531 {
7532 if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
7533 nflags |= GOVD_FIRSTPRIVATE;
7534 else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
7535 nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
7536 else
7537 gcc_unreachable ();
7538 }
7539 else if (ctx->defaultmap[gdmk] == 0)
7540 {
7541 tree d = lang_hooks.decls.omp_report_decl (decl);
7542 error ("%qE not specified in enclosing %<target%>",
7543 DECL_NAME (d));
7544 inform (ctx->location, "enclosing %<target%>");
7545 }
7546 else if (ctx->defaultmap[gdmk]
7547 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
7548 nflags |= ctx->defaultmap[gdmk];
7549 else
7550 {
7551 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
7552 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
7553 }
7554 }
7555 }
7556
7557 struct gimplify_omp_ctx *octx = ctx->outer_context;
7558 if ((ctx->region_type & ORT_ACC) && octx)
7559 {
7560 /* Look in outer OpenACC contexts, to see if there's a
7561 data attribute for this variable. */
7562 omp_notice_variable (octx, decl, in_code);
7563
7564 for (; octx; octx = octx->outer_context)
7565 {
7566 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7567 break;
7568 splay_tree_node n2
7569 = splay_tree_lookup (octx->variables,
7570 (splay_tree_key) decl);
7571 if (n2)
7572 {
7573 if (octx->region_type == ORT_ACC_HOST_DATA)
7574 error ("variable %qE declared in enclosing "
7575 "%<host_data%> region", DECL_NAME (decl));
7576 nflags |= GOVD_MAP;
7577 if (octx->region_type == ORT_ACC_DATA
7578 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7579 nflags |= GOVD_MAP_0LEN_ARRAY;
7580 goto found_outer;
7581 }
7582 }
7583 }
7584
7585 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
7586 | GOVD_MAP_ALLOC_ONLY)) == flags)
7587 {
7588 tree type = TREE_TYPE (decl);
7589
7590 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
7591 && lang_hooks.decls.omp_privatize_by_reference (decl))
7592 type = TREE_TYPE (type);
7593 if (!lang_hooks.types.omp_mappable_type (type))
7594 {
7595 error ("%qD referenced in target region does not have "
7596 "a mappable type", decl);
7597 nflags |= GOVD_MAP | GOVD_EXPLICIT;
7598 }
7599 else
7600 {
7601 if ((ctx->region_type & ORT_ACC) != 0)
7602 nflags = oacc_default_clause (ctx, decl, flags);
7603 else
7604 nflags |= GOVD_MAP;
7605 }
7606 }
7607 found_outer:
7608 omp_add_variable (ctx, decl, nflags);
7609 }
7610 else
7611 {
7612 /* If nothing changed, there's nothing left to do. */
7613 if ((n->value & flags) == flags)
7614 return ret;
7615 flags |= n->value;
7616 n->value = flags;
7617 }
7618 goto do_outer;
7619 }
7620
7621 if (n == NULL)
7622 {
7623 if (ctx->region_type == ORT_WORKSHARE
7624 || ctx->region_type == ORT_TASKGROUP
7625 || ctx->region_type == ORT_SIMD
7626 || ctx->region_type == ORT_ACC
7627 || (ctx->region_type & ORT_TARGET_DATA) != 0)
7628 goto do_outer;
7629
7630 flags = omp_default_clause (ctx, decl, in_code, flags);
7631
7632 if ((flags & GOVD_PRIVATE)
7633 && lang_hooks.decls.omp_private_outer_ref (decl))
7634 flags |= GOVD_PRIVATE_OUTER_REF;
7635
7636 omp_add_variable (ctx, decl, flags);
7637
7638 shared = (flags & GOVD_SHARED) != 0;
7639 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7640 goto do_outer;
7641 }
7642
7643 /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
7644 lb, b or incr expressions, those shouldn't be turned into simd arrays. */
7645 if (ctx->region_type == ORT_SIMD
7646 && ctx->in_for_exprs
7647 && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
7648 == GOVD_PRIVATE))
7649 flags &= ~GOVD_SEEN;
7650
7651 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7652 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7653 && DECL_SIZE (decl))
7654 {
7655 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7656 {
7657 splay_tree_node n2;
7658 tree t = DECL_VALUE_EXPR (decl);
7659 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7660 t = TREE_OPERAND (t, 0);
7661 gcc_assert (DECL_P (t));
7662 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7663 n2->value |= GOVD_SEEN;
7664 }
7665 else if (lang_hooks.decls.omp_privatize_by_reference (decl)
7666 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7667 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7668 != INTEGER_CST))
7669 {
7670 splay_tree_node n2;
7671 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7672 gcc_assert (DECL_P (t));
7673 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7674 if (n2)
7675 omp_notice_variable (ctx, t, true);
7676 }
7677 }
7678
7679 if (ctx->region_type & ORT_ACC)
7680 /* For OpenACC, as remarked above, defer expansion. */
7681 shared = false;
7682 else
7683 shared = ((flags | n->value) & GOVD_SHARED) != 0;
7684 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7685
7686 /* If nothing changed, there's nothing left to do. */
7687 if ((n->value & flags) == flags)
7688 return ret;
7689 flags |= n->value;
7690 n->value = flags;
7691
7692 do_outer:
7693 /* If the variable is private in the current context, then we don't
7694 need to propagate anything to an outer context. */
7695 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7696 return ret;
7697 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7698 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7699 return ret;
7700 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7701 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7702 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7703 return ret;
7704 if (ctx->outer_context
7705 && omp_notice_variable (ctx->outer_context, decl, in_code))
7706 return true;
7707 return ret;
7708 }
7709
7710 /* Verify that DECL is private within CTX. If there's specific information
7711 to the contrary in the innermost scope, generate an error. */
7712
7713 static bool
omp_is_private(struct gimplify_omp_ctx * ctx,tree decl,int simd)7714 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
7715 {
7716 splay_tree_node n;
7717
7718 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7719 if (n != NULL)
7720 {
7721 if (n->value & GOVD_SHARED)
7722 {
7723 if (ctx == gimplify_omp_ctxp)
7724 {
7725 if (simd)
7726 error ("iteration variable %qE is predetermined linear",
7727 DECL_NAME (decl));
7728 else
7729 error ("iteration variable %qE should be private",
7730 DECL_NAME (decl));
7731 n->value = GOVD_PRIVATE;
7732 return true;
7733 }
7734 else
7735 return false;
7736 }
7737 else if ((n->value & GOVD_EXPLICIT) != 0
7738 && (ctx == gimplify_omp_ctxp
7739 || (ctx->region_type == ORT_COMBINED_PARALLEL
7740 && gimplify_omp_ctxp->outer_context == ctx)))
7741 {
7742 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
7743 error ("iteration variable %qE should not be firstprivate",
7744 DECL_NAME (decl));
7745 else if ((n->value & GOVD_REDUCTION) != 0)
7746 error ("iteration variable %qE should not be reduction",
7747 DECL_NAME (decl));
7748 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
7749 error ("iteration variable %qE should not be linear",
7750 DECL_NAME (decl));
7751 }
7752 return (ctx == gimplify_omp_ctxp
7753 || (ctx->region_type == ORT_COMBINED_PARALLEL
7754 && gimplify_omp_ctxp->outer_context == ctx));
7755 }
7756
7757 if (ctx->region_type != ORT_WORKSHARE
7758 && ctx->region_type != ORT_TASKGROUP
7759 && ctx->region_type != ORT_SIMD
7760 && ctx->region_type != ORT_ACC)
7761 return false;
7762 else if (ctx->outer_context)
7763 return omp_is_private (ctx->outer_context, decl, simd);
7764 return false;
7765 }
7766
7767 /* Return true if DECL is private within a parallel region
7768 that binds to the current construct's context or in parallel
7769 region's REDUCTION clause. */
7770
7771 static bool
omp_check_private(struct gimplify_omp_ctx * ctx,tree decl,bool copyprivate)7772 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
7773 {
7774 splay_tree_node n;
7775
7776 do
7777 {
7778 ctx = ctx->outer_context;
7779 if (ctx == NULL)
7780 {
7781 if (is_global_var (decl))
7782 return false;
7783
7784 /* References might be private, but might be shared too,
7785 when checking for copyprivate, assume they might be
7786 private, otherwise assume they might be shared. */
7787 if (copyprivate)
7788 return true;
7789
7790 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7791 return false;
7792
7793 /* Treat C++ privatized non-static data members outside
7794 of the privatization the same. */
7795 if (omp_member_access_dummy_var (decl))
7796 return false;
7797
7798 return true;
7799 }
7800
7801 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
7802
7803 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7804 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
7805 {
7806 if ((ctx->region_type & ORT_TARGET_DATA) != 0
7807 || n == NULL
7808 || (n->value & GOVD_MAP) == 0)
7809 continue;
7810 return false;
7811 }
7812
7813 if (n != NULL)
7814 {
7815 if ((n->value & GOVD_LOCAL) != 0
7816 && omp_member_access_dummy_var (decl))
7817 return false;
7818 return (n->value & GOVD_SHARED) == 0;
7819 }
7820
7821 if (ctx->region_type == ORT_WORKSHARE
7822 || ctx->region_type == ORT_TASKGROUP
7823 || ctx->region_type == ORT_SIMD
7824 || ctx->region_type == ORT_ACC)
7825 continue;
7826
7827 break;
7828 }
7829 while (1);
7830 return false;
7831 }
7832
7833 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7834
7835 static tree
find_decl_expr(tree * tp,int * walk_subtrees,void * data)7836 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
7837 {
7838 tree t = *tp;
7839
7840 /* If this node has been visited, unmark it and keep looking. */
7841 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
7842 return t;
7843
7844 if (IS_TYPE_OR_DECL_P (t))
7845 *walk_subtrees = 0;
7846 return NULL_TREE;
7847 }
7848
7849 /* If *LIST_P contains any OpenMP depend clauses with iterators,
7850 lower all the depend clauses by populating corresponding depend
7851 array. Returns 0 if there are no such depend clauses, or
7852 2 if all depend clauses should be removed, 1 otherwise. */
7853
7854 static int
gimplify_omp_depend(tree * list_p,gimple_seq * pre_p)7855 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
7856 {
7857 tree c;
7858 gimple *g;
7859 size_t n[4] = { 0, 0, 0, 0 };
7860 bool unused[4];
7861 tree counts[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
7862 tree last_iter = NULL_TREE, last_count = NULL_TREE;
7863 size_t i, j;
7864 location_t first_loc = UNKNOWN_LOCATION;
7865
7866 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
7867 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
7868 {
7869 switch (OMP_CLAUSE_DEPEND_KIND (c))
7870 {
7871 case OMP_CLAUSE_DEPEND_IN:
7872 i = 2;
7873 break;
7874 case OMP_CLAUSE_DEPEND_OUT:
7875 case OMP_CLAUSE_DEPEND_INOUT:
7876 i = 0;
7877 break;
7878 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
7879 i = 1;
7880 break;
7881 case OMP_CLAUSE_DEPEND_DEPOBJ:
7882 i = 3;
7883 break;
7884 case OMP_CLAUSE_DEPEND_SOURCE:
7885 case OMP_CLAUSE_DEPEND_SINK:
7886 continue;
7887 default:
7888 gcc_unreachable ();
7889 }
7890 tree t = OMP_CLAUSE_DECL (c);
7891 if (first_loc == UNKNOWN_LOCATION)
7892 first_loc = OMP_CLAUSE_LOCATION (c);
7893 if (TREE_CODE (t) == TREE_LIST
7894 && TREE_PURPOSE (t)
7895 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
7896 {
7897 if (TREE_PURPOSE (t) != last_iter)
7898 {
7899 tree tcnt = size_one_node;
7900 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
7901 {
7902 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
7903 is_gimple_val, fb_rvalue) == GS_ERROR
7904 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
7905 is_gimple_val, fb_rvalue) == GS_ERROR
7906 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
7907 is_gimple_val, fb_rvalue) == GS_ERROR
7908 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
7909 is_gimple_val, fb_rvalue)
7910 == GS_ERROR))
7911 return 2;
7912 tree var = TREE_VEC_ELT (it, 0);
7913 tree begin = TREE_VEC_ELT (it, 1);
7914 tree end = TREE_VEC_ELT (it, 2);
7915 tree step = TREE_VEC_ELT (it, 3);
7916 tree orig_step = TREE_VEC_ELT (it, 4);
7917 tree type = TREE_TYPE (var);
7918 tree stype = TREE_TYPE (step);
7919 location_t loc = DECL_SOURCE_LOCATION (var);
7920 tree endmbegin;
7921 /* Compute count for this iterator as
7922 orig_step > 0
7923 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
7924 : (begin > end ? (end - begin + (step + 1)) / step : 0)
7925 and compute product of those for the entire depend
7926 clause. */
7927 if (POINTER_TYPE_P (type))
7928 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
7929 stype, end, begin);
7930 else
7931 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
7932 end, begin);
7933 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
7934 step,
7935 build_int_cst (stype, 1));
7936 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
7937 build_int_cst (stype, 1));
7938 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
7939 unshare_expr (endmbegin),
7940 stepm1);
7941 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
7942 pos, step);
7943 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
7944 endmbegin, stepp1);
7945 if (TYPE_UNSIGNED (stype))
7946 {
7947 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
7948 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
7949 }
7950 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
7951 neg, step);
7952 step = NULL_TREE;
7953 tree cond = fold_build2_loc (loc, LT_EXPR,
7954 boolean_type_node,
7955 begin, end);
7956 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
7957 build_int_cst (stype, 0));
7958 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
7959 end, begin);
7960 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
7961 build_int_cst (stype, 0));
7962 tree osteptype = TREE_TYPE (orig_step);
7963 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
7964 orig_step,
7965 build_int_cst (osteptype, 0));
7966 tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
7967 cond, pos, neg);
7968 cnt = fold_convert_loc (loc, sizetype, cnt);
7969 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
7970 fb_rvalue) == GS_ERROR)
7971 return 2;
7972 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
7973 }
7974 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
7975 fb_rvalue) == GS_ERROR)
7976 return 2;
7977 last_iter = TREE_PURPOSE (t);
7978 last_count = tcnt;
7979 }
7980 if (counts[i] == NULL_TREE)
7981 counts[i] = last_count;
7982 else
7983 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
7984 PLUS_EXPR, counts[i], last_count);
7985 }
7986 else
7987 n[i]++;
7988 }
7989 for (i = 0; i < 4; i++)
7990 if (counts[i])
7991 break;
7992 if (i == 4)
7993 return 0;
7994
7995 tree total = size_zero_node;
7996 for (i = 0; i < 4; i++)
7997 {
7998 unused[i] = counts[i] == NULL_TREE && n[i] == 0;
7999 if (counts[i] == NULL_TREE)
8000 counts[i] = size_zero_node;
8001 if (n[i])
8002 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
8003 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
8004 fb_rvalue) == GS_ERROR)
8005 return 2;
8006 total = size_binop (PLUS_EXPR, total, counts[i]);
8007 }
8008
8009 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
8010 == GS_ERROR)
8011 return 2;
8012 bool is_old = unused[1] && unused[3];
8013 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
8014 size_int (is_old ? 1 : 4));
8015 tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
8016 tree array = create_tmp_var_raw (type);
8017 TREE_ADDRESSABLE (array) = 1;
8018 if (!poly_int_tree_p (totalpx))
8019 {
8020 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
8021 gimplify_type_sizes (TREE_TYPE (array), pre_p);
8022 if (gimplify_omp_ctxp)
8023 {
8024 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8025 while (ctx
8026 && (ctx->region_type == ORT_WORKSHARE
8027 || ctx->region_type == ORT_TASKGROUP
8028 || ctx->region_type == ORT_SIMD
8029 || ctx->region_type == ORT_ACC))
8030 ctx = ctx->outer_context;
8031 if (ctx)
8032 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
8033 }
8034 gimplify_vla_decl (array, pre_p);
8035 }
8036 else
8037 gimple_add_tmp_var (array);
8038 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
8039 NULL_TREE);
8040 tree tem;
8041 if (!is_old)
8042 {
8043 tem = build2 (MODIFY_EXPR, void_type_node, r,
8044 build_int_cst (ptr_type_node, 0));
8045 gimplify_and_add (tem, pre_p);
8046 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
8047 NULL_TREE);
8048 }
8049 tem = build2 (MODIFY_EXPR, void_type_node, r,
8050 fold_convert (ptr_type_node, total));
8051 gimplify_and_add (tem, pre_p);
8052 for (i = 1; i < (is_old ? 2 : 4); i++)
8053 {
8054 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
8055 NULL_TREE, NULL_TREE);
8056 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
8057 gimplify_and_add (tem, pre_p);
8058 }
8059
8060 tree cnts[4];
8061 for (j = 4; j; j--)
8062 if (!unused[j - 1])
8063 break;
8064 for (i = 0; i < 4; i++)
8065 {
8066 if (i && (i >= j || unused[i - 1]))
8067 {
8068 cnts[i] = cnts[i - 1];
8069 continue;
8070 }
8071 cnts[i] = create_tmp_var (sizetype);
8072 if (i == 0)
8073 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
8074 else
8075 {
8076 tree t;
8077 if (is_old)
8078 t = size_binop (PLUS_EXPR, counts[0], size_int (2));
8079 else
8080 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
8081 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
8082 == GS_ERROR)
8083 return 2;
8084 g = gimple_build_assign (cnts[i], t);
8085 }
8086 gimple_seq_add_stmt (pre_p, g);
8087 }
8088
8089 last_iter = NULL_TREE;
8090 tree last_bind = NULL_TREE;
8091 tree *last_body = NULL;
8092 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8093 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8094 {
8095 switch (OMP_CLAUSE_DEPEND_KIND (c))
8096 {
8097 case OMP_CLAUSE_DEPEND_IN:
8098 i = 2;
8099 break;
8100 case OMP_CLAUSE_DEPEND_OUT:
8101 case OMP_CLAUSE_DEPEND_INOUT:
8102 i = 0;
8103 break;
8104 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8105 i = 1;
8106 break;
8107 case OMP_CLAUSE_DEPEND_DEPOBJ:
8108 i = 3;
8109 break;
8110 case OMP_CLAUSE_DEPEND_SOURCE:
8111 case OMP_CLAUSE_DEPEND_SINK:
8112 continue;
8113 default:
8114 gcc_unreachable ();
8115 }
8116 tree t = OMP_CLAUSE_DECL (c);
8117 if (TREE_CODE (t) == TREE_LIST
8118 && TREE_PURPOSE (t)
8119 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8120 {
8121 if (TREE_PURPOSE (t) != last_iter)
8122 {
8123 if (last_bind)
8124 gimplify_and_add (last_bind, pre_p);
8125 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8126 last_bind = build3 (BIND_EXPR, void_type_node,
8127 BLOCK_VARS (block), NULL, block);
8128 TREE_SIDE_EFFECTS (last_bind) = 1;
8129 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
8130 tree *p = &BIND_EXPR_BODY (last_bind);
8131 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8132 {
8133 tree var = TREE_VEC_ELT (it, 0);
8134 tree begin = TREE_VEC_ELT (it, 1);
8135 tree end = TREE_VEC_ELT (it, 2);
8136 tree step = TREE_VEC_ELT (it, 3);
8137 tree orig_step = TREE_VEC_ELT (it, 4);
8138 tree type = TREE_TYPE (var);
8139 location_t loc = DECL_SOURCE_LOCATION (var);
8140 /* Emit:
8141 var = begin;
8142 goto cond_label;
8143 beg_label:
8144 ...
8145 var = var + step;
8146 cond_label:
8147 if (orig_step > 0) {
8148 if (var < end) goto beg_label;
8149 } else {
8150 if (var > end) goto beg_label;
8151 }
8152 for each iterator, with inner iterators added to
8153 the ... above. */
8154 tree beg_label = create_artificial_label (loc);
8155 tree cond_label = NULL_TREE;
8156 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8157 var, begin);
8158 append_to_statement_list_force (tem, p);
8159 tem = build_and_jump (&cond_label);
8160 append_to_statement_list_force (tem, p);
8161 tem = build1 (LABEL_EXPR, void_type_node, beg_label);
8162 append_to_statement_list (tem, p);
8163 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
8164 NULL_TREE, NULL_TREE);
8165 TREE_SIDE_EFFECTS (bind) = 1;
8166 SET_EXPR_LOCATION (bind, loc);
8167 append_to_statement_list_force (bind, p);
8168 if (POINTER_TYPE_P (type))
8169 tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
8170 var, fold_convert_loc (loc, sizetype,
8171 step));
8172 else
8173 tem = build2_loc (loc, PLUS_EXPR, type, var, step);
8174 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8175 var, tem);
8176 append_to_statement_list_force (tem, p);
8177 tem = build1 (LABEL_EXPR, void_type_node, cond_label);
8178 append_to_statement_list (tem, p);
8179 tree cond = fold_build2_loc (loc, LT_EXPR,
8180 boolean_type_node,
8181 var, end);
8182 tree pos
8183 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8184 cond, build_and_jump (&beg_label),
8185 void_node);
8186 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8187 var, end);
8188 tree neg
8189 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8190 cond, build_and_jump (&beg_label),
8191 void_node);
8192 tree osteptype = TREE_TYPE (orig_step);
8193 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8194 orig_step,
8195 build_int_cst (osteptype, 0));
8196 tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
8197 cond, pos, neg);
8198 append_to_statement_list_force (tem, p);
8199 p = &BIND_EXPR_BODY (bind);
8200 }
8201 last_body = p;
8202 }
8203 last_iter = TREE_PURPOSE (t);
8204 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8205 {
8206 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
8207 0), last_body);
8208 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8209 }
8210 if (error_operand_p (TREE_VALUE (t)))
8211 return 2;
8212 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
8213 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8214 NULL_TREE, NULL_TREE);
8215 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8216 void_type_node, r, TREE_VALUE (t));
8217 append_to_statement_list_force (tem, last_body);
8218 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8219 void_type_node, cnts[i],
8220 size_binop (PLUS_EXPR, cnts[i], size_int (1)));
8221 append_to_statement_list_force (tem, last_body);
8222 TREE_VALUE (t) = null_pointer_node;
8223 }
8224 else
8225 {
8226 if (last_bind)
8227 {
8228 gimplify_and_add (last_bind, pre_p);
8229 last_bind = NULL_TREE;
8230 }
8231 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8232 {
8233 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8234 NULL, is_gimple_val, fb_rvalue);
8235 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8236 }
8237 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8238 return 2;
8239 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8240 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8241 is_gimple_val, fb_rvalue) == GS_ERROR)
8242 return 2;
8243 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8244 NULL_TREE, NULL_TREE);
8245 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
8246 gimplify_and_add (tem, pre_p);
8247 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, cnts[i],
8248 size_int (1)));
8249 gimple_seq_add_stmt (pre_p, g);
8250 }
8251 }
8252 if (last_bind)
8253 gimplify_and_add (last_bind, pre_p);
8254 tree cond = boolean_false_node;
8255 if (is_old)
8256 {
8257 if (!unused[0])
8258 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
8259 size_binop_loc (first_loc, PLUS_EXPR, counts[0],
8260 size_int (2)));
8261 if (!unused[2])
8262 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8263 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8264 cnts[2],
8265 size_binop_loc (first_loc, PLUS_EXPR,
8266 totalpx,
8267 size_int (1))));
8268 }
8269 else
8270 {
8271 tree prev = size_int (5);
8272 for (i = 0; i < 4; i++)
8273 {
8274 if (unused[i])
8275 continue;
8276 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
8277 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8278 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8279 cnts[i], unshare_expr (prev)));
8280 }
8281 }
8282 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
8283 build_call_expr_loc (first_loc,
8284 builtin_decl_explicit (BUILT_IN_TRAP),
8285 0), void_node);
8286 gimplify_and_add (tem, pre_p);
8287 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
8288 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
8289 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
8290 OMP_CLAUSE_CHAIN (c) = *list_p;
8291 *list_p = c;
8292 return 1;
8293 }
8294
8295 /* Insert a GOMP_MAP_ALLOC or GOMP_MAP_RELEASE node following a
8296 GOMP_MAP_STRUCT mapping. C is an always_pointer mapping. STRUCT_NODE is
8297 the struct node to insert the new mapping after (when the struct node is
8298 initially created). PREV_NODE is the first of two or three mappings for a
8299 pointer, and is either:
8300 - the node before C, when a pair of mappings is used, e.g. for a C/C++
8301 array section.
8302 - not the node before C. This is true when we have a reference-to-pointer
8303 type (with a mapping for the reference and for the pointer), or for
8304 Fortran derived-type mappings with a GOMP_MAP_TO_PSET.
8305 If SCP is non-null, the new node is inserted before *SCP.
8306 if SCP is null, the new node is inserted before PREV_NODE.
8307 The return type is:
8308 - PREV_NODE, if SCP is non-null.
8309 - The newly-created ALLOC or RELEASE node, if SCP is null.
8310 - The second newly-created ALLOC or RELEASE node, if we are mapping a
8311 reference to a pointer. */
8312
8313 static tree
insert_struct_comp_map(enum tree_code code,tree c,tree struct_node,tree prev_node,tree * scp)8314 insert_struct_comp_map (enum tree_code code, tree c, tree struct_node,
8315 tree prev_node, tree *scp)
8316 {
8317 enum gomp_map_kind mkind
8318 = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
8319 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8320
8321 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8322 tree cl = scp ? prev_node : c2;
8323 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8324 OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (c));
8325 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : prev_node;
8326 if (OMP_CLAUSE_CHAIN (prev_node) != c
8327 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8328 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8329 == GOMP_MAP_TO_PSET))
8330 OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (OMP_CLAUSE_CHAIN (prev_node));
8331 else
8332 OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
8333 if (struct_node)
8334 OMP_CLAUSE_CHAIN (struct_node) = c2;
8335
8336 /* We might need to create an additional mapping if we have a reference to a
8337 pointer (in C++). Don't do this if we have something other than a
8338 GOMP_MAP_ALWAYS_POINTER though, i.e. a GOMP_MAP_TO_PSET. */
8339 if (OMP_CLAUSE_CHAIN (prev_node) != c
8340 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8341 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8342 == GOMP_MAP_ALWAYS_POINTER)
8343 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8344 == GOMP_MAP_ATTACH_DETACH)))
8345 {
8346 tree c4 = OMP_CLAUSE_CHAIN (prev_node);
8347 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8348 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8349 OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (c4));
8350 OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
8351 OMP_CLAUSE_CHAIN (c3) = prev_node;
8352 if (!scp)
8353 OMP_CLAUSE_CHAIN (c2) = c3;
8354 else
8355 cl = c3;
8356 }
8357
8358 if (scp)
8359 *scp = c2;
8360
8361 return cl;
8362 }
8363
8364 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
8365 and set *BITPOSP and *POFFSETP to the bit offset of the access.
8366 If BASE_REF is non-NULL and the containing object is a reference, set
8367 *BASE_REF to that reference before dereferencing the object.
8368 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
8369 has array type, else return NULL. */
8370
8371 static tree
extract_base_bit_offset(tree base,tree * base_ref,poly_int64 * bitposp,poly_offset_int * poffsetp)8372 extract_base_bit_offset (tree base, tree *base_ref, poly_int64 *bitposp,
8373 poly_offset_int *poffsetp)
8374 {
8375 tree offset;
8376 poly_int64 bitsize, bitpos;
8377 machine_mode mode;
8378 int unsignedp, reversep, volatilep = 0;
8379 poly_offset_int poffset;
8380
8381 if (base_ref)
8382 {
8383 *base_ref = NULL_TREE;
8384
8385 while (TREE_CODE (base) == ARRAY_REF)
8386 base = TREE_OPERAND (base, 0);
8387
8388 if (TREE_CODE (base) == INDIRECT_REF)
8389 base = TREE_OPERAND (base, 0);
8390 }
8391 else
8392 {
8393 if (TREE_CODE (base) == ARRAY_REF)
8394 {
8395 while (TREE_CODE (base) == ARRAY_REF)
8396 base = TREE_OPERAND (base, 0);
8397 if (TREE_CODE (base) != COMPONENT_REF
8398 || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
8399 return NULL_TREE;
8400 }
8401 else if (TREE_CODE (base) == INDIRECT_REF
8402 && TREE_CODE (TREE_OPERAND (base, 0)) == COMPONENT_REF
8403 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
8404 == REFERENCE_TYPE))
8405 base = TREE_OPERAND (base, 0);
8406 }
8407
8408 base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
8409 &unsignedp, &reversep, &volatilep);
8410
8411 tree orig_base = base;
8412
8413 if ((TREE_CODE (base) == INDIRECT_REF
8414 || (TREE_CODE (base) == MEM_REF
8415 && integer_zerop (TREE_OPERAND (base, 1))))
8416 && DECL_P (TREE_OPERAND (base, 0))
8417 && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == REFERENCE_TYPE)
8418 base = TREE_OPERAND (base, 0);
8419
8420 gcc_assert (offset == NULL_TREE || poly_int_tree_p (offset));
8421
8422 if (offset)
8423 poffset = wi::to_poly_offset (offset);
8424 else
8425 poffset = 0;
8426
8427 if (maybe_ne (bitpos, 0))
8428 poffset += bits_to_bytes_round_down (bitpos);
8429
8430 *bitposp = bitpos;
8431 *poffsetp = poffset;
8432
8433 /* Set *BASE_REF if BASE was a dereferenced reference variable. */
8434 if (base_ref && orig_base != base)
8435 *base_ref = orig_base;
8436
8437 return base;
8438 }
8439
8440 /* Returns true if EXPR is or contains (as a sub-component) BASE_PTR. */
8441
8442 static bool
is_or_contains_p(tree expr,tree base_ptr)8443 is_or_contains_p (tree expr, tree base_ptr)
8444 {
8445 while (expr != base_ptr)
8446 if (TREE_CODE (base_ptr) == COMPONENT_REF)
8447 base_ptr = TREE_OPERAND (base_ptr, 0);
8448 else
8449 break;
8450 return expr == base_ptr;
8451 }
8452
8453 /* Implement OpenMP 5.x map ordering rules for target directives. There are
8454 several rules, and with some level of ambiguity, hopefully we can at least
8455 collect the complexity here in one place. */
8456
8457 static void
omp_target_reorder_clauses(tree * list_p)8458 omp_target_reorder_clauses (tree *list_p)
8459 {
8460 /* Collect refs to alloc/release/delete maps. */
8461 auto_vec<tree, 32> ard;
8462 tree *cp = list_p;
8463 while (*cp != NULL_TREE)
8464 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8465 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALLOC
8466 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_RELEASE
8467 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_DELETE))
8468 {
8469 /* Unlink cp and push to ard. */
8470 tree c = *cp;
8471 tree nc = OMP_CLAUSE_CHAIN (c);
8472 *cp = nc;
8473 ard.safe_push (c);
8474
8475 /* Any associated pointer type maps should also move along. */
8476 while (*cp != NULL_TREE
8477 && OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8478 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
8479 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_POINTER
8480 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH
8481 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_POINTER
8482 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALWAYS_POINTER
8483 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_TO_PSET))
8484 {
8485 c = *cp;
8486 nc = OMP_CLAUSE_CHAIN (c);
8487 *cp = nc;
8488 ard.safe_push (c);
8489 }
8490 }
8491 else
8492 cp = &OMP_CLAUSE_CHAIN (*cp);
8493
8494 /* Link alloc/release/delete maps to the end of list. */
8495 for (unsigned int i = 0; i < ard.length (); i++)
8496 {
8497 *cp = ard[i];
8498 cp = &OMP_CLAUSE_CHAIN (ard[i]);
8499 }
8500 *cp = NULL_TREE;
8501
8502 /* OpenMP 5.0 requires that pointer variables are mapped before
8503 its use as a base-pointer. */
8504 auto_vec<tree *, 32> atf;
8505 for (tree *cp = list_p; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
8506 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
8507 {
8508 /* Collect alloc, to, from, to/from clause tree pointers. */
8509 gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
8510 if (k == GOMP_MAP_ALLOC
8511 || k == GOMP_MAP_TO
8512 || k == GOMP_MAP_FROM
8513 || k == GOMP_MAP_TOFROM
8514 || k == GOMP_MAP_ALWAYS_TO
8515 || k == GOMP_MAP_ALWAYS_FROM
8516 || k == GOMP_MAP_ALWAYS_TOFROM)
8517 atf.safe_push (cp);
8518 }
8519
8520 for (unsigned int i = 0; i < atf.length (); i++)
8521 if (atf[i])
8522 {
8523 tree *cp = atf[i];
8524 tree decl = OMP_CLAUSE_DECL (*cp);
8525 if (TREE_CODE (decl) == INDIRECT_REF || TREE_CODE (decl) == MEM_REF)
8526 {
8527 tree base_ptr = TREE_OPERAND (decl, 0);
8528 STRIP_TYPE_NOPS (base_ptr);
8529 for (unsigned int j = i + 1; j < atf.length (); j++)
8530 {
8531 tree *cp2 = atf[j];
8532 tree decl2 = OMP_CLAUSE_DECL (*cp2);
8533 if (is_or_contains_p (decl2, base_ptr))
8534 {
8535 /* Move *cp2 to before *cp. */
8536 tree c = *cp2;
8537 *cp2 = OMP_CLAUSE_CHAIN (c);
8538 OMP_CLAUSE_CHAIN (c) = *cp;
8539 *cp = c;
8540 atf[j] = NULL;
8541 }
8542 }
8543 }
8544 }
8545 }
8546
8547 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
8548 and previous omp contexts. */
8549
8550 static void
gimplify_scan_omp_clauses(tree * list_p,gimple_seq * pre_p,enum omp_region_type region_type,enum tree_code code)8551 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
8552 enum omp_region_type region_type,
8553 enum tree_code code)
8554 {
8555 struct gimplify_omp_ctx *ctx, *outer_ctx;
8556 tree c;
8557 hash_map<tree, tree> *struct_map_to_clause = NULL;
8558 hash_set<tree> *struct_deref_set = NULL;
8559 tree *prev_list_p = NULL, *orig_list_p = list_p;
8560 int handled_depend_iterators = -1;
8561 int nowait = -1;
8562
8563 ctx = new_omp_context (region_type);
8564 ctx->code = code;
8565 outer_ctx = ctx->outer_context;
8566 if (code == OMP_TARGET)
8567 {
8568 if (!lang_GNU_Fortran ())
8569 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
8570 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
8571 }
8572 if (!lang_GNU_Fortran ())
8573 switch (code)
8574 {
8575 case OMP_TARGET:
8576 case OMP_TARGET_DATA:
8577 case OMP_TARGET_ENTER_DATA:
8578 case OMP_TARGET_EXIT_DATA:
8579 case OACC_DECLARE:
8580 case OACC_HOST_DATA:
8581 case OACC_PARALLEL:
8582 case OACC_KERNELS:
8583 ctx->target_firstprivatize_array_bases = true;
8584 default:
8585 break;
8586 }
8587
8588 if (code == OMP_TARGET
8589 || code == OMP_TARGET_DATA
8590 || code == OMP_TARGET_ENTER_DATA
8591 || code == OMP_TARGET_EXIT_DATA)
8592 omp_target_reorder_clauses (list_p);
8593
8594 while ((c = *list_p) != NULL)
8595 {
8596 bool remove = false;
8597 bool notice_outer = true;
8598 const char *check_non_private = NULL;
8599 unsigned int flags;
8600 tree decl;
8601
8602 switch (OMP_CLAUSE_CODE (c))
8603 {
8604 case OMP_CLAUSE_PRIVATE:
8605 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
8606 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
8607 {
8608 flags |= GOVD_PRIVATE_OUTER_REF;
8609 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
8610 }
8611 else
8612 notice_outer = false;
8613 goto do_add;
8614 case OMP_CLAUSE_SHARED:
8615 flags = GOVD_SHARED | GOVD_EXPLICIT;
8616 goto do_add;
8617 case OMP_CLAUSE_FIRSTPRIVATE:
8618 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8619 check_non_private = "firstprivate";
8620 goto do_add;
8621 case OMP_CLAUSE_LASTPRIVATE:
8622 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
8623 switch (code)
8624 {
8625 case OMP_DISTRIBUTE:
8626 error_at (OMP_CLAUSE_LOCATION (c),
8627 "conditional %<lastprivate%> clause on "
8628 "%qs construct", "distribute");
8629 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8630 break;
8631 case OMP_TASKLOOP:
8632 error_at (OMP_CLAUSE_LOCATION (c),
8633 "conditional %<lastprivate%> clause on "
8634 "%qs construct", "taskloop");
8635 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8636 break;
8637 default:
8638 break;
8639 }
8640 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
8641 if (code != OMP_LOOP)
8642 check_non_private = "lastprivate";
8643 decl = OMP_CLAUSE_DECL (c);
8644 if (error_operand_p (decl))
8645 goto do_add;
8646 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
8647 && !lang_hooks.decls.omp_scalar_p (decl))
8648 {
8649 error_at (OMP_CLAUSE_LOCATION (c),
8650 "non-scalar variable %qD in conditional "
8651 "%<lastprivate%> clause", decl);
8652 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8653 }
8654 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
8655 flags |= GOVD_LASTPRIVATE_CONDITIONAL;
8656 if (outer_ctx
8657 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
8658 || ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
8659 == ORT_COMBINED_TEAMS))
8660 && splay_tree_lookup (outer_ctx->variables,
8661 (splay_tree_key) decl) == NULL)
8662 {
8663 omp_add_variable (outer_ctx, decl, GOVD_SHARED | GOVD_SEEN);
8664 if (outer_ctx->outer_context)
8665 omp_notice_variable (outer_ctx->outer_context, decl, true);
8666 }
8667 else if (outer_ctx
8668 && (outer_ctx->region_type & ORT_TASK) != 0
8669 && outer_ctx->combined_loop
8670 && splay_tree_lookup (outer_ctx->variables,
8671 (splay_tree_key) decl) == NULL)
8672 {
8673 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8674 if (outer_ctx->outer_context)
8675 omp_notice_variable (outer_ctx->outer_context, decl, true);
8676 }
8677 else if (outer_ctx
8678 && (outer_ctx->region_type == ORT_WORKSHARE
8679 || outer_ctx->region_type == ORT_ACC)
8680 && outer_ctx->combined_loop
8681 && splay_tree_lookup (outer_ctx->variables,
8682 (splay_tree_key) decl) == NULL
8683 && !omp_check_private (outer_ctx, decl, false))
8684 {
8685 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8686 if (outer_ctx->outer_context
8687 && (outer_ctx->outer_context->region_type
8688 == ORT_COMBINED_PARALLEL)
8689 && splay_tree_lookup (outer_ctx->outer_context->variables,
8690 (splay_tree_key) decl) == NULL)
8691 {
8692 struct gimplify_omp_ctx *octx = outer_ctx->outer_context;
8693 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
8694 if (octx->outer_context)
8695 {
8696 octx = octx->outer_context;
8697 if (octx->region_type == ORT_WORKSHARE
8698 && octx->combined_loop
8699 && splay_tree_lookup (octx->variables,
8700 (splay_tree_key) decl) == NULL
8701 && !omp_check_private (octx, decl, false))
8702 {
8703 omp_add_variable (octx, decl,
8704 GOVD_LASTPRIVATE | GOVD_SEEN);
8705 octx = octx->outer_context;
8706 if (octx
8707 && ((octx->region_type & ORT_COMBINED_TEAMS)
8708 == ORT_COMBINED_TEAMS)
8709 && (splay_tree_lookup (octx->variables,
8710 (splay_tree_key) decl)
8711 == NULL))
8712 {
8713 omp_add_variable (octx, decl,
8714 GOVD_SHARED | GOVD_SEEN);
8715 octx = octx->outer_context;
8716 }
8717 }
8718 if (octx)
8719 omp_notice_variable (octx, decl, true);
8720 }
8721 }
8722 else if (outer_ctx->outer_context)
8723 omp_notice_variable (outer_ctx->outer_context, decl, true);
8724 }
8725 goto do_add;
8726 case OMP_CLAUSE_REDUCTION:
8727 if (OMP_CLAUSE_REDUCTION_TASK (c))
8728 {
8729 if (region_type == ORT_WORKSHARE)
8730 {
8731 if (nowait == -1)
8732 nowait = omp_find_clause (*list_p,
8733 OMP_CLAUSE_NOWAIT) != NULL_TREE;
8734 if (nowait
8735 && (outer_ctx == NULL
8736 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
8737 {
8738 error_at (OMP_CLAUSE_LOCATION (c),
8739 "%<task%> reduction modifier on a construct "
8740 "with a %<nowait%> clause");
8741 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
8742 }
8743 }
8744 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
8745 {
8746 error_at (OMP_CLAUSE_LOCATION (c),
8747 "invalid %<task%> reduction modifier on construct "
8748 "other than %<parallel%>, %qs or %<sections%>",
8749 lang_GNU_Fortran () ? "do" : "for");
8750 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
8751 }
8752 }
8753 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
8754 switch (code)
8755 {
8756 case OMP_SECTIONS:
8757 error_at (OMP_CLAUSE_LOCATION (c),
8758 "%<inscan%> %<reduction%> clause on "
8759 "%qs construct", "sections");
8760 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8761 break;
8762 case OMP_PARALLEL:
8763 error_at (OMP_CLAUSE_LOCATION (c),
8764 "%<inscan%> %<reduction%> clause on "
8765 "%qs construct", "parallel");
8766 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8767 break;
8768 case OMP_TEAMS:
8769 error_at (OMP_CLAUSE_LOCATION (c),
8770 "%<inscan%> %<reduction%> clause on "
8771 "%qs construct", "teams");
8772 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8773 break;
8774 case OMP_TASKLOOP:
8775 error_at (OMP_CLAUSE_LOCATION (c),
8776 "%<inscan%> %<reduction%> clause on "
8777 "%qs construct", "taskloop");
8778 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8779 break;
8780 default:
8781 break;
8782 }
8783 /* FALLTHRU */
8784 case OMP_CLAUSE_IN_REDUCTION:
8785 case OMP_CLAUSE_TASK_REDUCTION:
8786 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
8787 /* OpenACC permits reductions on private variables. */
8788 if (!(region_type & ORT_ACC)
8789 /* taskgroup is actually not a worksharing region. */
8790 && code != OMP_TASKGROUP)
8791 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
8792 decl = OMP_CLAUSE_DECL (c);
8793 if (TREE_CODE (decl) == MEM_REF)
8794 {
8795 tree type = TREE_TYPE (decl);
8796 bool saved_into_ssa = gimplify_ctxp->into_ssa;
8797 gimplify_ctxp->into_ssa = false;
8798 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
8799 NULL, is_gimple_val, fb_rvalue, false)
8800 == GS_ERROR)
8801 {
8802 gimplify_ctxp->into_ssa = saved_into_ssa;
8803 remove = true;
8804 break;
8805 }
8806 gimplify_ctxp->into_ssa = saved_into_ssa;
8807 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
8808 if (DECL_P (v))
8809 {
8810 omp_firstprivatize_variable (ctx, v);
8811 omp_notice_variable (ctx, v, true);
8812 }
8813 decl = TREE_OPERAND (decl, 0);
8814 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
8815 {
8816 gimplify_ctxp->into_ssa = false;
8817 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
8818 NULL, is_gimple_val, fb_rvalue, false)
8819 == GS_ERROR)
8820 {
8821 gimplify_ctxp->into_ssa = saved_into_ssa;
8822 remove = true;
8823 break;
8824 }
8825 gimplify_ctxp->into_ssa = saved_into_ssa;
8826 v = TREE_OPERAND (decl, 1);
8827 if (DECL_P (v))
8828 {
8829 omp_firstprivatize_variable (ctx, v);
8830 omp_notice_variable (ctx, v, true);
8831 }
8832 decl = TREE_OPERAND (decl, 0);
8833 }
8834 if (TREE_CODE (decl) == ADDR_EXPR
8835 || TREE_CODE (decl) == INDIRECT_REF)
8836 decl = TREE_OPERAND (decl, 0);
8837 }
8838 goto do_add_decl;
8839 case OMP_CLAUSE_LINEAR:
8840 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
8841 is_gimple_val, fb_rvalue) == GS_ERROR)
8842 {
8843 remove = true;
8844 break;
8845 }
8846 else
8847 {
8848 if (code == OMP_SIMD
8849 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
8850 {
8851 struct gimplify_omp_ctx *octx = outer_ctx;
8852 if (octx
8853 && octx->region_type == ORT_WORKSHARE
8854 && octx->combined_loop
8855 && !octx->distribute)
8856 {
8857 if (octx->outer_context
8858 && (octx->outer_context->region_type
8859 == ORT_COMBINED_PARALLEL))
8860 octx = octx->outer_context->outer_context;
8861 else
8862 octx = octx->outer_context;
8863 }
8864 if (octx
8865 && octx->region_type == ORT_WORKSHARE
8866 && octx->combined_loop
8867 && octx->distribute)
8868 {
8869 error_at (OMP_CLAUSE_LOCATION (c),
8870 "%<linear%> clause for variable other than "
8871 "loop iterator specified on construct "
8872 "combined with %<distribute%>");
8873 remove = true;
8874 break;
8875 }
8876 }
8877 /* For combined #pragma omp parallel for simd, need to put
8878 lastprivate and perhaps firstprivate too on the
8879 parallel. Similarly for #pragma omp for simd. */
8880 struct gimplify_omp_ctx *octx = outer_ctx;
8881 decl = NULL_TREE;
8882 do
8883 {
8884 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8885 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8886 break;
8887 decl = OMP_CLAUSE_DECL (c);
8888 if (error_operand_p (decl))
8889 {
8890 decl = NULL_TREE;
8891 break;
8892 }
8893 flags = GOVD_SEEN;
8894 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
8895 flags |= GOVD_FIRSTPRIVATE;
8896 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8897 flags |= GOVD_LASTPRIVATE;
8898 if (octx
8899 && octx->region_type == ORT_WORKSHARE
8900 && octx->combined_loop)
8901 {
8902 if (octx->outer_context
8903 && (octx->outer_context->region_type
8904 == ORT_COMBINED_PARALLEL))
8905 octx = octx->outer_context;
8906 else if (omp_check_private (octx, decl, false))
8907 break;
8908 }
8909 else if (octx
8910 && (octx->region_type & ORT_TASK) != 0
8911 && octx->combined_loop)
8912 ;
8913 else if (octx
8914 && octx->region_type == ORT_COMBINED_PARALLEL
8915 && ctx->region_type == ORT_WORKSHARE
8916 && octx == outer_ctx)
8917 flags = GOVD_SEEN | GOVD_SHARED;
8918 else if (octx
8919 && ((octx->region_type & ORT_COMBINED_TEAMS)
8920 == ORT_COMBINED_TEAMS))
8921 flags = GOVD_SEEN | GOVD_SHARED;
8922 else if (octx
8923 && octx->region_type == ORT_COMBINED_TARGET)
8924 {
8925 flags &= ~GOVD_LASTPRIVATE;
8926 if (flags == GOVD_SEEN)
8927 break;
8928 }
8929 else
8930 break;
8931 splay_tree_node on
8932 = splay_tree_lookup (octx->variables,
8933 (splay_tree_key) decl);
8934 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
8935 {
8936 octx = NULL;
8937 break;
8938 }
8939 omp_add_variable (octx, decl, flags);
8940 if (octx->outer_context == NULL)
8941 break;
8942 octx = octx->outer_context;
8943 }
8944 while (1);
8945 if (octx
8946 && decl
8947 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8948 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
8949 omp_notice_variable (octx, decl, true);
8950 }
8951 flags = GOVD_LINEAR | GOVD_EXPLICIT;
8952 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8953 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8954 {
8955 notice_outer = false;
8956 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
8957 }
8958 goto do_add;
8959
8960 case OMP_CLAUSE_MAP:
8961 decl = OMP_CLAUSE_DECL (c);
8962 if (error_operand_p (decl))
8963 remove = true;
8964 switch (code)
8965 {
8966 case OMP_TARGET:
8967 break;
8968 case OACC_DATA:
8969 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
8970 break;
8971 /* FALLTHRU */
8972 case OMP_TARGET_DATA:
8973 case OMP_TARGET_ENTER_DATA:
8974 case OMP_TARGET_EXIT_DATA:
8975 case OACC_ENTER_DATA:
8976 case OACC_EXIT_DATA:
8977 case OACC_HOST_DATA:
8978 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
8979 || (OMP_CLAUSE_MAP_KIND (c)
8980 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8981 /* For target {,enter ,exit }data only the array slice is
8982 mapped, but not the pointer to it. */
8983 remove = true;
8984 break;
8985 default:
8986 break;
8987 }
8988 /* For Fortran, not only the pointer to the data is mapped but also
8989 the address of the pointer, the array descriptor etc.; for
8990 'exit data' - and in particular for 'delete:' - having an 'alloc:'
8991 does not make sense. Likewise, for 'update' only transferring the
8992 data itself is needed as the rest has been handled in previous
8993 directives. However, for 'exit data', the array descriptor needs
8994 to be delete; hence, we turn the MAP_TO_PSET into a MAP_DELETE.
8995
8996 NOTE: Generally, it is not safe to perform "enter data" operations
8997 on arrays where the data *or the descriptor* may go out of scope
8998 before a corresponding "exit data" operation -- and such a
8999 descriptor may be synthesized temporarily, e.g. to pass an
9000 explicit-shape array to a function expecting an assumed-shape
9001 argument. Performing "enter data" inside the called function
9002 would thus be problematic. */
9003 if (code == OMP_TARGET_EXIT_DATA
9004 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
9005 OMP_CLAUSE_SET_MAP_KIND (c, OMP_CLAUSE_MAP_KIND (*prev_list_p)
9006 == GOMP_MAP_DELETE
9007 ? GOMP_MAP_DELETE : GOMP_MAP_RELEASE);
9008 else if ((code == OMP_TARGET_EXIT_DATA || code == OMP_TARGET_UPDATE)
9009 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9010 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET))
9011 remove = true;
9012
9013 if (remove)
9014 break;
9015 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
9016 {
9017 struct gimplify_omp_ctx *octx;
9018 for (octx = outer_ctx; octx; octx = octx->outer_context)
9019 {
9020 if (octx->region_type != ORT_ACC_HOST_DATA)
9021 break;
9022 splay_tree_node n2
9023 = splay_tree_lookup (octx->variables,
9024 (splay_tree_key) decl);
9025 if (n2)
9026 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
9027 "declared in enclosing %<host_data%> region",
9028 DECL_NAME (decl));
9029 }
9030 }
9031 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9032 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
9033 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
9034 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
9035 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
9036 {
9037 remove = true;
9038 break;
9039 }
9040 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9041 || (OMP_CLAUSE_MAP_KIND (c)
9042 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9043 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9044 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
9045 {
9046 OMP_CLAUSE_SIZE (c)
9047 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
9048 false);
9049 if ((region_type & ORT_TARGET) != 0)
9050 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
9051 GOVD_FIRSTPRIVATE | GOVD_SEEN);
9052 }
9053
9054 if (!DECL_P (decl))
9055 {
9056 tree d = decl, *pd;
9057 if (TREE_CODE (d) == ARRAY_REF)
9058 {
9059 while (TREE_CODE (d) == ARRAY_REF)
9060 d = TREE_OPERAND (d, 0);
9061 if (TREE_CODE (d) == COMPONENT_REF
9062 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
9063 decl = d;
9064 }
9065 pd = &OMP_CLAUSE_DECL (c);
9066 if (d == decl
9067 && TREE_CODE (decl) == INDIRECT_REF
9068 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
9069 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9070 == REFERENCE_TYPE))
9071 {
9072 pd = &TREE_OPERAND (decl, 0);
9073 decl = TREE_OPERAND (decl, 0);
9074 }
9075 bool indir_p = false;
9076 tree orig_decl = decl;
9077 tree decl_ref = NULL_TREE;
9078 if ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA)) != 0
9079 && TREE_CODE (*pd) == COMPONENT_REF
9080 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
9081 && code != OACC_UPDATE)
9082 {
9083 while (TREE_CODE (decl) == COMPONENT_REF)
9084 {
9085 decl = TREE_OPERAND (decl, 0);
9086 if (((TREE_CODE (decl) == MEM_REF
9087 && integer_zerop (TREE_OPERAND (decl, 1)))
9088 || INDIRECT_REF_P (decl))
9089 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9090 == POINTER_TYPE))
9091 {
9092 indir_p = true;
9093 decl = TREE_OPERAND (decl, 0);
9094 }
9095 if (TREE_CODE (decl) == INDIRECT_REF
9096 && DECL_P (TREE_OPERAND (decl, 0))
9097 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9098 == REFERENCE_TYPE))
9099 {
9100 decl_ref = decl;
9101 decl = TREE_OPERAND (decl, 0);
9102 }
9103 }
9104 }
9105 else if (TREE_CODE (decl) == COMPONENT_REF)
9106 {
9107 while (TREE_CODE (decl) == COMPONENT_REF)
9108 decl = TREE_OPERAND (decl, 0);
9109 if (TREE_CODE (decl) == INDIRECT_REF
9110 && DECL_P (TREE_OPERAND (decl, 0))
9111 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9112 == REFERENCE_TYPE))
9113 decl = TREE_OPERAND (decl, 0);
9114 }
9115 if (decl != orig_decl && DECL_P (decl) && indir_p)
9116 {
9117 gomp_map_kind k
9118 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9119 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9120 /* We have a dereference of a struct member. Make this an
9121 attach/detach operation, and ensure the base pointer is
9122 mapped as a FIRSTPRIVATE_POINTER. */
9123 OMP_CLAUSE_SET_MAP_KIND (c, k);
9124 flags = GOVD_MAP | GOVD_SEEN | GOVD_EXPLICIT;
9125 tree next_clause = OMP_CLAUSE_CHAIN (c);
9126 if (k == GOMP_MAP_ATTACH
9127 && code != OACC_ENTER_DATA
9128 && code != OMP_TARGET_ENTER_DATA
9129 && (!next_clause
9130 || (OMP_CLAUSE_CODE (next_clause) != OMP_CLAUSE_MAP)
9131 || (OMP_CLAUSE_MAP_KIND (next_clause)
9132 != GOMP_MAP_POINTER)
9133 || OMP_CLAUSE_DECL (next_clause) != decl)
9134 && (!struct_deref_set
9135 || !struct_deref_set->contains (decl)))
9136 {
9137 if (!struct_deref_set)
9138 struct_deref_set = new hash_set<tree> ();
9139 /* As well as the attach, we also need a
9140 FIRSTPRIVATE_POINTER clause to properly map the
9141 pointer to the struct base. */
9142 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9143 OMP_CLAUSE_MAP);
9144 OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALLOC);
9145 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c2)
9146 = 1;
9147 tree charptr_zero
9148 = build_int_cst (build_pointer_type (char_type_node),
9149 0);
9150 OMP_CLAUSE_DECL (c2)
9151 = build2 (MEM_REF, char_type_node,
9152 decl_ref ? decl_ref : decl, charptr_zero);
9153 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9154 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9155 OMP_CLAUSE_MAP);
9156 OMP_CLAUSE_SET_MAP_KIND (c3,
9157 GOMP_MAP_FIRSTPRIVATE_POINTER);
9158 OMP_CLAUSE_DECL (c3) = decl;
9159 OMP_CLAUSE_SIZE (c3) = size_zero_node;
9160 tree mapgrp = *prev_list_p;
9161 *prev_list_p = c2;
9162 OMP_CLAUSE_CHAIN (c3) = mapgrp;
9163 OMP_CLAUSE_CHAIN (c2) = c3;
9164
9165 struct_deref_set->add (decl);
9166 }
9167 goto do_add_decl;
9168 }
9169 /* An "attach/detach" operation on an update directive should
9170 behave as a GOMP_MAP_ALWAYS_POINTER. Beware that
9171 unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
9172 depends on the previous mapping. */
9173 if (code == OACC_UPDATE
9174 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9175 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
9176 if (DECL_P (decl)
9177 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
9178 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
9179 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
9180 && code != OACC_UPDATE
9181 && code != OMP_TARGET_UPDATE)
9182 {
9183 if (error_operand_p (decl))
9184 {
9185 remove = true;
9186 break;
9187 }
9188
9189 tree stype = TREE_TYPE (decl);
9190 if (TREE_CODE (stype) == REFERENCE_TYPE)
9191 stype = TREE_TYPE (stype);
9192 if (TYPE_SIZE_UNIT (stype) == NULL
9193 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
9194 {
9195 error_at (OMP_CLAUSE_LOCATION (c),
9196 "mapping field %qE of variable length "
9197 "structure", OMP_CLAUSE_DECL (c));
9198 remove = true;
9199 break;
9200 }
9201
9202 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
9203 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9204 {
9205 /* Error recovery. */
9206 if (prev_list_p == NULL)
9207 {
9208 remove = true;
9209 break;
9210 }
9211 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
9212 {
9213 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
9214 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
9215 {
9216 remove = true;
9217 break;
9218 }
9219 }
9220 }
9221
9222 poly_offset_int offset1;
9223 poly_int64 bitpos1;
9224 tree base_ref;
9225
9226 tree base
9227 = extract_base_bit_offset (OMP_CLAUSE_DECL (c), &base_ref,
9228 &bitpos1, &offset1);
9229
9230 gcc_assert (base == decl);
9231
9232 splay_tree_node n
9233 = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
9234 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
9235 == GOMP_MAP_ALWAYS_POINTER);
9236 bool attach_detach = (OMP_CLAUSE_MAP_KIND (c)
9237 == GOMP_MAP_ATTACH_DETACH);
9238 bool attach = OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9239 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH;
9240 bool has_attachments = false;
9241 /* For OpenACC, pointers in structs should trigger an
9242 attach action. */
9243 if (attach_detach
9244 && ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA))
9245 || code == OMP_TARGET_ENTER_DATA
9246 || code == OMP_TARGET_EXIT_DATA))
9247
9248 {
9249 /* Turn a GOMP_MAP_ATTACH_DETACH clause into a
9250 GOMP_MAP_ATTACH or GOMP_MAP_DETACH clause after we
9251 have detected a case that needs a GOMP_MAP_STRUCT
9252 mapping added. */
9253 gomp_map_kind k
9254 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9255 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9256 OMP_CLAUSE_SET_MAP_KIND (c, k);
9257 has_attachments = true;
9258 }
9259 if (n == NULL || (n->value & GOVD_MAP) == 0)
9260 {
9261 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9262 OMP_CLAUSE_MAP);
9263 gomp_map_kind k = attach ? GOMP_MAP_FORCE_PRESENT
9264 : GOMP_MAP_STRUCT;
9265
9266 OMP_CLAUSE_SET_MAP_KIND (l, k);
9267 if (base_ref)
9268 OMP_CLAUSE_DECL (l) = unshare_expr (base_ref);
9269 else
9270 OMP_CLAUSE_DECL (l) = decl;
9271 OMP_CLAUSE_SIZE (l)
9272 = (!attach
9273 ? size_int (1)
9274 : DECL_P (OMP_CLAUSE_DECL (l))
9275 ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l))
9276 : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l))));
9277 if (struct_map_to_clause == NULL)
9278 struct_map_to_clause = new hash_map<tree, tree>;
9279 struct_map_to_clause->put (decl, l);
9280 if (ptr || attach_detach)
9281 {
9282 insert_struct_comp_map (code, c, l, *prev_list_p,
9283 NULL);
9284 *prev_list_p = l;
9285 prev_list_p = NULL;
9286 }
9287 else
9288 {
9289 OMP_CLAUSE_CHAIN (l) = c;
9290 *list_p = l;
9291 list_p = &OMP_CLAUSE_CHAIN (l);
9292 }
9293 if (base_ref && code == OMP_TARGET)
9294 {
9295 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9296 OMP_CLAUSE_MAP);
9297 enum gomp_map_kind mkind
9298 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
9299 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9300 OMP_CLAUSE_DECL (c2) = decl;
9301 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9302 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
9303 OMP_CLAUSE_CHAIN (l) = c2;
9304 }
9305 flags = GOVD_MAP | GOVD_EXPLICIT;
9306 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9307 || ptr
9308 || attach_detach)
9309 flags |= GOVD_SEEN;
9310 if (has_attachments)
9311 flags |= GOVD_MAP_HAS_ATTACHMENTS;
9312 goto do_add_decl;
9313 }
9314 else if (struct_map_to_clause)
9315 {
9316 tree *osc = struct_map_to_clause->get (decl);
9317 tree *sc = NULL, *scp = NULL;
9318 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9319 || ptr
9320 || attach_detach)
9321 n->value |= GOVD_SEEN;
9322 sc = &OMP_CLAUSE_CHAIN (*osc);
9323 if (*sc != c
9324 && (OMP_CLAUSE_MAP_KIND (*sc)
9325 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9326 sc = &OMP_CLAUSE_CHAIN (*sc);
9327 /* Here "prev_list_p" is the end of the inserted
9328 alloc/release nodes after the struct node, OSC. */
9329 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
9330 if ((ptr || attach_detach) && sc == prev_list_p)
9331 break;
9332 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9333 != COMPONENT_REF
9334 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9335 != INDIRECT_REF)
9336 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9337 != ARRAY_REF))
9338 break;
9339 else
9340 {
9341 tree sc_decl = OMP_CLAUSE_DECL (*sc);
9342 poly_offset_int offsetn;
9343 poly_int64 bitposn;
9344 tree base
9345 = extract_base_bit_offset (sc_decl, NULL,
9346 &bitposn, &offsetn);
9347 if (base != decl)
9348 break;
9349 if (scp)
9350 continue;
9351 if ((region_type & ORT_ACC) != 0)
9352 {
9353 /* This duplicate checking code is currently only
9354 enabled for OpenACC. */
9355 tree d1 = OMP_CLAUSE_DECL (*sc);
9356 tree d2 = OMP_CLAUSE_DECL (c);
9357 while (TREE_CODE (d1) == ARRAY_REF)
9358 d1 = TREE_OPERAND (d1, 0);
9359 while (TREE_CODE (d2) == ARRAY_REF)
9360 d2 = TREE_OPERAND (d2, 0);
9361 if (TREE_CODE (d1) == INDIRECT_REF)
9362 d1 = TREE_OPERAND (d1, 0);
9363 if (TREE_CODE (d2) == INDIRECT_REF)
9364 d2 = TREE_OPERAND (d2, 0);
9365 while (TREE_CODE (d1) == COMPONENT_REF)
9366 if (TREE_CODE (d2) == COMPONENT_REF
9367 && TREE_OPERAND (d1, 1)
9368 == TREE_OPERAND (d2, 1))
9369 {
9370 d1 = TREE_OPERAND (d1, 0);
9371 d2 = TREE_OPERAND (d2, 0);
9372 }
9373 else
9374 break;
9375 if (d1 == d2)
9376 {
9377 error_at (OMP_CLAUSE_LOCATION (c),
9378 "%qE appears more than once in map "
9379 "clauses", OMP_CLAUSE_DECL (c));
9380 remove = true;
9381 break;
9382 }
9383 }
9384 if (maybe_lt (offset1, offsetn)
9385 || (known_eq (offset1, offsetn)
9386 && maybe_lt (bitpos1, bitposn)))
9387 {
9388 if (ptr || attach_detach)
9389 scp = sc;
9390 else
9391 break;
9392 }
9393 }
9394 if (remove)
9395 break;
9396 if (!attach)
9397 OMP_CLAUSE_SIZE (*osc)
9398 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
9399 size_one_node);
9400 if (ptr || attach_detach)
9401 {
9402 tree cl = insert_struct_comp_map (code, c, NULL,
9403 *prev_list_p, scp);
9404 if (sc == prev_list_p)
9405 {
9406 *sc = cl;
9407 prev_list_p = NULL;
9408 }
9409 else
9410 {
9411 *prev_list_p = OMP_CLAUSE_CHAIN (c);
9412 list_p = prev_list_p;
9413 prev_list_p = NULL;
9414 OMP_CLAUSE_CHAIN (c) = *sc;
9415 *sc = cl;
9416 continue;
9417 }
9418 }
9419 else if (*sc != c)
9420 {
9421 *list_p = OMP_CLAUSE_CHAIN (c);
9422 OMP_CLAUSE_CHAIN (c) = *sc;
9423 *sc = c;
9424 continue;
9425 }
9426 }
9427 }
9428 else if ((code == OACC_ENTER_DATA
9429 || code == OACC_EXIT_DATA
9430 || code == OACC_DATA
9431 || code == OACC_PARALLEL
9432 || code == OACC_KERNELS
9433 || code == OACC_SERIAL)
9434 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9435 {
9436 gomp_map_kind k = (code == OACC_EXIT_DATA
9437 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9438 OMP_CLAUSE_SET_MAP_KIND (c, k);
9439 }
9440
9441 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, fb_lvalue)
9442 == GS_ERROR)
9443 {
9444 remove = true;
9445 break;
9446 }
9447
9448 if (!remove
9449 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
9450 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
9451 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
9452 && OMP_CLAUSE_CHAIN (c)
9453 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
9454 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9455 == GOMP_MAP_ALWAYS_POINTER)
9456 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9457 == GOMP_MAP_ATTACH_DETACH)
9458 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9459 == GOMP_MAP_TO_PSET)))
9460 prev_list_p = list_p;
9461
9462 break;
9463 }
9464 else
9465 {
9466 /* DECL_P (decl) == true */
9467 tree *sc;
9468 if (struct_map_to_clause
9469 && (sc = struct_map_to_clause->get (decl)) != NULL
9470 && OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_STRUCT
9471 && decl == OMP_CLAUSE_DECL (*sc))
9472 {
9473 /* We have found a map of the whole structure after a
9474 leading GOMP_MAP_STRUCT has been created, so refill the
9475 leading clause into a map of the whole structure
9476 variable, and remove the current one.
9477 TODO: we should be able to remove some maps of the
9478 following structure element maps if they are of
9479 compatible TO/FROM/ALLOC type. */
9480 OMP_CLAUSE_SET_MAP_KIND (*sc, OMP_CLAUSE_MAP_KIND (c));
9481 OMP_CLAUSE_SIZE (*sc) = unshare_expr (OMP_CLAUSE_SIZE (c));
9482 remove = true;
9483 break;
9484 }
9485 }
9486 flags = GOVD_MAP | GOVD_EXPLICIT;
9487 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
9488 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
9489 flags |= GOVD_MAP_ALWAYS_TO;
9490
9491 if ((code == OMP_TARGET
9492 || code == OMP_TARGET_DATA
9493 || code == OMP_TARGET_ENTER_DATA
9494 || code == OMP_TARGET_EXIT_DATA)
9495 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9496 {
9497 for (struct gimplify_omp_ctx *octx = outer_ctx; octx;
9498 octx = octx->outer_context)
9499 {
9500 splay_tree_node n
9501 = splay_tree_lookup (octx->variables,
9502 (splay_tree_key) OMP_CLAUSE_DECL (c));
9503 /* If this is contained in an outer OpenMP region as a
9504 firstprivate value, remove the attach/detach. */
9505 if (n && (n->value & GOVD_FIRSTPRIVATE))
9506 {
9507 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FIRSTPRIVATE_POINTER);
9508 goto do_add;
9509 }
9510 }
9511
9512 enum gomp_map_kind map_kind = (code == OMP_TARGET_EXIT_DATA
9513 ? GOMP_MAP_DETACH
9514 : GOMP_MAP_ATTACH);
9515 OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
9516 }
9517
9518 goto do_add;
9519
9520 case OMP_CLAUSE_DEPEND:
9521 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
9522 {
9523 tree deps = OMP_CLAUSE_DECL (c);
9524 while (deps && TREE_CODE (deps) == TREE_LIST)
9525 {
9526 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
9527 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
9528 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
9529 pre_p, NULL, is_gimple_val, fb_rvalue);
9530 deps = TREE_CHAIN (deps);
9531 }
9532 break;
9533 }
9534 else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
9535 break;
9536 if (handled_depend_iterators == -1)
9537 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
9538 if (handled_depend_iterators)
9539 {
9540 if (handled_depend_iterators == 2)
9541 remove = true;
9542 break;
9543 }
9544 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
9545 {
9546 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
9547 NULL, is_gimple_val, fb_rvalue);
9548 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
9549 }
9550 if (error_operand_p (OMP_CLAUSE_DECL (c)))
9551 {
9552 remove = true;
9553 break;
9554 }
9555 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
9556 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
9557 is_gimple_val, fb_rvalue) == GS_ERROR)
9558 {
9559 remove = true;
9560 break;
9561 }
9562 if (code == OMP_TASK)
9563 ctx->has_depend = true;
9564 break;
9565
9566 case OMP_CLAUSE_TO:
9567 case OMP_CLAUSE_FROM:
9568 case OMP_CLAUSE__CACHE_:
9569 decl = OMP_CLAUSE_DECL (c);
9570 if (error_operand_p (decl))
9571 {
9572 remove = true;
9573 break;
9574 }
9575 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9576 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
9577 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
9578 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
9579 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
9580 {
9581 remove = true;
9582 break;
9583 }
9584 if (!DECL_P (decl))
9585 {
9586 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
9587 NULL, is_gimple_lvalue, fb_lvalue)
9588 == GS_ERROR)
9589 {
9590 remove = true;
9591 break;
9592 }
9593 break;
9594 }
9595 goto do_notice;
9596
9597 case OMP_CLAUSE_USE_DEVICE_PTR:
9598 case OMP_CLAUSE_USE_DEVICE_ADDR:
9599 flags = GOVD_EXPLICIT;
9600 goto do_add;
9601
9602 case OMP_CLAUSE_IS_DEVICE_PTR:
9603 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
9604 goto do_add;
9605
9606 do_add:
9607 decl = OMP_CLAUSE_DECL (c);
9608 do_add_decl:
9609 if (error_operand_p (decl))
9610 {
9611 remove = true;
9612 break;
9613 }
9614 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
9615 {
9616 tree t = omp_member_access_dummy_var (decl);
9617 if (t)
9618 {
9619 tree v = DECL_VALUE_EXPR (decl);
9620 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
9621 if (outer_ctx)
9622 omp_notice_variable (outer_ctx, t, true);
9623 }
9624 }
9625 if (code == OACC_DATA
9626 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9627 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
9628 flags |= GOVD_MAP_0LEN_ARRAY;
9629 omp_add_variable (ctx, decl, flags);
9630 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9631 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
9632 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
9633 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
9634 {
9635 omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
9636 GOVD_LOCAL | GOVD_SEEN);
9637 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
9638 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
9639 find_decl_expr,
9640 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
9641 NULL) == NULL_TREE)
9642 omp_add_variable (ctx,
9643 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
9644 GOVD_LOCAL | GOVD_SEEN);
9645 gimplify_omp_ctxp = ctx;
9646 push_gimplify_context ();
9647
9648 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
9649 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
9650
9651 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
9652 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
9653 pop_gimplify_context
9654 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
9655 push_gimplify_context ();
9656 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
9657 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
9658 pop_gimplify_context
9659 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
9660 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
9661 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
9662
9663 gimplify_omp_ctxp = outer_ctx;
9664 }
9665 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
9666 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
9667 {
9668 gimplify_omp_ctxp = ctx;
9669 push_gimplify_context ();
9670 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
9671 {
9672 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
9673 NULL, NULL);
9674 TREE_SIDE_EFFECTS (bind) = 1;
9675 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
9676 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
9677 }
9678 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
9679 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
9680 pop_gimplify_context
9681 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
9682 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
9683
9684 gimplify_omp_ctxp = outer_ctx;
9685 }
9686 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9687 && OMP_CLAUSE_LINEAR_STMT (c))
9688 {
9689 gimplify_omp_ctxp = ctx;
9690 push_gimplify_context ();
9691 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
9692 {
9693 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
9694 NULL, NULL);
9695 TREE_SIDE_EFFECTS (bind) = 1;
9696 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
9697 OMP_CLAUSE_LINEAR_STMT (c) = bind;
9698 }
9699 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
9700 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
9701 pop_gimplify_context
9702 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
9703 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
9704
9705 gimplify_omp_ctxp = outer_ctx;
9706 }
9707 if (notice_outer)
9708 goto do_notice;
9709 break;
9710
9711 case OMP_CLAUSE_COPYIN:
9712 case OMP_CLAUSE_COPYPRIVATE:
9713 decl = OMP_CLAUSE_DECL (c);
9714 if (error_operand_p (decl))
9715 {
9716 remove = true;
9717 break;
9718 }
9719 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
9720 && !remove
9721 && !omp_check_private (ctx, decl, true))
9722 {
9723 remove = true;
9724 if (is_global_var (decl))
9725 {
9726 if (DECL_THREAD_LOCAL_P (decl))
9727 remove = false;
9728 else if (DECL_HAS_VALUE_EXPR_P (decl))
9729 {
9730 tree value = get_base_address (DECL_VALUE_EXPR (decl));
9731
9732 if (value
9733 && DECL_P (value)
9734 && DECL_THREAD_LOCAL_P (value))
9735 remove = false;
9736 }
9737 }
9738 if (remove)
9739 error_at (OMP_CLAUSE_LOCATION (c),
9740 "copyprivate variable %qE is not threadprivate"
9741 " or private in outer context", DECL_NAME (decl));
9742 }
9743 do_notice:
9744 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9745 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
9746 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
9747 && outer_ctx
9748 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
9749 || (region_type == ORT_WORKSHARE
9750 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9751 && (OMP_CLAUSE_REDUCTION_INSCAN (c)
9752 || code == OMP_LOOP)))
9753 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
9754 || (code == OMP_LOOP
9755 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9756 && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
9757 == ORT_COMBINED_TEAMS))))
9758 {
9759 splay_tree_node on
9760 = splay_tree_lookup (outer_ctx->variables,
9761 (splay_tree_key)decl);
9762 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
9763 {
9764 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9765 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
9766 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
9767 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
9768 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
9769 == POINTER_TYPE))))
9770 omp_firstprivatize_variable (outer_ctx, decl);
9771 else
9772 {
9773 omp_add_variable (outer_ctx, decl,
9774 GOVD_SEEN | GOVD_SHARED);
9775 if (outer_ctx->outer_context)
9776 omp_notice_variable (outer_ctx->outer_context, decl,
9777 true);
9778 }
9779 }
9780 }
9781 if (outer_ctx)
9782 omp_notice_variable (outer_ctx, decl, true);
9783 if (check_non_private
9784 && region_type == ORT_WORKSHARE
9785 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
9786 || decl == OMP_CLAUSE_DECL (c)
9787 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
9788 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
9789 == ADDR_EXPR
9790 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
9791 == POINTER_PLUS_EXPR
9792 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
9793 (OMP_CLAUSE_DECL (c), 0), 0))
9794 == ADDR_EXPR)))))
9795 && omp_check_private (ctx, decl, false))
9796 {
9797 error ("%s variable %qE is private in outer context",
9798 check_non_private, DECL_NAME (decl));
9799 remove = true;
9800 }
9801 break;
9802
9803 case OMP_CLAUSE_DETACH:
9804 flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
9805 goto do_add;
9806
9807 case OMP_CLAUSE_IF:
9808 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
9809 && OMP_CLAUSE_IF_MODIFIER (c) != code)
9810 {
9811 const char *p[2];
9812 for (int i = 0; i < 2; i++)
9813 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
9814 {
9815 case VOID_CST: p[i] = "cancel"; break;
9816 case OMP_PARALLEL: p[i] = "parallel"; break;
9817 case OMP_SIMD: p[i] = "simd"; break;
9818 case OMP_TASK: p[i] = "task"; break;
9819 case OMP_TASKLOOP: p[i] = "taskloop"; break;
9820 case OMP_TARGET_DATA: p[i] = "target data"; break;
9821 case OMP_TARGET: p[i] = "target"; break;
9822 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
9823 case OMP_TARGET_ENTER_DATA:
9824 p[i] = "target enter data"; break;
9825 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
9826 default: gcc_unreachable ();
9827 }
9828 error_at (OMP_CLAUSE_LOCATION (c),
9829 "expected %qs %<if%> clause modifier rather than %qs",
9830 p[0], p[1]);
9831 remove = true;
9832 }
9833 /* Fall through. */
9834
9835 case OMP_CLAUSE_FINAL:
9836 OMP_CLAUSE_OPERAND (c, 0)
9837 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
9838 /* Fall through. */
9839
9840 case OMP_CLAUSE_SCHEDULE:
9841 case OMP_CLAUSE_NUM_THREADS:
9842 case OMP_CLAUSE_NUM_TEAMS:
9843 case OMP_CLAUSE_THREAD_LIMIT:
9844 case OMP_CLAUSE_DIST_SCHEDULE:
9845 case OMP_CLAUSE_DEVICE:
9846 case OMP_CLAUSE_PRIORITY:
9847 case OMP_CLAUSE_GRAINSIZE:
9848 case OMP_CLAUSE_NUM_TASKS:
9849 case OMP_CLAUSE_HINT:
9850 case OMP_CLAUSE_ASYNC:
9851 case OMP_CLAUSE_WAIT:
9852 case OMP_CLAUSE_NUM_GANGS:
9853 case OMP_CLAUSE_NUM_WORKERS:
9854 case OMP_CLAUSE_VECTOR_LENGTH:
9855 case OMP_CLAUSE_WORKER:
9856 case OMP_CLAUSE_VECTOR:
9857 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
9858 is_gimple_val, fb_rvalue) == GS_ERROR)
9859 remove = true;
9860 break;
9861
9862 case OMP_CLAUSE_GANG:
9863 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
9864 is_gimple_val, fb_rvalue) == GS_ERROR)
9865 remove = true;
9866 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
9867 is_gimple_val, fb_rvalue) == GS_ERROR)
9868 remove = true;
9869 break;
9870
9871 case OMP_CLAUSE_NOWAIT:
9872 nowait = 1;
9873 break;
9874
9875 case OMP_CLAUSE_ORDERED:
9876 case OMP_CLAUSE_UNTIED:
9877 case OMP_CLAUSE_COLLAPSE:
9878 case OMP_CLAUSE_TILE:
9879 case OMP_CLAUSE_AUTO:
9880 case OMP_CLAUSE_SEQ:
9881 case OMP_CLAUSE_INDEPENDENT:
9882 case OMP_CLAUSE_MERGEABLE:
9883 case OMP_CLAUSE_PROC_BIND:
9884 case OMP_CLAUSE_SAFELEN:
9885 case OMP_CLAUSE_SIMDLEN:
9886 case OMP_CLAUSE_NOGROUP:
9887 case OMP_CLAUSE_THREADS:
9888 case OMP_CLAUSE_SIMD:
9889 case OMP_CLAUSE_BIND:
9890 case OMP_CLAUSE_IF_PRESENT:
9891 case OMP_CLAUSE_FINALIZE:
9892 break;
9893
9894 case OMP_CLAUSE_ORDER:
9895 ctx->order_concurrent = true;
9896 break;
9897
9898 case OMP_CLAUSE_DEFAULTMAP:
9899 enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
9900 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
9901 {
9902 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
9903 gdmkmin = GDMK_SCALAR;
9904 gdmkmax = GDMK_POINTER;
9905 break;
9906 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
9907 gdmkmin = gdmkmax = GDMK_SCALAR;
9908 break;
9909 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
9910 gdmkmin = gdmkmax = GDMK_AGGREGATE;
9911 break;
9912 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
9913 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
9914 break;
9915 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
9916 gdmkmin = gdmkmax = GDMK_POINTER;
9917 break;
9918 default:
9919 gcc_unreachable ();
9920 }
9921 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
9922 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
9923 {
9924 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
9925 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
9926 break;
9927 case OMP_CLAUSE_DEFAULTMAP_TO:
9928 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
9929 break;
9930 case OMP_CLAUSE_DEFAULTMAP_FROM:
9931 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
9932 break;
9933 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
9934 ctx->defaultmap[gdmk] = GOVD_MAP;
9935 break;
9936 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
9937 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
9938 break;
9939 case OMP_CLAUSE_DEFAULTMAP_NONE:
9940 ctx->defaultmap[gdmk] = 0;
9941 break;
9942 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
9943 switch (gdmk)
9944 {
9945 case GDMK_SCALAR:
9946 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
9947 break;
9948 case GDMK_AGGREGATE:
9949 case GDMK_ALLOCATABLE:
9950 ctx->defaultmap[gdmk] = GOVD_MAP;
9951 break;
9952 case GDMK_POINTER:
9953 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
9954 break;
9955 default:
9956 gcc_unreachable ();
9957 }
9958 break;
9959 default:
9960 gcc_unreachable ();
9961 }
9962 break;
9963
9964 case OMP_CLAUSE_ALIGNED:
9965 decl = OMP_CLAUSE_DECL (c);
9966 if (error_operand_p (decl))
9967 {
9968 remove = true;
9969 break;
9970 }
9971 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
9972 is_gimple_val, fb_rvalue) == GS_ERROR)
9973 {
9974 remove = true;
9975 break;
9976 }
9977 if (!is_global_var (decl)
9978 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
9979 omp_add_variable (ctx, decl, GOVD_ALIGNED);
9980 break;
9981
9982 case OMP_CLAUSE_NONTEMPORAL:
9983 decl = OMP_CLAUSE_DECL (c);
9984 if (error_operand_p (decl))
9985 {
9986 remove = true;
9987 break;
9988 }
9989 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
9990 break;
9991
9992 case OMP_CLAUSE_ALLOCATE:
9993 decl = OMP_CLAUSE_DECL (c);
9994 if (error_operand_p (decl))
9995 {
9996 remove = true;
9997 break;
9998 }
9999 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL,
10000 is_gimple_val, fb_rvalue) == GS_ERROR)
10001 {
10002 remove = true;
10003 break;
10004 }
10005 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
10006 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
10007 == INTEGER_CST))
10008 ;
10009 else if (code == OMP_TASKLOOP
10010 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
10011 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
10012 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
10013 pre_p, NULL, false);
10014 break;
10015
10016 case OMP_CLAUSE_DEFAULT:
10017 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
10018 break;
10019
10020 case OMP_CLAUSE_INCLUSIVE:
10021 case OMP_CLAUSE_EXCLUSIVE:
10022 decl = OMP_CLAUSE_DECL (c);
10023 {
10024 splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
10025 (splay_tree_key) decl);
10026 if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
10027 {
10028 error_at (OMP_CLAUSE_LOCATION (c),
10029 "%qD specified in %qs clause but not in %<inscan%> "
10030 "%<reduction%> clause on the containing construct",
10031 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10032 remove = true;
10033 }
10034 else
10035 {
10036 n->value |= GOVD_REDUCTION_INSCAN;
10037 if (outer_ctx->region_type == ORT_SIMD
10038 && outer_ctx->outer_context
10039 && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
10040 {
10041 n = splay_tree_lookup (outer_ctx->outer_context->variables,
10042 (splay_tree_key) decl);
10043 if (n && (n->value & GOVD_REDUCTION) != 0)
10044 n->value |= GOVD_REDUCTION_INSCAN;
10045 }
10046 }
10047 }
10048 break;
10049
10050 default:
10051 gcc_unreachable ();
10052 }
10053
10054 if (code == OACC_DATA
10055 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10056 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
10057 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
10058 remove = true;
10059 if (remove)
10060 *list_p = OMP_CLAUSE_CHAIN (c);
10061 else
10062 list_p = &OMP_CLAUSE_CHAIN (c);
10063 }
10064
10065 ctx->clauses = *orig_list_p;
10066 gimplify_omp_ctxp = ctx;
10067 if (struct_map_to_clause)
10068 delete struct_map_to_clause;
10069 if (struct_deref_set)
10070 delete struct_deref_set;
10071 }
10072
10073 /* Return true if DECL is a candidate for shared to firstprivate
10074 optimization. We only consider non-addressable scalars, not
10075 too big, and not references. */
10076
10077 static bool
omp_shared_to_firstprivate_optimizable_decl_p(tree decl)10078 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
10079 {
10080 if (TREE_ADDRESSABLE (decl))
10081 return false;
10082 tree type = TREE_TYPE (decl);
10083 if (!is_gimple_reg_type (type)
10084 || TREE_CODE (type) == REFERENCE_TYPE
10085 || TREE_ADDRESSABLE (type))
10086 return false;
10087 /* Don't optimize too large decls, as each thread/task will have
10088 its own. */
10089 HOST_WIDE_INT len = int_size_in_bytes (type);
10090 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
10091 return false;
10092 if (lang_hooks.decls.omp_privatize_by_reference (decl))
10093 return false;
10094 return true;
10095 }
10096
10097 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
10098 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
10099 GOVD_WRITTEN in outer contexts. */
10100
10101 static void
omp_mark_stores(struct gimplify_omp_ctx * ctx,tree decl)10102 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
10103 {
10104 for (; ctx; ctx = ctx->outer_context)
10105 {
10106 splay_tree_node n = splay_tree_lookup (ctx->variables,
10107 (splay_tree_key) decl);
10108 if (n == NULL)
10109 continue;
10110 else if (n->value & GOVD_SHARED)
10111 {
10112 n->value |= GOVD_WRITTEN;
10113 return;
10114 }
10115 else if (n->value & GOVD_DATA_SHARE_CLASS)
10116 return;
10117 }
10118 }
10119
10120 /* Helper callback for walk_gimple_seq to discover possible stores
10121 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10122 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10123 for those. */
10124
10125 static tree
omp_find_stores_op(tree * tp,int * walk_subtrees,void * data)10126 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
10127 {
10128 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
10129
10130 *walk_subtrees = 0;
10131 if (!wi->is_lhs)
10132 return NULL_TREE;
10133
10134 tree op = *tp;
10135 do
10136 {
10137 if (handled_component_p (op))
10138 op = TREE_OPERAND (op, 0);
10139 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
10140 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
10141 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
10142 else
10143 break;
10144 }
10145 while (1);
10146 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
10147 return NULL_TREE;
10148
10149 omp_mark_stores (gimplify_omp_ctxp, op);
10150 return NULL_TREE;
10151 }
10152
10153 /* Helper callback for walk_gimple_seq to discover possible stores
10154 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10155 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10156 for those. */
10157
10158 static tree
omp_find_stores_stmt(gimple_stmt_iterator * gsi_p,bool * handled_ops_p,struct walk_stmt_info * wi)10159 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
10160 bool *handled_ops_p,
10161 struct walk_stmt_info *wi)
10162 {
10163 gimple *stmt = gsi_stmt (*gsi_p);
10164 switch (gimple_code (stmt))
10165 {
10166 /* Don't recurse on OpenMP constructs for which
10167 gimplify_adjust_omp_clauses already handled the bodies,
10168 except handle gimple_omp_for_pre_body. */
10169 case GIMPLE_OMP_FOR:
10170 *handled_ops_p = true;
10171 if (gimple_omp_for_pre_body (stmt))
10172 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
10173 omp_find_stores_stmt, omp_find_stores_op, wi);
10174 break;
10175 case GIMPLE_OMP_PARALLEL:
10176 case GIMPLE_OMP_TASK:
10177 case GIMPLE_OMP_SECTIONS:
10178 case GIMPLE_OMP_SINGLE:
10179 case GIMPLE_OMP_TARGET:
10180 case GIMPLE_OMP_TEAMS:
10181 case GIMPLE_OMP_CRITICAL:
10182 *handled_ops_p = true;
10183 break;
10184 default:
10185 break;
10186 }
10187 return NULL_TREE;
10188 }
10189
10190 struct gimplify_adjust_omp_clauses_data
10191 {
10192 tree *list_p;
10193 gimple_seq *pre_p;
10194 };
10195
10196 /* For all variables that were not actually used within the context,
10197 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
10198
10199 static int
gimplify_adjust_omp_clauses_1(splay_tree_node n,void * data)10200 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
10201 {
10202 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
10203 gimple_seq *pre_p
10204 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
10205 tree decl = (tree) n->key;
10206 unsigned flags = n->value;
10207 enum omp_clause_code code;
10208 tree clause;
10209 bool private_debug;
10210
10211 if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
10212 && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
10213 flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
10214 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
10215 return 0;
10216 if ((flags & GOVD_SEEN) == 0)
10217 return 0;
10218 if ((flags & GOVD_MAP_HAS_ATTACHMENTS) != 0)
10219 return 0;
10220 if (flags & GOVD_DEBUG_PRIVATE)
10221 {
10222 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
10223 private_debug = true;
10224 }
10225 else if (flags & GOVD_MAP)
10226 private_debug = false;
10227 else
10228 private_debug
10229 = lang_hooks.decls.omp_private_debug_clause (decl,
10230 !!(flags & GOVD_SHARED));
10231 if (private_debug)
10232 code = OMP_CLAUSE_PRIVATE;
10233 else if (flags & GOVD_MAP)
10234 {
10235 code = OMP_CLAUSE_MAP;
10236 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
10237 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
10238 {
10239 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
10240 return 0;
10241 }
10242 if (VAR_P (decl)
10243 && DECL_IN_CONSTANT_POOL (decl)
10244 && !lookup_attribute ("omp declare target",
10245 DECL_ATTRIBUTES (decl)))
10246 {
10247 tree id = get_identifier ("omp declare target");
10248 DECL_ATTRIBUTES (decl)
10249 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
10250 varpool_node *node = varpool_node::get (decl);
10251 if (node)
10252 {
10253 node->offloadable = 1;
10254 if (ENABLE_OFFLOADING)
10255 g->have_offload = true;
10256 }
10257 }
10258 }
10259 else if (flags & GOVD_SHARED)
10260 {
10261 if (is_global_var (decl))
10262 {
10263 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
10264 while (ctx != NULL)
10265 {
10266 splay_tree_node on
10267 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10268 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
10269 | GOVD_PRIVATE | GOVD_REDUCTION
10270 | GOVD_LINEAR | GOVD_MAP)) != 0)
10271 break;
10272 ctx = ctx->outer_context;
10273 }
10274 if (ctx == NULL)
10275 return 0;
10276 }
10277 code = OMP_CLAUSE_SHARED;
10278 /* Don't optimize shared into firstprivate for read-only vars
10279 on tasks with depend clause, we shouldn't try to copy them
10280 until the dependencies are satisfied. */
10281 if (gimplify_omp_ctxp->has_depend)
10282 flags |= GOVD_WRITTEN;
10283 }
10284 else if (flags & GOVD_PRIVATE)
10285 code = OMP_CLAUSE_PRIVATE;
10286 else if (flags & GOVD_FIRSTPRIVATE)
10287 {
10288 code = OMP_CLAUSE_FIRSTPRIVATE;
10289 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
10290 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
10291 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
10292 {
10293 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
10294 "%<target%> construct", decl);
10295 return 0;
10296 }
10297 }
10298 else if (flags & GOVD_LASTPRIVATE)
10299 code = OMP_CLAUSE_LASTPRIVATE;
10300 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
10301 return 0;
10302 else if (flags & GOVD_CONDTEMP)
10303 {
10304 code = OMP_CLAUSE__CONDTEMP_;
10305 gimple_add_tmp_var (decl);
10306 }
10307 else
10308 gcc_unreachable ();
10309
10310 if (((flags & GOVD_LASTPRIVATE)
10311 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
10312 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10313 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10314
10315 tree chain = *list_p;
10316 clause = build_omp_clause (input_location, code);
10317 OMP_CLAUSE_DECL (clause) = decl;
10318 OMP_CLAUSE_CHAIN (clause) = chain;
10319 if (private_debug)
10320 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
10321 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
10322 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
10323 else if (code == OMP_CLAUSE_SHARED
10324 && (flags & GOVD_WRITTEN) == 0
10325 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10326 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
10327 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
10328 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
10329 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
10330 {
10331 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
10332 OMP_CLAUSE_DECL (nc) = decl;
10333 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
10334 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
10335 OMP_CLAUSE_DECL (clause)
10336 = build_simple_mem_ref_loc (input_location, decl);
10337 OMP_CLAUSE_DECL (clause)
10338 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
10339 build_int_cst (build_pointer_type (char_type_node), 0));
10340 OMP_CLAUSE_SIZE (clause) = size_zero_node;
10341 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10342 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
10343 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
10344 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
10345 OMP_CLAUSE_CHAIN (nc) = chain;
10346 OMP_CLAUSE_CHAIN (clause) = nc;
10347 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10348 gimplify_omp_ctxp = ctx->outer_context;
10349 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
10350 pre_p, NULL, is_gimple_val, fb_rvalue);
10351 gimplify_omp_ctxp = ctx;
10352 }
10353 else if (code == OMP_CLAUSE_MAP)
10354 {
10355 int kind;
10356 /* Not all combinations of these GOVD_MAP flags are actually valid. */
10357 switch (flags & (GOVD_MAP_TO_ONLY
10358 | GOVD_MAP_FORCE
10359 | GOVD_MAP_FORCE_PRESENT
10360 | GOVD_MAP_ALLOC_ONLY
10361 | GOVD_MAP_FROM_ONLY))
10362 {
10363 case 0:
10364 kind = GOMP_MAP_TOFROM;
10365 break;
10366 case GOVD_MAP_FORCE:
10367 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
10368 break;
10369 case GOVD_MAP_TO_ONLY:
10370 kind = GOMP_MAP_TO;
10371 break;
10372 case GOVD_MAP_FROM_ONLY:
10373 kind = GOMP_MAP_FROM;
10374 break;
10375 case GOVD_MAP_ALLOC_ONLY:
10376 kind = GOMP_MAP_ALLOC;
10377 break;
10378 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
10379 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
10380 break;
10381 case GOVD_MAP_FORCE_PRESENT:
10382 kind = GOMP_MAP_FORCE_PRESENT;
10383 break;
10384 default:
10385 gcc_unreachable ();
10386 }
10387 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
10388 if (DECL_SIZE (decl)
10389 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
10390 {
10391 tree decl2 = DECL_VALUE_EXPR (decl);
10392 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
10393 decl2 = TREE_OPERAND (decl2, 0);
10394 gcc_assert (DECL_P (decl2));
10395 tree mem = build_simple_mem_ref (decl2);
10396 OMP_CLAUSE_DECL (clause) = mem;
10397 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
10398 if (gimplify_omp_ctxp->outer_context)
10399 {
10400 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
10401 omp_notice_variable (ctx, decl2, true);
10402 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
10403 }
10404 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
10405 OMP_CLAUSE_MAP);
10406 OMP_CLAUSE_DECL (nc) = decl;
10407 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10408 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
10409 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
10410 else
10411 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
10412 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
10413 OMP_CLAUSE_CHAIN (clause) = nc;
10414 }
10415 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
10416 && lang_hooks.decls.omp_privatize_by_reference (decl))
10417 {
10418 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
10419 OMP_CLAUSE_SIZE (clause)
10420 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
10421 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10422 gimplify_omp_ctxp = ctx->outer_context;
10423 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
10424 pre_p, NULL, is_gimple_val, fb_rvalue);
10425 gimplify_omp_ctxp = ctx;
10426 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
10427 OMP_CLAUSE_MAP);
10428 OMP_CLAUSE_DECL (nc) = decl;
10429 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10430 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
10431 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
10432 OMP_CLAUSE_CHAIN (clause) = nc;
10433 }
10434 else
10435 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
10436 }
10437 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
10438 {
10439 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
10440 OMP_CLAUSE_DECL (nc) = decl;
10441 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
10442 OMP_CLAUSE_CHAIN (nc) = chain;
10443 OMP_CLAUSE_CHAIN (clause) = nc;
10444 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10445 gimplify_omp_ctxp = ctx->outer_context;
10446 lang_hooks.decls.omp_finish_clause (nc, pre_p,
10447 (ctx->region_type & ORT_ACC) != 0);
10448 gimplify_omp_ctxp = ctx;
10449 }
10450 *list_p = clause;
10451 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10452 gimplify_omp_ctxp = ctx->outer_context;
10453 lang_hooks.decls.omp_finish_clause (clause, pre_p,
10454 (ctx->region_type & ORT_ACC) != 0);
10455 if (gimplify_omp_ctxp)
10456 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
10457 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
10458 && DECL_P (OMP_CLAUSE_SIZE (clause)))
10459 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
10460 true);
10461 gimplify_omp_ctxp = ctx;
10462 return 0;
10463 }
10464
10465 static void
gimplify_adjust_omp_clauses(gimple_seq * pre_p,gimple_seq body,tree * list_p,enum tree_code code)10466 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
10467 enum tree_code code)
10468 {
10469 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10470 tree *orig_list_p = list_p;
10471 tree c, decl;
10472 bool has_inscan_reductions = false;
10473
10474 if (body)
10475 {
10476 struct gimplify_omp_ctx *octx;
10477 for (octx = ctx; octx; octx = octx->outer_context)
10478 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
10479 break;
10480 if (octx)
10481 {
10482 struct walk_stmt_info wi;
10483 memset (&wi, 0, sizeof (wi));
10484 walk_gimple_seq (body, omp_find_stores_stmt,
10485 omp_find_stores_op, &wi);
10486 }
10487 }
10488
10489 if (ctx->add_safelen1)
10490 {
10491 /* If there are VLAs in the body of simd loop, prevent
10492 vectorization. */
10493 gcc_assert (ctx->region_type == ORT_SIMD);
10494 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
10495 OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
10496 OMP_CLAUSE_CHAIN (c) = *list_p;
10497 *list_p = c;
10498 list_p = &OMP_CLAUSE_CHAIN (c);
10499 }
10500
10501 if (ctx->region_type == ORT_WORKSHARE
10502 && ctx->outer_context
10503 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
10504 {
10505 for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
10506 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10507 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
10508 {
10509 decl = OMP_CLAUSE_DECL (c);
10510 splay_tree_node n
10511 = splay_tree_lookup (ctx->outer_context->variables,
10512 (splay_tree_key) decl);
10513 gcc_checking_assert (!splay_tree_lookup (ctx->variables,
10514 (splay_tree_key) decl));
10515 omp_add_variable (ctx, decl, n->value);
10516 tree c2 = copy_node (c);
10517 OMP_CLAUSE_CHAIN (c2) = *list_p;
10518 *list_p = c2;
10519 if ((n->value & GOVD_FIRSTPRIVATE) == 0)
10520 continue;
10521 c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10522 OMP_CLAUSE_FIRSTPRIVATE);
10523 OMP_CLAUSE_DECL (c2) = decl;
10524 OMP_CLAUSE_CHAIN (c2) = *list_p;
10525 *list_p = c2;
10526 }
10527 }
10528 while ((c = *list_p) != NULL)
10529 {
10530 splay_tree_node n;
10531 bool remove = false;
10532
10533 switch (OMP_CLAUSE_CODE (c))
10534 {
10535 case OMP_CLAUSE_FIRSTPRIVATE:
10536 if ((ctx->region_type & ORT_TARGET)
10537 && (ctx->region_type & ORT_ACC) == 0
10538 && TYPE_ATOMIC (strip_array_types
10539 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
10540 {
10541 error_at (OMP_CLAUSE_LOCATION (c),
10542 "%<_Atomic%> %qD in %<firstprivate%> clause on "
10543 "%<target%> construct", OMP_CLAUSE_DECL (c));
10544 remove = true;
10545 break;
10546 }
10547 /* FALLTHRU */
10548 case OMP_CLAUSE_PRIVATE:
10549 case OMP_CLAUSE_SHARED:
10550 case OMP_CLAUSE_LINEAR:
10551 decl = OMP_CLAUSE_DECL (c);
10552 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10553 remove = !(n->value & GOVD_SEEN);
10554 if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
10555 && code == OMP_PARALLEL
10556 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
10557 remove = true;
10558 if (! remove)
10559 {
10560 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
10561 if ((n->value & GOVD_DEBUG_PRIVATE)
10562 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
10563 {
10564 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
10565 || ((n->value & GOVD_DATA_SHARE_CLASS)
10566 == GOVD_SHARED));
10567 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
10568 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
10569 }
10570 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10571 && ctx->has_depend
10572 && DECL_P (decl))
10573 n->value |= GOVD_WRITTEN;
10574 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10575 && (n->value & GOVD_WRITTEN) == 0
10576 && DECL_P (decl)
10577 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10578 OMP_CLAUSE_SHARED_READONLY (c) = 1;
10579 else if (DECL_P (decl)
10580 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10581 && (n->value & GOVD_WRITTEN) != 0)
10582 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10583 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
10584 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10585 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10586 }
10587 else
10588 n->value &= ~GOVD_EXPLICIT;
10589 break;
10590
10591 case OMP_CLAUSE_LASTPRIVATE:
10592 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
10593 accurately reflect the presence of a FIRSTPRIVATE clause. */
10594 decl = OMP_CLAUSE_DECL (c);
10595 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10596 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
10597 = (n->value & GOVD_FIRSTPRIVATE) != 0;
10598 if (code == OMP_DISTRIBUTE
10599 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
10600 {
10601 remove = true;
10602 error_at (OMP_CLAUSE_LOCATION (c),
10603 "same variable used in %<firstprivate%> and "
10604 "%<lastprivate%> clauses on %<distribute%> "
10605 "construct");
10606 }
10607 if (!remove
10608 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10609 && DECL_P (decl)
10610 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10611 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10612 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
10613 remove = true;
10614 break;
10615
10616 case OMP_CLAUSE_ALIGNED:
10617 decl = OMP_CLAUSE_DECL (c);
10618 if (!is_global_var (decl))
10619 {
10620 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10621 remove = n == NULL || !(n->value & GOVD_SEEN);
10622 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
10623 {
10624 struct gimplify_omp_ctx *octx;
10625 if (n != NULL
10626 && (n->value & (GOVD_DATA_SHARE_CLASS
10627 & ~GOVD_FIRSTPRIVATE)))
10628 remove = true;
10629 else
10630 for (octx = ctx->outer_context; octx;
10631 octx = octx->outer_context)
10632 {
10633 n = splay_tree_lookup (octx->variables,
10634 (splay_tree_key) decl);
10635 if (n == NULL)
10636 continue;
10637 if (n->value & GOVD_LOCAL)
10638 break;
10639 /* We have to avoid assigning a shared variable
10640 to itself when trying to add
10641 __builtin_assume_aligned. */
10642 if (n->value & GOVD_SHARED)
10643 {
10644 remove = true;
10645 break;
10646 }
10647 }
10648 }
10649 }
10650 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
10651 {
10652 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10653 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
10654 remove = true;
10655 }
10656 break;
10657
10658 case OMP_CLAUSE_NONTEMPORAL:
10659 decl = OMP_CLAUSE_DECL (c);
10660 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10661 remove = n == NULL || !(n->value & GOVD_SEEN);
10662 break;
10663
10664 case OMP_CLAUSE_MAP:
10665 if (code == OMP_TARGET_EXIT_DATA
10666 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
10667 {
10668 remove = true;
10669 break;
10670 }
10671 decl = OMP_CLAUSE_DECL (c);
10672 /* Data clauses associated with reductions must be
10673 compatible with present_or_copy. Warn and adjust the clause
10674 if that is not the case. */
10675 if (ctx->region_type == ORT_ACC_PARALLEL
10676 || ctx->region_type == ORT_ACC_SERIAL)
10677 {
10678 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
10679 n = NULL;
10680
10681 if (DECL_P (t))
10682 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
10683
10684 if (n && (n->value & GOVD_REDUCTION))
10685 {
10686 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
10687
10688 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
10689 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
10690 && kind != GOMP_MAP_FORCE_PRESENT
10691 && kind != GOMP_MAP_POINTER)
10692 {
10693 warning_at (OMP_CLAUSE_LOCATION (c), 0,
10694 "incompatible data clause with reduction "
10695 "on %qE; promoting to %<present_or_copy%>",
10696 DECL_NAME (t));
10697 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
10698 }
10699 }
10700 }
10701 if (!DECL_P (decl))
10702 {
10703 if ((ctx->region_type & ORT_TARGET) != 0
10704 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
10705 {
10706 if (TREE_CODE (decl) == INDIRECT_REF
10707 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
10708 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
10709 == REFERENCE_TYPE))
10710 decl = TREE_OPERAND (decl, 0);
10711 if (TREE_CODE (decl) == COMPONENT_REF)
10712 {
10713 while (TREE_CODE (decl) == COMPONENT_REF)
10714 decl = TREE_OPERAND (decl, 0);
10715 if (DECL_P (decl))
10716 {
10717 n = splay_tree_lookup (ctx->variables,
10718 (splay_tree_key) decl);
10719 if (!(n->value & GOVD_SEEN))
10720 remove = true;
10721 }
10722 }
10723 }
10724 break;
10725 }
10726 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10727 if ((ctx->region_type & ORT_TARGET) != 0
10728 && !(n->value & GOVD_SEEN)
10729 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
10730 && (!is_global_var (decl)
10731 || !lookup_attribute ("omp declare target link",
10732 DECL_ATTRIBUTES (decl))))
10733 {
10734 remove = true;
10735 /* For struct element mapping, if struct is never referenced
10736 in target block and none of the mapping has always modifier,
10737 remove all the struct element mappings, which immediately
10738 follow the GOMP_MAP_STRUCT map clause. */
10739 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
10740 {
10741 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
10742 while (cnt--)
10743 OMP_CLAUSE_CHAIN (c)
10744 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
10745 }
10746 }
10747 else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
10748 && (code == OMP_TARGET_EXIT_DATA
10749 || code == OACC_EXIT_DATA))
10750 remove = true;
10751 else if (DECL_SIZE (decl)
10752 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
10753 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
10754 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
10755 && (OMP_CLAUSE_MAP_KIND (c)
10756 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
10757 {
10758 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
10759 for these, TREE_CODE (DECL_SIZE (decl)) will always be
10760 INTEGER_CST. */
10761 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
10762
10763 tree decl2 = DECL_VALUE_EXPR (decl);
10764 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
10765 decl2 = TREE_OPERAND (decl2, 0);
10766 gcc_assert (DECL_P (decl2));
10767 tree mem = build_simple_mem_ref (decl2);
10768 OMP_CLAUSE_DECL (c) = mem;
10769 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
10770 if (ctx->outer_context)
10771 {
10772 omp_notice_variable (ctx->outer_context, decl2, true);
10773 omp_notice_variable (ctx->outer_context,
10774 OMP_CLAUSE_SIZE (c), true);
10775 }
10776 if (((ctx->region_type & ORT_TARGET) != 0
10777 || !ctx->target_firstprivatize_array_bases)
10778 && ((n->value & GOVD_SEEN) == 0
10779 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
10780 {
10781 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10782 OMP_CLAUSE_MAP);
10783 OMP_CLAUSE_DECL (nc) = decl;
10784 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10785 if (ctx->target_firstprivatize_array_bases)
10786 OMP_CLAUSE_SET_MAP_KIND (nc,
10787 GOMP_MAP_FIRSTPRIVATE_POINTER);
10788 else
10789 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
10790 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
10791 OMP_CLAUSE_CHAIN (c) = nc;
10792 c = nc;
10793 }
10794 }
10795 else
10796 {
10797 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10798 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
10799 gcc_assert ((n->value & GOVD_SEEN) == 0
10800 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
10801 == 0));
10802 }
10803 break;
10804
10805 case OMP_CLAUSE_TO:
10806 case OMP_CLAUSE_FROM:
10807 case OMP_CLAUSE__CACHE_:
10808 decl = OMP_CLAUSE_DECL (c);
10809 if (!DECL_P (decl))
10810 break;
10811 if (DECL_SIZE (decl)
10812 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
10813 {
10814 tree decl2 = DECL_VALUE_EXPR (decl);
10815 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
10816 decl2 = TREE_OPERAND (decl2, 0);
10817 gcc_assert (DECL_P (decl2));
10818 tree mem = build_simple_mem_ref (decl2);
10819 OMP_CLAUSE_DECL (c) = mem;
10820 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
10821 if (ctx->outer_context)
10822 {
10823 omp_notice_variable (ctx->outer_context, decl2, true);
10824 omp_notice_variable (ctx->outer_context,
10825 OMP_CLAUSE_SIZE (c), true);
10826 }
10827 }
10828 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10829 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
10830 break;
10831
10832 case OMP_CLAUSE_REDUCTION:
10833 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
10834 {
10835 decl = OMP_CLAUSE_DECL (c);
10836 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10837 if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
10838 {
10839 remove = true;
10840 error_at (OMP_CLAUSE_LOCATION (c),
10841 "%qD specified in %<inscan%> %<reduction%> clause "
10842 "but not in %<scan%> directive clause", decl);
10843 break;
10844 }
10845 has_inscan_reductions = true;
10846 }
10847 /* FALLTHRU */
10848 case OMP_CLAUSE_IN_REDUCTION:
10849 case OMP_CLAUSE_TASK_REDUCTION:
10850 decl = OMP_CLAUSE_DECL (c);
10851 /* OpenACC reductions need a present_or_copy data clause.
10852 Add one if necessary. Emit error when the reduction is private. */
10853 if (ctx->region_type == ORT_ACC_PARALLEL
10854 || ctx->region_type == ORT_ACC_SERIAL)
10855 {
10856 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10857 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
10858 {
10859 remove = true;
10860 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
10861 "reduction on %qE", DECL_NAME (decl));
10862 }
10863 else if ((n->value & GOVD_MAP) == 0)
10864 {
10865 tree next = OMP_CLAUSE_CHAIN (c);
10866 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
10867 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
10868 OMP_CLAUSE_DECL (nc) = decl;
10869 OMP_CLAUSE_CHAIN (c) = nc;
10870 lang_hooks.decls.omp_finish_clause (nc, pre_p,
10871 (ctx->region_type
10872 & ORT_ACC) != 0);
10873 while (1)
10874 {
10875 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
10876 if (OMP_CLAUSE_CHAIN (nc) == NULL)
10877 break;
10878 nc = OMP_CLAUSE_CHAIN (nc);
10879 }
10880 OMP_CLAUSE_CHAIN (nc) = next;
10881 n->value |= GOVD_MAP;
10882 }
10883 }
10884 if (DECL_P (decl)
10885 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10886 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10887 break;
10888
10889 case OMP_CLAUSE_ALLOCATE:
10890 decl = OMP_CLAUSE_DECL (c);
10891 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10892 if (n != NULL && !(n->value & GOVD_SEEN))
10893 {
10894 if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR))
10895 != 0
10896 && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0)
10897 remove = true;
10898 }
10899 if (!remove
10900 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
10901 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST
10902 && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0
10903 || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK
10904 || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS))
10905 {
10906 tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
10907 n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator);
10908 if (n == NULL)
10909 {
10910 enum omp_clause_default_kind default_kind
10911 = ctx->default_kind;
10912 ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
10913 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
10914 true);
10915 ctx->default_kind = default_kind;
10916 }
10917 else
10918 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
10919 true);
10920 }
10921 break;
10922
10923 case OMP_CLAUSE_COPYIN:
10924 case OMP_CLAUSE_COPYPRIVATE:
10925 case OMP_CLAUSE_IF:
10926 case OMP_CLAUSE_NUM_THREADS:
10927 case OMP_CLAUSE_NUM_TEAMS:
10928 case OMP_CLAUSE_THREAD_LIMIT:
10929 case OMP_CLAUSE_DIST_SCHEDULE:
10930 case OMP_CLAUSE_DEVICE:
10931 case OMP_CLAUSE_SCHEDULE:
10932 case OMP_CLAUSE_NOWAIT:
10933 case OMP_CLAUSE_ORDERED:
10934 case OMP_CLAUSE_DEFAULT:
10935 case OMP_CLAUSE_UNTIED:
10936 case OMP_CLAUSE_COLLAPSE:
10937 case OMP_CLAUSE_FINAL:
10938 case OMP_CLAUSE_MERGEABLE:
10939 case OMP_CLAUSE_PROC_BIND:
10940 case OMP_CLAUSE_SAFELEN:
10941 case OMP_CLAUSE_SIMDLEN:
10942 case OMP_CLAUSE_DEPEND:
10943 case OMP_CLAUSE_PRIORITY:
10944 case OMP_CLAUSE_GRAINSIZE:
10945 case OMP_CLAUSE_NUM_TASKS:
10946 case OMP_CLAUSE_NOGROUP:
10947 case OMP_CLAUSE_THREADS:
10948 case OMP_CLAUSE_SIMD:
10949 case OMP_CLAUSE_HINT:
10950 case OMP_CLAUSE_DEFAULTMAP:
10951 case OMP_CLAUSE_ORDER:
10952 case OMP_CLAUSE_BIND:
10953 case OMP_CLAUSE_DETACH:
10954 case OMP_CLAUSE_USE_DEVICE_PTR:
10955 case OMP_CLAUSE_USE_DEVICE_ADDR:
10956 case OMP_CLAUSE_IS_DEVICE_PTR:
10957 case OMP_CLAUSE_ASYNC:
10958 case OMP_CLAUSE_WAIT:
10959 case OMP_CLAUSE_INDEPENDENT:
10960 case OMP_CLAUSE_NUM_GANGS:
10961 case OMP_CLAUSE_NUM_WORKERS:
10962 case OMP_CLAUSE_VECTOR_LENGTH:
10963 case OMP_CLAUSE_GANG:
10964 case OMP_CLAUSE_WORKER:
10965 case OMP_CLAUSE_VECTOR:
10966 case OMP_CLAUSE_AUTO:
10967 case OMP_CLAUSE_SEQ:
10968 case OMP_CLAUSE_TILE:
10969 case OMP_CLAUSE_IF_PRESENT:
10970 case OMP_CLAUSE_FINALIZE:
10971 case OMP_CLAUSE_INCLUSIVE:
10972 case OMP_CLAUSE_EXCLUSIVE:
10973 break;
10974
10975 default:
10976 gcc_unreachable ();
10977 }
10978
10979 if (remove)
10980 *list_p = OMP_CLAUSE_CHAIN (c);
10981 else
10982 list_p = &OMP_CLAUSE_CHAIN (c);
10983 }
10984
10985 /* Add in any implicit data sharing. */
10986 struct gimplify_adjust_omp_clauses_data data;
10987 data.list_p = list_p;
10988 data.pre_p = pre_p;
10989 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
10990
10991 if (has_inscan_reductions)
10992 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
10993 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10994 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
10995 {
10996 error_at (OMP_CLAUSE_LOCATION (c),
10997 "%<inscan%> %<reduction%> clause used together with "
10998 "%<linear%> clause for a variable other than loop "
10999 "iterator");
11000 break;
11001 }
11002
11003 gimplify_omp_ctxp = ctx->outer_context;
11004 delete_omp_context (ctx);
11005 }
11006
11007 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
11008 -1 if unknown yet (simd is involved, won't be known until vectorization)
11009 and 1 if they do. If SCORES is non-NULL, it should point to an array
11010 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
11011 of the CONSTRUCTS (position -1 if it will never match) followed by
11012 number of constructs in the OpenMP context construct trait. If the
11013 score depends on whether it will be in a declare simd clone or not,
11014 the function returns 2 and there will be two sets of the scores, the first
11015 one for the case that it is not in a declare simd clone, the other
11016 that it is in a declare simd clone. */
11017
11018 int
omp_construct_selector_matches(enum tree_code * constructs,int nconstructs,int * scores)11019 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
11020 int *scores)
11021 {
11022 int matched = 0, cnt = 0;
11023 bool simd_seen = false;
11024 bool target_seen = false;
11025 int declare_simd_cnt = -1;
11026 auto_vec<enum tree_code, 16> codes;
11027 for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
11028 {
11029 if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
11030 || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
11031 == ORT_TARGET && ctx->code == OMP_TARGET)
11032 || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
11033 || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
11034 || (ctx->region_type == ORT_SIMD
11035 && ctx->code == OMP_SIMD
11036 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
11037 {
11038 ++cnt;
11039 if (scores)
11040 codes.safe_push (ctx->code);
11041 else if (matched < nconstructs && ctx->code == constructs[matched])
11042 {
11043 if (ctx->code == OMP_SIMD)
11044 {
11045 if (matched)
11046 return 0;
11047 simd_seen = true;
11048 }
11049 ++matched;
11050 }
11051 if (ctx->code == OMP_TARGET)
11052 {
11053 if (scores == NULL)
11054 return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
11055 target_seen = true;
11056 break;
11057 }
11058 }
11059 else if (ctx->region_type == ORT_WORKSHARE
11060 && ctx->code == OMP_LOOP
11061 && ctx->outer_context
11062 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
11063 && ctx->outer_context->outer_context
11064 && ctx->outer_context->outer_context->code == OMP_LOOP
11065 && ctx->outer_context->outer_context->distribute)
11066 ctx = ctx->outer_context->outer_context;
11067 ctx = ctx->outer_context;
11068 }
11069 if (!target_seen
11070 && lookup_attribute ("omp declare simd",
11071 DECL_ATTRIBUTES (current_function_decl)))
11072 {
11073 /* Declare simd is a maybe case, it is supposed to be added only to the
11074 omp-simd-clone.c added clones and not to the base function. */
11075 declare_simd_cnt = cnt++;
11076 if (scores)
11077 codes.safe_push (OMP_SIMD);
11078 else if (cnt == 0
11079 && constructs[0] == OMP_SIMD)
11080 {
11081 gcc_assert (matched == 0);
11082 simd_seen = true;
11083 if (++matched == nconstructs)
11084 return -1;
11085 }
11086 }
11087 if (tree attr = lookup_attribute ("omp declare variant variant",
11088 DECL_ATTRIBUTES (current_function_decl)))
11089 {
11090 enum tree_code variant_constructs[5];
11091 int variant_nconstructs = 0;
11092 if (!target_seen)
11093 variant_nconstructs
11094 = omp_constructor_traits_to_codes (TREE_VALUE (attr),
11095 variant_constructs);
11096 for (int i = 0; i < variant_nconstructs; i++)
11097 {
11098 ++cnt;
11099 if (scores)
11100 codes.safe_push (variant_constructs[i]);
11101 else if (matched < nconstructs
11102 && variant_constructs[i] == constructs[matched])
11103 {
11104 if (variant_constructs[i] == OMP_SIMD)
11105 {
11106 if (matched)
11107 return 0;
11108 simd_seen = true;
11109 }
11110 ++matched;
11111 }
11112 }
11113 }
11114 if (!target_seen
11115 && lookup_attribute ("omp declare target block",
11116 DECL_ATTRIBUTES (current_function_decl)))
11117 {
11118 if (scores)
11119 codes.safe_push (OMP_TARGET);
11120 else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
11121 ++matched;
11122 }
11123 if (scores)
11124 {
11125 for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
11126 {
11127 int j = codes.length () - 1;
11128 for (int i = nconstructs - 1; i >= 0; i--)
11129 {
11130 while (j >= 0
11131 && (pass != 0 || declare_simd_cnt != j)
11132 && constructs[i] != codes[j])
11133 --j;
11134 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
11135 *scores++ = j - 1;
11136 else
11137 *scores++ = j;
11138 }
11139 *scores++ = ((pass == 0 && declare_simd_cnt != -1)
11140 ? codes.length () - 1 : codes.length ());
11141 }
11142 return declare_simd_cnt == -1 ? 1 : 2;
11143 }
11144 if (matched == nconstructs)
11145 return simd_seen ? -1 : 1;
11146 return 0;
11147 }
11148
11149 /* Gimplify OACC_CACHE. */
11150
11151 static void
gimplify_oacc_cache(tree * expr_p,gimple_seq * pre_p)11152 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
11153 {
11154 tree expr = *expr_p;
11155
11156 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
11157 OACC_CACHE);
11158 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
11159 OACC_CACHE);
11160
11161 /* TODO: Do something sensible with this information. */
11162
11163 *expr_p = NULL_TREE;
11164 }
11165
11166 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
11167 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
11168 kind. The entry kind will replace the one in CLAUSE, while the exit
11169 kind will be used in a new omp_clause and returned to the caller. */
11170
11171 static tree
gimplify_oacc_declare_1(tree clause)11172 gimplify_oacc_declare_1 (tree clause)
11173 {
11174 HOST_WIDE_INT kind, new_op;
11175 bool ret = false;
11176 tree c = NULL;
11177
11178 kind = OMP_CLAUSE_MAP_KIND (clause);
11179
11180 switch (kind)
11181 {
11182 case GOMP_MAP_ALLOC:
11183 new_op = GOMP_MAP_RELEASE;
11184 ret = true;
11185 break;
11186
11187 case GOMP_MAP_FROM:
11188 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
11189 new_op = GOMP_MAP_FROM;
11190 ret = true;
11191 break;
11192
11193 case GOMP_MAP_TOFROM:
11194 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
11195 new_op = GOMP_MAP_FROM;
11196 ret = true;
11197 break;
11198
11199 case GOMP_MAP_DEVICE_RESIDENT:
11200 case GOMP_MAP_FORCE_DEVICEPTR:
11201 case GOMP_MAP_FORCE_PRESENT:
11202 case GOMP_MAP_LINK:
11203 case GOMP_MAP_POINTER:
11204 case GOMP_MAP_TO:
11205 break;
11206
11207 default:
11208 gcc_unreachable ();
11209 break;
11210 }
11211
11212 if (ret)
11213 {
11214 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
11215 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
11216 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
11217 }
11218
11219 return c;
11220 }
11221
11222 /* Gimplify OACC_DECLARE. */
11223
11224 static void
gimplify_oacc_declare(tree * expr_p,gimple_seq * pre_p)11225 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
11226 {
11227 tree expr = *expr_p;
11228 gomp_target *stmt;
11229 tree clauses, t, decl;
11230
11231 clauses = OACC_DECLARE_CLAUSES (expr);
11232
11233 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
11234 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
11235
11236 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
11237 {
11238 decl = OMP_CLAUSE_DECL (t);
11239
11240 if (TREE_CODE (decl) == MEM_REF)
11241 decl = TREE_OPERAND (decl, 0);
11242
11243 if (VAR_P (decl) && !is_oacc_declared (decl))
11244 {
11245 tree attr = get_identifier ("oacc declare target");
11246 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
11247 DECL_ATTRIBUTES (decl));
11248 }
11249
11250 if (VAR_P (decl)
11251 && !is_global_var (decl)
11252 && DECL_CONTEXT (decl) == current_function_decl)
11253 {
11254 tree c = gimplify_oacc_declare_1 (t);
11255 if (c)
11256 {
11257 if (oacc_declare_returns == NULL)
11258 oacc_declare_returns = new hash_map<tree, tree>;
11259
11260 oacc_declare_returns->put (decl, c);
11261 }
11262 }
11263
11264 if (gimplify_omp_ctxp)
11265 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
11266 }
11267
11268 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
11269 clauses);
11270
11271 gimplify_seq_add_stmt (pre_p, stmt);
11272
11273 *expr_p = NULL_TREE;
11274 }
11275
11276 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
11277 gimplification of the body, as well as scanning the body for used
11278 variables. We need to do this scan now, because variable-sized
11279 decls will be decomposed during gimplification. */
11280
11281 static void
gimplify_omp_parallel(tree * expr_p,gimple_seq * pre_p)11282 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
11283 {
11284 tree expr = *expr_p;
11285 gimple *g;
11286 gimple_seq body = NULL;
11287
11288 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
11289 OMP_PARALLEL_COMBINED (expr)
11290 ? ORT_COMBINED_PARALLEL
11291 : ORT_PARALLEL, OMP_PARALLEL);
11292
11293 push_gimplify_context ();
11294
11295 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
11296 if (gimple_code (g) == GIMPLE_BIND)
11297 pop_gimplify_context (g);
11298 else
11299 pop_gimplify_context (NULL);
11300
11301 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
11302 OMP_PARALLEL);
11303
11304 g = gimple_build_omp_parallel (body,
11305 OMP_PARALLEL_CLAUSES (expr),
11306 NULL_TREE, NULL_TREE);
11307 if (OMP_PARALLEL_COMBINED (expr))
11308 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
11309 gimplify_seq_add_stmt (pre_p, g);
11310 *expr_p = NULL_TREE;
11311 }
11312
11313 /* Gimplify the contents of an OMP_TASK statement. This involves
11314 gimplification of the body, as well as scanning the body for used
11315 variables. We need to do this scan now, because variable-sized
11316 decls will be decomposed during gimplification. */
11317
11318 static void
gimplify_omp_task(tree * expr_p,gimple_seq * pre_p)11319 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
11320 {
11321 tree expr = *expr_p;
11322 gimple *g;
11323 gimple_seq body = NULL;
11324
11325 if (OMP_TASK_BODY (expr) == NULL_TREE)
11326 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
11327 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
11328 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
11329 {
11330 error_at (OMP_CLAUSE_LOCATION (c),
11331 "%<mutexinoutset%> kind in %<depend%> clause on a "
11332 "%<taskwait%> construct");
11333 break;
11334 }
11335
11336 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
11337 omp_find_clause (OMP_TASK_CLAUSES (expr),
11338 OMP_CLAUSE_UNTIED)
11339 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
11340
11341 if (OMP_TASK_BODY (expr))
11342 {
11343 push_gimplify_context ();
11344
11345 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
11346 if (gimple_code (g) == GIMPLE_BIND)
11347 pop_gimplify_context (g);
11348 else
11349 pop_gimplify_context (NULL);
11350 }
11351
11352 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
11353 OMP_TASK);
11354
11355 g = gimple_build_omp_task (body,
11356 OMP_TASK_CLAUSES (expr),
11357 NULL_TREE, NULL_TREE,
11358 NULL_TREE, NULL_TREE, NULL_TREE);
11359 if (OMP_TASK_BODY (expr) == NULL_TREE)
11360 gimple_omp_task_set_taskwait_p (g, true);
11361 gimplify_seq_add_stmt (pre_p, g);
11362 *expr_p = NULL_TREE;
11363 }
11364
11365 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
11366 force it into a temporary initialized in PRE_P and add firstprivate clause
11367 to ORIG_FOR_STMT. */
11368
11369 static void
gimplify_omp_taskloop_expr(tree type,tree * tp,gimple_seq * pre_p,tree orig_for_stmt)11370 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
11371 tree orig_for_stmt)
11372 {
11373 if (*tp == NULL || is_gimple_constant (*tp))
11374 return;
11375
11376 *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
11377 /* Reference to pointer conversion is considered useless,
11378 but is significant for firstprivate clause. Force it
11379 here. */
11380 if (type
11381 && TREE_CODE (type) == POINTER_TYPE
11382 && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
11383 {
11384 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
11385 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
11386 gimplify_and_add (m, pre_p);
11387 *tp = v;
11388 }
11389
11390 tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
11391 OMP_CLAUSE_DECL (c) = *tp;
11392 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
11393 OMP_FOR_CLAUSES (orig_for_stmt) = c;
11394 }
11395
11396 /* Gimplify the gross structure of an OMP_FOR statement. */
11397
11398 static enum gimplify_status
gimplify_omp_for(tree * expr_p,gimple_seq * pre_p)11399 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
11400 {
11401 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
11402 enum gimplify_status ret = GS_ALL_DONE;
11403 enum gimplify_status tret;
11404 gomp_for *gfor;
11405 gimple_seq for_body, for_pre_body;
11406 int i;
11407 bitmap has_decl_expr = NULL;
11408 enum omp_region_type ort = ORT_WORKSHARE;
11409 bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
11410
11411 orig_for_stmt = for_stmt = *expr_p;
11412
11413 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
11414 != NULL_TREE);
11415 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
11416 {
11417 tree *data[4] = { NULL, NULL, NULL, NULL };
11418 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
11419 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
11420 find_combined_omp_for, data, NULL);
11421 if (inner_for_stmt == NULL_TREE)
11422 {
11423 gcc_assert (seen_error ());
11424 *expr_p = NULL_TREE;
11425 return GS_ERROR;
11426 }
11427 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
11428 {
11429 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
11430 &OMP_FOR_PRE_BODY (for_stmt));
11431 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
11432 }
11433 if (OMP_FOR_PRE_BODY (inner_for_stmt))
11434 {
11435 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
11436 &OMP_FOR_PRE_BODY (for_stmt));
11437 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
11438 }
11439
11440 if (data[0])
11441 {
11442 /* We have some statements or variable declarations in between
11443 the composite construct directives. Move them around the
11444 inner_for_stmt. */
11445 data[0] = expr_p;
11446 for (i = 0; i < 3; i++)
11447 if (data[i])
11448 {
11449 tree t = *data[i];
11450 if (i < 2 && data[i + 1] == &OMP_BODY (t))
11451 data[i + 1] = data[i];
11452 *data[i] = OMP_BODY (t);
11453 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
11454 NULL_TREE, make_node (BLOCK));
11455 OMP_BODY (t) = body;
11456 append_to_statement_list_force (inner_for_stmt,
11457 &BIND_EXPR_BODY (body));
11458 *data[3] = t;
11459 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
11460 gcc_assert (*data[3] == inner_for_stmt);
11461 }
11462 return GS_OK;
11463 }
11464
11465 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
11466 if (!loop_p
11467 && OMP_FOR_ORIG_DECLS (inner_for_stmt)
11468 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11469 i)) == TREE_LIST
11470 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11471 i)))
11472 {
11473 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
11474 /* Class iterators aren't allowed on OMP_SIMD, so the only
11475 case we need to solve is distribute parallel for. They are
11476 allowed on the loop construct, but that is already handled
11477 in gimplify_omp_loop. */
11478 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
11479 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
11480 && data[1]);
11481 tree orig_decl = TREE_PURPOSE (orig);
11482 tree last = TREE_VALUE (orig);
11483 tree *pc;
11484 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
11485 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
11486 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
11487 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
11488 && OMP_CLAUSE_DECL (*pc) == orig_decl)
11489 break;
11490 if (*pc == NULL_TREE)
11491 {
11492 tree *spc;
11493 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
11494 *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
11495 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
11496 && OMP_CLAUSE_DECL (*spc) == orig_decl)
11497 break;
11498 if (*spc)
11499 {
11500 tree c = *spc;
11501 *spc = OMP_CLAUSE_CHAIN (c);
11502 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
11503 *pc = c;
11504 }
11505 }
11506 if (*pc == NULL_TREE)
11507 ;
11508 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
11509 {
11510 /* private clause will appear only on inner_for_stmt.
11511 Change it into firstprivate, and add private clause
11512 on for_stmt. */
11513 tree c = copy_node (*pc);
11514 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
11515 OMP_FOR_CLAUSES (for_stmt) = c;
11516 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
11517 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
11518 }
11519 else
11520 {
11521 /* lastprivate clause will appear on both inner_for_stmt
11522 and for_stmt. Add firstprivate clause to
11523 inner_for_stmt. */
11524 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
11525 OMP_CLAUSE_FIRSTPRIVATE);
11526 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
11527 OMP_CLAUSE_CHAIN (c) = *pc;
11528 *pc = c;
11529 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
11530 }
11531 tree c = build_omp_clause (UNKNOWN_LOCATION,
11532 OMP_CLAUSE_FIRSTPRIVATE);
11533 OMP_CLAUSE_DECL (c) = last;
11534 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
11535 OMP_PARALLEL_CLAUSES (*data[1]) = c;
11536 c = build_omp_clause (UNKNOWN_LOCATION,
11537 *pc ? OMP_CLAUSE_SHARED
11538 : OMP_CLAUSE_FIRSTPRIVATE);
11539 OMP_CLAUSE_DECL (c) = orig_decl;
11540 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
11541 OMP_PARALLEL_CLAUSES (*data[1]) = c;
11542 }
11543 /* Similarly, take care of C++ range for temporaries, those should
11544 be firstprivate on OMP_PARALLEL if any. */
11545 if (data[1])
11546 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
11547 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
11548 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11549 i)) == TREE_LIST
11550 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11551 i)))
11552 {
11553 tree orig
11554 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
11555 tree v = TREE_CHAIN (orig);
11556 tree c = build_omp_clause (UNKNOWN_LOCATION,
11557 OMP_CLAUSE_FIRSTPRIVATE);
11558 /* First add firstprivate clause for the __for_end artificial
11559 decl. */
11560 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
11561 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
11562 == REFERENCE_TYPE)
11563 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
11564 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
11565 OMP_PARALLEL_CLAUSES (*data[1]) = c;
11566 if (TREE_VEC_ELT (v, 0))
11567 {
11568 /* And now the same for __for_range artificial decl if it
11569 exists. */
11570 c = build_omp_clause (UNKNOWN_LOCATION,
11571 OMP_CLAUSE_FIRSTPRIVATE);
11572 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
11573 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
11574 == REFERENCE_TYPE)
11575 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
11576 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
11577 OMP_PARALLEL_CLAUSES (*data[1]) = c;
11578 }
11579 }
11580 }
11581
11582 switch (TREE_CODE (for_stmt))
11583 {
11584 case OMP_FOR:
11585 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
11586 {
11587 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
11588 OMP_CLAUSE_SCHEDULE))
11589 error_at (EXPR_LOCATION (for_stmt),
11590 "%qs clause may not appear on non-rectangular %qs",
11591 "schedule", "for");
11592 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
11593 error_at (EXPR_LOCATION (for_stmt),
11594 "%qs clause may not appear on non-rectangular %qs",
11595 "ordered", "for");
11596 }
11597 break;
11598 case OMP_DISTRIBUTE:
11599 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
11600 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
11601 OMP_CLAUSE_DIST_SCHEDULE))
11602 error_at (EXPR_LOCATION (for_stmt),
11603 "%qs clause may not appear on non-rectangular %qs",
11604 "dist_schedule", "distribute");
11605 break;
11606 case OACC_LOOP:
11607 ort = ORT_ACC;
11608 break;
11609 case OMP_TASKLOOP:
11610 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
11611 ort = ORT_UNTIED_TASKLOOP;
11612 else
11613 ort = ORT_TASKLOOP;
11614 break;
11615 case OMP_SIMD:
11616 ort = ORT_SIMD;
11617 break;
11618 default:
11619 gcc_unreachable ();
11620 }
11621
11622 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
11623 clause for the IV. */
11624 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
11625 {
11626 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
11627 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
11628 decl = TREE_OPERAND (t, 0);
11629 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
11630 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11631 && OMP_CLAUSE_DECL (c) == decl)
11632 {
11633 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
11634 break;
11635 }
11636 }
11637
11638 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
11639 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
11640 loop_p && TREE_CODE (for_stmt) != OMP_SIMD
11641 ? OMP_LOOP : TREE_CODE (for_stmt));
11642
11643 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
11644 gimplify_omp_ctxp->distribute = true;
11645
11646 /* Handle OMP_FOR_INIT. */
11647 for_pre_body = NULL;
11648 if ((ort == ORT_SIMD
11649 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
11650 && OMP_FOR_PRE_BODY (for_stmt))
11651 {
11652 has_decl_expr = BITMAP_ALLOC (NULL);
11653 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
11654 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
11655 == VAR_DECL)
11656 {
11657 t = OMP_FOR_PRE_BODY (for_stmt);
11658 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
11659 }
11660 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
11661 {
11662 tree_stmt_iterator si;
11663 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
11664 tsi_next (&si))
11665 {
11666 t = tsi_stmt (si);
11667 if (TREE_CODE (t) == DECL_EXPR
11668 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
11669 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
11670 }
11671 }
11672 }
11673 if (OMP_FOR_PRE_BODY (for_stmt))
11674 {
11675 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
11676 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
11677 else
11678 {
11679 struct gimplify_omp_ctx ctx;
11680 memset (&ctx, 0, sizeof (ctx));
11681 ctx.region_type = ORT_NONE;
11682 gimplify_omp_ctxp = &ctx;
11683 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
11684 gimplify_omp_ctxp = NULL;
11685 }
11686 }
11687 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
11688
11689 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
11690 for_stmt = inner_for_stmt;
11691
11692 /* For taskloop, need to gimplify the start, end and step before the
11693 taskloop, outside of the taskloop omp context. */
11694 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11695 {
11696 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11697 {
11698 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11699 gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
11700 ? pre_p : &for_pre_body);
11701 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
11702 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
11703 {
11704 tree v = TREE_OPERAND (t, 1);
11705 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
11706 for_pre_p, orig_for_stmt);
11707 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
11708 for_pre_p, orig_for_stmt);
11709 }
11710 else
11711 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
11712 orig_for_stmt);
11713
11714 /* Handle OMP_FOR_COND. */
11715 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
11716 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
11717 {
11718 tree v = TREE_OPERAND (t, 1);
11719 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
11720 for_pre_p, orig_for_stmt);
11721 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
11722 for_pre_p, orig_for_stmt);
11723 }
11724 else
11725 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
11726 orig_for_stmt);
11727
11728 /* Handle OMP_FOR_INCR. */
11729 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11730 if (TREE_CODE (t) == MODIFY_EXPR)
11731 {
11732 decl = TREE_OPERAND (t, 0);
11733 t = TREE_OPERAND (t, 1);
11734 tree *tp = &TREE_OPERAND (t, 1);
11735 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
11736 tp = &TREE_OPERAND (t, 0);
11737
11738 gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
11739 orig_for_stmt);
11740 }
11741 }
11742
11743 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
11744 OMP_TASKLOOP);
11745 }
11746
11747 if (orig_for_stmt != for_stmt)
11748 gimplify_omp_ctxp->combined_loop = true;
11749
11750 for_body = NULL;
11751 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
11752 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
11753 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
11754 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
11755
11756 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
11757 bool is_doacross = false;
11758 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
11759 {
11760 is_doacross = true;
11761 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
11762 (OMP_FOR_INIT (for_stmt))
11763 * 2);
11764 }
11765 int collapse = 1, tile = 0;
11766 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
11767 if (c)
11768 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
11769 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
11770 if (c)
11771 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
11772 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
11773 hash_set<tree> *allocate_uids = NULL;
11774 if (c)
11775 {
11776 allocate_uids = new hash_set<tree>;
11777 for (; c; c = OMP_CLAUSE_CHAIN (c))
11778 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
11779 allocate_uids->add (OMP_CLAUSE_DECL (c));
11780 }
11781 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11782 {
11783 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11784 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
11785 decl = TREE_OPERAND (t, 0);
11786 gcc_assert (DECL_P (decl));
11787 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
11788 || POINTER_TYPE_P (TREE_TYPE (decl)));
11789 if (is_doacross)
11790 {
11791 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
11792 {
11793 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
11794 if (TREE_CODE (orig_decl) == TREE_LIST)
11795 {
11796 orig_decl = TREE_PURPOSE (orig_decl);
11797 if (!orig_decl)
11798 orig_decl = decl;
11799 }
11800 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
11801 }
11802 else
11803 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
11804 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
11805 }
11806
11807 /* Make sure the iteration variable is private. */
11808 tree c = NULL_TREE;
11809 tree c2 = NULL_TREE;
11810 if (orig_for_stmt != for_stmt)
11811 {
11812 /* Preserve this information until we gimplify the inner simd. */
11813 if (has_decl_expr
11814 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
11815 TREE_PRIVATE (t) = 1;
11816 }
11817 else if (ort == ORT_SIMD)
11818 {
11819 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
11820 (splay_tree_key) decl);
11821 omp_is_private (gimplify_omp_ctxp, decl,
11822 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
11823 != 1));
11824 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
11825 {
11826 omp_notice_variable (gimplify_omp_ctxp, decl, true);
11827 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
11828 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
11829 OMP_CLAUSE_LASTPRIVATE);
11830 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
11831 OMP_CLAUSE_LASTPRIVATE))
11832 if (OMP_CLAUSE_DECL (c3) == decl)
11833 {
11834 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
11835 "conditional %<lastprivate%> on loop "
11836 "iterator %qD ignored", decl);
11837 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
11838 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
11839 }
11840 }
11841 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
11842 {
11843 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
11844 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
11845 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
11846 if ((has_decl_expr
11847 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
11848 || TREE_PRIVATE (t))
11849 {
11850 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
11851 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
11852 }
11853 struct gimplify_omp_ctx *outer
11854 = gimplify_omp_ctxp->outer_context;
11855 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
11856 {
11857 if (outer->region_type == ORT_WORKSHARE
11858 && outer->combined_loop)
11859 {
11860 n = splay_tree_lookup (outer->variables,
11861 (splay_tree_key)decl);
11862 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
11863 {
11864 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
11865 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
11866 }
11867 else
11868 {
11869 struct gimplify_omp_ctx *octx = outer->outer_context;
11870 if (octx
11871 && octx->region_type == ORT_COMBINED_PARALLEL
11872 && octx->outer_context
11873 && (octx->outer_context->region_type
11874 == ORT_WORKSHARE)
11875 && octx->outer_context->combined_loop)
11876 {
11877 octx = octx->outer_context;
11878 n = splay_tree_lookup (octx->variables,
11879 (splay_tree_key)decl);
11880 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
11881 {
11882 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
11883 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
11884 }
11885 }
11886 }
11887 }
11888 }
11889
11890 OMP_CLAUSE_DECL (c) = decl;
11891 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
11892 OMP_FOR_CLAUSES (for_stmt) = c;
11893 omp_add_variable (gimplify_omp_ctxp, decl, flags);
11894 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
11895 {
11896 if (outer->region_type == ORT_WORKSHARE
11897 && outer->combined_loop)
11898 {
11899 if (outer->outer_context
11900 && (outer->outer_context->region_type
11901 == ORT_COMBINED_PARALLEL))
11902 outer = outer->outer_context;
11903 else if (omp_check_private (outer, decl, false))
11904 outer = NULL;
11905 }
11906 else if (((outer->region_type & ORT_TASKLOOP)
11907 == ORT_TASKLOOP)
11908 && outer->combined_loop
11909 && !omp_check_private (gimplify_omp_ctxp,
11910 decl, false))
11911 ;
11912 else if (outer->region_type != ORT_COMBINED_PARALLEL)
11913 {
11914 omp_notice_variable (outer, decl, true);
11915 outer = NULL;
11916 }
11917 if (outer)
11918 {
11919 n = splay_tree_lookup (outer->variables,
11920 (splay_tree_key)decl);
11921 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11922 {
11923 omp_add_variable (outer, decl,
11924 GOVD_LASTPRIVATE | GOVD_SEEN);
11925 if (outer->region_type == ORT_COMBINED_PARALLEL
11926 && outer->outer_context
11927 && (outer->outer_context->region_type
11928 == ORT_WORKSHARE)
11929 && outer->outer_context->combined_loop)
11930 {
11931 outer = outer->outer_context;
11932 n = splay_tree_lookup (outer->variables,
11933 (splay_tree_key)decl);
11934 if (omp_check_private (outer, decl, false))
11935 outer = NULL;
11936 else if (n == NULL
11937 || ((n->value & GOVD_DATA_SHARE_CLASS)
11938 == 0))
11939 omp_add_variable (outer, decl,
11940 GOVD_LASTPRIVATE
11941 | GOVD_SEEN);
11942 else
11943 outer = NULL;
11944 }
11945 if (outer && outer->outer_context
11946 && ((outer->outer_context->region_type
11947 & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS
11948 || (((outer->region_type & ORT_TASKLOOP)
11949 == ORT_TASKLOOP)
11950 && (outer->outer_context->region_type
11951 == ORT_COMBINED_PARALLEL))))
11952 {
11953 outer = outer->outer_context;
11954 n = splay_tree_lookup (outer->variables,
11955 (splay_tree_key)decl);
11956 if (n == NULL
11957 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11958 omp_add_variable (outer, decl,
11959 GOVD_SHARED | GOVD_SEEN);
11960 else
11961 outer = NULL;
11962 }
11963 if (outer && outer->outer_context)
11964 omp_notice_variable (outer->outer_context, decl,
11965 true);
11966 }
11967 }
11968 }
11969 }
11970 else
11971 {
11972 bool lastprivate
11973 = (!has_decl_expr
11974 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
11975 if (TREE_PRIVATE (t))
11976 lastprivate = false;
11977 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
11978 {
11979 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
11980 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
11981 lastprivate = false;
11982 }
11983
11984 struct gimplify_omp_ctx *outer
11985 = gimplify_omp_ctxp->outer_context;
11986 if (outer && lastprivate)
11987 {
11988 if (outer->region_type == ORT_WORKSHARE
11989 && outer->combined_loop)
11990 {
11991 n = splay_tree_lookup (outer->variables,
11992 (splay_tree_key)decl);
11993 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
11994 {
11995 lastprivate = false;
11996 outer = NULL;
11997 }
11998 else if (outer->outer_context
11999 && (outer->outer_context->region_type
12000 == ORT_COMBINED_PARALLEL))
12001 outer = outer->outer_context;
12002 else if (omp_check_private (outer, decl, false))
12003 outer = NULL;
12004 }
12005 else if (((outer->region_type & ORT_TASKLOOP)
12006 == ORT_TASKLOOP)
12007 && outer->combined_loop
12008 && !omp_check_private (gimplify_omp_ctxp,
12009 decl, false))
12010 ;
12011 else if (outer->region_type != ORT_COMBINED_PARALLEL)
12012 {
12013 omp_notice_variable (outer, decl, true);
12014 outer = NULL;
12015 }
12016 if (outer)
12017 {
12018 n = splay_tree_lookup (outer->variables,
12019 (splay_tree_key)decl);
12020 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
12021 {
12022 omp_add_variable (outer, decl,
12023 GOVD_LASTPRIVATE | GOVD_SEEN);
12024 if (outer->region_type == ORT_COMBINED_PARALLEL
12025 && outer->outer_context
12026 && (outer->outer_context->region_type
12027 == ORT_WORKSHARE)
12028 && outer->outer_context->combined_loop)
12029 {
12030 outer = outer->outer_context;
12031 n = splay_tree_lookup (outer->variables,
12032 (splay_tree_key)decl);
12033 if (omp_check_private (outer, decl, false))
12034 outer = NULL;
12035 else if (n == NULL
12036 || ((n->value & GOVD_DATA_SHARE_CLASS)
12037 == 0))
12038 omp_add_variable (outer, decl,
12039 GOVD_LASTPRIVATE
12040 | GOVD_SEEN);
12041 else
12042 outer = NULL;
12043 }
12044 if (outer && outer->outer_context
12045 && ((outer->outer_context->region_type
12046 & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS
12047 || (((outer->region_type & ORT_TASKLOOP)
12048 == ORT_TASKLOOP)
12049 && (outer->outer_context->region_type
12050 == ORT_COMBINED_PARALLEL))))
12051 {
12052 outer = outer->outer_context;
12053 n = splay_tree_lookup (outer->variables,
12054 (splay_tree_key)decl);
12055 if (n == NULL
12056 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
12057 omp_add_variable (outer, decl,
12058 GOVD_SHARED | GOVD_SEEN);
12059 else
12060 outer = NULL;
12061 }
12062 if (outer && outer->outer_context)
12063 omp_notice_variable (outer->outer_context, decl,
12064 true);
12065 }
12066 }
12067 }
12068
12069 c = build_omp_clause (input_location,
12070 lastprivate ? OMP_CLAUSE_LASTPRIVATE
12071 : OMP_CLAUSE_PRIVATE);
12072 OMP_CLAUSE_DECL (c) = decl;
12073 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12074 OMP_FOR_CLAUSES (for_stmt) = c;
12075 omp_add_variable (gimplify_omp_ctxp, decl,
12076 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
12077 | GOVD_EXPLICIT | GOVD_SEEN);
12078 c = NULL_TREE;
12079 }
12080 }
12081 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
12082 {
12083 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12084 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12085 (splay_tree_key) decl);
12086 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
12087 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12088 OMP_CLAUSE_LASTPRIVATE);
12089 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12090 OMP_CLAUSE_LASTPRIVATE))
12091 if (OMP_CLAUSE_DECL (c3) == decl)
12092 {
12093 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12094 "conditional %<lastprivate%> on loop "
12095 "iterator %qD ignored", decl);
12096 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12097 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12098 }
12099 }
12100 else
12101 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
12102
12103 /* If DECL is not a gimple register, create a temporary variable to act
12104 as an iteration counter. This is valid, since DECL cannot be
12105 modified in the body of the loop. Similarly for any iteration vars
12106 in simd with collapse > 1 where the iterator vars must be
12107 lastprivate. And similarly for vars mentioned in allocate clauses. */
12108 if (orig_for_stmt != for_stmt)
12109 var = decl;
12110 else if (!is_gimple_reg (decl)
12111 || (ort == ORT_SIMD
12112 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
12113 || (allocate_uids && allocate_uids->contains (decl)))
12114 {
12115 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12116 /* Make sure omp_add_variable is not called on it prematurely.
12117 We call it ourselves a few lines later. */
12118 gimplify_omp_ctxp = NULL;
12119 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
12120 gimplify_omp_ctxp = ctx;
12121 TREE_OPERAND (t, 0) = var;
12122
12123 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
12124
12125 if (ort == ORT_SIMD
12126 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12127 {
12128 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12129 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
12130 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
12131 OMP_CLAUSE_DECL (c2) = var;
12132 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
12133 OMP_FOR_CLAUSES (for_stmt) = c2;
12134 omp_add_variable (gimplify_omp_ctxp, var,
12135 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
12136 if (c == NULL_TREE)
12137 {
12138 c = c2;
12139 c2 = NULL_TREE;
12140 }
12141 }
12142 else
12143 omp_add_variable (gimplify_omp_ctxp, var,
12144 GOVD_PRIVATE | GOVD_SEEN);
12145 }
12146 else
12147 var = decl;
12148
12149 gimplify_omp_ctxp->in_for_exprs = true;
12150 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12151 {
12152 tree lb = TREE_OPERAND (t, 1);
12153 tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
12154 is_gimple_val, fb_rvalue, false);
12155 ret = MIN (ret, tret);
12156 tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
12157 is_gimple_val, fb_rvalue, false);
12158 }
12159 else
12160 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12161 is_gimple_val, fb_rvalue, false);
12162 gimplify_omp_ctxp->in_for_exprs = false;
12163 ret = MIN (ret, tret);
12164 if (ret == GS_ERROR)
12165 return ret;
12166
12167 /* Handle OMP_FOR_COND. */
12168 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12169 gcc_assert (COMPARISON_CLASS_P (t));
12170 gcc_assert (TREE_OPERAND (t, 0) == decl);
12171
12172 gimplify_omp_ctxp->in_for_exprs = true;
12173 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12174 {
12175 tree ub = TREE_OPERAND (t, 1);
12176 tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
12177 is_gimple_val, fb_rvalue, false);
12178 ret = MIN (ret, tret);
12179 tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
12180 is_gimple_val, fb_rvalue, false);
12181 }
12182 else
12183 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12184 is_gimple_val, fb_rvalue, false);
12185 gimplify_omp_ctxp->in_for_exprs = false;
12186 ret = MIN (ret, tret);
12187
12188 /* Handle OMP_FOR_INCR. */
12189 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12190 switch (TREE_CODE (t))
12191 {
12192 case PREINCREMENT_EXPR:
12193 case POSTINCREMENT_EXPR:
12194 {
12195 tree decl = TREE_OPERAND (t, 0);
12196 /* c_omp_for_incr_canonicalize_ptr() should have been
12197 called to massage things appropriately. */
12198 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
12199
12200 if (orig_for_stmt != for_stmt)
12201 break;
12202 t = build_int_cst (TREE_TYPE (decl), 1);
12203 if (c)
12204 OMP_CLAUSE_LINEAR_STEP (c) = t;
12205 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
12206 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
12207 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
12208 break;
12209 }
12210
12211 case PREDECREMENT_EXPR:
12212 case POSTDECREMENT_EXPR:
12213 /* c_omp_for_incr_canonicalize_ptr() should have been
12214 called to massage things appropriately. */
12215 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
12216 if (orig_for_stmt != for_stmt)
12217 break;
12218 t = build_int_cst (TREE_TYPE (decl), -1);
12219 if (c)
12220 OMP_CLAUSE_LINEAR_STEP (c) = t;
12221 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
12222 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
12223 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
12224 break;
12225
12226 case MODIFY_EXPR:
12227 gcc_assert (TREE_OPERAND (t, 0) == decl);
12228 TREE_OPERAND (t, 0) = var;
12229
12230 t = TREE_OPERAND (t, 1);
12231 switch (TREE_CODE (t))
12232 {
12233 case PLUS_EXPR:
12234 if (TREE_OPERAND (t, 1) == decl)
12235 {
12236 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
12237 TREE_OPERAND (t, 0) = var;
12238 break;
12239 }
12240
12241 /* Fallthru. */
12242 case MINUS_EXPR:
12243 case POINTER_PLUS_EXPR:
12244 gcc_assert (TREE_OPERAND (t, 0) == decl);
12245 TREE_OPERAND (t, 0) = var;
12246 break;
12247 default:
12248 gcc_unreachable ();
12249 }
12250
12251 gimplify_omp_ctxp->in_for_exprs = true;
12252 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12253 is_gimple_val, fb_rvalue, false);
12254 ret = MIN (ret, tret);
12255 if (c)
12256 {
12257 tree step = TREE_OPERAND (t, 1);
12258 tree stept = TREE_TYPE (decl);
12259 if (POINTER_TYPE_P (stept))
12260 stept = sizetype;
12261 step = fold_convert (stept, step);
12262 if (TREE_CODE (t) == MINUS_EXPR)
12263 step = fold_build1 (NEGATE_EXPR, stept, step);
12264 OMP_CLAUSE_LINEAR_STEP (c) = step;
12265 if (step != TREE_OPERAND (t, 1))
12266 {
12267 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
12268 &for_pre_body, NULL,
12269 is_gimple_val, fb_rvalue, false);
12270 ret = MIN (ret, tret);
12271 }
12272 }
12273 gimplify_omp_ctxp->in_for_exprs = false;
12274 break;
12275
12276 default:
12277 gcc_unreachable ();
12278 }
12279
12280 if (c2)
12281 {
12282 gcc_assert (c);
12283 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
12284 }
12285
12286 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
12287 {
12288 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
12289 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12290 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
12291 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12292 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
12293 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
12294 && OMP_CLAUSE_DECL (c) == decl)
12295 {
12296 if (is_doacross && (collapse == 1 || i >= collapse))
12297 t = var;
12298 else
12299 {
12300 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12301 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12302 gcc_assert (TREE_OPERAND (t, 0) == var);
12303 t = TREE_OPERAND (t, 1);
12304 gcc_assert (TREE_CODE (t) == PLUS_EXPR
12305 || TREE_CODE (t) == MINUS_EXPR
12306 || TREE_CODE (t) == POINTER_PLUS_EXPR);
12307 gcc_assert (TREE_OPERAND (t, 0) == var);
12308 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
12309 is_doacross ? var : decl,
12310 TREE_OPERAND (t, 1));
12311 }
12312 gimple_seq *seq;
12313 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
12314 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
12315 else
12316 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
12317 push_gimplify_context ();
12318 gimplify_assign (decl, t, seq);
12319 gimple *bind = NULL;
12320 if (gimplify_ctxp->temps)
12321 {
12322 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
12323 *seq = NULL;
12324 gimplify_seq_add_stmt (seq, bind);
12325 }
12326 pop_gimplify_context (bind);
12327 }
12328 }
12329 if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
12330 for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
12331 {
12332 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
12333 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12334 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12335 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12336 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12337 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
12338 gcc_assert (COMPARISON_CLASS_P (t));
12339 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12340 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12341 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12342 }
12343 }
12344
12345 BITMAP_FREE (has_decl_expr);
12346 delete allocate_uids;
12347
12348 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
12349 || (loop_p && orig_for_stmt == for_stmt))
12350 {
12351 push_gimplify_context ();
12352 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
12353 {
12354 OMP_FOR_BODY (orig_for_stmt)
12355 = build3 (BIND_EXPR, void_type_node, NULL,
12356 OMP_FOR_BODY (orig_for_stmt), NULL);
12357 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
12358 }
12359 }
12360
12361 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
12362 &for_body);
12363
12364 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
12365 || (loop_p && orig_for_stmt == for_stmt))
12366 {
12367 if (gimple_code (g) == GIMPLE_BIND)
12368 pop_gimplify_context (g);
12369 else
12370 pop_gimplify_context (NULL);
12371 }
12372
12373 if (orig_for_stmt != for_stmt)
12374 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12375 {
12376 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12377 decl = TREE_OPERAND (t, 0);
12378 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12379 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12380 gimplify_omp_ctxp = ctx->outer_context;
12381 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
12382 gimplify_omp_ctxp = ctx;
12383 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
12384 TREE_OPERAND (t, 0) = var;
12385 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12386 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12387 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
12388 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
12389 for (int j = i + 1;
12390 j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
12391 {
12392 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
12393 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12394 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12395 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12396 {
12397 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12398 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12399 }
12400 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
12401 gcc_assert (COMPARISON_CLASS_P (t));
12402 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12403 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12404 {
12405 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12406 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12407 }
12408 }
12409 }
12410
12411 gimplify_adjust_omp_clauses (pre_p, for_body,
12412 &OMP_FOR_CLAUSES (orig_for_stmt),
12413 TREE_CODE (orig_for_stmt));
12414
12415 int kind;
12416 switch (TREE_CODE (orig_for_stmt))
12417 {
12418 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
12419 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
12420 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
12421 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
12422 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
12423 default:
12424 gcc_unreachable ();
12425 }
12426 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
12427 {
12428 gimplify_seq_add_seq (pre_p, for_pre_body);
12429 for_pre_body = NULL;
12430 }
12431 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
12432 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
12433 for_pre_body);
12434 if (orig_for_stmt != for_stmt)
12435 gimple_omp_for_set_combined_p (gfor, true);
12436 if (gimplify_omp_ctxp
12437 && (gimplify_omp_ctxp->combined_loop
12438 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
12439 && gimplify_omp_ctxp->outer_context
12440 && gimplify_omp_ctxp->outer_context->combined_loop)))
12441 {
12442 gimple_omp_for_set_combined_into_p (gfor, true);
12443 if (gimplify_omp_ctxp->combined_loop)
12444 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
12445 else
12446 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
12447 }
12448
12449 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12450 {
12451 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12452 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
12453 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
12454 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12455 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
12456 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
12457 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12458 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
12459 }
12460
12461 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
12462 constructs with GIMPLE_OMP_TASK sandwiched in between them.
12463 The outer taskloop stands for computing the number of iterations,
12464 counts for collapsed loops and holding taskloop specific clauses.
12465 The task construct stands for the effect of data sharing on the
12466 explicit task it creates and the inner taskloop stands for expansion
12467 of the static loop inside of the explicit task construct. */
12468 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12469 {
12470 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
12471 tree task_clauses = NULL_TREE;
12472 tree c = *gfor_clauses_ptr;
12473 tree *gtask_clauses_ptr = &task_clauses;
12474 tree outer_for_clauses = NULL_TREE;
12475 tree *gforo_clauses_ptr = &outer_for_clauses;
12476 bitmap lastprivate_uids = NULL;
12477 if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
12478 {
12479 c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
12480 if (c)
12481 {
12482 lastprivate_uids = BITMAP_ALLOC (NULL);
12483 for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
12484 OMP_CLAUSE_LASTPRIVATE))
12485 bitmap_set_bit (lastprivate_uids,
12486 DECL_UID (OMP_CLAUSE_DECL (c)));
12487 }
12488 c = *gfor_clauses_ptr;
12489 }
12490 for (; c; c = OMP_CLAUSE_CHAIN (c))
12491 switch (OMP_CLAUSE_CODE (c))
12492 {
12493 /* These clauses are allowed on task, move them there. */
12494 case OMP_CLAUSE_SHARED:
12495 case OMP_CLAUSE_FIRSTPRIVATE:
12496 case OMP_CLAUSE_DEFAULT:
12497 case OMP_CLAUSE_IF:
12498 case OMP_CLAUSE_UNTIED:
12499 case OMP_CLAUSE_FINAL:
12500 case OMP_CLAUSE_MERGEABLE:
12501 case OMP_CLAUSE_PRIORITY:
12502 case OMP_CLAUSE_REDUCTION:
12503 case OMP_CLAUSE_IN_REDUCTION:
12504 *gtask_clauses_ptr = c;
12505 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12506 break;
12507 case OMP_CLAUSE_PRIVATE:
12508 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
12509 {
12510 /* We want private on outer for and firstprivate
12511 on task. */
12512 *gtask_clauses_ptr
12513 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12514 OMP_CLAUSE_FIRSTPRIVATE);
12515 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12516 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
12517 openacc);
12518 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12519 *gforo_clauses_ptr = c;
12520 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12521 }
12522 else
12523 {
12524 *gtask_clauses_ptr = c;
12525 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12526 }
12527 break;
12528 /* These clauses go into outer taskloop clauses. */
12529 case OMP_CLAUSE_GRAINSIZE:
12530 case OMP_CLAUSE_NUM_TASKS:
12531 case OMP_CLAUSE_NOGROUP:
12532 *gforo_clauses_ptr = c;
12533 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12534 break;
12535 /* Collapse clause we duplicate on both taskloops. */
12536 case OMP_CLAUSE_COLLAPSE:
12537 *gfor_clauses_ptr = c;
12538 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12539 *gforo_clauses_ptr = copy_node (c);
12540 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
12541 break;
12542 /* For lastprivate, keep the clause on inner taskloop, and add
12543 a shared clause on task. If the same decl is also firstprivate,
12544 add also firstprivate clause on the inner taskloop. */
12545 case OMP_CLAUSE_LASTPRIVATE:
12546 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
12547 {
12548 /* For taskloop C++ lastprivate IVs, we want:
12549 1) private on outer taskloop
12550 2) firstprivate and shared on task
12551 3) lastprivate on inner taskloop */
12552 *gtask_clauses_ptr
12553 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12554 OMP_CLAUSE_FIRSTPRIVATE);
12555 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12556 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
12557 openacc);
12558 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12559 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
12560 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12561 OMP_CLAUSE_PRIVATE);
12562 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
12563 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
12564 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
12565 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
12566 }
12567 *gfor_clauses_ptr = c;
12568 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12569 *gtask_clauses_ptr
12570 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
12571 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12572 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
12573 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
12574 gtask_clauses_ptr
12575 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12576 break;
12577 /* Allocate clause we duplicate on task and inner taskloop
12578 if the decl is lastprivate, otherwise just put on task. */
12579 case OMP_CLAUSE_ALLOCATE:
12580 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
12581 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
12582 {
12583 /* Additionally, put firstprivate clause on task
12584 for the allocator if it is not constant. */
12585 *gtask_clauses_ptr
12586 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12587 OMP_CLAUSE_FIRSTPRIVATE);
12588 OMP_CLAUSE_DECL (*gtask_clauses_ptr)
12589 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
12590 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12591 }
12592 if (lastprivate_uids
12593 && bitmap_bit_p (lastprivate_uids,
12594 DECL_UID (OMP_CLAUSE_DECL (c))))
12595 {
12596 *gfor_clauses_ptr = c;
12597 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12598 *gtask_clauses_ptr = copy_node (c);
12599 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12600 }
12601 else
12602 {
12603 *gtask_clauses_ptr = c;
12604 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12605 }
12606 break;
12607 default:
12608 gcc_unreachable ();
12609 }
12610 *gfor_clauses_ptr = NULL_TREE;
12611 *gtask_clauses_ptr = NULL_TREE;
12612 *gforo_clauses_ptr = NULL_TREE;
12613 BITMAP_FREE (lastprivate_uids);
12614 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
12615 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
12616 NULL_TREE, NULL_TREE, NULL_TREE);
12617 gimple_omp_task_set_taskloop_p (g, true);
12618 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
12619 gomp_for *gforo
12620 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
12621 gimple_omp_for_collapse (gfor),
12622 gimple_omp_for_pre_body (gfor));
12623 gimple_omp_for_set_pre_body (gfor, NULL);
12624 gimple_omp_for_set_combined_p (gforo, true);
12625 gimple_omp_for_set_combined_into_p (gfor, true);
12626 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
12627 {
12628 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
12629 tree v = create_tmp_var (type);
12630 gimple_omp_for_set_index (gforo, i, v);
12631 t = unshare_expr (gimple_omp_for_initial (gfor, i));
12632 gimple_omp_for_set_initial (gforo, i, t);
12633 gimple_omp_for_set_cond (gforo, i,
12634 gimple_omp_for_cond (gfor, i));
12635 t = unshare_expr (gimple_omp_for_final (gfor, i));
12636 gimple_omp_for_set_final (gforo, i, t);
12637 t = unshare_expr (gimple_omp_for_incr (gfor, i));
12638 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
12639 TREE_OPERAND (t, 0) = v;
12640 gimple_omp_for_set_incr (gforo, i, t);
12641 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
12642 OMP_CLAUSE_DECL (t) = v;
12643 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
12644 gimple_omp_for_set_clauses (gforo, t);
12645 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
12646 {
12647 tree *p1 = NULL, *p2 = NULL;
12648 t = gimple_omp_for_initial (gforo, i);
12649 if (TREE_CODE (t) == TREE_VEC)
12650 p1 = &TREE_VEC_ELT (t, 0);
12651 t = gimple_omp_for_final (gforo, i);
12652 if (TREE_CODE (t) == TREE_VEC)
12653 {
12654 if (p1)
12655 p2 = &TREE_VEC_ELT (t, 0);
12656 else
12657 p1 = &TREE_VEC_ELT (t, 0);
12658 }
12659 if (p1)
12660 {
12661 int j;
12662 for (j = 0; j < i; j++)
12663 if (*p1 == gimple_omp_for_index (gfor, j))
12664 {
12665 *p1 = gimple_omp_for_index (gforo, j);
12666 if (p2)
12667 *p2 = *p1;
12668 break;
12669 }
12670 gcc_assert (j < i);
12671 }
12672 }
12673 }
12674 gimplify_seq_add_stmt (pre_p, gforo);
12675 }
12676 else
12677 gimplify_seq_add_stmt (pre_p, gfor);
12678
12679 if (TREE_CODE (orig_for_stmt) == OMP_FOR)
12680 {
12681 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12682 unsigned lastprivate_conditional = 0;
12683 while (ctx
12684 && (ctx->region_type == ORT_TARGET_DATA
12685 || ctx->region_type == ORT_TASKGROUP))
12686 ctx = ctx->outer_context;
12687 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
12688 for (tree c = gimple_omp_for_clauses (gfor);
12689 c; c = OMP_CLAUSE_CHAIN (c))
12690 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12691 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
12692 ++lastprivate_conditional;
12693 if (lastprivate_conditional)
12694 {
12695 struct omp_for_data fd;
12696 omp_extract_for_data (gfor, &fd, NULL);
12697 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
12698 lastprivate_conditional);
12699 tree var = create_tmp_var_raw (type);
12700 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
12701 OMP_CLAUSE_DECL (c) = var;
12702 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
12703 gimple_omp_for_set_clauses (gfor, c);
12704 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
12705 }
12706 }
12707 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
12708 {
12709 unsigned lastprivate_conditional = 0;
12710 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
12711 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12712 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
12713 ++lastprivate_conditional;
12714 if (lastprivate_conditional)
12715 {
12716 struct omp_for_data fd;
12717 omp_extract_for_data (gfor, &fd, NULL);
12718 tree type = unsigned_type_for (fd.iter_type);
12719 while (lastprivate_conditional--)
12720 {
12721 tree c = build_omp_clause (UNKNOWN_LOCATION,
12722 OMP_CLAUSE__CONDTEMP_);
12723 OMP_CLAUSE_DECL (c) = create_tmp_var (type);
12724 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
12725 gimple_omp_for_set_clauses (gfor, c);
12726 }
12727 }
12728 }
12729
12730 if (ret != GS_ALL_DONE)
12731 return GS_ERROR;
12732 *expr_p = NULL_TREE;
12733 return GS_ALL_DONE;
12734 }
12735
12736 /* Helper for gimplify_omp_loop, called through walk_tree. */
12737
12738 static tree
replace_reduction_placeholders(tree * tp,int * walk_subtrees,void * data)12739 replace_reduction_placeholders (tree *tp, int *walk_subtrees, void *data)
12740 {
12741 if (DECL_P (*tp))
12742 {
12743 tree *d = (tree *) data;
12744 if (*tp == OMP_CLAUSE_REDUCTION_PLACEHOLDER (d[0]))
12745 {
12746 *tp = OMP_CLAUSE_REDUCTION_PLACEHOLDER (d[1]);
12747 *walk_subtrees = 0;
12748 }
12749 else if (*tp == OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d[0]))
12750 {
12751 *tp = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d[1]);
12752 *walk_subtrees = 0;
12753 }
12754 }
12755 return NULL_TREE;
12756 }
12757
12758 /* Gimplify the gross structure of an OMP_LOOP statement. */
12759
12760 static enum gimplify_status
gimplify_omp_loop(tree * expr_p,gimple_seq * pre_p)12761 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
12762 {
12763 tree for_stmt = *expr_p;
12764 tree clauses = OMP_FOR_CLAUSES (for_stmt);
12765 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
12766 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
12767 int i;
12768
12769 /* If order is not present, the behavior is as if order(concurrent)
12770 appeared. */
12771 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
12772 if (order == NULL_TREE)
12773 {
12774 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
12775 OMP_CLAUSE_CHAIN (order) = clauses;
12776 OMP_FOR_CLAUSES (for_stmt) = clauses = order;
12777 }
12778
12779 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
12780 if (bind == NULL_TREE)
12781 {
12782 if (!flag_openmp) /* flag_openmp_simd */
12783 ;
12784 else if (octx && (octx->region_type & ORT_TEAMS) != 0)
12785 kind = OMP_CLAUSE_BIND_TEAMS;
12786 else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
12787 kind = OMP_CLAUSE_BIND_PARALLEL;
12788 else
12789 {
12790 for (; octx; octx = octx->outer_context)
12791 {
12792 if ((octx->region_type & ORT_ACC) != 0
12793 || octx->region_type == ORT_NONE
12794 || octx->region_type == ORT_IMPLICIT_TARGET)
12795 continue;
12796 break;
12797 }
12798 if (octx == NULL && !in_omp_construct)
12799 error_at (EXPR_LOCATION (for_stmt),
12800 "%<bind%> clause not specified on a %<loop%> "
12801 "construct not nested inside another OpenMP construct");
12802 }
12803 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
12804 OMP_CLAUSE_CHAIN (bind) = clauses;
12805 OMP_CLAUSE_BIND_KIND (bind) = kind;
12806 OMP_FOR_CLAUSES (for_stmt) = bind;
12807 }
12808 else
12809 switch (OMP_CLAUSE_BIND_KIND (bind))
12810 {
12811 case OMP_CLAUSE_BIND_THREAD:
12812 break;
12813 case OMP_CLAUSE_BIND_PARALLEL:
12814 if (!flag_openmp) /* flag_openmp_simd */
12815 {
12816 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12817 break;
12818 }
12819 for (; octx; octx = octx->outer_context)
12820 if (octx->region_type == ORT_SIMD
12821 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
12822 {
12823 error_at (EXPR_LOCATION (for_stmt),
12824 "%<bind(parallel)%> on a %<loop%> construct nested "
12825 "inside %<simd%> construct");
12826 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12827 break;
12828 }
12829 kind = OMP_CLAUSE_BIND_PARALLEL;
12830 break;
12831 case OMP_CLAUSE_BIND_TEAMS:
12832 if (!flag_openmp) /* flag_openmp_simd */
12833 {
12834 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12835 break;
12836 }
12837 if ((octx
12838 && octx->region_type != ORT_IMPLICIT_TARGET
12839 && octx->region_type != ORT_NONE
12840 && (octx->region_type & ORT_TEAMS) == 0)
12841 || in_omp_construct)
12842 {
12843 error_at (EXPR_LOCATION (for_stmt),
12844 "%<bind(teams)%> on a %<loop%> region not strictly "
12845 "nested inside of a %<teams%> region");
12846 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12847 break;
12848 }
12849 kind = OMP_CLAUSE_BIND_TEAMS;
12850 break;
12851 default:
12852 gcc_unreachable ();
12853 }
12854
12855 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
12856 switch (OMP_CLAUSE_CODE (*pc))
12857 {
12858 case OMP_CLAUSE_REDUCTION:
12859 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
12860 {
12861 error_at (OMP_CLAUSE_LOCATION (*pc),
12862 "%<inscan%> %<reduction%> clause on "
12863 "%qs construct", "loop");
12864 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
12865 }
12866 if (OMP_CLAUSE_REDUCTION_TASK (*pc))
12867 {
12868 error_at (OMP_CLAUSE_LOCATION (*pc),
12869 "invalid %<task%> reduction modifier on construct "
12870 "other than %<parallel%>, %qs or %<sections%>",
12871 lang_GNU_Fortran () ? "do" : "for");
12872 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
12873 }
12874 pc = &OMP_CLAUSE_CHAIN (*pc);
12875 break;
12876 case OMP_CLAUSE_LASTPRIVATE:
12877 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12878 {
12879 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12880 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12881 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
12882 break;
12883 if (OMP_FOR_ORIG_DECLS (for_stmt)
12884 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
12885 i)) == TREE_LIST
12886 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
12887 i)))
12888 {
12889 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12890 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
12891 break;
12892 }
12893 }
12894 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
12895 {
12896 error_at (OMP_CLAUSE_LOCATION (*pc),
12897 "%<lastprivate%> clause on a %<loop%> construct refers "
12898 "to a variable %qD which is not the loop iterator",
12899 OMP_CLAUSE_DECL (*pc));
12900 *pc = OMP_CLAUSE_CHAIN (*pc);
12901 break;
12902 }
12903 pc = &OMP_CLAUSE_CHAIN (*pc);
12904 break;
12905 default:
12906 pc = &OMP_CLAUSE_CHAIN (*pc);
12907 break;
12908 }
12909
12910 TREE_SET_CODE (for_stmt, OMP_SIMD);
12911
12912 int last;
12913 switch (kind)
12914 {
12915 case OMP_CLAUSE_BIND_THREAD: last = 0; break;
12916 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
12917 case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
12918 }
12919 for (int pass = 1; pass <= last; pass++)
12920 {
12921 if (pass == 2)
12922 {
12923 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
12924 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
12925 *expr_p = make_node (OMP_PARALLEL);
12926 TREE_TYPE (*expr_p) = void_type_node;
12927 OMP_PARALLEL_BODY (*expr_p) = bind;
12928 OMP_PARALLEL_COMBINED (*expr_p) = 1;
12929 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
12930 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
12931 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12932 if (OMP_FOR_ORIG_DECLS (for_stmt)
12933 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
12934 == TREE_LIST))
12935 {
12936 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12937 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
12938 {
12939 *pc = build_omp_clause (UNKNOWN_LOCATION,
12940 OMP_CLAUSE_FIRSTPRIVATE);
12941 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
12942 pc = &OMP_CLAUSE_CHAIN (*pc);
12943 }
12944 }
12945 }
12946 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
12947 tree *pc = &OMP_FOR_CLAUSES (t);
12948 TREE_TYPE (t) = void_type_node;
12949 OMP_FOR_BODY (t) = *expr_p;
12950 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
12951 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
12952 switch (OMP_CLAUSE_CODE (c))
12953 {
12954 case OMP_CLAUSE_BIND:
12955 case OMP_CLAUSE_ORDER:
12956 case OMP_CLAUSE_COLLAPSE:
12957 *pc = copy_node (c);
12958 pc = &OMP_CLAUSE_CHAIN (*pc);
12959 break;
12960 case OMP_CLAUSE_PRIVATE:
12961 case OMP_CLAUSE_FIRSTPRIVATE:
12962 /* Only needed on innermost. */
12963 break;
12964 case OMP_CLAUSE_LASTPRIVATE:
12965 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
12966 {
12967 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12968 OMP_CLAUSE_FIRSTPRIVATE);
12969 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
12970 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
12971 pc = &OMP_CLAUSE_CHAIN (*pc);
12972 }
12973 *pc = copy_node (c);
12974 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
12975 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
12976 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
12977 {
12978 if (pass != last)
12979 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
12980 else
12981 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
12982 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
12983 }
12984 pc = &OMP_CLAUSE_CHAIN (*pc);
12985 break;
12986 case OMP_CLAUSE_REDUCTION:
12987 *pc = copy_node (c);
12988 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
12989 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
12990 OMP_CLAUSE_REDUCTION_INIT (*pc)
12991 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
12992 OMP_CLAUSE_REDUCTION_MERGE (*pc)
12993 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
12994 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
12995 {
12996 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
12997 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
12998 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
12999 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
13000 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
13001 tree nc = *pc;
13002 tree data[2] = { c, nc };
13003 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (nc),
13004 replace_reduction_placeholders,
13005 data);
13006 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (nc),
13007 replace_reduction_placeholders,
13008 data);
13009 }
13010 pc = &OMP_CLAUSE_CHAIN (*pc);
13011 break;
13012 default:
13013 gcc_unreachable ();
13014 }
13015 *pc = NULL_TREE;
13016 *expr_p = t;
13017 }
13018 return gimplify_omp_for (expr_p, pre_p);
13019 }
13020
13021
13022 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
13023 of OMP_TARGET's body. */
13024
13025 static tree
find_omp_teams(tree * tp,int * walk_subtrees,void *)13026 find_omp_teams (tree *tp, int *walk_subtrees, void *)
13027 {
13028 *walk_subtrees = 0;
13029 switch (TREE_CODE (*tp))
13030 {
13031 case OMP_TEAMS:
13032 return *tp;
13033 case BIND_EXPR:
13034 case STATEMENT_LIST:
13035 *walk_subtrees = 1;
13036 break;
13037 default:
13038 break;
13039 }
13040 return NULL_TREE;
13041 }
13042
13043 /* Helper function of optimize_target_teams, determine if the expression
13044 can be computed safely before the target construct on the host. */
13045
13046 static tree
computable_teams_clause(tree * tp,int * walk_subtrees,void *)13047 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
13048 {
13049 splay_tree_node n;
13050
13051 if (TYPE_P (*tp))
13052 {
13053 *walk_subtrees = 0;
13054 return NULL_TREE;
13055 }
13056 switch (TREE_CODE (*tp))
13057 {
13058 case VAR_DECL:
13059 case PARM_DECL:
13060 case RESULT_DECL:
13061 *walk_subtrees = 0;
13062 if (error_operand_p (*tp)
13063 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
13064 || DECL_HAS_VALUE_EXPR_P (*tp)
13065 || DECL_THREAD_LOCAL_P (*tp)
13066 || TREE_SIDE_EFFECTS (*tp)
13067 || TREE_THIS_VOLATILE (*tp))
13068 return *tp;
13069 if (is_global_var (*tp)
13070 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
13071 || lookup_attribute ("omp declare target link",
13072 DECL_ATTRIBUTES (*tp))))
13073 return *tp;
13074 if (VAR_P (*tp)
13075 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
13076 && !is_global_var (*tp)
13077 && decl_function_context (*tp) == current_function_decl)
13078 return *tp;
13079 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
13080 (splay_tree_key) *tp);
13081 if (n == NULL)
13082 {
13083 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
13084 return NULL_TREE;
13085 return *tp;
13086 }
13087 else if (n->value & GOVD_LOCAL)
13088 return *tp;
13089 else if (n->value & GOVD_FIRSTPRIVATE)
13090 return NULL_TREE;
13091 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13092 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13093 return NULL_TREE;
13094 return *tp;
13095 case INTEGER_CST:
13096 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13097 return *tp;
13098 return NULL_TREE;
13099 case TARGET_EXPR:
13100 if (TARGET_EXPR_INITIAL (*tp)
13101 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
13102 return *tp;
13103 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
13104 walk_subtrees, NULL);
13105 /* Allow some reasonable subset of integral arithmetics. */
13106 case PLUS_EXPR:
13107 case MINUS_EXPR:
13108 case MULT_EXPR:
13109 case TRUNC_DIV_EXPR:
13110 case CEIL_DIV_EXPR:
13111 case FLOOR_DIV_EXPR:
13112 case ROUND_DIV_EXPR:
13113 case TRUNC_MOD_EXPR:
13114 case CEIL_MOD_EXPR:
13115 case FLOOR_MOD_EXPR:
13116 case ROUND_MOD_EXPR:
13117 case RDIV_EXPR:
13118 case EXACT_DIV_EXPR:
13119 case MIN_EXPR:
13120 case MAX_EXPR:
13121 case LSHIFT_EXPR:
13122 case RSHIFT_EXPR:
13123 case BIT_IOR_EXPR:
13124 case BIT_XOR_EXPR:
13125 case BIT_AND_EXPR:
13126 case NEGATE_EXPR:
13127 case ABS_EXPR:
13128 case BIT_NOT_EXPR:
13129 case NON_LVALUE_EXPR:
13130 CASE_CONVERT:
13131 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13132 return *tp;
13133 return NULL_TREE;
13134 /* And disallow anything else, except for comparisons. */
13135 default:
13136 if (COMPARISON_CLASS_P (*tp))
13137 return NULL_TREE;
13138 return *tp;
13139 }
13140 }
13141
13142 /* Try to determine if the num_teams and/or thread_limit expressions
13143 can have their values determined already before entering the
13144 target construct.
13145 INTEGER_CSTs trivially are,
13146 integral decls that are firstprivate (explicitly or implicitly)
13147 or explicitly map(always, to:) or map(always, tofrom:) on the target
13148 region too, and expressions involving simple arithmetics on those
13149 too, function calls are not ok, dereferencing something neither etc.
13150 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
13151 EXPR based on what we find:
13152 0 stands for clause not specified at all, use implementation default
13153 -1 stands for value that can't be determined easily before entering
13154 the target construct.
13155 If teams construct is not present at all, use 1 for num_teams
13156 and 0 for thread_limit (only one team is involved, and the thread
13157 limit is implementation defined. */
13158
13159 static void
optimize_target_teams(tree target,gimple_seq * pre_p)13160 optimize_target_teams (tree target, gimple_seq *pre_p)
13161 {
13162 tree body = OMP_BODY (target);
13163 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
13164 tree num_teams = integer_zero_node;
13165 tree thread_limit = integer_zero_node;
13166 location_t num_teams_loc = EXPR_LOCATION (target);
13167 location_t thread_limit_loc = EXPR_LOCATION (target);
13168 tree c, *p, expr;
13169 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
13170
13171 if (teams == NULL_TREE)
13172 num_teams = integer_one_node;
13173 else
13174 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
13175 {
13176 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
13177 {
13178 p = &num_teams;
13179 num_teams_loc = OMP_CLAUSE_LOCATION (c);
13180 }
13181 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
13182 {
13183 p = &thread_limit;
13184 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
13185 }
13186 else
13187 continue;
13188 expr = OMP_CLAUSE_OPERAND (c, 0);
13189 if (TREE_CODE (expr) == INTEGER_CST)
13190 {
13191 *p = expr;
13192 continue;
13193 }
13194 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
13195 {
13196 *p = integer_minus_one_node;
13197 continue;
13198 }
13199 *p = expr;
13200 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
13201 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
13202 == GS_ERROR)
13203 {
13204 gimplify_omp_ctxp = target_ctx;
13205 *p = integer_minus_one_node;
13206 continue;
13207 }
13208 gimplify_omp_ctxp = target_ctx;
13209 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
13210 OMP_CLAUSE_OPERAND (c, 0) = *p;
13211 }
13212 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
13213 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
13214 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
13215 OMP_TARGET_CLAUSES (target) = c;
13216 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
13217 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
13218 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
13219 OMP_TARGET_CLAUSES (target) = c;
13220 }
13221
13222 /* Gimplify the gross structure of several OMP constructs. */
13223
13224 static void
gimplify_omp_workshare(tree * expr_p,gimple_seq * pre_p)13225 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
13226 {
13227 tree expr = *expr_p;
13228 gimple *stmt;
13229 gimple_seq body = NULL;
13230 enum omp_region_type ort;
13231
13232 switch (TREE_CODE (expr))
13233 {
13234 case OMP_SECTIONS:
13235 case OMP_SINGLE:
13236 ort = ORT_WORKSHARE;
13237 break;
13238 case OMP_TARGET:
13239 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
13240 break;
13241 case OACC_KERNELS:
13242 ort = ORT_ACC_KERNELS;
13243 break;
13244 case OACC_PARALLEL:
13245 ort = ORT_ACC_PARALLEL;
13246 break;
13247 case OACC_SERIAL:
13248 ort = ORT_ACC_SERIAL;
13249 break;
13250 case OACC_DATA:
13251 ort = ORT_ACC_DATA;
13252 break;
13253 case OMP_TARGET_DATA:
13254 ort = ORT_TARGET_DATA;
13255 break;
13256 case OMP_TEAMS:
13257 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
13258 if (gimplify_omp_ctxp == NULL
13259 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
13260 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
13261 break;
13262 case OACC_HOST_DATA:
13263 ort = ORT_ACC_HOST_DATA;
13264 break;
13265 default:
13266 gcc_unreachable ();
13267 }
13268
13269 bool save_in_omp_construct = in_omp_construct;
13270 if ((ort & ORT_ACC) == 0)
13271 in_omp_construct = false;
13272 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
13273 TREE_CODE (expr));
13274 if (TREE_CODE (expr) == OMP_TARGET)
13275 optimize_target_teams (expr, pre_p);
13276 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
13277 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
13278 {
13279 push_gimplify_context ();
13280 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
13281 if (gimple_code (g) == GIMPLE_BIND)
13282 pop_gimplify_context (g);
13283 else
13284 pop_gimplify_context (NULL);
13285 if ((ort & ORT_TARGET_DATA) != 0)
13286 {
13287 enum built_in_function end_ix;
13288 switch (TREE_CODE (expr))
13289 {
13290 case OACC_DATA:
13291 case OACC_HOST_DATA:
13292 end_ix = BUILT_IN_GOACC_DATA_END;
13293 break;
13294 case OMP_TARGET_DATA:
13295 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
13296 break;
13297 default:
13298 gcc_unreachable ();
13299 }
13300 tree fn = builtin_decl_explicit (end_ix);
13301 g = gimple_build_call (fn, 0);
13302 gimple_seq cleanup = NULL;
13303 gimple_seq_add_stmt (&cleanup, g);
13304 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
13305 body = NULL;
13306 gimple_seq_add_stmt (&body, g);
13307 }
13308 }
13309 else
13310 gimplify_and_add (OMP_BODY (expr), &body);
13311 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
13312 TREE_CODE (expr));
13313 in_omp_construct = save_in_omp_construct;
13314
13315 switch (TREE_CODE (expr))
13316 {
13317 case OACC_DATA:
13318 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
13319 OMP_CLAUSES (expr));
13320 break;
13321 case OACC_HOST_DATA:
13322 if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
13323 {
13324 for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13325 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
13326 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
13327 }
13328
13329 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
13330 OMP_CLAUSES (expr));
13331 break;
13332 case OACC_KERNELS:
13333 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
13334 OMP_CLAUSES (expr));
13335 break;
13336 case OACC_PARALLEL:
13337 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
13338 OMP_CLAUSES (expr));
13339 break;
13340 case OACC_SERIAL:
13341 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
13342 OMP_CLAUSES (expr));
13343 break;
13344 case OMP_SECTIONS:
13345 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
13346 break;
13347 case OMP_SINGLE:
13348 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
13349 break;
13350 case OMP_TARGET:
13351 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
13352 OMP_CLAUSES (expr));
13353 break;
13354 case OMP_TARGET_DATA:
13355 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
13356 to be evaluated before the use_device_{ptr,addr} clauses if they
13357 refer to the same variables. */
13358 {
13359 tree use_device_clauses;
13360 tree *pc, *uc = &use_device_clauses;
13361 for (pc = &OMP_CLAUSES (expr); *pc; )
13362 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
13363 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
13364 {
13365 *uc = *pc;
13366 *pc = OMP_CLAUSE_CHAIN (*pc);
13367 uc = &OMP_CLAUSE_CHAIN (*uc);
13368 }
13369 else
13370 pc = &OMP_CLAUSE_CHAIN (*pc);
13371 *uc = NULL_TREE;
13372 *pc = use_device_clauses;
13373 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
13374 OMP_CLAUSES (expr));
13375 }
13376 break;
13377 case OMP_TEAMS:
13378 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
13379 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
13380 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
13381 break;
13382 default:
13383 gcc_unreachable ();
13384 }
13385
13386 gimplify_seq_add_stmt (pre_p, stmt);
13387 *expr_p = NULL_TREE;
13388 }
13389
13390 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
13391 target update constructs. */
13392
13393 static void
gimplify_omp_target_update(tree * expr_p,gimple_seq * pre_p)13394 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
13395 {
13396 tree expr = *expr_p;
13397 int kind;
13398 gomp_target *stmt;
13399 enum omp_region_type ort = ORT_WORKSHARE;
13400
13401 switch (TREE_CODE (expr))
13402 {
13403 case OACC_ENTER_DATA:
13404 case OACC_EXIT_DATA:
13405 kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
13406 ort = ORT_ACC;
13407 break;
13408 case OACC_UPDATE:
13409 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
13410 ort = ORT_ACC;
13411 break;
13412 case OMP_TARGET_UPDATE:
13413 kind = GF_OMP_TARGET_KIND_UPDATE;
13414 break;
13415 case OMP_TARGET_ENTER_DATA:
13416 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
13417 break;
13418 case OMP_TARGET_EXIT_DATA:
13419 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
13420 break;
13421 default:
13422 gcc_unreachable ();
13423 }
13424 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
13425 ort, TREE_CODE (expr));
13426 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
13427 TREE_CODE (expr));
13428 if (TREE_CODE (expr) == OACC_UPDATE
13429 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
13430 OMP_CLAUSE_IF_PRESENT))
13431 {
13432 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
13433 clause. */
13434 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13435 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
13436 switch (OMP_CLAUSE_MAP_KIND (c))
13437 {
13438 case GOMP_MAP_FORCE_TO:
13439 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
13440 break;
13441 case GOMP_MAP_FORCE_FROM:
13442 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
13443 break;
13444 default:
13445 break;
13446 }
13447 }
13448 else if (TREE_CODE (expr) == OACC_EXIT_DATA
13449 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
13450 OMP_CLAUSE_FINALIZE))
13451 {
13452 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
13453 semantics. */
13454 bool have_clause = false;
13455 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13456 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
13457 switch (OMP_CLAUSE_MAP_KIND (c))
13458 {
13459 case GOMP_MAP_FROM:
13460 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
13461 have_clause = true;
13462 break;
13463 case GOMP_MAP_RELEASE:
13464 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
13465 have_clause = true;
13466 break;
13467 case GOMP_MAP_TO_PSET:
13468 /* Fortran arrays with descriptors must map that descriptor when
13469 doing standalone "attach" operations (in OpenACC). In that
13470 case GOMP_MAP_TO_PSET appears by itself with no preceding
13471 clause (see trans-openmp.c:gfc_trans_omp_clauses). */
13472 break;
13473 case GOMP_MAP_POINTER:
13474 /* TODO PR92929: we may see these here, but they'll always follow
13475 one of the clauses above, and will be handled by libgomp as
13476 one group, so no handling required here. */
13477 gcc_assert (have_clause);
13478 break;
13479 case GOMP_MAP_DETACH:
13480 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
13481 have_clause = false;
13482 break;
13483 case GOMP_MAP_STRUCT:
13484 have_clause = false;
13485 break;
13486 default:
13487 gcc_unreachable ();
13488 }
13489 }
13490 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
13491
13492 gimplify_seq_add_stmt (pre_p, stmt);
13493 *expr_p = NULL_TREE;
13494 }
13495
13496 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
13497 stabilized the lhs of the atomic operation as *ADDR. Return true if
13498 EXPR is this stabilized form. */
13499
13500 static bool
goa_lhs_expr_p(tree expr,tree addr)13501 goa_lhs_expr_p (tree expr, tree addr)
13502 {
13503 /* Also include casts to other type variants. The C front end is fond
13504 of adding these for e.g. volatile variables. This is like
13505 STRIP_TYPE_NOPS but includes the main variant lookup. */
13506 STRIP_USELESS_TYPE_CONVERSION (expr);
13507
13508 if (TREE_CODE (expr) == INDIRECT_REF)
13509 {
13510 expr = TREE_OPERAND (expr, 0);
13511 while (expr != addr
13512 && (CONVERT_EXPR_P (expr)
13513 || TREE_CODE (expr) == NON_LVALUE_EXPR)
13514 && TREE_CODE (expr) == TREE_CODE (addr)
13515 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
13516 {
13517 expr = TREE_OPERAND (expr, 0);
13518 addr = TREE_OPERAND (addr, 0);
13519 }
13520 if (expr == addr)
13521 return true;
13522 return (TREE_CODE (addr) == ADDR_EXPR
13523 && TREE_CODE (expr) == ADDR_EXPR
13524 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
13525 }
13526 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
13527 return true;
13528 return false;
13529 }
13530
13531 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
13532 expression does not involve the lhs, evaluate it into a temporary.
13533 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
13534 or -1 if an error was encountered. */
13535
13536 static int
goa_stabilize_expr(tree * expr_p,gimple_seq * pre_p,tree lhs_addr,tree lhs_var)13537 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
13538 tree lhs_var)
13539 {
13540 tree expr = *expr_p;
13541 int saw_lhs;
13542
13543 if (goa_lhs_expr_p (expr, lhs_addr))
13544 {
13545 *expr_p = lhs_var;
13546 return 1;
13547 }
13548 if (is_gimple_val (expr))
13549 return 0;
13550
13551 saw_lhs = 0;
13552 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
13553 {
13554 case tcc_binary:
13555 case tcc_comparison:
13556 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
13557 lhs_var);
13558 /* FALLTHRU */
13559 case tcc_unary:
13560 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
13561 lhs_var);
13562 break;
13563 case tcc_expression:
13564 switch (TREE_CODE (expr))
13565 {
13566 case TRUTH_ANDIF_EXPR:
13567 case TRUTH_ORIF_EXPR:
13568 case TRUTH_AND_EXPR:
13569 case TRUTH_OR_EXPR:
13570 case TRUTH_XOR_EXPR:
13571 case BIT_INSERT_EXPR:
13572 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
13573 lhs_addr, lhs_var);
13574 /* FALLTHRU */
13575 case TRUTH_NOT_EXPR:
13576 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
13577 lhs_addr, lhs_var);
13578 break;
13579 case COMPOUND_EXPR:
13580 /* Break out any preevaluations from cp_build_modify_expr. */
13581 for (; TREE_CODE (expr) == COMPOUND_EXPR;
13582 expr = TREE_OPERAND (expr, 1))
13583 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
13584 *expr_p = expr;
13585 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var);
13586 default:
13587 break;
13588 }
13589 break;
13590 case tcc_reference:
13591 if (TREE_CODE (expr) == BIT_FIELD_REF)
13592 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
13593 lhs_addr, lhs_var);
13594 break;
13595 default:
13596 break;
13597 }
13598
13599 if (saw_lhs == 0)
13600 {
13601 enum gimplify_status gs;
13602 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
13603 if (gs != GS_ALL_DONE)
13604 saw_lhs = -1;
13605 }
13606
13607 return saw_lhs;
13608 }
13609
13610 /* Gimplify an OMP_ATOMIC statement. */
13611
13612 static enum gimplify_status
gimplify_omp_atomic(tree * expr_p,gimple_seq * pre_p)13613 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
13614 {
13615 tree addr = TREE_OPERAND (*expr_p, 0);
13616 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
13617 ? NULL : TREE_OPERAND (*expr_p, 1);
13618 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
13619 tree tmp_load;
13620 gomp_atomic_load *loadstmt;
13621 gomp_atomic_store *storestmt;
13622
13623 tmp_load = create_tmp_reg (type);
13624 if (rhs && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load) < 0)
13625 return GS_ERROR;
13626
13627 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
13628 != GS_ALL_DONE)
13629 return GS_ERROR;
13630
13631 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
13632 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
13633 gimplify_seq_add_stmt (pre_p, loadstmt);
13634 if (rhs)
13635 {
13636 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
13637 representatives. Use BIT_FIELD_REF on the lhs instead. */
13638 if (TREE_CODE (rhs) == BIT_INSERT_EXPR
13639 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
13640 {
13641 tree bitpos = TREE_OPERAND (rhs, 2);
13642 tree op1 = TREE_OPERAND (rhs, 1);
13643 tree bitsize;
13644 tree tmp_store = tmp_load;
13645 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
13646 tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
13647 if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
13648 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
13649 else
13650 bitsize = TYPE_SIZE (TREE_TYPE (op1));
13651 gcc_assert (TREE_OPERAND (rhs, 0) == tmp_load);
13652 tree t = build2_loc (EXPR_LOCATION (rhs),
13653 MODIFY_EXPR, void_type_node,
13654 build3_loc (EXPR_LOCATION (rhs), BIT_FIELD_REF,
13655 TREE_TYPE (op1), tmp_store, bitsize,
13656 bitpos), op1);
13657 gimplify_and_add (t, pre_p);
13658 rhs = tmp_store;
13659 }
13660 if (gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
13661 != GS_ALL_DONE)
13662 return GS_ERROR;
13663 }
13664
13665 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
13666 rhs = tmp_load;
13667 storestmt
13668 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
13669 gimplify_seq_add_stmt (pre_p, storestmt);
13670 switch (TREE_CODE (*expr_p))
13671 {
13672 case OMP_ATOMIC_READ:
13673 case OMP_ATOMIC_CAPTURE_OLD:
13674 *expr_p = tmp_load;
13675 gimple_omp_atomic_set_need_value (loadstmt);
13676 break;
13677 case OMP_ATOMIC_CAPTURE_NEW:
13678 *expr_p = rhs;
13679 gimple_omp_atomic_set_need_value (storestmt);
13680 break;
13681 default:
13682 *expr_p = NULL;
13683 break;
13684 }
13685
13686 return GS_ALL_DONE;
13687 }
13688
13689 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
13690 body, and adding some EH bits. */
13691
13692 static enum gimplify_status
gimplify_transaction(tree * expr_p,gimple_seq * pre_p)13693 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
13694 {
13695 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
13696 gimple *body_stmt;
13697 gtransaction *trans_stmt;
13698 gimple_seq body = NULL;
13699 int subcode = 0;
13700
13701 /* Wrap the transaction body in a BIND_EXPR so we have a context
13702 where to put decls for OMP. */
13703 if (TREE_CODE (tbody) != BIND_EXPR)
13704 {
13705 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
13706 TREE_SIDE_EFFECTS (bind) = 1;
13707 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
13708 TRANSACTION_EXPR_BODY (expr) = bind;
13709 }
13710
13711 push_gimplify_context ();
13712 temp = voidify_wrapper_expr (*expr_p, NULL);
13713
13714 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
13715 pop_gimplify_context (body_stmt);
13716
13717 trans_stmt = gimple_build_transaction (body);
13718 if (TRANSACTION_EXPR_OUTER (expr))
13719 subcode = GTMA_IS_OUTER;
13720 else if (TRANSACTION_EXPR_RELAXED (expr))
13721 subcode = GTMA_IS_RELAXED;
13722 gimple_transaction_set_subcode (trans_stmt, subcode);
13723
13724 gimplify_seq_add_stmt (pre_p, trans_stmt);
13725
13726 if (temp)
13727 {
13728 *expr_p = temp;
13729 return GS_OK;
13730 }
13731
13732 *expr_p = NULL_TREE;
13733 return GS_ALL_DONE;
13734 }
13735
13736 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
13737 is the OMP_BODY of the original EXPR (which has already been
13738 gimplified so it's not present in the EXPR).
13739
13740 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
13741
13742 static gimple *
gimplify_omp_ordered(tree expr,gimple_seq body)13743 gimplify_omp_ordered (tree expr, gimple_seq body)
13744 {
13745 tree c, decls;
13746 int failures = 0;
13747 unsigned int i;
13748 tree source_c = NULL_TREE;
13749 tree sink_c = NULL_TREE;
13750
13751 if (gimplify_omp_ctxp)
13752 {
13753 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13754 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
13755 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
13756 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
13757 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
13758 {
13759 error_at (OMP_CLAUSE_LOCATION (c),
13760 "%<ordered%> construct with %<depend%> clause must be "
13761 "closely nested inside a loop with %<ordered%> clause "
13762 "with a parameter");
13763 failures++;
13764 }
13765 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
13766 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
13767 {
13768 bool fail = false;
13769 for (decls = OMP_CLAUSE_DECL (c), i = 0;
13770 decls && TREE_CODE (decls) == TREE_LIST;
13771 decls = TREE_CHAIN (decls), ++i)
13772 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
13773 continue;
13774 else if (TREE_VALUE (decls)
13775 != gimplify_omp_ctxp->loop_iter_var[2 * i])
13776 {
13777 error_at (OMP_CLAUSE_LOCATION (c),
13778 "variable %qE is not an iteration "
13779 "of outermost loop %d, expected %qE",
13780 TREE_VALUE (decls), i + 1,
13781 gimplify_omp_ctxp->loop_iter_var[2 * i]);
13782 fail = true;
13783 failures++;
13784 }
13785 else
13786 TREE_VALUE (decls)
13787 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
13788 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
13789 {
13790 error_at (OMP_CLAUSE_LOCATION (c),
13791 "number of variables in %<depend%> clause with "
13792 "%<sink%> modifier does not match number of "
13793 "iteration variables");
13794 failures++;
13795 }
13796 sink_c = c;
13797 }
13798 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
13799 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
13800 {
13801 if (source_c)
13802 {
13803 error_at (OMP_CLAUSE_LOCATION (c),
13804 "more than one %<depend%> clause with %<source%> "
13805 "modifier on an %<ordered%> construct");
13806 failures++;
13807 }
13808 else
13809 source_c = c;
13810 }
13811 }
13812 if (source_c && sink_c)
13813 {
13814 error_at (OMP_CLAUSE_LOCATION (source_c),
13815 "%<depend%> clause with %<source%> modifier specified "
13816 "together with %<depend%> clauses with %<sink%> modifier "
13817 "on the same construct");
13818 failures++;
13819 }
13820
13821 if (failures)
13822 return gimple_build_nop ();
13823 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
13824 }
13825
13826 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
13827 expression produces a value to be used as an operand inside a GIMPLE
13828 statement, the value will be stored back in *EXPR_P. This value will
13829 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
13830 an SSA_NAME. The corresponding sequence of GIMPLE statements is
13831 emitted in PRE_P and POST_P.
13832
13833 Additionally, this process may overwrite parts of the input
13834 expression during gimplification. Ideally, it should be
13835 possible to do non-destructive gimplification.
13836
13837 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
13838 the expression needs to evaluate to a value to be used as
13839 an operand in a GIMPLE statement, this value will be stored in
13840 *EXPR_P on exit. This happens when the caller specifies one
13841 of fb_lvalue or fb_rvalue fallback flags.
13842
13843 PRE_P will contain the sequence of GIMPLE statements corresponding
13844 to the evaluation of EXPR and all the side-effects that must
13845 be executed before the main expression. On exit, the last
13846 statement of PRE_P is the core statement being gimplified. For
13847 instance, when gimplifying 'if (++a)' the last statement in
13848 PRE_P will be 'if (t.1)' where t.1 is the result of
13849 pre-incrementing 'a'.
13850
13851 POST_P will contain the sequence of GIMPLE statements corresponding
13852 to the evaluation of all the side-effects that must be executed
13853 after the main expression. If this is NULL, the post
13854 side-effects are stored at the end of PRE_P.
13855
13856 The reason why the output is split in two is to handle post
13857 side-effects explicitly. In some cases, an expression may have
13858 inner and outer post side-effects which need to be emitted in
13859 an order different from the one given by the recursive
13860 traversal. For instance, for the expression (*p--)++ the post
13861 side-effects of '--' must actually occur *after* the post
13862 side-effects of '++'. However, gimplification will first visit
13863 the inner expression, so if a separate POST sequence was not
13864 used, the resulting sequence would be:
13865
13866 1 t.1 = *p
13867 2 p = p - 1
13868 3 t.2 = t.1 + 1
13869 4 *p = t.2
13870
13871 However, the post-decrement operation in line #2 must not be
13872 evaluated until after the store to *p at line #4, so the
13873 correct sequence should be:
13874
13875 1 t.1 = *p
13876 2 t.2 = t.1 + 1
13877 3 *p = t.2
13878 4 p = p - 1
13879
13880 So, by specifying a separate post queue, it is possible
13881 to emit the post side-effects in the correct order.
13882 If POST_P is NULL, an internal queue will be used. Before
13883 returning to the caller, the sequence POST_P is appended to
13884 the main output sequence PRE_P.
13885
13886 GIMPLE_TEST_F points to a function that takes a tree T and
13887 returns nonzero if T is in the GIMPLE form requested by the
13888 caller. The GIMPLE predicates are in gimple.c.
13889
13890 FALLBACK tells the function what sort of a temporary we want if
13891 gimplification cannot produce an expression that complies with
13892 GIMPLE_TEST_F.
13893
13894 fb_none means that no temporary should be generated
13895 fb_rvalue means that an rvalue is OK to generate
13896 fb_lvalue means that an lvalue is OK to generate
13897 fb_either means that either is OK, but an lvalue is preferable.
13898 fb_mayfail means that gimplification may fail (in which case
13899 GS_ERROR will be returned)
13900
13901 The return value is either GS_ERROR or GS_ALL_DONE, since this
13902 function iterates until EXPR is completely gimplified or an error
13903 occurs. */
13904
13905 enum gimplify_status
gimplify_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p,bool (* gimple_test_f)(tree),fallback_t fallback)13906 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
13907 bool (*gimple_test_f) (tree), fallback_t fallback)
13908 {
13909 tree tmp;
13910 gimple_seq internal_pre = NULL;
13911 gimple_seq internal_post = NULL;
13912 tree save_expr;
13913 bool is_statement;
13914 location_t saved_location;
13915 enum gimplify_status ret;
13916 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
13917 tree label;
13918
13919 save_expr = *expr_p;
13920 if (save_expr == NULL_TREE)
13921 return GS_ALL_DONE;
13922
13923 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
13924 is_statement = gimple_test_f == is_gimple_stmt;
13925 if (is_statement)
13926 gcc_assert (pre_p);
13927
13928 /* Consistency checks. */
13929 if (gimple_test_f == is_gimple_reg)
13930 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
13931 else if (gimple_test_f == is_gimple_val
13932 || gimple_test_f == is_gimple_call_addr
13933 || gimple_test_f == is_gimple_condexpr
13934 || gimple_test_f == is_gimple_condexpr_for_cond
13935 || gimple_test_f == is_gimple_mem_rhs
13936 || gimple_test_f == is_gimple_mem_rhs_or_call
13937 || gimple_test_f == is_gimple_reg_rhs
13938 || gimple_test_f == is_gimple_reg_rhs_or_call
13939 || gimple_test_f == is_gimple_asm_val
13940 || gimple_test_f == is_gimple_mem_ref_addr)
13941 gcc_assert (fallback & fb_rvalue);
13942 else if (gimple_test_f == is_gimple_min_lval
13943 || gimple_test_f == is_gimple_lvalue)
13944 gcc_assert (fallback & fb_lvalue);
13945 else if (gimple_test_f == is_gimple_addressable)
13946 gcc_assert (fallback & fb_either);
13947 else if (gimple_test_f == is_gimple_stmt)
13948 gcc_assert (fallback == fb_none);
13949 else
13950 {
13951 /* We should have recognized the GIMPLE_TEST_F predicate to
13952 know what kind of fallback to use in case a temporary is
13953 needed to hold the value or address of *EXPR_P. */
13954 gcc_unreachable ();
13955 }
13956
13957 /* We used to check the predicate here and return immediately if it
13958 succeeds. This is wrong; the design is for gimplification to be
13959 idempotent, and for the predicates to only test for valid forms, not
13960 whether they are fully simplified. */
13961 if (pre_p == NULL)
13962 pre_p = &internal_pre;
13963
13964 if (post_p == NULL)
13965 post_p = &internal_post;
13966
13967 /* Remember the last statements added to PRE_P and POST_P. Every
13968 new statement added by the gimplification helpers needs to be
13969 annotated with location information. To centralize the
13970 responsibility, we remember the last statement that had been
13971 added to both queues before gimplifying *EXPR_P. If
13972 gimplification produces new statements in PRE_P and POST_P, those
13973 statements will be annotated with the same location information
13974 as *EXPR_P. */
13975 pre_last_gsi = gsi_last (*pre_p);
13976 post_last_gsi = gsi_last (*post_p);
13977
13978 saved_location = input_location;
13979 if (save_expr != error_mark_node
13980 && EXPR_HAS_LOCATION (*expr_p))
13981 input_location = EXPR_LOCATION (*expr_p);
13982
13983 /* Loop over the specific gimplifiers until the toplevel node
13984 remains the same. */
13985 do
13986 {
13987 /* Strip away as many useless type conversions as possible
13988 at the toplevel. */
13989 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
13990
13991 /* Remember the expr. */
13992 save_expr = *expr_p;
13993
13994 /* Die, die, die, my darling. */
13995 if (error_operand_p (save_expr))
13996 {
13997 ret = GS_ERROR;
13998 break;
13999 }
14000
14001 /* Do any language-specific gimplification. */
14002 ret = ((enum gimplify_status)
14003 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
14004 if (ret == GS_OK)
14005 {
14006 if (*expr_p == NULL_TREE)
14007 break;
14008 if (*expr_p != save_expr)
14009 continue;
14010 }
14011 else if (ret != GS_UNHANDLED)
14012 break;
14013
14014 /* Make sure that all the cases set 'ret' appropriately. */
14015 ret = GS_UNHANDLED;
14016 switch (TREE_CODE (*expr_p))
14017 {
14018 /* First deal with the special cases. */
14019
14020 case POSTINCREMENT_EXPR:
14021 case POSTDECREMENT_EXPR:
14022 case PREINCREMENT_EXPR:
14023 case PREDECREMENT_EXPR:
14024 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
14025 fallback != fb_none,
14026 TREE_TYPE (*expr_p));
14027 break;
14028
14029 case VIEW_CONVERT_EXPR:
14030 if ((fallback & fb_rvalue)
14031 && is_gimple_reg_type (TREE_TYPE (*expr_p))
14032 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
14033 {
14034 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14035 post_p, is_gimple_val, fb_rvalue);
14036 recalculate_side_effects (*expr_p);
14037 break;
14038 }
14039 /* Fallthru. */
14040
14041 case ARRAY_REF:
14042 case ARRAY_RANGE_REF:
14043 case REALPART_EXPR:
14044 case IMAGPART_EXPR:
14045 case COMPONENT_REF:
14046 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
14047 fallback ? fallback : fb_rvalue);
14048 break;
14049
14050 case COND_EXPR:
14051 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
14052
14053 /* C99 code may assign to an array in a structure value of a
14054 conditional expression, and this has undefined behavior
14055 only on execution, so create a temporary if an lvalue is
14056 required. */
14057 if (fallback == fb_lvalue)
14058 {
14059 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14060 mark_addressable (*expr_p);
14061 ret = GS_OK;
14062 }
14063 break;
14064
14065 case CALL_EXPR:
14066 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
14067
14068 /* C99 code may assign to an array in a structure returned
14069 from a function, and this has undefined behavior only on
14070 execution, so create a temporary if an lvalue is
14071 required. */
14072 if (fallback == fb_lvalue)
14073 {
14074 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14075 mark_addressable (*expr_p);
14076 ret = GS_OK;
14077 }
14078 break;
14079
14080 case TREE_LIST:
14081 gcc_unreachable ();
14082
14083 case COMPOUND_EXPR:
14084 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
14085 break;
14086
14087 case COMPOUND_LITERAL_EXPR:
14088 ret = gimplify_compound_literal_expr (expr_p, pre_p,
14089 gimple_test_f, fallback);
14090 break;
14091
14092 case MODIFY_EXPR:
14093 case INIT_EXPR:
14094 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
14095 fallback != fb_none);
14096 break;
14097
14098 case TRUTH_ANDIF_EXPR:
14099 case TRUTH_ORIF_EXPR:
14100 {
14101 /* Preserve the original type of the expression and the
14102 source location of the outer expression. */
14103 tree org_type = TREE_TYPE (*expr_p);
14104 *expr_p = gimple_boolify (*expr_p);
14105 *expr_p = build3_loc (input_location, COND_EXPR,
14106 org_type, *expr_p,
14107 fold_convert_loc
14108 (input_location,
14109 org_type, boolean_true_node),
14110 fold_convert_loc
14111 (input_location,
14112 org_type, boolean_false_node));
14113 ret = GS_OK;
14114 break;
14115 }
14116
14117 case TRUTH_NOT_EXPR:
14118 {
14119 tree type = TREE_TYPE (*expr_p);
14120 /* The parsers are careful to generate TRUTH_NOT_EXPR
14121 only with operands that are always zero or one.
14122 We do not fold here but handle the only interesting case
14123 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
14124 *expr_p = gimple_boolify (*expr_p);
14125 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
14126 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
14127 TREE_TYPE (*expr_p),
14128 TREE_OPERAND (*expr_p, 0));
14129 else
14130 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
14131 TREE_TYPE (*expr_p),
14132 TREE_OPERAND (*expr_p, 0),
14133 build_int_cst (TREE_TYPE (*expr_p), 1));
14134 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
14135 *expr_p = fold_convert_loc (input_location, type, *expr_p);
14136 ret = GS_OK;
14137 break;
14138 }
14139
14140 case ADDR_EXPR:
14141 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
14142 break;
14143
14144 case ANNOTATE_EXPR:
14145 {
14146 tree cond = TREE_OPERAND (*expr_p, 0);
14147 tree kind = TREE_OPERAND (*expr_p, 1);
14148 tree data = TREE_OPERAND (*expr_p, 2);
14149 tree type = TREE_TYPE (cond);
14150 if (!INTEGRAL_TYPE_P (type))
14151 {
14152 *expr_p = cond;
14153 ret = GS_OK;
14154 break;
14155 }
14156 tree tmp = create_tmp_var (type);
14157 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
14158 gcall *call
14159 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
14160 gimple_call_set_lhs (call, tmp);
14161 gimplify_seq_add_stmt (pre_p, call);
14162 *expr_p = tmp;
14163 ret = GS_ALL_DONE;
14164 break;
14165 }
14166
14167 case VA_ARG_EXPR:
14168 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
14169 break;
14170
14171 CASE_CONVERT:
14172 if (IS_EMPTY_STMT (*expr_p))
14173 {
14174 ret = GS_ALL_DONE;
14175 break;
14176 }
14177
14178 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
14179 || fallback == fb_none)
14180 {
14181 /* Just strip a conversion to void (or in void context) and
14182 try again. */
14183 *expr_p = TREE_OPERAND (*expr_p, 0);
14184 ret = GS_OK;
14185 break;
14186 }
14187
14188 ret = gimplify_conversion (expr_p);
14189 if (ret == GS_ERROR)
14190 break;
14191 if (*expr_p != save_expr)
14192 break;
14193 /* FALLTHRU */
14194
14195 case FIX_TRUNC_EXPR:
14196 /* unary_expr: ... | '(' cast ')' val | ... */
14197 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14198 is_gimple_val, fb_rvalue);
14199 recalculate_side_effects (*expr_p);
14200 break;
14201
14202 case INDIRECT_REF:
14203 {
14204 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
14205 bool notrap = TREE_THIS_NOTRAP (*expr_p);
14206 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
14207
14208 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
14209 if (*expr_p != save_expr)
14210 {
14211 ret = GS_OK;
14212 break;
14213 }
14214
14215 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14216 is_gimple_reg, fb_rvalue);
14217 if (ret == GS_ERROR)
14218 break;
14219
14220 recalculate_side_effects (*expr_p);
14221 *expr_p = fold_build2_loc (input_location, MEM_REF,
14222 TREE_TYPE (*expr_p),
14223 TREE_OPERAND (*expr_p, 0),
14224 build_int_cst (saved_ptr_type, 0));
14225 TREE_THIS_VOLATILE (*expr_p) = volatilep;
14226 TREE_THIS_NOTRAP (*expr_p) = notrap;
14227 ret = GS_OK;
14228 break;
14229 }
14230
14231 /* We arrive here through the various re-gimplifcation paths. */
14232 case MEM_REF:
14233 /* First try re-folding the whole thing. */
14234 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
14235 TREE_OPERAND (*expr_p, 0),
14236 TREE_OPERAND (*expr_p, 1));
14237 if (tmp)
14238 {
14239 REF_REVERSE_STORAGE_ORDER (tmp)
14240 = REF_REVERSE_STORAGE_ORDER (*expr_p);
14241 *expr_p = tmp;
14242 recalculate_side_effects (*expr_p);
14243 ret = GS_OK;
14244 break;
14245 }
14246 /* Avoid re-gimplifying the address operand if it is already
14247 in suitable form. Re-gimplifying would mark the address
14248 operand addressable. Always gimplify when not in SSA form
14249 as we still may have to gimplify decls with value-exprs. */
14250 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
14251 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
14252 {
14253 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14254 is_gimple_mem_ref_addr, fb_rvalue);
14255 if (ret == GS_ERROR)
14256 break;
14257 }
14258 recalculate_side_effects (*expr_p);
14259 ret = GS_ALL_DONE;
14260 break;
14261
14262 /* Constants need not be gimplified. */
14263 case INTEGER_CST:
14264 case REAL_CST:
14265 case FIXED_CST:
14266 case STRING_CST:
14267 case COMPLEX_CST:
14268 case VECTOR_CST:
14269 /* Drop the overflow flag on constants, we do not want
14270 that in the GIMPLE IL. */
14271 if (TREE_OVERFLOW_P (*expr_p))
14272 *expr_p = drop_tree_overflow (*expr_p);
14273 ret = GS_ALL_DONE;
14274 break;
14275
14276 case CONST_DECL:
14277 /* If we require an lvalue, such as for ADDR_EXPR, retain the
14278 CONST_DECL node. Otherwise the decl is replaceable by its
14279 value. */
14280 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
14281 if (fallback & fb_lvalue)
14282 ret = GS_ALL_DONE;
14283 else
14284 {
14285 *expr_p = DECL_INITIAL (*expr_p);
14286 ret = GS_OK;
14287 }
14288 break;
14289
14290 case DECL_EXPR:
14291 ret = gimplify_decl_expr (expr_p, pre_p);
14292 break;
14293
14294 case BIND_EXPR:
14295 ret = gimplify_bind_expr (expr_p, pre_p);
14296 break;
14297
14298 case LOOP_EXPR:
14299 ret = gimplify_loop_expr (expr_p, pre_p);
14300 break;
14301
14302 case SWITCH_EXPR:
14303 ret = gimplify_switch_expr (expr_p, pre_p);
14304 break;
14305
14306 case EXIT_EXPR:
14307 ret = gimplify_exit_expr (expr_p);
14308 break;
14309
14310 case GOTO_EXPR:
14311 /* If the target is not LABEL, then it is a computed jump
14312 and the target needs to be gimplified. */
14313 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
14314 {
14315 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
14316 NULL, is_gimple_val, fb_rvalue);
14317 if (ret == GS_ERROR)
14318 break;
14319 }
14320 gimplify_seq_add_stmt (pre_p,
14321 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
14322 ret = GS_ALL_DONE;
14323 break;
14324
14325 case PREDICT_EXPR:
14326 gimplify_seq_add_stmt (pre_p,
14327 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
14328 PREDICT_EXPR_OUTCOME (*expr_p)));
14329 ret = GS_ALL_DONE;
14330 break;
14331
14332 case LABEL_EXPR:
14333 ret = gimplify_label_expr (expr_p, pre_p);
14334 label = LABEL_EXPR_LABEL (*expr_p);
14335 gcc_assert (decl_function_context (label) == current_function_decl);
14336
14337 /* If the label is used in a goto statement, or address of the label
14338 is taken, we need to unpoison all variables that were seen so far.
14339 Doing so would prevent us from reporting a false positives. */
14340 if (asan_poisoned_variables
14341 && asan_used_labels != NULL
14342 && asan_used_labels->contains (label)
14343 && !gimplify_omp_ctxp)
14344 asan_poison_variables (asan_poisoned_variables, false, pre_p);
14345 break;
14346
14347 case CASE_LABEL_EXPR:
14348 ret = gimplify_case_label_expr (expr_p, pre_p);
14349
14350 if (gimplify_ctxp->live_switch_vars)
14351 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
14352 pre_p);
14353 break;
14354
14355 case RETURN_EXPR:
14356 ret = gimplify_return_expr (*expr_p, pre_p);
14357 break;
14358
14359 case CONSTRUCTOR:
14360 /* Don't reduce this in place; let gimplify_init_constructor work its
14361 magic. Buf if we're just elaborating this for side effects, just
14362 gimplify any element that has side-effects. */
14363 if (fallback == fb_none)
14364 {
14365 unsigned HOST_WIDE_INT ix;
14366 tree val;
14367 tree temp = NULL_TREE;
14368 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
14369 if (TREE_SIDE_EFFECTS (val))
14370 append_to_statement_list (val, &temp);
14371
14372 *expr_p = temp;
14373 ret = temp ? GS_OK : GS_ALL_DONE;
14374 }
14375 /* C99 code may assign to an array in a constructed
14376 structure or union, and this has undefined behavior only
14377 on execution, so create a temporary if an lvalue is
14378 required. */
14379 else if (fallback == fb_lvalue)
14380 {
14381 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14382 mark_addressable (*expr_p);
14383 ret = GS_OK;
14384 }
14385 else
14386 ret = GS_ALL_DONE;
14387 break;
14388
14389 /* The following are special cases that are not handled by the
14390 original GIMPLE grammar. */
14391
14392 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
14393 eliminated. */
14394 case SAVE_EXPR:
14395 ret = gimplify_save_expr (expr_p, pre_p, post_p);
14396 break;
14397
14398 case BIT_FIELD_REF:
14399 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14400 post_p, is_gimple_lvalue, fb_either);
14401 recalculate_side_effects (*expr_p);
14402 break;
14403
14404 case TARGET_MEM_REF:
14405 {
14406 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
14407
14408 if (TMR_BASE (*expr_p))
14409 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
14410 post_p, is_gimple_mem_ref_addr, fb_either);
14411 if (TMR_INDEX (*expr_p))
14412 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
14413 post_p, is_gimple_val, fb_rvalue);
14414 if (TMR_INDEX2 (*expr_p))
14415 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
14416 post_p, is_gimple_val, fb_rvalue);
14417 /* TMR_STEP and TMR_OFFSET are always integer constants. */
14418 ret = MIN (r0, r1);
14419 }
14420 break;
14421
14422 case NON_LVALUE_EXPR:
14423 /* This should have been stripped above. */
14424 gcc_unreachable ();
14425
14426 case ASM_EXPR:
14427 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
14428 break;
14429
14430 case TRY_FINALLY_EXPR:
14431 case TRY_CATCH_EXPR:
14432 {
14433 gimple_seq eval, cleanup;
14434 gtry *try_;
14435
14436 /* Calls to destructors are generated automatically in FINALLY/CATCH
14437 block. They should have location as UNKNOWN_LOCATION. However,
14438 gimplify_call_expr will reset these call stmts to input_location
14439 if it finds stmt's location is unknown. To prevent resetting for
14440 destructors, we set the input_location to unknown.
14441 Note that this only affects the destructor calls in FINALLY/CATCH
14442 block, and will automatically reset to its original value by the
14443 end of gimplify_expr. */
14444 input_location = UNKNOWN_LOCATION;
14445 eval = cleanup = NULL;
14446 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
14447 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
14448 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
14449 {
14450 gimple_seq n = NULL, e = NULL;
14451 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
14452 0), &n);
14453 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
14454 1), &e);
14455 if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
14456 {
14457 geh_else *stmt = gimple_build_eh_else (n, e);
14458 gimple_seq_add_stmt (&cleanup, stmt);
14459 }
14460 }
14461 else
14462 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
14463 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
14464 if (gimple_seq_empty_p (cleanup))
14465 {
14466 gimple_seq_add_seq (pre_p, eval);
14467 ret = GS_ALL_DONE;
14468 break;
14469 }
14470 try_ = gimple_build_try (eval, cleanup,
14471 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
14472 ? GIMPLE_TRY_FINALLY
14473 : GIMPLE_TRY_CATCH);
14474 if (EXPR_HAS_LOCATION (save_expr))
14475 gimple_set_location (try_, EXPR_LOCATION (save_expr));
14476 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
14477 gimple_set_location (try_, saved_location);
14478 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
14479 gimple_try_set_catch_is_cleanup (try_,
14480 TRY_CATCH_IS_CLEANUP (*expr_p));
14481 gimplify_seq_add_stmt (pre_p, try_);
14482 ret = GS_ALL_DONE;
14483 break;
14484 }
14485
14486 case CLEANUP_POINT_EXPR:
14487 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
14488 break;
14489
14490 case TARGET_EXPR:
14491 ret = gimplify_target_expr (expr_p, pre_p, post_p);
14492 break;
14493
14494 case CATCH_EXPR:
14495 {
14496 gimple *c;
14497 gimple_seq handler = NULL;
14498 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
14499 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
14500 gimplify_seq_add_stmt (pre_p, c);
14501 ret = GS_ALL_DONE;
14502 break;
14503 }
14504
14505 case EH_FILTER_EXPR:
14506 {
14507 gimple *ehf;
14508 gimple_seq failure = NULL;
14509
14510 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
14511 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
14512 gimple_set_no_warning (ehf, TREE_NO_WARNING (*expr_p));
14513 gimplify_seq_add_stmt (pre_p, ehf);
14514 ret = GS_ALL_DONE;
14515 break;
14516 }
14517
14518 case OBJ_TYPE_REF:
14519 {
14520 enum gimplify_status r0, r1;
14521 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
14522 post_p, is_gimple_val, fb_rvalue);
14523 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
14524 post_p, is_gimple_val, fb_rvalue);
14525 TREE_SIDE_EFFECTS (*expr_p) = 0;
14526 ret = MIN (r0, r1);
14527 }
14528 break;
14529
14530 case LABEL_DECL:
14531 /* We get here when taking the address of a label. We mark
14532 the label as "forced"; meaning it can never be removed and
14533 it is a potential target for any computed goto. */
14534 FORCED_LABEL (*expr_p) = 1;
14535 ret = GS_ALL_DONE;
14536 break;
14537
14538 case STATEMENT_LIST:
14539 ret = gimplify_statement_list (expr_p, pre_p);
14540 break;
14541
14542 case WITH_SIZE_EXPR:
14543 {
14544 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14545 post_p == &internal_post ? NULL : post_p,
14546 gimple_test_f, fallback);
14547 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
14548 is_gimple_val, fb_rvalue);
14549 ret = GS_ALL_DONE;
14550 }
14551 break;
14552
14553 case VAR_DECL:
14554 case PARM_DECL:
14555 ret = gimplify_var_or_parm_decl (expr_p);
14556 break;
14557
14558 case RESULT_DECL:
14559 /* When within an OMP context, notice uses of variables. */
14560 if (gimplify_omp_ctxp)
14561 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
14562 ret = GS_ALL_DONE;
14563 break;
14564
14565 case DEBUG_EXPR_DECL:
14566 gcc_unreachable ();
14567
14568 case DEBUG_BEGIN_STMT:
14569 gimplify_seq_add_stmt (pre_p,
14570 gimple_build_debug_begin_stmt
14571 (TREE_BLOCK (*expr_p),
14572 EXPR_LOCATION (*expr_p)));
14573 ret = GS_ALL_DONE;
14574 *expr_p = NULL;
14575 break;
14576
14577 case SSA_NAME:
14578 /* Allow callbacks into the gimplifier during optimization. */
14579 ret = GS_ALL_DONE;
14580 break;
14581
14582 case OMP_PARALLEL:
14583 gimplify_omp_parallel (expr_p, pre_p);
14584 ret = GS_ALL_DONE;
14585 break;
14586
14587 case OMP_TASK:
14588 gimplify_omp_task (expr_p, pre_p);
14589 ret = GS_ALL_DONE;
14590 break;
14591
14592 case OMP_FOR:
14593 case OMP_SIMD:
14594 case OMP_DISTRIBUTE:
14595 case OMP_TASKLOOP:
14596 case OACC_LOOP:
14597 ret = gimplify_omp_for (expr_p, pre_p);
14598 break;
14599
14600 case OMP_LOOP:
14601 ret = gimplify_omp_loop (expr_p, pre_p);
14602 break;
14603
14604 case OACC_CACHE:
14605 gimplify_oacc_cache (expr_p, pre_p);
14606 ret = GS_ALL_DONE;
14607 break;
14608
14609 case OACC_DECLARE:
14610 gimplify_oacc_declare (expr_p, pre_p);
14611 ret = GS_ALL_DONE;
14612 break;
14613
14614 case OACC_HOST_DATA:
14615 case OACC_DATA:
14616 case OACC_KERNELS:
14617 case OACC_PARALLEL:
14618 case OACC_SERIAL:
14619 case OMP_SECTIONS:
14620 case OMP_SINGLE:
14621 case OMP_TARGET:
14622 case OMP_TARGET_DATA:
14623 case OMP_TEAMS:
14624 gimplify_omp_workshare (expr_p, pre_p);
14625 ret = GS_ALL_DONE;
14626 break;
14627
14628 case OACC_ENTER_DATA:
14629 case OACC_EXIT_DATA:
14630 case OACC_UPDATE:
14631 case OMP_TARGET_UPDATE:
14632 case OMP_TARGET_ENTER_DATA:
14633 case OMP_TARGET_EXIT_DATA:
14634 gimplify_omp_target_update (expr_p, pre_p);
14635 ret = GS_ALL_DONE;
14636 break;
14637
14638 case OMP_SECTION:
14639 case OMP_MASTER:
14640 case OMP_ORDERED:
14641 case OMP_CRITICAL:
14642 case OMP_SCAN:
14643 {
14644 gimple_seq body = NULL;
14645 gimple *g;
14646 bool saved_in_omp_construct = in_omp_construct;
14647
14648 in_omp_construct = true;
14649 gimplify_and_add (OMP_BODY (*expr_p), &body);
14650 in_omp_construct = saved_in_omp_construct;
14651 switch (TREE_CODE (*expr_p))
14652 {
14653 case OMP_SECTION:
14654 g = gimple_build_omp_section (body);
14655 break;
14656 case OMP_MASTER:
14657 g = gimple_build_omp_master (body);
14658 break;
14659 case OMP_ORDERED:
14660 g = gimplify_omp_ordered (*expr_p, body);
14661 break;
14662 case OMP_CRITICAL:
14663 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
14664 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
14665 gimplify_adjust_omp_clauses (pre_p, body,
14666 &OMP_CRITICAL_CLAUSES (*expr_p),
14667 OMP_CRITICAL);
14668 g = gimple_build_omp_critical (body,
14669 OMP_CRITICAL_NAME (*expr_p),
14670 OMP_CRITICAL_CLAUSES (*expr_p));
14671 break;
14672 case OMP_SCAN:
14673 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
14674 pre_p, ORT_WORKSHARE, OMP_SCAN);
14675 gimplify_adjust_omp_clauses (pre_p, body,
14676 &OMP_SCAN_CLAUSES (*expr_p),
14677 OMP_SCAN);
14678 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
14679 break;
14680 default:
14681 gcc_unreachable ();
14682 }
14683 gimplify_seq_add_stmt (pre_p, g);
14684 ret = GS_ALL_DONE;
14685 break;
14686 }
14687
14688 case OMP_TASKGROUP:
14689 {
14690 gimple_seq body = NULL;
14691
14692 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
14693 bool saved_in_omp_construct = in_omp_construct;
14694 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
14695 OMP_TASKGROUP);
14696 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
14697
14698 in_omp_construct = true;
14699 gimplify_and_add (OMP_BODY (*expr_p), &body);
14700 in_omp_construct = saved_in_omp_construct;
14701 gimple_seq cleanup = NULL;
14702 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
14703 gimple *g = gimple_build_call (fn, 0);
14704 gimple_seq_add_stmt (&cleanup, g);
14705 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
14706 body = NULL;
14707 gimple_seq_add_stmt (&body, g);
14708 g = gimple_build_omp_taskgroup (body, *pclauses);
14709 gimplify_seq_add_stmt (pre_p, g);
14710 ret = GS_ALL_DONE;
14711 break;
14712 }
14713
14714 case OMP_ATOMIC:
14715 case OMP_ATOMIC_READ:
14716 case OMP_ATOMIC_CAPTURE_OLD:
14717 case OMP_ATOMIC_CAPTURE_NEW:
14718 ret = gimplify_omp_atomic (expr_p, pre_p);
14719 break;
14720
14721 case TRANSACTION_EXPR:
14722 ret = gimplify_transaction (expr_p, pre_p);
14723 break;
14724
14725 case TRUTH_AND_EXPR:
14726 case TRUTH_OR_EXPR:
14727 case TRUTH_XOR_EXPR:
14728 {
14729 tree orig_type = TREE_TYPE (*expr_p);
14730 tree new_type, xop0, xop1;
14731 *expr_p = gimple_boolify (*expr_p);
14732 new_type = TREE_TYPE (*expr_p);
14733 if (!useless_type_conversion_p (orig_type, new_type))
14734 {
14735 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
14736 ret = GS_OK;
14737 break;
14738 }
14739
14740 /* Boolified binary truth expressions are semantically equivalent
14741 to bitwise binary expressions. Canonicalize them to the
14742 bitwise variant. */
14743 switch (TREE_CODE (*expr_p))
14744 {
14745 case TRUTH_AND_EXPR:
14746 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
14747 break;
14748 case TRUTH_OR_EXPR:
14749 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
14750 break;
14751 case TRUTH_XOR_EXPR:
14752 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
14753 break;
14754 default:
14755 break;
14756 }
14757 /* Now make sure that operands have compatible type to
14758 expression's new_type. */
14759 xop0 = TREE_OPERAND (*expr_p, 0);
14760 xop1 = TREE_OPERAND (*expr_p, 1);
14761 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
14762 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
14763 new_type,
14764 xop0);
14765 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
14766 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
14767 new_type,
14768 xop1);
14769 /* Continue classified as tcc_binary. */
14770 goto expr_2;
14771 }
14772
14773 case VEC_COND_EXPR:
14774 goto expr_3;
14775
14776 case VEC_PERM_EXPR:
14777 /* Classified as tcc_expression. */
14778 goto expr_3;
14779
14780 case BIT_INSERT_EXPR:
14781 /* Argument 3 is a constant. */
14782 goto expr_2;
14783
14784 case POINTER_PLUS_EXPR:
14785 {
14786 enum gimplify_status r0, r1;
14787 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14788 post_p, is_gimple_val, fb_rvalue);
14789 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
14790 post_p, is_gimple_val, fb_rvalue);
14791 recalculate_side_effects (*expr_p);
14792 ret = MIN (r0, r1);
14793 break;
14794 }
14795
14796 default:
14797 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
14798 {
14799 case tcc_comparison:
14800 /* Handle comparison of objects of non scalar mode aggregates
14801 with a call to memcmp. It would be nice to only have to do
14802 this for variable-sized objects, but then we'd have to allow
14803 the same nest of reference nodes we allow for MODIFY_EXPR and
14804 that's too complex.
14805
14806 Compare scalar mode aggregates as scalar mode values. Using
14807 memcmp for them would be very inefficient at best, and is
14808 plain wrong if bitfields are involved. */
14809 {
14810 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
14811
14812 /* Vector comparisons need no boolification. */
14813 if (TREE_CODE (type) == VECTOR_TYPE)
14814 goto expr_2;
14815 else if (!AGGREGATE_TYPE_P (type))
14816 {
14817 tree org_type = TREE_TYPE (*expr_p);
14818 *expr_p = gimple_boolify (*expr_p);
14819 if (!useless_type_conversion_p (org_type,
14820 TREE_TYPE (*expr_p)))
14821 {
14822 *expr_p = fold_convert_loc (input_location,
14823 org_type, *expr_p);
14824 ret = GS_OK;
14825 }
14826 else
14827 goto expr_2;
14828 }
14829 else if (TYPE_MODE (type) != BLKmode)
14830 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
14831 else
14832 ret = gimplify_variable_sized_compare (expr_p);
14833
14834 break;
14835 }
14836
14837 /* If *EXPR_P does not need to be special-cased, handle it
14838 according to its class. */
14839 case tcc_unary:
14840 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14841 post_p, is_gimple_val, fb_rvalue);
14842 break;
14843
14844 case tcc_binary:
14845 expr_2:
14846 {
14847 enum gimplify_status r0, r1;
14848
14849 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14850 post_p, is_gimple_val, fb_rvalue);
14851 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
14852 post_p, is_gimple_val, fb_rvalue);
14853
14854 ret = MIN (r0, r1);
14855 break;
14856 }
14857
14858 expr_3:
14859 {
14860 enum gimplify_status r0, r1, r2;
14861
14862 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14863 post_p, is_gimple_val, fb_rvalue);
14864 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
14865 post_p, is_gimple_val, fb_rvalue);
14866 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
14867 post_p, is_gimple_val, fb_rvalue);
14868
14869 ret = MIN (MIN (r0, r1), r2);
14870 break;
14871 }
14872
14873 case tcc_declaration:
14874 case tcc_constant:
14875 ret = GS_ALL_DONE;
14876 goto dont_recalculate;
14877
14878 default:
14879 gcc_unreachable ();
14880 }
14881
14882 recalculate_side_effects (*expr_p);
14883
14884 dont_recalculate:
14885 break;
14886 }
14887
14888 gcc_assert (*expr_p || ret != GS_OK);
14889 }
14890 while (ret == GS_OK);
14891
14892 /* If we encountered an error_mark somewhere nested inside, either
14893 stub out the statement or propagate the error back out. */
14894 if (ret == GS_ERROR)
14895 {
14896 if (is_statement)
14897 *expr_p = NULL;
14898 goto out;
14899 }
14900
14901 /* This was only valid as a return value from the langhook, which
14902 we handled. Make sure it doesn't escape from any other context. */
14903 gcc_assert (ret != GS_UNHANDLED);
14904
14905 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
14906 {
14907 /* We aren't looking for a value, and we don't have a valid
14908 statement. If it doesn't have side-effects, throw it away.
14909 We can also get here with code such as "*&&L;", where L is
14910 a LABEL_DECL that is marked as FORCED_LABEL. */
14911 if (TREE_CODE (*expr_p) == LABEL_DECL
14912 || !TREE_SIDE_EFFECTS (*expr_p))
14913 *expr_p = NULL;
14914 else if (!TREE_THIS_VOLATILE (*expr_p))
14915 {
14916 /* This is probably a _REF that contains something nested that
14917 has side effects. Recurse through the operands to find it. */
14918 enum tree_code code = TREE_CODE (*expr_p);
14919
14920 switch (code)
14921 {
14922 case COMPONENT_REF:
14923 case REALPART_EXPR:
14924 case IMAGPART_EXPR:
14925 case VIEW_CONVERT_EXPR:
14926 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14927 gimple_test_f, fallback);
14928 break;
14929
14930 case ARRAY_REF:
14931 case ARRAY_RANGE_REF:
14932 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14933 gimple_test_f, fallback);
14934 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
14935 gimple_test_f, fallback);
14936 break;
14937
14938 default:
14939 /* Anything else with side-effects must be converted to
14940 a valid statement before we get here. */
14941 gcc_unreachable ();
14942 }
14943
14944 *expr_p = NULL;
14945 }
14946 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
14947 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode)
14948 {
14949 /* Historically, the compiler has treated a bare reference
14950 to a non-BLKmode volatile lvalue as forcing a load. */
14951 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
14952
14953 /* Normally, we do not want to create a temporary for a
14954 TREE_ADDRESSABLE type because such a type should not be
14955 copied by bitwise-assignment. However, we make an
14956 exception here, as all we are doing here is ensuring that
14957 we read the bytes that make up the type. We use
14958 create_tmp_var_raw because create_tmp_var will abort when
14959 given a TREE_ADDRESSABLE type. */
14960 tree tmp = create_tmp_var_raw (type, "vol");
14961 gimple_add_tmp_var (tmp);
14962 gimplify_assign (tmp, *expr_p, pre_p);
14963 *expr_p = NULL;
14964 }
14965 else
14966 /* We can't do anything useful with a volatile reference to
14967 an incomplete type, so just throw it away. Likewise for
14968 a BLKmode type, since any implicit inner load should
14969 already have been turned into an explicit one by the
14970 gimplification process. */
14971 *expr_p = NULL;
14972 }
14973
14974 /* If we are gimplifying at the statement level, we're done. Tack
14975 everything together and return. */
14976 if (fallback == fb_none || is_statement)
14977 {
14978 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
14979 it out for GC to reclaim it. */
14980 *expr_p = NULL_TREE;
14981
14982 if (!gimple_seq_empty_p (internal_pre)
14983 || !gimple_seq_empty_p (internal_post))
14984 {
14985 gimplify_seq_add_seq (&internal_pre, internal_post);
14986 gimplify_seq_add_seq (pre_p, internal_pre);
14987 }
14988
14989 /* The result of gimplifying *EXPR_P is going to be the last few
14990 statements in *PRE_P and *POST_P. Add location information
14991 to all the statements that were added by the gimplification
14992 helpers. */
14993 if (!gimple_seq_empty_p (*pre_p))
14994 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
14995
14996 if (!gimple_seq_empty_p (*post_p))
14997 annotate_all_with_location_after (*post_p, post_last_gsi,
14998 input_location);
14999
15000 goto out;
15001 }
15002
15003 #ifdef ENABLE_GIMPLE_CHECKING
15004 if (*expr_p)
15005 {
15006 enum tree_code code = TREE_CODE (*expr_p);
15007 /* These expressions should already be in gimple IR form. */
15008 gcc_assert (code != MODIFY_EXPR
15009 && code != ASM_EXPR
15010 && code != BIND_EXPR
15011 && code != CATCH_EXPR
15012 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
15013 && code != EH_FILTER_EXPR
15014 && code != GOTO_EXPR
15015 && code != LABEL_EXPR
15016 && code != LOOP_EXPR
15017 && code != SWITCH_EXPR
15018 && code != TRY_FINALLY_EXPR
15019 && code != EH_ELSE_EXPR
15020 && code != OACC_PARALLEL
15021 && code != OACC_KERNELS
15022 && code != OACC_SERIAL
15023 && code != OACC_DATA
15024 && code != OACC_HOST_DATA
15025 && code != OACC_DECLARE
15026 && code != OACC_UPDATE
15027 && code != OACC_ENTER_DATA
15028 && code != OACC_EXIT_DATA
15029 && code != OACC_CACHE
15030 && code != OMP_CRITICAL
15031 && code != OMP_FOR
15032 && code != OACC_LOOP
15033 && code != OMP_MASTER
15034 && code != OMP_TASKGROUP
15035 && code != OMP_ORDERED
15036 && code != OMP_PARALLEL
15037 && code != OMP_SCAN
15038 && code != OMP_SECTIONS
15039 && code != OMP_SECTION
15040 && code != OMP_SINGLE);
15041 }
15042 #endif
15043
15044 /* Otherwise we're gimplifying a subexpression, so the resulting
15045 value is interesting. If it's a valid operand that matches
15046 GIMPLE_TEST_F, we're done. Unless we are handling some
15047 post-effects internally; if that's the case, we need to copy into
15048 a temporary before adding the post-effects to POST_P. */
15049 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
15050 goto out;
15051
15052 /* Otherwise, we need to create a new temporary for the gimplified
15053 expression. */
15054
15055 /* We can't return an lvalue if we have an internal postqueue. The
15056 object the lvalue refers to would (probably) be modified by the
15057 postqueue; we need to copy the value out first, which means an
15058 rvalue. */
15059 if ((fallback & fb_lvalue)
15060 && gimple_seq_empty_p (internal_post)
15061 && is_gimple_addressable (*expr_p))
15062 {
15063 /* An lvalue will do. Take the address of the expression, store it
15064 in a temporary, and replace the expression with an INDIRECT_REF of
15065 that temporary. */
15066 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
15067 unsigned int ref_align = get_object_alignment (*expr_p);
15068 tree ref_type = TREE_TYPE (*expr_p);
15069 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
15070 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
15071 if (TYPE_ALIGN (ref_type) != ref_align)
15072 ref_type = build_aligned_type (ref_type, ref_align);
15073 *expr_p = build2 (MEM_REF, ref_type,
15074 tmp, build_zero_cst (ref_alias_type));
15075 }
15076 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
15077 {
15078 /* An rvalue will do. Assign the gimplified expression into a
15079 new temporary TMP and replace the original expression with
15080 TMP. First, make sure that the expression has a type so that
15081 it can be assigned into a temporary. */
15082 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
15083 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
15084 }
15085 else
15086 {
15087 #ifdef ENABLE_GIMPLE_CHECKING
15088 if (!(fallback & fb_mayfail))
15089 {
15090 fprintf (stderr, "gimplification failed:\n");
15091 print_generic_expr (stderr, *expr_p);
15092 debug_tree (*expr_p);
15093 internal_error ("gimplification failed");
15094 }
15095 #endif
15096 gcc_assert (fallback & fb_mayfail);
15097
15098 /* If this is an asm statement, and the user asked for the
15099 impossible, don't die. Fail and let gimplify_asm_expr
15100 issue an error. */
15101 ret = GS_ERROR;
15102 goto out;
15103 }
15104
15105 /* Make sure the temporary matches our predicate. */
15106 gcc_assert ((*gimple_test_f) (*expr_p));
15107
15108 if (!gimple_seq_empty_p (internal_post))
15109 {
15110 annotate_all_with_location (internal_post, input_location);
15111 gimplify_seq_add_seq (pre_p, internal_post);
15112 }
15113
15114 out:
15115 input_location = saved_location;
15116 return ret;
15117 }
15118
15119 /* Like gimplify_expr but make sure the gimplified result is not itself
15120 a SSA name (but a decl if it were). Temporaries required by
15121 evaluating *EXPR_P may be still SSA names. */
15122
15123 static enum gimplify_status
gimplify_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p,bool (* gimple_test_f)(tree),fallback_t fallback,bool allow_ssa)15124 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
15125 bool (*gimple_test_f) (tree), fallback_t fallback,
15126 bool allow_ssa)
15127 {
15128 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
15129 gimple_test_f, fallback);
15130 if (! allow_ssa
15131 && TREE_CODE (*expr_p) == SSA_NAME)
15132 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
15133 return ret;
15134 }
15135
15136 /* Look through TYPE for variable-sized objects and gimplify each such
15137 size that we find. Add to LIST_P any statements generated. */
15138
15139 void
gimplify_type_sizes(tree type,gimple_seq * list_p)15140 gimplify_type_sizes (tree type, gimple_seq *list_p)
15141 {
15142 tree field, t;
15143
15144 if (type == NULL || type == error_mark_node)
15145 return;
15146
15147 /* We first do the main variant, then copy into any other variants. */
15148 type = TYPE_MAIN_VARIANT (type);
15149
15150 /* Avoid infinite recursion. */
15151 if (TYPE_SIZES_GIMPLIFIED (type))
15152 return;
15153
15154 TYPE_SIZES_GIMPLIFIED (type) = 1;
15155
15156 switch (TREE_CODE (type))
15157 {
15158 case INTEGER_TYPE:
15159 case ENUMERAL_TYPE:
15160 case BOOLEAN_TYPE:
15161 case REAL_TYPE:
15162 case FIXED_POINT_TYPE:
15163 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
15164 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
15165
15166 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
15167 {
15168 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
15169 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
15170 }
15171 break;
15172
15173 case ARRAY_TYPE:
15174 /* These types may not have declarations, so handle them here. */
15175 gimplify_type_sizes (TREE_TYPE (type), list_p);
15176 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
15177 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
15178 with assigned stack slots, for -O1+ -g they should be tracked
15179 by VTA. */
15180 if (!(TYPE_NAME (type)
15181 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
15182 && DECL_IGNORED_P (TYPE_NAME (type)))
15183 && TYPE_DOMAIN (type)
15184 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
15185 {
15186 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
15187 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
15188 DECL_IGNORED_P (t) = 0;
15189 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
15190 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
15191 DECL_IGNORED_P (t) = 0;
15192 }
15193 break;
15194
15195 case RECORD_TYPE:
15196 case UNION_TYPE:
15197 case QUAL_UNION_TYPE:
15198 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
15199 if (TREE_CODE (field) == FIELD_DECL)
15200 {
15201 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
15202 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
15203 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
15204 gimplify_type_sizes (TREE_TYPE (field), list_p);
15205 }
15206 break;
15207
15208 case POINTER_TYPE:
15209 case REFERENCE_TYPE:
15210 /* We used to recurse on the pointed-to type here, which turned out to
15211 be incorrect because its definition might refer to variables not
15212 yet initialized at this point if a forward declaration is involved.
15213
15214 It was actually useful for anonymous pointed-to types to ensure
15215 that the sizes evaluation dominates every possible later use of the
15216 values. Restricting to such types here would be safe since there
15217 is no possible forward declaration around, but would introduce an
15218 undesirable middle-end semantic to anonymity. We then defer to
15219 front-ends the responsibility of ensuring that the sizes are
15220 evaluated both early and late enough, e.g. by attaching artificial
15221 type declarations to the tree. */
15222 break;
15223
15224 default:
15225 break;
15226 }
15227
15228 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
15229 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
15230
15231 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
15232 {
15233 TYPE_SIZE (t) = TYPE_SIZE (type);
15234 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
15235 TYPE_SIZES_GIMPLIFIED (t) = 1;
15236 }
15237 }
15238
15239 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
15240 a size or position, has had all of its SAVE_EXPRs evaluated.
15241 We add any required statements to *STMT_P. */
15242
15243 void
gimplify_one_sizepos(tree * expr_p,gimple_seq * stmt_p)15244 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
15245 {
15246 tree expr = *expr_p;
15247
15248 /* We don't do anything if the value isn't there, is constant, or contains
15249 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
15250 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
15251 will want to replace it with a new variable, but that will cause problems
15252 if this type is from outside the function. It's OK to have that here. */
15253 if (expr == NULL_TREE
15254 || is_gimple_constant (expr)
15255 || TREE_CODE (expr) == VAR_DECL
15256 || CONTAINS_PLACEHOLDER_P (expr))
15257 return;
15258
15259 *expr_p = unshare_expr (expr);
15260
15261 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
15262 if the def vanishes. */
15263 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
15264
15265 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
15266 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
15267 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
15268 if (is_gimple_constant (*expr_p))
15269 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
15270 }
15271
15272 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
15273 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
15274 is true, also gimplify the parameters. */
15275
15276 gbind *
gimplify_body(tree fndecl,bool do_parms)15277 gimplify_body (tree fndecl, bool do_parms)
15278 {
15279 location_t saved_location = input_location;
15280 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
15281 gimple *outer_stmt;
15282 gbind *outer_bind;
15283
15284 timevar_push (TV_TREE_GIMPLIFY);
15285
15286 init_tree_ssa (cfun);
15287
15288 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
15289 gimplification. */
15290 default_rtl_profile ();
15291
15292 gcc_assert (gimplify_ctxp == NULL);
15293 push_gimplify_context (true);
15294
15295 if (flag_openacc || flag_openmp)
15296 {
15297 gcc_assert (gimplify_omp_ctxp == NULL);
15298 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
15299 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
15300 }
15301
15302 /* Unshare most shared trees in the body and in that of any nested functions.
15303 It would seem we don't have to do this for nested functions because
15304 they are supposed to be output and then the outer function gimplified
15305 first, but the g++ front end doesn't always do it that way. */
15306 unshare_body (fndecl);
15307 unvisit_body (fndecl);
15308
15309 /* Make sure input_location isn't set to something weird. */
15310 input_location = DECL_SOURCE_LOCATION (fndecl);
15311
15312 /* Resolve callee-copies. This has to be done before processing
15313 the body so that DECL_VALUE_EXPR gets processed correctly. */
15314 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
15315
15316 /* Gimplify the function's body. */
15317 seq = NULL;
15318 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
15319 outer_stmt = gimple_seq_first_nondebug_stmt (seq);
15320 if (!outer_stmt)
15321 {
15322 outer_stmt = gimple_build_nop ();
15323 gimplify_seq_add_stmt (&seq, outer_stmt);
15324 }
15325
15326 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
15327 not the case, wrap everything in a GIMPLE_BIND to make it so. */
15328 if (gimple_code (outer_stmt) == GIMPLE_BIND
15329 && (gimple_seq_first_nondebug_stmt (seq)
15330 == gimple_seq_last_nondebug_stmt (seq)))
15331 {
15332 outer_bind = as_a <gbind *> (outer_stmt);
15333 if (gimple_seq_first_stmt (seq) != outer_stmt
15334 || gimple_seq_last_stmt (seq) != outer_stmt)
15335 {
15336 /* If there are debug stmts before or after outer_stmt, move them
15337 inside of outer_bind body. */
15338 gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
15339 gimple_seq second_seq = NULL;
15340 if (gimple_seq_first_stmt (seq) != outer_stmt
15341 && gimple_seq_last_stmt (seq) != outer_stmt)
15342 {
15343 second_seq = gsi_split_seq_after (gsi);
15344 gsi_remove (&gsi, false);
15345 }
15346 else if (gimple_seq_first_stmt (seq) != outer_stmt)
15347 gsi_remove (&gsi, false);
15348 else
15349 {
15350 gsi_remove (&gsi, false);
15351 second_seq = seq;
15352 seq = NULL;
15353 }
15354 gimple_seq_add_seq_without_update (&seq,
15355 gimple_bind_body (outer_bind));
15356 gimple_seq_add_seq_without_update (&seq, second_seq);
15357 gimple_bind_set_body (outer_bind, seq);
15358 }
15359 }
15360 else
15361 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
15362
15363 DECL_SAVED_TREE (fndecl) = NULL_TREE;
15364
15365 /* If we had callee-copies statements, insert them at the beginning
15366 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
15367 if (!gimple_seq_empty_p (parm_stmts))
15368 {
15369 tree parm;
15370
15371 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
15372 if (parm_cleanup)
15373 {
15374 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
15375 GIMPLE_TRY_FINALLY);
15376 parm_stmts = NULL;
15377 gimple_seq_add_stmt (&parm_stmts, g);
15378 }
15379 gimple_bind_set_body (outer_bind, parm_stmts);
15380
15381 for (parm = DECL_ARGUMENTS (current_function_decl);
15382 parm; parm = DECL_CHAIN (parm))
15383 if (DECL_HAS_VALUE_EXPR_P (parm))
15384 {
15385 DECL_HAS_VALUE_EXPR_P (parm) = 0;
15386 DECL_IGNORED_P (parm) = 0;
15387 }
15388 }
15389
15390 if ((flag_openacc || flag_openmp || flag_openmp_simd)
15391 && gimplify_omp_ctxp)
15392 {
15393 delete_omp_context (gimplify_omp_ctxp);
15394 gimplify_omp_ctxp = NULL;
15395 }
15396
15397 pop_gimplify_context (outer_bind);
15398 gcc_assert (gimplify_ctxp == NULL);
15399
15400 if (flag_checking && !seen_error ())
15401 verify_gimple_in_seq (gimple_bind_body (outer_bind));
15402
15403 timevar_pop (TV_TREE_GIMPLIFY);
15404 input_location = saved_location;
15405
15406 return outer_bind;
15407 }
15408
15409 typedef char *char_p; /* For DEF_VEC_P. */
15410
15411 /* Return whether we should exclude FNDECL from instrumentation. */
15412
15413 static bool
flag_instrument_functions_exclude_p(tree fndecl)15414 flag_instrument_functions_exclude_p (tree fndecl)
15415 {
15416 vec<char_p> *v;
15417
15418 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
15419 if (v && v->length () > 0)
15420 {
15421 const char *name;
15422 int i;
15423 char *s;
15424
15425 name = lang_hooks.decl_printable_name (fndecl, 1);
15426 FOR_EACH_VEC_ELT (*v, i, s)
15427 if (strstr (name, s) != NULL)
15428 return true;
15429 }
15430
15431 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
15432 if (v && v->length () > 0)
15433 {
15434 const char *name;
15435 int i;
15436 char *s;
15437
15438 name = DECL_SOURCE_FILE (fndecl);
15439 FOR_EACH_VEC_ELT (*v, i, s)
15440 if (strstr (name, s) != NULL)
15441 return true;
15442 }
15443
15444 return false;
15445 }
15446
15447 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
15448 node for the function we want to gimplify.
15449
15450 Return the sequence of GIMPLE statements corresponding to the body
15451 of FNDECL. */
15452
15453 void
gimplify_function_tree(tree fndecl)15454 gimplify_function_tree (tree fndecl)
15455 {
15456 gimple_seq seq;
15457 gbind *bind;
15458
15459 gcc_assert (!gimple_body (fndecl));
15460
15461 if (DECL_STRUCT_FUNCTION (fndecl))
15462 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
15463 else
15464 push_struct_function (fndecl);
15465
15466 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
15467 if necessary. */
15468 cfun->curr_properties |= PROP_gimple_lva;
15469
15470 if (asan_sanitize_use_after_scope ())
15471 asan_poisoned_variables = new hash_set<tree> ();
15472 bind = gimplify_body (fndecl, true);
15473 if (asan_poisoned_variables)
15474 {
15475 delete asan_poisoned_variables;
15476 asan_poisoned_variables = NULL;
15477 }
15478
15479 /* The tree body of the function is no longer needed, replace it
15480 with the new GIMPLE body. */
15481 seq = NULL;
15482 gimple_seq_add_stmt (&seq, bind);
15483 gimple_set_body (fndecl, seq);
15484
15485 /* If we're instrumenting function entry/exit, then prepend the call to
15486 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
15487 catch the exit hook. */
15488 /* ??? Add some way to ignore exceptions for this TFE. */
15489 if (flag_instrument_function_entry_exit
15490 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
15491 /* Do not instrument extern inline functions. */
15492 && !(DECL_DECLARED_INLINE_P (fndecl)
15493 && DECL_EXTERNAL (fndecl)
15494 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
15495 && !flag_instrument_functions_exclude_p (fndecl))
15496 {
15497 tree x;
15498 gbind *new_bind;
15499 gimple *tf;
15500 gimple_seq cleanup = NULL, body = NULL;
15501 tree tmp_var, this_fn_addr;
15502 gcall *call;
15503
15504 /* The instrumentation hooks aren't going to call the instrumented
15505 function and the address they receive is expected to be matchable
15506 against symbol addresses. Make sure we don't create a trampoline,
15507 in case the current function is nested. */
15508 this_fn_addr = build_fold_addr_expr (current_function_decl);
15509 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
15510
15511 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
15512 call = gimple_build_call (x, 1, integer_zero_node);
15513 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
15514 gimple_call_set_lhs (call, tmp_var);
15515 gimplify_seq_add_stmt (&cleanup, call);
15516 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
15517 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
15518 gimplify_seq_add_stmt (&cleanup, call);
15519 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
15520
15521 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
15522 call = gimple_build_call (x, 1, integer_zero_node);
15523 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
15524 gimple_call_set_lhs (call, tmp_var);
15525 gimplify_seq_add_stmt (&body, call);
15526 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
15527 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
15528 gimplify_seq_add_stmt (&body, call);
15529 gimplify_seq_add_stmt (&body, tf);
15530 new_bind = gimple_build_bind (NULL, body, NULL);
15531
15532 /* Replace the current function body with the body
15533 wrapped in the try/finally TF. */
15534 seq = NULL;
15535 gimple_seq_add_stmt (&seq, new_bind);
15536 gimple_set_body (fndecl, seq);
15537 bind = new_bind;
15538 }
15539
15540 if (sanitize_flags_p (SANITIZE_THREAD)
15541 && param_tsan_instrument_func_entry_exit)
15542 {
15543 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
15544 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
15545 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
15546 /* Replace the current function body with the body
15547 wrapped in the try/finally TF. */
15548 seq = NULL;
15549 gimple_seq_add_stmt (&seq, new_bind);
15550 gimple_set_body (fndecl, seq);
15551 }
15552
15553 DECL_SAVED_TREE (fndecl) = NULL_TREE;
15554 cfun->curr_properties |= PROP_gimple_any;
15555
15556 pop_cfun ();
15557
15558 dump_function (TDI_gimple, fndecl);
15559 }
15560
15561 /* Return a dummy expression of type TYPE in order to keep going after an
15562 error. */
15563
15564 static tree
dummy_object(tree type)15565 dummy_object (tree type)
15566 {
15567 tree t = build_int_cst (build_pointer_type (type), 0);
15568 return build2 (MEM_REF, type, t, t);
15569 }
15570
15571 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
15572 builtin function, but a very special sort of operator. */
15573
15574 enum gimplify_status
gimplify_va_arg_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p ATTRIBUTE_UNUSED)15575 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
15576 gimple_seq *post_p ATTRIBUTE_UNUSED)
15577 {
15578 tree promoted_type, have_va_type;
15579 tree valist = TREE_OPERAND (*expr_p, 0);
15580 tree type = TREE_TYPE (*expr_p);
15581 tree t, tag, aptag;
15582 location_t loc = EXPR_LOCATION (*expr_p);
15583
15584 /* Verify that valist is of the proper type. */
15585 have_va_type = TREE_TYPE (valist);
15586 if (have_va_type == error_mark_node)
15587 return GS_ERROR;
15588 have_va_type = targetm.canonical_va_list_type (have_va_type);
15589 if (have_va_type == NULL_TREE
15590 && POINTER_TYPE_P (TREE_TYPE (valist)))
15591 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
15592 have_va_type
15593 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
15594 gcc_assert (have_va_type != NULL_TREE);
15595
15596 /* Generate a diagnostic for requesting data of a type that cannot
15597 be passed through `...' due to type promotion at the call site. */
15598 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
15599 != type)
15600 {
15601 static bool gave_help;
15602 bool warned;
15603 /* Use the expansion point to handle cases such as passing bool (defined
15604 in a system header) through `...'. */
15605 location_t xloc
15606 = expansion_point_location_if_in_system_header (loc);
15607
15608 /* Unfortunately, this is merely undefined, rather than a constraint
15609 violation, so we cannot make this an error. If this call is never
15610 executed, the program is still strictly conforming. */
15611 auto_diagnostic_group d;
15612 warned = warning_at (xloc, 0,
15613 "%qT is promoted to %qT when passed through %<...%>",
15614 type, promoted_type);
15615 if (!gave_help && warned)
15616 {
15617 gave_help = true;
15618 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
15619 promoted_type, type);
15620 }
15621
15622 /* We can, however, treat "undefined" any way we please.
15623 Call abort to encourage the user to fix the program. */
15624 if (warned)
15625 inform (xloc, "if this code is reached, the program will abort");
15626 /* Before the abort, allow the evaluation of the va_list
15627 expression to exit or longjmp. */
15628 gimplify_and_add (valist, pre_p);
15629 t = build_call_expr_loc (loc,
15630 builtin_decl_implicit (BUILT_IN_TRAP), 0);
15631 gimplify_and_add (t, pre_p);
15632
15633 /* This is dead code, but go ahead and finish so that the
15634 mode of the result comes out right. */
15635 *expr_p = dummy_object (type);
15636 return GS_ALL_DONE;
15637 }
15638
15639 tag = build_int_cst (build_pointer_type (type), 0);
15640 aptag = build_int_cst (TREE_TYPE (valist), 0);
15641
15642 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
15643 valist, tag, aptag);
15644
15645 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
15646 needs to be expanded. */
15647 cfun->curr_properties &= ~PROP_gimple_lva;
15648
15649 return GS_OK;
15650 }
15651
15652 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
15653
15654 DST/SRC are the destination and source respectively. You can pass
15655 ungimplified trees in DST or SRC, in which case they will be
15656 converted to a gimple operand if necessary.
15657
15658 This function returns the newly created GIMPLE_ASSIGN tuple. */
15659
15660 gimple *
gimplify_assign(tree dst,tree src,gimple_seq * seq_p)15661 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
15662 {
15663 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
15664 gimplify_and_add (t, seq_p);
15665 ggc_free (t);
15666 return gimple_seq_last_stmt (*seq_p);
15667 }
15668
15669 inline hashval_t
hash(const elt_t * p)15670 gimplify_hasher::hash (const elt_t *p)
15671 {
15672 tree t = p->val;
15673 return iterative_hash_expr (t, 0);
15674 }
15675
15676 inline bool
equal(const elt_t * p1,const elt_t * p2)15677 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
15678 {
15679 tree t1 = p1->val;
15680 tree t2 = p2->val;
15681 enum tree_code code = TREE_CODE (t1);
15682
15683 if (TREE_CODE (t2) != code
15684 || TREE_TYPE (t1) != TREE_TYPE (t2))
15685 return false;
15686
15687 if (!operand_equal_p (t1, t2, 0))
15688 return false;
15689
15690 /* Only allow them to compare equal if they also hash equal; otherwise
15691 results are nondeterminate, and we fail bootstrap comparison. */
15692 gcc_checking_assert (hash (p1) == hash (p2));
15693
15694 return true;
15695 }
15696