typeck.c (cp_truthvalue_conversion): Add tsubst_flags_t parameter and use it in calls...
[official-gcc.git] / gcc / gimplify.c
blob0bbd475b3dd1b37f3333b8268661d487c60d64fb
1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2019 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>.
7 This file is part of GCC.
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.
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.
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/>. */
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"
71 /* Hash set of poisoned variables in a bind expr. */
72 static hash_set<tree> *asan_poisoned_variables = NULL;
74 enum gimplify_omp_var_data
76 GOVD_SEEN = 0x000001,
77 GOVD_EXPLICIT = 0x000002,
78 GOVD_SHARED = 0x000004,
79 GOVD_PRIVATE = 0x000008,
80 GOVD_FIRSTPRIVATE = 0x000010,
81 GOVD_LASTPRIVATE = 0x000020,
82 GOVD_REDUCTION = 0x000040,
83 GOVD_LOCAL = 0x00080,
84 GOVD_MAP = 0x000100,
85 GOVD_DEBUG_PRIVATE = 0x000200,
86 GOVD_PRIVATE_OUTER_REF = 0x000400,
87 GOVD_LINEAR = 0x000800,
88 GOVD_ALIGNED = 0x001000,
90 /* Flag for GOVD_MAP: don't copy back. */
91 GOVD_MAP_TO_ONLY = 0x002000,
93 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
94 GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 0x004000,
96 GOVD_MAP_0LEN_ARRAY = 0x008000,
98 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
99 GOVD_MAP_ALWAYS_TO = 0x010000,
101 /* Flag for shared vars that are or might be stored to in the region. */
102 GOVD_WRITTEN = 0x020000,
104 /* Flag for GOVD_MAP, if it is a forced mapping. */
105 GOVD_MAP_FORCE = 0x040000,
107 /* Flag for GOVD_MAP: must be present already. */
108 GOVD_MAP_FORCE_PRESENT = 0x080000,
110 /* Flag for GOVD_MAP: only allocate. */
111 GOVD_MAP_ALLOC_ONLY = 0x100000,
113 /* Flag for GOVD_MAP: only copy back. */
114 GOVD_MAP_FROM_ONLY = 0x200000,
116 GOVD_NONTEMPORAL = 0x400000,
118 /* Flag for GOVD_LASTPRIVATE: conditional modifier. */
119 GOVD_LASTPRIVATE_CONDITIONAL = 0x800000,
121 GOVD_CONDTEMP = 0x1000000,
123 /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause. */
124 GOVD_REDUCTION_INSCAN = 0x2000000,
126 GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
127 | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
128 | GOVD_LOCAL)
132 enum omp_region_type
134 ORT_WORKSHARE = 0x00,
135 ORT_TASKGROUP = 0x01,
136 ORT_SIMD = 0x04,
138 ORT_PARALLEL = 0x08,
139 ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1,
141 ORT_TASK = 0x10,
142 ORT_UNTIED_TASK = ORT_TASK | 1,
143 ORT_TASKLOOP = ORT_TASK | 2,
144 ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2,
146 ORT_TEAMS = 0x20,
147 ORT_COMBINED_TEAMS = ORT_TEAMS | 1,
148 ORT_HOST_TEAMS = ORT_TEAMS | 2,
149 ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2,
151 /* Data region. */
152 ORT_TARGET_DATA = 0x40,
154 /* Data region with offloading. */
155 ORT_TARGET = 0x80,
156 ORT_COMBINED_TARGET = ORT_TARGET | 1,
157 ORT_IMPLICIT_TARGET = ORT_TARGET | 2,
159 /* OpenACC variants. */
160 ORT_ACC = 0x100, /* A generic OpenACC region. */
161 ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */
162 ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */
163 ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 2, /* Kernels construct. */
164 ORT_ACC_SERIAL = ORT_ACC | ORT_TARGET | 4, /* Serial construct. */
165 ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2, /* Host data. */
167 /* Dummy OpenMP region, used to disable expansion of
168 DECL_VALUE_EXPRs in taskloop pre body. */
169 ORT_NONE = 0x200
172 /* Gimplify hashtable helper. */
174 struct gimplify_hasher : free_ptr_hash <elt_t>
176 static inline hashval_t hash (const elt_t *);
177 static inline bool equal (const elt_t *, const elt_t *);
180 struct gimplify_ctx
182 struct gimplify_ctx *prev_context;
184 vec<gbind *> bind_expr_stack;
185 tree temps;
186 gimple_seq conditional_cleanups;
187 tree exit_label;
188 tree return_temp;
190 vec<tree> case_labels;
191 hash_set<tree> *live_switch_vars;
192 /* The formal temporary table. Should this be persistent? */
193 hash_table<gimplify_hasher> *temp_htab;
195 int conditions;
196 unsigned into_ssa : 1;
197 unsigned allow_rhs_cond_expr : 1;
198 unsigned in_cleanup_point_expr : 1;
199 unsigned keep_stack : 1;
200 unsigned save_stack : 1;
201 unsigned in_switch_expr : 1;
204 enum gimplify_defaultmap_kind
206 GDMK_SCALAR,
207 GDMK_AGGREGATE,
208 GDMK_ALLOCATABLE,
209 GDMK_POINTER
212 struct gimplify_omp_ctx
214 struct gimplify_omp_ctx *outer_context;
215 splay_tree variables;
216 hash_set<tree> *privatized_types;
217 tree clauses;
218 /* Iteration variables in an OMP_FOR. */
219 vec<tree> loop_iter_var;
220 location_t location;
221 enum omp_clause_default_kind default_kind;
222 enum omp_region_type region_type;
223 enum tree_code code;
224 bool combined_loop;
225 bool distribute;
226 bool target_firstprivatize_array_bases;
227 bool add_safelen1;
228 bool order_concurrent;
229 int defaultmap[4];
232 static struct gimplify_ctx *gimplify_ctxp;
233 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
234 static bool in_omp_construct;
236 /* Forward declaration. */
237 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
238 static hash_map<tree, tree> *oacc_declare_returns;
239 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
240 bool (*) (tree), fallback_t, bool);
242 /* Shorter alias name for the above function for use in gimplify.c
243 only. */
245 static inline void
246 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
248 gimple_seq_add_stmt_without_update (seq_p, gs);
251 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
252 NULL, a new sequence is allocated. This function is
253 similar to gimple_seq_add_seq, but does not scan the operands.
254 During gimplification, we need to manipulate statement sequences
255 before the def/use vectors have been constructed. */
257 static void
258 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
260 gimple_stmt_iterator si;
262 if (src == NULL)
263 return;
265 si = gsi_last (*dst_p);
266 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
270 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
271 and popping gimplify contexts. */
273 static struct gimplify_ctx *ctx_pool = NULL;
275 /* Return a gimplify context struct from the pool. */
277 static inline struct gimplify_ctx *
278 ctx_alloc (void)
280 struct gimplify_ctx * c = ctx_pool;
282 if (c)
283 ctx_pool = c->prev_context;
284 else
285 c = XNEW (struct gimplify_ctx);
287 memset (c, '\0', sizeof (*c));
288 return c;
291 /* Put gimplify context C back into the pool. */
293 static inline void
294 ctx_free (struct gimplify_ctx *c)
296 c->prev_context = ctx_pool;
297 ctx_pool = c;
300 /* Free allocated ctx stack memory. */
302 void
303 free_gimplify_stack (void)
305 struct gimplify_ctx *c;
307 while ((c = ctx_pool))
309 ctx_pool = c->prev_context;
310 free (c);
315 /* Set up a context for the gimplifier. */
317 void
318 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
320 struct gimplify_ctx *c = ctx_alloc ();
322 c->prev_context = gimplify_ctxp;
323 gimplify_ctxp = c;
324 gimplify_ctxp->into_ssa = in_ssa;
325 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
328 /* Tear down a context for the gimplifier. If BODY is non-null, then
329 put the temporaries into the outer BIND_EXPR. Otherwise, put them
330 in the local_decls.
332 BODY is not a sequence, but the first tuple in a sequence. */
334 void
335 pop_gimplify_context (gimple *body)
337 struct gimplify_ctx *c = gimplify_ctxp;
339 gcc_assert (c
340 && (!c->bind_expr_stack.exists ()
341 || c->bind_expr_stack.is_empty ()));
342 c->bind_expr_stack.release ();
343 gimplify_ctxp = c->prev_context;
345 if (body)
346 declare_vars (c->temps, body, false);
347 else
348 record_vars (c->temps);
350 delete c->temp_htab;
351 c->temp_htab = NULL;
352 ctx_free (c);
355 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
357 static void
358 gimple_push_bind_expr (gbind *bind_stmt)
360 gimplify_ctxp->bind_expr_stack.reserve (8);
361 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
364 /* Pop the first element off the stack of bindings. */
366 static void
367 gimple_pop_bind_expr (void)
369 gimplify_ctxp->bind_expr_stack.pop ();
372 /* Return the first element of the stack of bindings. */
374 gbind *
375 gimple_current_bind_expr (void)
377 return gimplify_ctxp->bind_expr_stack.last ();
380 /* Return the stack of bindings created during gimplification. */
382 vec<gbind *>
383 gimple_bind_expr_stack (void)
385 return gimplify_ctxp->bind_expr_stack;
388 /* Return true iff there is a COND_EXPR between us and the innermost
389 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
391 static bool
392 gimple_conditional_context (void)
394 return gimplify_ctxp->conditions > 0;
397 /* Note that we've entered a COND_EXPR. */
399 static void
400 gimple_push_condition (void)
402 #ifdef ENABLE_GIMPLE_CHECKING
403 if (gimplify_ctxp->conditions == 0)
404 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
405 #endif
406 ++(gimplify_ctxp->conditions);
409 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
410 now, add any conditional cleanups we've seen to the prequeue. */
412 static void
413 gimple_pop_condition (gimple_seq *pre_p)
415 int conds = --(gimplify_ctxp->conditions);
417 gcc_assert (conds >= 0);
418 if (conds == 0)
420 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
421 gimplify_ctxp->conditional_cleanups = NULL;
425 /* A stable comparison routine for use with splay trees and DECLs. */
427 static int
428 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
430 tree a = (tree) xa;
431 tree b = (tree) xb;
433 return DECL_UID (a) - DECL_UID (b);
436 /* Create a new omp construct that deals with variable remapping. */
438 static struct gimplify_omp_ctx *
439 new_omp_context (enum omp_region_type region_type)
441 struct gimplify_omp_ctx *c;
443 c = XCNEW (struct gimplify_omp_ctx);
444 c->outer_context = gimplify_omp_ctxp;
445 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
446 c->privatized_types = new hash_set<tree>;
447 c->location = input_location;
448 c->region_type = region_type;
449 if ((region_type & ORT_TASK) == 0)
450 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
451 else
452 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
453 c->defaultmap[GDMK_SCALAR] = GOVD_MAP;
454 c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
455 c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
456 c->defaultmap[GDMK_POINTER] = GOVD_MAP;
458 return c;
461 /* Destroy an omp construct that deals with variable remapping. */
463 static void
464 delete_omp_context (struct gimplify_omp_ctx *c)
466 splay_tree_delete (c->variables);
467 delete c->privatized_types;
468 c->loop_iter_var.release ();
469 XDELETE (c);
472 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
473 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
475 /* Both gimplify the statement T and append it to *SEQ_P. This function
476 behaves exactly as gimplify_stmt, but you don't have to pass T as a
477 reference. */
479 void
480 gimplify_and_add (tree t, gimple_seq *seq_p)
482 gimplify_stmt (&t, seq_p);
485 /* Gimplify statement T into sequence *SEQ_P, and return the first
486 tuple in the sequence of generated tuples for this statement.
487 Return NULL if gimplifying T produced no tuples. */
489 static gimple *
490 gimplify_and_return_first (tree t, gimple_seq *seq_p)
492 gimple_stmt_iterator last = gsi_last (*seq_p);
494 gimplify_and_add (t, seq_p);
496 if (!gsi_end_p (last))
498 gsi_next (&last);
499 return gsi_stmt (last);
501 else
502 return gimple_seq_first_stmt (*seq_p);
505 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
506 LHS, or for a call argument. */
508 static bool
509 is_gimple_mem_rhs (tree t)
511 /* If we're dealing with a renamable type, either source or dest must be
512 a renamed variable. */
513 if (is_gimple_reg_type (TREE_TYPE (t)))
514 return is_gimple_val (t);
515 else
516 return is_gimple_val (t) || is_gimple_lvalue (t);
519 /* Return true if T is a CALL_EXPR or an expression that can be
520 assigned to a temporary. Note that this predicate should only be
521 used during gimplification. See the rationale for this in
522 gimplify_modify_expr. */
524 static bool
525 is_gimple_reg_rhs_or_call (tree t)
527 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
528 || TREE_CODE (t) == CALL_EXPR);
531 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
532 this predicate should only be used during gimplification. See the
533 rationale for this in gimplify_modify_expr. */
535 static bool
536 is_gimple_mem_rhs_or_call (tree t)
538 /* If we're dealing with a renamable type, either source or dest must be
539 a renamed variable. */
540 if (is_gimple_reg_type (TREE_TYPE (t)))
541 return is_gimple_val (t);
542 else
543 return (is_gimple_val (t)
544 || is_gimple_lvalue (t)
545 || TREE_CLOBBER_P (t)
546 || TREE_CODE (t) == CALL_EXPR);
549 /* Create a temporary with a name derived from VAL. Subroutine of
550 lookup_tmp_var; nobody else should call this function. */
552 static inline tree
553 create_tmp_from_val (tree val)
555 /* Drop all qualifiers and address-space information from the value type. */
556 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
557 tree var = create_tmp_var (type, get_name (val));
558 if (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
559 || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
560 DECL_GIMPLE_REG_P (var) = 1;
561 return var;
564 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
565 an existing expression temporary. */
567 static tree
568 lookup_tmp_var (tree val, bool is_formal)
570 tree ret;
572 /* If not optimizing, never really reuse a temporary. local-alloc
573 won't allocate any variable that is used in more than one basic
574 block, which means it will go into memory, causing much extra
575 work in reload and final and poorer code generation, outweighing
576 the extra memory allocation here. */
577 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
578 ret = create_tmp_from_val (val);
579 else
581 elt_t elt, *elt_p;
582 elt_t **slot;
584 elt.val = val;
585 if (!gimplify_ctxp->temp_htab)
586 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
587 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
588 if (*slot == NULL)
590 elt_p = XNEW (elt_t);
591 elt_p->val = val;
592 elt_p->temp = ret = create_tmp_from_val (val);
593 *slot = elt_p;
595 else
597 elt_p = *slot;
598 ret = elt_p->temp;
602 return ret;
605 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
607 static tree
608 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
609 bool is_formal, bool allow_ssa)
611 tree t, mod;
613 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
614 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
615 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
616 fb_rvalue);
618 if (allow_ssa
619 && gimplify_ctxp->into_ssa
620 && is_gimple_reg_type (TREE_TYPE (val)))
622 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
623 if (! gimple_in_ssa_p (cfun))
625 const char *name = get_name (val);
626 if (name)
627 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
630 else
631 t = lookup_tmp_var (val, is_formal);
633 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
635 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
637 /* gimplify_modify_expr might want to reduce this further. */
638 gimplify_and_add (mod, pre_p);
639 ggc_free (mod);
641 return t;
644 /* Return a formal temporary variable initialized with VAL. PRE_P is as
645 in gimplify_expr. Only use this function if:
647 1) The value of the unfactored expression represented by VAL will not
648 change between the initialization and use of the temporary, and
649 2) The temporary will not be otherwise modified.
651 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
652 and #2 means it is inappropriate for && temps.
654 For other cases, use get_initialized_tmp_var instead. */
656 tree
657 get_formal_tmp_var (tree val, gimple_seq *pre_p)
659 return internal_get_tmp_var (val, pre_p, NULL, true, true);
662 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
663 are as in gimplify_expr. */
665 tree
666 get_initialized_tmp_var (tree val, gimple_seq *pre_p,
667 gimple_seq *post_p /* = NULL */,
668 bool allow_ssa /* = true */)
670 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
673 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
674 generate debug info for them; otherwise don't. */
676 void
677 declare_vars (tree vars, gimple *gs, bool debug_info)
679 tree last = vars;
680 if (last)
682 tree temps, block;
684 gbind *scope = as_a <gbind *> (gs);
686 temps = nreverse (last);
688 block = gimple_bind_block (scope);
689 gcc_assert (!block || TREE_CODE (block) == BLOCK);
690 if (!block || !debug_info)
692 DECL_CHAIN (last) = gimple_bind_vars (scope);
693 gimple_bind_set_vars (scope, temps);
695 else
697 /* We need to attach the nodes both to the BIND_EXPR and to its
698 associated BLOCK for debugging purposes. The key point here
699 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
700 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
701 if (BLOCK_VARS (block))
702 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
703 else
705 gimple_bind_set_vars (scope,
706 chainon (gimple_bind_vars (scope), temps));
707 BLOCK_VARS (block) = temps;
713 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
714 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
715 no such upper bound can be obtained. */
717 static void
718 force_constant_size (tree var)
720 /* The only attempt we make is by querying the maximum size of objects
721 of the variable's type. */
723 HOST_WIDE_INT max_size;
725 gcc_assert (VAR_P (var));
727 max_size = max_int_size_in_bytes (TREE_TYPE (var));
729 gcc_assert (max_size >= 0);
731 DECL_SIZE_UNIT (var)
732 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
733 DECL_SIZE (var)
734 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
737 /* Push the temporary variable TMP into the current binding. */
739 void
740 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
742 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
744 /* Later processing assumes that the object size is constant, which might
745 not be true at this point. Force the use of a constant upper bound in
746 this case. */
747 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
748 force_constant_size (tmp);
750 DECL_CONTEXT (tmp) = fn->decl;
751 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
753 record_vars_into (tmp, fn->decl);
756 /* Push the temporary variable TMP into the current binding. */
758 void
759 gimple_add_tmp_var (tree tmp)
761 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
763 /* Later processing assumes that the object size is constant, which might
764 not be true at this point. Force the use of a constant upper bound in
765 this case. */
766 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
767 force_constant_size (tmp);
769 DECL_CONTEXT (tmp) = current_function_decl;
770 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
772 if (gimplify_ctxp)
774 DECL_CHAIN (tmp) = gimplify_ctxp->temps;
775 gimplify_ctxp->temps = tmp;
777 /* Mark temporaries local within the nearest enclosing parallel. */
778 if (gimplify_omp_ctxp)
780 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
781 int flag = GOVD_LOCAL;
782 while (ctx
783 && (ctx->region_type == ORT_WORKSHARE
784 || ctx->region_type == ORT_TASKGROUP
785 || ctx->region_type == ORT_SIMD
786 || ctx->region_type == ORT_ACC))
788 if (ctx->region_type == ORT_SIMD
789 && TREE_ADDRESSABLE (tmp)
790 && !TREE_STATIC (tmp))
792 if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
793 ctx->add_safelen1 = true;
794 else
795 flag = GOVD_PRIVATE;
796 break;
798 ctx = ctx->outer_context;
800 if (ctx)
801 omp_add_variable (ctx, tmp, flag | GOVD_SEEN);
804 else if (cfun)
805 record_vars (tmp);
806 else
808 gimple_seq body_seq;
810 /* This case is for nested functions. We need to expose the locals
811 they create. */
812 body_seq = gimple_body (current_function_decl);
813 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
819 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
820 nodes that are referenced more than once in GENERIC functions. This is
821 necessary because gimplification (translation into GIMPLE) is performed
822 by modifying tree nodes in-place, so gimplication of a shared node in a
823 first context could generate an invalid GIMPLE form in a second context.
825 This is achieved with a simple mark/copy/unmark algorithm that walks the
826 GENERIC representation top-down, marks nodes with TREE_VISITED the first
827 time it encounters them, duplicates them if they already have TREE_VISITED
828 set, and finally removes the TREE_VISITED marks it has set.
830 The algorithm works only at the function level, i.e. it generates a GENERIC
831 representation of a function with no nodes shared within the function when
832 passed a GENERIC function (except for nodes that are allowed to be shared).
834 At the global level, it is also necessary to unshare tree nodes that are
835 referenced in more than one function, for the same aforementioned reason.
836 This requires some cooperation from the front-end. There are 2 strategies:
838 1. Manual unsharing. The front-end needs to call unshare_expr on every
839 expression that might end up being shared across functions.
841 2. Deep unsharing. This is an extension of regular unsharing. Instead
842 of calling unshare_expr on expressions that might be shared across
843 functions, the front-end pre-marks them with TREE_VISITED. This will
844 ensure that they are unshared on the first reference within functions
845 when the regular unsharing algorithm runs. The counterpart is that
846 this algorithm must look deeper than for manual unsharing, which is
847 specified by LANG_HOOKS_DEEP_UNSHARING.
849 If there are only few specific cases of node sharing across functions, it is
850 probably easier for a front-end to unshare the expressions manually. On the
851 contrary, if the expressions generated at the global level are as widespread
852 as expressions generated within functions, deep unsharing is very likely the
853 way to go. */
855 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
856 These nodes model computations that must be done once. If we were to
857 unshare something like SAVE_EXPR(i++), the gimplification process would
858 create wrong code. However, if DATA is non-null, it must hold a pointer
859 set that is used to unshare the subtrees of these nodes. */
861 static tree
862 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
864 tree t = *tp;
865 enum tree_code code = TREE_CODE (t);
867 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
868 copy their subtrees if we can make sure to do it only once. */
869 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
871 if (data && !((hash_set<tree> *)data)->add (t))
873 else
874 *walk_subtrees = 0;
877 /* Stop at types, decls, constants like copy_tree_r. */
878 else if (TREE_CODE_CLASS (code) == tcc_type
879 || TREE_CODE_CLASS (code) == tcc_declaration
880 || TREE_CODE_CLASS (code) == tcc_constant)
881 *walk_subtrees = 0;
883 /* Cope with the statement expression extension. */
884 else if (code == STATEMENT_LIST)
887 /* Leave the bulk of the work to copy_tree_r itself. */
888 else
889 copy_tree_r (tp, walk_subtrees, NULL);
891 return NULL_TREE;
894 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
895 If *TP has been visited already, then *TP is deeply copied by calling
896 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
898 static tree
899 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
901 tree t = *tp;
902 enum tree_code code = TREE_CODE (t);
904 /* Skip types, decls, and constants. But we do want to look at their
905 types and the bounds of types. Mark them as visited so we properly
906 unmark their subtrees on the unmark pass. If we've already seen them,
907 don't look down further. */
908 if (TREE_CODE_CLASS (code) == tcc_type
909 || TREE_CODE_CLASS (code) == tcc_declaration
910 || TREE_CODE_CLASS (code) == tcc_constant)
912 if (TREE_VISITED (t))
913 *walk_subtrees = 0;
914 else
915 TREE_VISITED (t) = 1;
918 /* If this node has been visited already, unshare it and don't look
919 any deeper. */
920 else if (TREE_VISITED (t))
922 walk_tree (tp, mostly_copy_tree_r, data, NULL);
923 *walk_subtrees = 0;
926 /* Otherwise, mark the node as visited and keep looking. */
927 else
928 TREE_VISITED (t) = 1;
930 return NULL_TREE;
933 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
934 copy_if_shared_r callback unmodified. */
936 static inline void
937 copy_if_shared (tree *tp, void *data)
939 walk_tree (tp, copy_if_shared_r, data, NULL);
942 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
943 any nested functions. */
945 static void
946 unshare_body (tree fndecl)
948 struct cgraph_node *cgn = cgraph_node::get (fndecl);
949 /* If the language requires deep unsharing, we need a pointer set to make
950 sure we don't repeatedly unshare subtrees of unshareable nodes. */
951 hash_set<tree> *visited
952 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
954 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
955 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
956 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
958 delete visited;
960 if (cgn)
961 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
962 unshare_body (cgn->decl);
965 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
966 Subtrees are walked until the first unvisited node is encountered. */
968 static tree
969 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
971 tree t = *tp;
973 /* If this node has been visited, unmark it and keep looking. */
974 if (TREE_VISITED (t))
975 TREE_VISITED (t) = 0;
977 /* Otherwise, don't look any deeper. */
978 else
979 *walk_subtrees = 0;
981 return NULL_TREE;
984 /* Unmark the visited trees rooted at *TP. */
986 static inline void
987 unmark_visited (tree *tp)
989 walk_tree (tp, unmark_visited_r, NULL, NULL);
992 /* Likewise, but mark all trees as not visited. */
994 static void
995 unvisit_body (tree fndecl)
997 struct cgraph_node *cgn = cgraph_node::get (fndecl);
999 unmark_visited (&DECL_SAVED_TREE (fndecl));
1000 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
1001 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
1003 if (cgn)
1004 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
1005 unvisit_body (cgn->decl);
1008 /* Unconditionally make an unshared copy of EXPR. This is used when using
1009 stored expressions which span multiple functions, such as BINFO_VTABLE,
1010 as the normal unsharing process can't tell that they're shared. */
1012 tree
1013 unshare_expr (tree expr)
1015 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1016 return expr;
1019 /* Worker for unshare_expr_without_location. */
1021 static tree
1022 prune_expr_location (tree *tp, int *walk_subtrees, void *)
1024 if (EXPR_P (*tp))
1025 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
1026 else
1027 *walk_subtrees = 0;
1028 return NULL_TREE;
1031 /* Similar to unshare_expr but also prune all expression locations
1032 from EXPR. */
1034 tree
1035 unshare_expr_without_location (tree expr)
1037 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1038 if (EXPR_P (expr))
1039 walk_tree (&expr, prune_expr_location, NULL, NULL);
1040 return expr;
1043 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1044 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1045 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1046 EXPR is the location of the EXPR. */
1048 static location_t
1049 rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION)
1051 if (!expr)
1052 return or_else;
1054 if (EXPR_HAS_LOCATION (expr))
1055 return EXPR_LOCATION (expr);
1057 if (TREE_CODE (expr) != STATEMENT_LIST)
1058 return or_else;
1060 tree_stmt_iterator i = tsi_start (expr);
1062 bool found = false;
1063 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
1065 found = true;
1066 tsi_next (&i);
1069 if (!found || !tsi_one_before_end_p (i))
1070 return or_else;
1072 return rexpr_location (tsi_stmt (i), or_else);
1075 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1076 rexpr_location for the potential recursion. */
1078 static inline bool
1079 rexpr_has_location (tree expr)
1081 return rexpr_location (expr) != UNKNOWN_LOCATION;
1085 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1086 contain statements and have a value. Assign its value to a temporary
1087 and give it void_type_node. Return the temporary, or NULL_TREE if
1088 WRAPPER was already void. */
1090 tree
1091 voidify_wrapper_expr (tree wrapper, tree temp)
1093 tree type = TREE_TYPE (wrapper);
1094 if (type && !VOID_TYPE_P (type))
1096 tree *p;
1098 /* Set p to point to the body of the wrapper. Loop until we find
1099 something that isn't a wrapper. */
1100 for (p = &wrapper; p && *p; )
1102 switch (TREE_CODE (*p))
1104 case BIND_EXPR:
1105 TREE_SIDE_EFFECTS (*p) = 1;
1106 TREE_TYPE (*p) = void_type_node;
1107 /* For a BIND_EXPR, the body is operand 1. */
1108 p = &BIND_EXPR_BODY (*p);
1109 break;
1111 case CLEANUP_POINT_EXPR:
1112 case TRY_FINALLY_EXPR:
1113 case TRY_CATCH_EXPR:
1114 TREE_SIDE_EFFECTS (*p) = 1;
1115 TREE_TYPE (*p) = void_type_node;
1116 p = &TREE_OPERAND (*p, 0);
1117 break;
1119 case STATEMENT_LIST:
1121 tree_stmt_iterator i = tsi_last (*p);
1122 TREE_SIDE_EFFECTS (*p) = 1;
1123 TREE_TYPE (*p) = void_type_node;
1124 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1126 break;
1128 case COMPOUND_EXPR:
1129 /* Advance to the last statement. Set all container types to
1130 void. */
1131 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1133 TREE_SIDE_EFFECTS (*p) = 1;
1134 TREE_TYPE (*p) = void_type_node;
1136 break;
1138 case TRANSACTION_EXPR:
1139 TREE_SIDE_EFFECTS (*p) = 1;
1140 TREE_TYPE (*p) = void_type_node;
1141 p = &TRANSACTION_EXPR_BODY (*p);
1142 break;
1144 default:
1145 /* Assume that any tree upon which voidify_wrapper_expr is
1146 directly called is a wrapper, and that its body is op0. */
1147 if (p == &wrapper)
1149 TREE_SIDE_EFFECTS (*p) = 1;
1150 TREE_TYPE (*p) = void_type_node;
1151 p = &TREE_OPERAND (*p, 0);
1152 break;
1154 goto out;
1158 out:
1159 if (p == NULL || IS_EMPTY_STMT (*p))
1160 temp = NULL_TREE;
1161 else if (temp)
1163 /* The wrapper is on the RHS of an assignment that we're pushing
1164 down. */
1165 gcc_assert (TREE_CODE (temp) == INIT_EXPR
1166 || TREE_CODE (temp) == MODIFY_EXPR);
1167 TREE_OPERAND (temp, 1) = *p;
1168 *p = temp;
1170 else
1172 temp = create_tmp_var (type, "retval");
1173 *p = build2 (INIT_EXPR, type, temp, *p);
1176 return temp;
1179 return NULL_TREE;
1182 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1183 a temporary through which they communicate. */
1185 static void
1186 build_stack_save_restore (gcall **save, gcall **restore)
1188 tree tmp_var;
1190 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1191 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1192 gimple_call_set_lhs (*save, tmp_var);
1194 *restore
1195 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1196 1, tmp_var);
1199 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1201 static tree
1202 build_asan_poison_call_expr (tree decl)
1204 /* Do not poison variables that have size equal to zero. */
1205 tree unit_size = DECL_SIZE_UNIT (decl);
1206 if (zerop (unit_size))
1207 return NULL_TREE;
1209 tree base = build_fold_addr_expr (decl);
1211 return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
1212 void_type_node, 3,
1213 build_int_cst (integer_type_node,
1214 ASAN_MARK_POISON),
1215 base, unit_size);
1218 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1219 on POISON flag, shadow memory of a DECL variable. The call will be
1220 put on location identified by IT iterator, where BEFORE flag drives
1221 position where the stmt will be put. */
1223 static void
1224 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
1225 bool before)
1227 tree unit_size = DECL_SIZE_UNIT (decl);
1228 tree base = build_fold_addr_expr (decl);
1230 /* Do not poison variables that have size equal to zero. */
1231 if (zerop (unit_size))
1232 return;
1234 /* It's necessary to have all stack variables aligned to ASAN granularity
1235 bytes. */
1236 if (DECL_ALIGN_UNIT (decl) <= ASAN_SHADOW_GRANULARITY)
1237 SET_DECL_ALIGN (decl, BITS_PER_UNIT * ASAN_SHADOW_GRANULARITY);
1239 HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
1241 gimple *g
1242 = gimple_build_call_internal (IFN_ASAN_MARK, 3,
1243 build_int_cst (integer_type_node, flags),
1244 base, unit_size);
1246 if (before)
1247 gsi_insert_before (it, g, GSI_NEW_STMT);
1248 else
1249 gsi_insert_after (it, g, GSI_NEW_STMT);
1252 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1253 either poisons or unpoisons a DECL. Created statement is appended
1254 to SEQ_P gimple sequence. */
1256 static void
1257 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
1259 gimple_stmt_iterator it = gsi_last (*seq_p);
1260 bool before = false;
1262 if (gsi_end_p (it))
1263 before = true;
1265 asan_poison_variable (decl, poison, &it, before);
1268 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1270 static int
1271 sort_by_decl_uid (const void *a, const void *b)
1273 const tree *t1 = (const tree *)a;
1274 const tree *t2 = (const tree *)b;
1276 int uid1 = DECL_UID (*t1);
1277 int uid2 = DECL_UID (*t2);
1279 if (uid1 < uid2)
1280 return -1;
1281 else if (uid1 > uid2)
1282 return 1;
1283 else
1284 return 0;
1287 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1288 depending on POISON flag. Created statement is appended
1289 to SEQ_P gimple sequence. */
1291 static void
1292 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
1294 unsigned c = variables->elements ();
1295 if (c == 0)
1296 return;
1298 auto_vec<tree> sorted_variables (c);
1300 for (hash_set<tree>::iterator it = variables->begin ();
1301 it != variables->end (); ++it)
1302 sorted_variables.safe_push (*it);
1304 sorted_variables.qsort (sort_by_decl_uid);
1306 unsigned i;
1307 tree var;
1308 FOR_EACH_VEC_ELT (sorted_variables, i, var)
1310 asan_poison_variable (var, poison, seq_p);
1312 /* Add use_after_scope_memory attribute for the variable in order
1313 to prevent re-written into SSA. */
1314 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
1315 DECL_ATTRIBUTES (var)))
1316 DECL_ATTRIBUTES (var)
1317 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
1318 integer_one_node,
1319 DECL_ATTRIBUTES (var));
1323 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1325 static enum gimplify_status
1326 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1328 tree bind_expr = *expr_p;
1329 bool old_keep_stack = gimplify_ctxp->keep_stack;
1330 bool old_save_stack = gimplify_ctxp->save_stack;
1331 tree t;
1332 gbind *bind_stmt;
1333 gimple_seq body, cleanup;
1334 gcall *stack_save;
1335 location_t start_locus = 0, end_locus = 0;
1336 tree ret_clauses = NULL;
1338 tree temp = voidify_wrapper_expr (bind_expr, NULL);
1340 /* Mark variables seen in this bind expr. */
1341 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1343 if (VAR_P (t))
1345 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1347 /* Mark variable as local. */
1348 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t))
1350 if (! DECL_SEEN_IN_BIND_EXPR_P (t)
1351 || splay_tree_lookup (ctx->variables,
1352 (splay_tree_key) t) == NULL)
1354 int flag = GOVD_LOCAL;
1355 if (ctx->region_type == ORT_SIMD
1356 && TREE_ADDRESSABLE (t)
1357 && !TREE_STATIC (t))
1359 if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST)
1360 ctx->add_safelen1 = true;
1361 else
1362 flag = GOVD_PRIVATE;
1364 omp_add_variable (ctx, t, flag | GOVD_SEEN);
1366 /* Static locals inside of target construct or offloaded
1367 routines need to be "omp declare target". */
1368 if (TREE_STATIC (t))
1369 for (; ctx; ctx = ctx->outer_context)
1370 if ((ctx->region_type & ORT_TARGET) != 0)
1372 if (!lookup_attribute ("omp declare target",
1373 DECL_ATTRIBUTES (t)))
1375 tree id = get_identifier ("omp declare target");
1376 DECL_ATTRIBUTES (t)
1377 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
1378 varpool_node *node = varpool_node::get (t);
1379 if (node)
1381 node->offloadable = 1;
1382 if (ENABLE_OFFLOADING && !DECL_EXTERNAL (t))
1384 g->have_offload = true;
1385 if (!in_lto_p)
1386 vec_safe_push (offload_vars, t);
1390 break;
1394 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1396 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1397 cfun->has_local_explicit_reg_vars = true;
1400 /* Preliminarily mark non-addressed complex variables as eligible
1401 for promotion to gimple registers. We'll transform their uses
1402 as we find them. */
1403 if ((TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
1404 || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
1405 && !TREE_THIS_VOLATILE (t)
1406 && (VAR_P (t) && !DECL_HARD_REGISTER (t))
1407 && !needs_to_live_in_memory (t))
1408 DECL_GIMPLE_REG_P (t) = 1;
1411 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1412 BIND_EXPR_BLOCK (bind_expr));
1413 gimple_push_bind_expr (bind_stmt);
1415 gimplify_ctxp->keep_stack = false;
1416 gimplify_ctxp->save_stack = false;
1418 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1419 body = NULL;
1420 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1421 gimple_bind_set_body (bind_stmt, body);
1423 /* Source location wise, the cleanup code (stack_restore and clobbers)
1424 belongs to the end of the block, so propagate what we have. The
1425 stack_save operation belongs to the beginning of block, which we can
1426 infer from the bind_expr directly if the block has no explicit
1427 assignment. */
1428 if (BIND_EXPR_BLOCK (bind_expr))
1430 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1431 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1433 if (start_locus == 0)
1434 start_locus = EXPR_LOCATION (bind_expr);
1436 cleanup = NULL;
1437 stack_save = NULL;
1439 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1440 the stack space allocated to the VLAs. */
1441 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1443 gcall *stack_restore;
1445 /* Save stack on entry and restore it on exit. Add a try_finally
1446 block to achieve this. */
1447 build_stack_save_restore (&stack_save, &stack_restore);
1449 gimple_set_location (stack_save, start_locus);
1450 gimple_set_location (stack_restore, end_locus);
1452 gimplify_seq_add_stmt (&cleanup, stack_restore);
1455 /* Add clobbers for all variables that go out of scope. */
1456 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1458 if (VAR_P (t)
1459 && !is_global_var (t)
1460 && DECL_CONTEXT (t) == current_function_decl)
1462 if (!DECL_HARD_REGISTER (t)
1463 && !TREE_THIS_VOLATILE (t)
1464 && !DECL_HAS_VALUE_EXPR_P (t)
1465 /* Only care for variables that have to be in memory. Others
1466 will be rewritten into SSA names, hence moved to the
1467 top-level. */
1468 && !is_gimple_reg (t)
1469 && flag_stack_reuse != SR_NONE)
1471 tree clobber = build_clobber (TREE_TYPE (t));
1472 gimple *clobber_stmt;
1473 clobber_stmt = gimple_build_assign (t, clobber);
1474 gimple_set_location (clobber_stmt, end_locus);
1475 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1478 if (flag_openacc && oacc_declare_returns != NULL)
1480 tree *c = oacc_declare_returns->get (t);
1481 if (c != NULL)
1483 if (ret_clauses)
1484 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1486 ret_clauses = *c;
1488 oacc_declare_returns->remove (t);
1490 if (oacc_declare_returns->is_empty ())
1492 delete oacc_declare_returns;
1493 oacc_declare_returns = NULL;
1499 if (asan_poisoned_variables != NULL
1500 && asan_poisoned_variables->contains (t))
1502 asan_poisoned_variables->remove (t);
1503 asan_poison_variable (t, true, &cleanup);
1506 if (gimplify_ctxp->live_switch_vars != NULL
1507 && gimplify_ctxp->live_switch_vars->contains (t))
1508 gimplify_ctxp->live_switch_vars->remove (t);
1511 if (ret_clauses)
1513 gomp_target *stmt;
1514 gimple_stmt_iterator si = gsi_start (cleanup);
1516 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1517 ret_clauses);
1518 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1521 if (cleanup)
1523 gtry *gs;
1524 gimple_seq new_body;
1526 new_body = NULL;
1527 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1528 GIMPLE_TRY_FINALLY);
1530 if (stack_save)
1531 gimplify_seq_add_stmt (&new_body, stack_save);
1532 gimplify_seq_add_stmt (&new_body, gs);
1533 gimple_bind_set_body (bind_stmt, new_body);
1536 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1537 if (!gimplify_ctxp->keep_stack)
1538 gimplify_ctxp->keep_stack = old_keep_stack;
1539 gimplify_ctxp->save_stack = old_save_stack;
1541 gimple_pop_bind_expr ();
1543 gimplify_seq_add_stmt (pre_p, bind_stmt);
1545 if (temp)
1547 *expr_p = temp;
1548 return GS_OK;
1551 *expr_p = NULL_TREE;
1552 return GS_ALL_DONE;
1555 /* Maybe add early return predict statement to PRE_P sequence. */
1557 static void
1558 maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
1560 /* If we are not in a conditional context, add PREDICT statement. */
1561 if (gimple_conditional_context ())
1563 gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
1564 NOT_TAKEN);
1565 gimplify_seq_add_stmt (pre_p, predict);
1569 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1570 GIMPLE value, it is assigned to a new temporary and the statement is
1571 re-written to return the temporary.
1573 PRE_P points to the sequence where side effects that must happen before
1574 STMT should be stored. */
1576 static enum gimplify_status
1577 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1579 greturn *ret;
1580 tree ret_expr = TREE_OPERAND (stmt, 0);
1581 tree result_decl, result;
1583 if (ret_expr == error_mark_node)
1584 return GS_ERROR;
1586 if (!ret_expr
1587 || TREE_CODE (ret_expr) == RESULT_DECL)
1589 maybe_add_early_return_predict_stmt (pre_p);
1590 greturn *ret = gimple_build_return (ret_expr);
1591 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1592 gimplify_seq_add_stmt (pre_p, ret);
1593 return GS_ALL_DONE;
1596 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1597 result_decl = NULL_TREE;
1598 else
1600 result_decl = TREE_OPERAND (ret_expr, 0);
1602 /* See through a return by reference. */
1603 if (TREE_CODE (result_decl) == INDIRECT_REF)
1604 result_decl = TREE_OPERAND (result_decl, 0);
1606 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1607 || TREE_CODE (ret_expr) == INIT_EXPR)
1608 && TREE_CODE (result_decl) == RESULT_DECL);
1611 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1612 Recall that aggregate_value_p is FALSE for any aggregate type that is
1613 returned in registers. If we're returning values in registers, then
1614 we don't want to extend the lifetime of the RESULT_DECL, particularly
1615 across another call. In addition, for those aggregates for which
1616 hard_function_value generates a PARALLEL, we'll die during normal
1617 expansion of structure assignments; there's special code in expand_return
1618 to handle this case that does not exist in expand_expr. */
1619 if (!result_decl)
1620 result = NULL_TREE;
1621 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1623 if (TREE_CODE (DECL_SIZE (result_decl)) != INTEGER_CST)
1625 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1626 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1627 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1628 should be effectively allocated by the caller, i.e. all calls to
1629 this function must be subject to the Return Slot Optimization. */
1630 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1631 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1633 result = result_decl;
1635 else if (gimplify_ctxp->return_temp)
1636 result = gimplify_ctxp->return_temp;
1637 else
1639 result = create_tmp_reg (TREE_TYPE (result_decl));
1641 /* ??? With complex control flow (usually involving abnormal edges),
1642 we can wind up warning about an uninitialized value for this. Due
1643 to how this variable is constructed and initialized, this is never
1644 true. Give up and never warn. */
1645 TREE_NO_WARNING (result) = 1;
1647 gimplify_ctxp->return_temp = result;
1650 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1651 Then gimplify the whole thing. */
1652 if (result != result_decl)
1653 TREE_OPERAND (ret_expr, 0) = result;
1655 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1657 maybe_add_early_return_predict_stmt (pre_p);
1658 ret = gimple_build_return (result);
1659 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1660 gimplify_seq_add_stmt (pre_p, ret);
1662 return GS_ALL_DONE;
1665 /* Gimplify a variable-length array DECL. */
1667 static void
1668 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1670 /* This is a variable-sized decl. Simplify its size and mark it
1671 for deferred expansion. */
1672 tree t, addr, ptr_type;
1674 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1675 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1677 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1678 if (DECL_HAS_VALUE_EXPR_P (decl))
1679 return;
1681 /* All occurrences of this decl in final gimplified code will be
1682 replaced by indirection. Setting DECL_VALUE_EXPR does two
1683 things: First, it lets the rest of the gimplifier know what
1684 replacement to use. Second, it lets the debug info know
1685 where to find the value. */
1686 ptr_type = build_pointer_type (TREE_TYPE (decl));
1687 addr = create_tmp_var (ptr_type, get_name (decl));
1688 DECL_IGNORED_P (addr) = 0;
1689 t = build_fold_indirect_ref (addr);
1690 TREE_THIS_NOTRAP (t) = 1;
1691 SET_DECL_VALUE_EXPR (decl, t);
1692 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1694 t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
1695 max_int_size_in_bytes (TREE_TYPE (decl)));
1696 /* The call has been built for a variable-sized object. */
1697 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1698 t = fold_convert (ptr_type, t);
1699 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1701 gimplify_and_add (t, seq_p);
1703 /* Record the dynamic allocation associated with DECL if requested. */
1704 if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)
1705 record_dynamic_alloc (decl);
1708 /* A helper function to be called via walk_tree. Mark all labels under *TP
1709 as being forced. To be called for DECL_INITIAL of static variables. */
1711 static tree
1712 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1714 if (TYPE_P (*tp))
1715 *walk_subtrees = 0;
1716 if (TREE_CODE (*tp) == LABEL_DECL)
1718 FORCED_LABEL (*tp) = 1;
1719 cfun->has_forced_label_in_static = 1;
1722 return NULL_TREE;
1725 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1726 and initialization explicit. */
1728 static enum gimplify_status
1729 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1731 tree stmt = *stmt_p;
1732 tree decl = DECL_EXPR_DECL (stmt);
1734 *stmt_p = NULL_TREE;
1736 if (TREE_TYPE (decl) == error_mark_node)
1737 return GS_ERROR;
1739 if ((TREE_CODE (decl) == TYPE_DECL
1740 || VAR_P (decl))
1741 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1743 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1744 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1745 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1748 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1749 in case its size expressions contain problematic nodes like CALL_EXPR. */
1750 if (TREE_CODE (decl) == TYPE_DECL
1751 && DECL_ORIGINAL_TYPE (decl)
1752 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1754 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1755 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1756 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1759 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1761 tree init = DECL_INITIAL (decl);
1762 bool is_vla = false;
1764 poly_uint64 size;
1765 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
1766 || (!TREE_STATIC (decl)
1767 && flag_stack_check == GENERIC_STACK_CHECK
1768 && maybe_gt (size,
1769 (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
1771 gimplify_vla_decl (decl, seq_p);
1772 is_vla = true;
1775 if (asan_poisoned_variables
1776 && !is_vla
1777 && TREE_ADDRESSABLE (decl)
1778 && !TREE_STATIC (decl)
1779 && !DECL_HAS_VALUE_EXPR_P (decl)
1780 && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
1781 && dbg_cnt (asan_use_after_scope)
1782 && !gimplify_omp_ctxp)
1784 asan_poisoned_variables->add (decl);
1785 asan_poison_variable (decl, false, seq_p);
1786 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
1787 gimplify_ctxp->live_switch_vars->add (decl);
1790 /* Some front ends do not explicitly declare all anonymous
1791 artificial variables. We compensate here by declaring the
1792 variables, though it would be better if the front ends would
1793 explicitly declare them. */
1794 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1795 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1796 gimple_add_tmp_var (decl);
1798 if (init && init != error_mark_node)
1800 if (!TREE_STATIC (decl))
1802 DECL_INITIAL (decl) = NULL_TREE;
1803 init = build2 (INIT_EXPR, void_type_node, decl, init);
1804 gimplify_and_add (init, seq_p);
1805 ggc_free (init);
1807 else
1808 /* We must still examine initializers for static variables
1809 as they may contain a label address. */
1810 walk_tree (&init, force_labels_r, NULL, NULL);
1814 return GS_ALL_DONE;
1817 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1818 and replacing the LOOP_EXPR with goto, but if the loop contains an
1819 EXIT_EXPR, we need to append a label for it to jump to. */
1821 static enum gimplify_status
1822 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1824 tree saved_label = gimplify_ctxp->exit_label;
1825 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1827 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1829 gimplify_ctxp->exit_label = NULL_TREE;
1831 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1833 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
1835 if (gimplify_ctxp->exit_label)
1836 gimplify_seq_add_stmt (pre_p,
1837 gimple_build_label (gimplify_ctxp->exit_label));
1839 gimplify_ctxp->exit_label = saved_label;
1841 *expr_p = NULL;
1842 return GS_ALL_DONE;
1845 /* Gimplify a statement list onto a sequence. These may be created either
1846 by an enlightened front-end, or by shortcut_cond_expr. */
1848 static enum gimplify_status
1849 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
1851 tree temp = voidify_wrapper_expr (*expr_p, NULL);
1853 tree_stmt_iterator i = tsi_start (*expr_p);
1855 while (!tsi_end_p (i))
1857 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
1858 tsi_delink (&i);
1861 if (temp)
1863 *expr_p = temp;
1864 return GS_OK;
1867 return GS_ALL_DONE;
1870 /* Callback for walk_gimple_seq. */
1872 static tree
1873 warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
1874 struct walk_stmt_info *wi)
1876 gimple *stmt = gsi_stmt (*gsi_p);
1878 *handled_ops_p = true;
1879 switch (gimple_code (stmt))
1881 case GIMPLE_TRY:
1882 /* A compiler-generated cleanup or a user-written try block.
1883 If it's empty, don't dive into it--that would result in
1884 worse location info. */
1885 if (gimple_try_eval (stmt) == NULL)
1887 wi->info = stmt;
1888 return integer_zero_node;
1890 /* Fall through. */
1891 case GIMPLE_BIND:
1892 case GIMPLE_CATCH:
1893 case GIMPLE_EH_FILTER:
1894 case GIMPLE_TRANSACTION:
1895 /* Walk the sub-statements. */
1896 *handled_ops_p = false;
1897 break;
1899 case GIMPLE_DEBUG:
1900 /* Ignore these. We may generate them before declarations that
1901 are never executed. If there's something to warn about,
1902 there will be non-debug stmts too, and we'll catch those. */
1903 break;
1905 case GIMPLE_CALL:
1906 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
1908 *handled_ops_p = false;
1909 break;
1911 /* Fall through. */
1912 default:
1913 /* Save the first "real" statement (not a decl/lexical scope/...). */
1914 wi->info = stmt;
1915 return integer_zero_node;
1917 return NULL_TREE;
1920 /* Possibly warn about unreachable statements between switch's controlling
1921 expression and the first case. SEQ is the body of a switch expression. */
1923 static void
1924 maybe_warn_switch_unreachable (gimple_seq seq)
1926 if (!warn_switch_unreachable
1927 /* This warning doesn't play well with Fortran when optimizations
1928 are on. */
1929 || lang_GNU_Fortran ()
1930 || seq == NULL)
1931 return;
1933 struct walk_stmt_info wi;
1934 memset (&wi, 0, sizeof (wi));
1935 walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi);
1936 gimple *stmt = (gimple *) wi.info;
1938 if (stmt && gimple_code (stmt) != GIMPLE_LABEL)
1940 if (gimple_code (stmt) == GIMPLE_GOTO
1941 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
1942 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
1943 /* Don't warn for compiler-generated gotos. These occur
1944 in Duff's devices, for example. */;
1945 else
1946 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
1947 "statement will never be executed");
1952 /* A label entry that pairs label and a location. */
1953 struct label_entry
1955 tree label;
1956 location_t loc;
1959 /* Find LABEL in vector of label entries VEC. */
1961 static struct label_entry *
1962 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
1964 unsigned int i;
1965 struct label_entry *l;
1967 FOR_EACH_VEC_ELT (*vec, i, l)
1968 if (l->label == label)
1969 return l;
1970 return NULL;
1973 /* Return true if LABEL, a LABEL_DECL, represents a case label
1974 in a vector of labels CASES. */
1976 static bool
1977 case_label_p (const vec<tree> *cases, tree label)
1979 unsigned int i;
1980 tree l;
1982 FOR_EACH_VEC_ELT (*cases, i, l)
1983 if (CASE_LABEL (l) == label)
1984 return true;
1985 return false;
1988 /* Find the last nondebug statement in a scope STMT. */
1990 static gimple *
1991 last_stmt_in_scope (gimple *stmt)
1993 if (!stmt)
1994 return NULL;
1996 switch (gimple_code (stmt))
1998 case GIMPLE_BIND:
2000 gbind *bind = as_a <gbind *> (stmt);
2001 stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
2002 return last_stmt_in_scope (stmt);
2005 case GIMPLE_TRY:
2007 gtry *try_stmt = as_a <gtry *> (stmt);
2008 stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
2009 gimple *last_eval = last_stmt_in_scope (stmt);
2010 if (gimple_stmt_may_fallthru (last_eval)
2011 && (last_eval == NULL
2012 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
2013 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
2015 stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
2016 return last_stmt_in_scope (stmt);
2018 else
2019 return last_eval;
2022 case GIMPLE_DEBUG:
2023 gcc_unreachable ();
2025 default:
2026 return stmt;
2030 /* Collect interesting labels in LABELS and return the statement preceding
2031 another case label, or a user-defined label. Store a location useful
2032 to give warnings at *PREVLOC (usually the location of the returned
2033 statement or of its surrounding scope). */
2035 static gimple *
2036 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
2037 auto_vec <struct label_entry> *labels,
2038 location_t *prevloc)
2040 gimple *prev = NULL;
2042 *prevloc = UNKNOWN_LOCATION;
2045 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
2047 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2048 which starts on a GIMPLE_SWITCH and ends with a break label.
2049 Handle that as a single statement that can fall through. */
2050 gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
2051 gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
2052 gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
2053 if (last
2054 && gimple_code (first) == GIMPLE_SWITCH
2055 && gimple_code (last) == GIMPLE_LABEL)
2057 tree label = gimple_label_label (as_a <glabel *> (last));
2058 if (SWITCH_BREAK_LABEL_P (label))
2060 prev = bind;
2061 gsi_next (gsi_p);
2062 continue;
2066 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
2067 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
2069 /* Nested scope. Only look at the last statement of
2070 the innermost scope. */
2071 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
2072 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
2073 if (last)
2075 prev = last;
2076 /* It might be a label without a location. Use the
2077 location of the scope then. */
2078 if (!gimple_has_location (prev))
2079 *prevloc = bind_loc;
2081 gsi_next (gsi_p);
2082 continue;
2085 /* Ifs are tricky. */
2086 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
2088 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
2089 tree false_lab = gimple_cond_false_label (cond_stmt);
2090 location_t if_loc = gimple_location (cond_stmt);
2092 /* If we have e.g.
2093 if (i > 1) goto <D.2259>; else goto D;
2094 we can't do much with the else-branch. */
2095 if (!DECL_ARTIFICIAL (false_lab))
2096 break;
2098 /* Go on until the false label, then one step back. */
2099 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
2101 gimple *stmt = gsi_stmt (*gsi_p);
2102 if (gimple_code (stmt) == GIMPLE_LABEL
2103 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
2104 break;
2107 /* Not found? Oops. */
2108 if (gsi_end_p (*gsi_p))
2109 break;
2111 struct label_entry l = { false_lab, if_loc };
2112 labels->safe_push (l);
2114 /* Go to the last statement of the then branch. */
2115 gsi_prev (gsi_p);
2117 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2118 <D.1759>:
2119 <stmt>;
2120 goto <D.1761>;
2121 <D.1760>:
2123 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2124 && !gimple_has_location (gsi_stmt (*gsi_p)))
2126 /* Look at the statement before, it might be
2127 attribute fallthrough, in which case don't warn. */
2128 gsi_prev (gsi_p);
2129 bool fallthru_before_dest
2130 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2131 gsi_next (gsi_p);
2132 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2133 if (!fallthru_before_dest)
2135 struct label_entry l = { goto_dest, if_loc };
2136 labels->safe_push (l);
2139 /* And move back. */
2140 gsi_next (gsi_p);
2143 /* Remember the last statement. Skip labels that are of no interest
2144 to us. */
2145 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2147 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2148 if (find_label_entry (labels, label))
2149 prev = gsi_stmt (*gsi_p);
2151 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2153 else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
2155 else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2156 prev = gsi_stmt (*gsi_p);
2157 gsi_next (gsi_p);
2159 while (!gsi_end_p (*gsi_p)
2160 /* Stop if we find a case or a user-defined label. */
2161 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2162 || !gimple_has_location (gsi_stmt (*gsi_p))));
2164 if (prev && gimple_has_location (prev))
2165 *prevloc = gimple_location (prev);
2166 return prev;
2169 /* Return true if the switch fallthough warning should occur. LABEL is
2170 the label statement that we're falling through to. */
2172 static bool
2173 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2175 gimple_stmt_iterator gsi = *gsi_p;
2177 /* Don't warn if the label is marked with a "falls through" comment. */
2178 if (FALLTHROUGH_LABEL_P (label))
2179 return false;
2181 /* Don't warn for non-case labels followed by a statement:
2182 case 0:
2183 foo ();
2184 label:
2185 bar ();
2186 as these are likely intentional. */
2187 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2189 tree l;
2190 while (!gsi_end_p (gsi)
2191 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2192 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2193 && !case_label_p (&gimplify_ctxp->case_labels, l))
2194 gsi_next_nondebug (&gsi);
2195 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2196 return false;
2199 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2200 immediately breaks. */
2201 gsi = *gsi_p;
2203 /* Skip all immediately following labels. */
2204 while (!gsi_end_p (gsi)
2205 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2206 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2207 gsi_next_nondebug (&gsi);
2209 /* { ... something; default:; } */
2210 if (gsi_end_p (gsi)
2211 /* { ... something; default: break; } or
2212 { ... something; default: goto L; } */
2213 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2214 /* { ... something; default: return; } */
2215 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2216 return false;
2218 return true;
2221 /* Callback for walk_gimple_seq. */
2223 static tree
2224 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2225 struct walk_stmt_info *)
2227 gimple *stmt = gsi_stmt (*gsi_p);
2229 *handled_ops_p = true;
2230 switch (gimple_code (stmt))
2232 case GIMPLE_TRY:
2233 case GIMPLE_BIND:
2234 case GIMPLE_CATCH:
2235 case GIMPLE_EH_FILTER:
2236 case GIMPLE_TRANSACTION:
2237 /* Walk the sub-statements. */
2238 *handled_ops_p = false;
2239 break;
2241 /* Find a sequence of form:
2243 GIMPLE_LABEL
2244 [...]
2245 <may fallthru stmt>
2246 GIMPLE_LABEL
2248 and possibly warn. */
2249 case GIMPLE_LABEL:
2251 /* Found a label. Skip all immediately following labels. */
2252 while (!gsi_end_p (*gsi_p)
2253 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2254 gsi_next_nondebug (gsi_p);
2256 /* There might be no more statements. */
2257 if (gsi_end_p (*gsi_p))
2258 return integer_zero_node;
2260 /* Vector of labels that fall through. */
2261 auto_vec <struct label_entry> labels;
2262 location_t prevloc;
2263 gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
2265 /* There might be no more statements. */
2266 if (gsi_end_p (*gsi_p))
2267 return integer_zero_node;
2269 gimple *next = gsi_stmt (*gsi_p);
2270 tree label;
2271 /* If what follows is a label, then we may have a fallthrough. */
2272 if (gimple_code (next) == GIMPLE_LABEL
2273 && gimple_has_location (next)
2274 && (label = gimple_label_label (as_a <glabel *> (next)))
2275 && prev != NULL)
2277 struct label_entry *l;
2278 bool warned_p = false;
2279 auto_diagnostic_group d;
2280 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2281 /* Quiet. */;
2282 else if (gimple_code (prev) == GIMPLE_LABEL
2283 && (label = gimple_label_label (as_a <glabel *> (prev)))
2284 && (l = find_label_entry (&labels, label)))
2285 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2286 "this statement may fall through");
2287 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2288 /* Try to be clever and don't warn when the statement
2289 can't actually fall through. */
2290 && gimple_stmt_may_fallthru (prev)
2291 && prevloc != UNKNOWN_LOCATION)
2292 warned_p = warning_at (prevloc,
2293 OPT_Wimplicit_fallthrough_,
2294 "this statement may fall through");
2295 if (warned_p)
2296 inform (gimple_location (next), "here");
2298 /* Mark this label as processed so as to prevent multiple
2299 warnings in nested switches. */
2300 FALLTHROUGH_LABEL_P (label) = true;
2302 /* So that next warn_implicit_fallthrough_r will start looking for
2303 a new sequence starting with this label. */
2304 gsi_prev (gsi_p);
2307 break;
2308 default:
2309 break;
2311 return NULL_TREE;
2314 /* Warn when a switch case falls through. */
2316 static void
2317 maybe_warn_implicit_fallthrough (gimple_seq seq)
2319 if (!warn_implicit_fallthrough)
2320 return;
2322 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2323 if (!(lang_GNU_C ()
2324 || lang_GNU_CXX ()
2325 || lang_GNU_OBJC ()))
2326 return;
2328 struct walk_stmt_info wi;
2329 memset (&wi, 0, sizeof (wi));
2330 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2333 /* Callback for walk_gimple_seq. */
2335 static tree
2336 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2337 struct walk_stmt_info *wi)
2339 gimple *stmt = gsi_stmt (*gsi_p);
2341 *handled_ops_p = true;
2342 switch (gimple_code (stmt))
2344 case GIMPLE_TRY:
2345 case GIMPLE_BIND:
2346 case GIMPLE_CATCH:
2347 case GIMPLE_EH_FILTER:
2348 case GIMPLE_TRANSACTION:
2349 /* Walk the sub-statements. */
2350 *handled_ops_p = false;
2351 break;
2352 case GIMPLE_CALL:
2353 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2355 gsi_remove (gsi_p, true);
2356 if (gsi_end_p (*gsi_p))
2358 *static_cast<location_t *>(wi->info) = gimple_location (stmt);
2359 return integer_zero_node;
2362 bool found = false;
2363 location_t loc = gimple_location (stmt);
2365 gimple_stmt_iterator gsi2 = *gsi_p;
2366 stmt = gsi_stmt (gsi2);
2367 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2369 /* Go on until the artificial label. */
2370 tree goto_dest = gimple_goto_dest (stmt);
2371 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2373 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2374 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2375 == goto_dest)
2376 break;
2379 /* Not found? Stop. */
2380 if (gsi_end_p (gsi2))
2381 break;
2383 /* Look one past it. */
2384 gsi_next (&gsi2);
2387 /* We're looking for a case label or default label here. */
2388 while (!gsi_end_p (gsi2))
2390 stmt = gsi_stmt (gsi2);
2391 if (gimple_code (stmt) == GIMPLE_LABEL)
2393 tree label = gimple_label_label (as_a <glabel *> (stmt));
2394 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2396 found = true;
2397 break;
2400 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2402 else if (!is_gimple_debug (stmt))
2403 /* Anything else is not expected. */
2404 break;
2405 gsi_next (&gsi2);
2407 if (!found)
2408 warning_at (loc, 0, "attribute %<fallthrough%> not preceding "
2409 "a case label or default label");
2411 break;
2412 default:
2413 break;
2415 return NULL_TREE;
2418 /* Expand all FALLTHROUGH () calls in SEQ. */
2420 static void
2421 expand_FALLTHROUGH (gimple_seq *seq_p)
2423 struct walk_stmt_info wi;
2424 location_t loc;
2425 memset (&wi, 0, sizeof (wi));
2426 wi.info = (void *) &loc;
2427 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2428 if (wi.callback_result == integer_zero_node)
2429 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2430 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2431 warning_at (loc, 0, "attribute %<fallthrough%> not preceding "
2432 "a case label or default label");
2436 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2437 branch to. */
2439 static enum gimplify_status
2440 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2442 tree switch_expr = *expr_p;
2443 gimple_seq switch_body_seq = NULL;
2444 enum gimplify_status ret;
2445 tree index_type = TREE_TYPE (switch_expr);
2446 if (index_type == NULL_TREE)
2447 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2449 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2450 fb_rvalue);
2451 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2452 return ret;
2454 if (SWITCH_BODY (switch_expr))
2456 vec<tree> labels;
2457 vec<tree> saved_labels;
2458 hash_set<tree> *saved_live_switch_vars = NULL;
2459 tree default_case = NULL_TREE;
2460 gswitch *switch_stmt;
2462 /* Save old labels, get new ones from body, then restore the old
2463 labels. Save all the things from the switch body to append after. */
2464 saved_labels = gimplify_ctxp->case_labels;
2465 gimplify_ctxp->case_labels.create (8);
2467 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2468 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2469 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2470 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2471 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2472 else
2473 gimplify_ctxp->live_switch_vars = NULL;
2475 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2476 gimplify_ctxp->in_switch_expr = true;
2478 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2480 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2481 maybe_warn_switch_unreachable (switch_body_seq);
2482 maybe_warn_implicit_fallthrough (switch_body_seq);
2483 /* Only do this for the outermost GIMPLE_SWITCH. */
2484 if (!gimplify_ctxp->in_switch_expr)
2485 expand_FALLTHROUGH (&switch_body_seq);
2487 labels = gimplify_ctxp->case_labels;
2488 gimplify_ctxp->case_labels = saved_labels;
2490 if (gimplify_ctxp->live_switch_vars)
2492 gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
2493 delete gimplify_ctxp->live_switch_vars;
2495 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2497 preprocess_case_label_vec_for_gimple (labels, index_type,
2498 &default_case);
2500 bool add_bind = false;
2501 if (!default_case)
2503 glabel *new_default;
2505 default_case
2506 = build_case_label (NULL_TREE, NULL_TREE,
2507 create_artificial_label (UNKNOWN_LOCATION));
2508 if (old_in_switch_expr)
2510 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2511 add_bind = true;
2513 new_default = gimple_build_label (CASE_LABEL (default_case));
2514 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2516 else if (old_in_switch_expr)
2518 gimple *last = gimple_seq_last_stmt (switch_body_seq);
2519 if (last && gimple_code (last) == GIMPLE_LABEL)
2521 tree label = gimple_label_label (as_a <glabel *> (last));
2522 if (SWITCH_BREAK_LABEL_P (label))
2523 add_bind = true;
2527 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2528 default_case, labels);
2529 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2530 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2531 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2532 so that we can easily find the start and end of the switch
2533 statement. */
2534 if (add_bind)
2536 gimple_seq bind_body = NULL;
2537 gimplify_seq_add_stmt (&bind_body, switch_stmt);
2538 gimple_seq_add_seq (&bind_body, switch_body_seq);
2539 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
2540 gimple_set_location (bind, EXPR_LOCATION (switch_expr));
2541 gimplify_seq_add_stmt (pre_p, bind);
2543 else
2545 gimplify_seq_add_stmt (pre_p, switch_stmt);
2546 gimplify_seq_add_seq (pre_p, switch_body_seq);
2548 labels.release ();
2550 else
2551 gcc_unreachable ();
2553 return GS_ALL_DONE;
2556 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2558 static enum gimplify_status
2559 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2561 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2562 == current_function_decl);
2564 tree label = LABEL_EXPR_LABEL (*expr_p);
2565 glabel *label_stmt = gimple_build_label (label);
2566 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2567 gimplify_seq_add_stmt (pre_p, label_stmt);
2569 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2570 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2571 NOT_TAKEN));
2572 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2573 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2574 TAKEN));
2576 return GS_ALL_DONE;
2579 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2581 static enum gimplify_status
2582 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2584 struct gimplify_ctx *ctxp;
2585 glabel *label_stmt;
2587 /* Invalid programs can play Duff's Device type games with, for example,
2588 #pragma omp parallel. At least in the C front end, we don't
2589 detect such invalid branches until after gimplification, in the
2590 diagnose_omp_blocks pass. */
2591 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2592 if (ctxp->case_labels.exists ())
2593 break;
2595 tree label = CASE_LABEL (*expr_p);
2596 label_stmt = gimple_build_label (label);
2597 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2598 ctxp->case_labels.safe_push (*expr_p);
2599 gimplify_seq_add_stmt (pre_p, label_stmt);
2601 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2602 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2603 NOT_TAKEN));
2604 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2605 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2606 TAKEN));
2608 return GS_ALL_DONE;
2611 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2612 if necessary. */
2614 tree
2615 build_and_jump (tree *label_p)
2617 if (label_p == NULL)
2618 /* If there's nowhere to jump, just fall through. */
2619 return NULL_TREE;
2621 if (*label_p == NULL_TREE)
2623 tree label = create_artificial_label (UNKNOWN_LOCATION);
2624 *label_p = label;
2627 return build1 (GOTO_EXPR, void_type_node, *label_p);
2630 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2631 This also involves building a label to jump to and communicating it to
2632 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2634 static enum gimplify_status
2635 gimplify_exit_expr (tree *expr_p)
2637 tree cond = TREE_OPERAND (*expr_p, 0);
2638 tree expr;
2640 expr = build_and_jump (&gimplify_ctxp->exit_label);
2641 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2642 *expr_p = expr;
2644 return GS_OK;
2647 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2648 different from its canonical type, wrap the whole thing inside a
2649 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2650 type.
2652 The canonical type of a COMPONENT_REF is the type of the field being
2653 referenced--unless the field is a bit-field which can be read directly
2654 in a smaller mode, in which case the canonical type is the
2655 sign-appropriate type corresponding to that mode. */
2657 static void
2658 canonicalize_component_ref (tree *expr_p)
2660 tree expr = *expr_p;
2661 tree type;
2663 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2665 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2666 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2667 else
2668 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2670 /* One could argue that all the stuff below is not necessary for
2671 the non-bitfield case and declare it a FE error if type
2672 adjustment would be needed. */
2673 if (TREE_TYPE (expr) != type)
2675 #ifdef ENABLE_TYPES_CHECKING
2676 tree old_type = TREE_TYPE (expr);
2677 #endif
2678 int type_quals;
2680 /* We need to preserve qualifiers and propagate them from
2681 operand 0. */
2682 type_quals = TYPE_QUALS (type)
2683 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2684 if (TYPE_QUALS (type) != type_quals)
2685 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2687 /* Set the type of the COMPONENT_REF to the underlying type. */
2688 TREE_TYPE (expr) = type;
2690 #ifdef ENABLE_TYPES_CHECKING
2691 /* It is now a FE error, if the conversion from the canonical
2692 type to the original expression type is not useless. */
2693 gcc_assert (useless_type_conversion_p (old_type, type));
2694 #endif
2698 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2699 to foo, embed that change in the ADDR_EXPR by converting
2700 T array[U];
2701 (T *)&array
2703 &array[L]
2704 where L is the lower bound. For simplicity, only do this for constant
2705 lower bound.
2706 The constraint is that the type of &array[L] is trivially convertible
2707 to T *. */
2709 static void
2710 canonicalize_addr_expr (tree *expr_p)
2712 tree expr = *expr_p;
2713 tree addr_expr = TREE_OPERAND (expr, 0);
2714 tree datype, ddatype, pddatype;
2716 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2717 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2718 || TREE_CODE (addr_expr) != ADDR_EXPR)
2719 return;
2721 /* The addr_expr type should be a pointer to an array. */
2722 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2723 if (TREE_CODE (datype) != ARRAY_TYPE)
2724 return;
2726 /* The pointer to element type shall be trivially convertible to
2727 the expression pointer type. */
2728 ddatype = TREE_TYPE (datype);
2729 pddatype = build_pointer_type (ddatype);
2730 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2731 pddatype))
2732 return;
2734 /* The lower bound and element sizes must be constant. */
2735 if (!TYPE_SIZE_UNIT (ddatype)
2736 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2737 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2738 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2739 return;
2741 /* All checks succeeded. Build a new node to merge the cast. */
2742 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2743 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2744 NULL_TREE, NULL_TREE);
2745 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2747 /* We can have stripped a required restrict qualifier above. */
2748 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2749 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2752 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2753 underneath as appropriate. */
2755 static enum gimplify_status
2756 gimplify_conversion (tree *expr_p)
2758 location_t loc = EXPR_LOCATION (*expr_p);
2759 gcc_assert (CONVERT_EXPR_P (*expr_p));
2761 /* Then strip away all but the outermost conversion. */
2762 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
2764 /* And remove the outermost conversion if it's useless. */
2765 if (tree_ssa_useless_type_conversion (*expr_p))
2766 *expr_p = TREE_OPERAND (*expr_p, 0);
2768 /* If we still have a conversion at the toplevel,
2769 then canonicalize some constructs. */
2770 if (CONVERT_EXPR_P (*expr_p))
2772 tree sub = TREE_OPERAND (*expr_p, 0);
2774 /* If a NOP conversion is changing the type of a COMPONENT_REF
2775 expression, then canonicalize its type now in order to expose more
2776 redundant conversions. */
2777 if (TREE_CODE (sub) == COMPONENT_REF)
2778 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
2780 /* If a NOP conversion is changing a pointer to array of foo
2781 to a pointer to foo, embed that change in the ADDR_EXPR. */
2782 else if (TREE_CODE (sub) == ADDR_EXPR)
2783 canonicalize_addr_expr (expr_p);
2786 /* If we have a conversion to a non-register type force the
2787 use of a VIEW_CONVERT_EXPR instead. */
2788 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
2789 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
2790 TREE_OPERAND (*expr_p, 0));
2792 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2793 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
2794 TREE_SET_CODE (*expr_p, NOP_EXPR);
2796 return GS_OK;
2799 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2800 DECL_VALUE_EXPR, and it's worth re-examining things. */
2802 static enum gimplify_status
2803 gimplify_var_or_parm_decl (tree *expr_p)
2805 tree decl = *expr_p;
2807 /* ??? If this is a local variable, and it has not been seen in any
2808 outer BIND_EXPR, then it's probably the result of a duplicate
2809 declaration, for which we've already issued an error. It would
2810 be really nice if the front end wouldn't leak these at all.
2811 Currently the only known culprit is C++ destructors, as seen
2812 in g++.old-deja/g++.jason/binding.C. */
2813 if (VAR_P (decl)
2814 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
2815 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
2816 && decl_function_context (decl) == current_function_decl)
2818 gcc_assert (seen_error ());
2819 return GS_ERROR;
2822 /* When within an OMP context, notice uses of variables. */
2823 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
2824 return GS_ALL_DONE;
2826 /* If the decl is an alias for another expression, substitute it now. */
2827 if (DECL_HAS_VALUE_EXPR_P (decl))
2829 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
2830 return GS_OK;
2833 return GS_ALL_DONE;
2836 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2838 static void
2839 recalculate_side_effects (tree t)
2841 enum tree_code code = TREE_CODE (t);
2842 int len = TREE_OPERAND_LENGTH (t);
2843 int i;
2845 switch (TREE_CODE_CLASS (code))
2847 case tcc_expression:
2848 switch (code)
2850 case INIT_EXPR:
2851 case MODIFY_EXPR:
2852 case VA_ARG_EXPR:
2853 case PREDECREMENT_EXPR:
2854 case PREINCREMENT_EXPR:
2855 case POSTDECREMENT_EXPR:
2856 case POSTINCREMENT_EXPR:
2857 /* All of these have side-effects, no matter what their
2858 operands are. */
2859 return;
2861 default:
2862 break;
2864 /* Fall through. */
2866 case tcc_comparison: /* a comparison expression */
2867 case tcc_unary: /* a unary arithmetic expression */
2868 case tcc_binary: /* a binary arithmetic expression */
2869 case tcc_reference: /* a reference */
2870 case tcc_vl_exp: /* a function call */
2871 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
2872 for (i = 0; i < len; ++i)
2874 tree op = TREE_OPERAND (t, i);
2875 if (op && TREE_SIDE_EFFECTS (op))
2876 TREE_SIDE_EFFECTS (t) = 1;
2878 break;
2880 case tcc_constant:
2881 /* No side-effects. */
2882 return;
2884 default:
2885 gcc_unreachable ();
2889 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
2890 node *EXPR_P.
2892 compound_lval
2893 : min_lval '[' val ']'
2894 | min_lval '.' ID
2895 | compound_lval '[' val ']'
2896 | compound_lval '.' ID
2898 This is not part of the original SIMPLE definition, which separates
2899 array and member references, but it seems reasonable to handle them
2900 together. Also, this way we don't run into problems with union
2901 aliasing; gcc requires that for accesses through a union to alias, the
2902 union reference must be explicit, which was not always the case when we
2903 were splitting up array and member refs.
2905 PRE_P points to the sequence where side effects that must happen before
2906 *EXPR_P should be stored.
2908 POST_P points to the sequence where side effects that must happen after
2909 *EXPR_P should be stored. */
2911 static enum gimplify_status
2912 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2913 fallback_t fallback)
2915 tree *p;
2916 enum gimplify_status ret = GS_ALL_DONE, tret;
2917 int i;
2918 location_t loc = EXPR_LOCATION (*expr_p);
2919 tree expr = *expr_p;
2921 /* Create a stack of the subexpressions so later we can walk them in
2922 order from inner to outer. */
2923 auto_vec<tree, 10> expr_stack;
2925 /* We can handle anything that get_inner_reference can deal with. */
2926 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
2928 restart:
2929 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
2930 if (TREE_CODE (*p) == INDIRECT_REF)
2931 *p = fold_indirect_ref_loc (loc, *p);
2933 if (handled_component_p (*p))
2935 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
2936 additional COMPONENT_REFs. */
2937 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
2938 && gimplify_var_or_parm_decl (p) == GS_OK)
2939 goto restart;
2940 else
2941 break;
2943 expr_stack.safe_push (*p);
2946 gcc_assert (expr_stack.length ());
2948 /* Now EXPR_STACK is a stack of pointers to all the refs we've
2949 walked through and P points to the innermost expression.
2951 Java requires that we elaborated nodes in source order. That
2952 means we must gimplify the inner expression followed by each of
2953 the indices, in order. But we can't gimplify the inner
2954 expression until we deal with any variable bounds, sizes, or
2955 positions in order to deal with PLACEHOLDER_EXPRs.
2957 So we do this in three steps. First we deal with the annotations
2958 for any variables in the components, then we gimplify the base,
2959 then we gimplify any indices, from left to right. */
2960 for (i = expr_stack.length () - 1; i >= 0; i--)
2962 tree t = expr_stack[i];
2964 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2966 /* Gimplify the low bound and element type size and put them into
2967 the ARRAY_REF. If these values are set, they have already been
2968 gimplified. */
2969 if (TREE_OPERAND (t, 2) == NULL_TREE)
2971 tree low = unshare_expr (array_ref_low_bound (t));
2972 if (!is_gimple_min_invariant (low))
2974 TREE_OPERAND (t, 2) = low;
2975 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2976 post_p, is_gimple_reg,
2977 fb_rvalue);
2978 ret = MIN (ret, tret);
2981 else
2983 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2984 is_gimple_reg, fb_rvalue);
2985 ret = MIN (ret, tret);
2988 if (TREE_OPERAND (t, 3) == NULL_TREE)
2990 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
2991 tree elmt_size = unshare_expr (array_ref_element_size (t));
2992 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
2994 /* Divide the element size by the alignment of the element
2995 type (above). */
2996 elmt_size
2997 = size_binop_loc (loc, EXACT_DIV_EXPR, elmt_size, factor);
2999 if (!is_gimple_min_invariant (elmt_size))
3001 TREE_OPERAND (t, 3) = elmt_size;
3002 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
3003 post_p, is_gimple_reg,
3004 fb_rvalue);
3005 ret = MIN (ret, tret);
3008 else
3010 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
3011 is_gimple_reg, fb_rvalue);
3012 ret = MIN (ret, tret);
3015 else if (TREE_CODE (t) == COMPONENT_REF)
3017 /* Set the field offset into T and gimplify it. */
3018 if (TREE_OPERAND (t, 2) == NULL_TREE)
3020 tree offset = unshare_expr (component_ref_field_offset (t));
3021 tree field = TREE_OPERAND (t, 1);
3022 tree factor
3023 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
3025 /* Divide the offset by its alignment. */
3026 offset = size_binop_loc (loc, EXACT_DIV_EXPR, offset, factor);
3028 if (!is_gimple_min_invariant (offset))
3030 TREE_OPERAND (t, 2) = offset;
3031 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
3032 post_p, is_gimple_reg,
3033 fb_rvalue);
3034 ret = MIN (ret, tret);
3037 else
3039 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3040 is_gimple_reg, fb_rvalue);
3041 ret = MIN (ret, tret);
3046 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3047 so as to match the min_lval predicate. Failure to do so may result
3048 in the creation of large aggregate temporaries. */
3049 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
3050 fallback | fb_lvalue);
3051 ret = MIN (ret, tret);
3053 /* And finally, the indices and operands of ARRAY_REF. During this
3054 loop we also remove any useless conversions. */
3055 for (; expr_stack.length () > 0; )
3057 tree t = expr_stack.pop ();
3059 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3061 /* Gimplify the dimension. */
3062 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
3064 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
3065 is_gimple_val, fb_rvalue);
3066 ret = MIN (ret, tret);
3070 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
3072 /* The innermost expression P may have originally had
3073 TREE_SIDE_EFFECTS set which would have caused all the outer
3074 expressions in *EXPR_P leading to P to also have had
3075 TREE_SIDE_EFFECTS set. */
3076 recalculate_side_effects (t);
3079 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3080 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
3082 canonicalize_component_ref (expr_p);
3085 expr_stack.release ();
3087 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
3089 return ret;
3092 /* Gimplify the self modifying expression pointed to by EXPR_P
3093 (++, --, +=, -=).
3095 PRE_P points to the list where side effects that must happen before
3096 *EXPR_P should be stored.
3098 POST_P points to the list where side effects that must happen after
3099 *EXPR_P should be stored.
3101 WANT_VALUE is nonzero iff we want to use the value of this expression
3102 in another expression.
3104 ARITH_TYPE is the type the computation should be performed in. */
3106 enum gimplify_status
3107 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3108 bool want_value, tree arith_type)
3110 enum tree_code code;
3111 tree lhs, lvalue, rhs, t1;
3112 gimple_seq post = NULL, *orig_post_p = post_p;
3113 bool postfix;
3114 enum tree_code arith_code;
3115 enum gimplify_status ret;
3116 location_t loc = EXPR_LOCATION (*expr_p);
3118 code = TREE_CODE (*expr_p);
3120 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3121 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3123 /* Prefix or postfix? */
3124 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3125 /* Faster to treat as prefix if result is not used. */
3126 postfix = want_value;
3127 else
3128 postfix = false;
3130 /* For postfix, make sure the inner expression's post side effects
3131 are executed after side effects from this expression. */
3132 if (postfix)
3133 post_p = &post;
3135 /* Add or subtract? */
3136 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3137 arith_code = PLUS_EXPR;
3138 else
3139 arith_code = MINUS_EXPR;
3141 /* Gimplify the LHS into a GIMPLE lvalue. */
3142 lvalue = TREE_OPERAND (*expr_p, 0);
3143 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3144 if (ret == GS_ERROR)
3145 return ret;
3147 /* Extract the operands to the arithmetic operation. */
3148 lhs = lvalue;
3149 rhs = TREE_OPERAND (*expr_p, 1);
3151 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3152 that as the result value and in the postqueue operation. */
3153 if (postfix)
3155 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3156 if (ret == GS_ERROR)
3157 return ret;
3159 lhs = get_initialized_tmp_var (lhs, pre_p);
3162 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3163 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3165 rhs = convert_to_ptrofftype_loc (loc, rhs);
3166 if (arith_code == MINUS_EXPR)
3167 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3168 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3170 else
3171 t1 = fold_convert (TREE_TYPE (*expr_p),
3172 fold_build2 (arith_code, arith_type,
3173 fold_convert (arith_type, lhs),
3174 fold_convert (arith_type, rhs)));
3176 if (postfix)
3178 gimplify_assign (lvalue, t1, pre_p);
3179 gimplify_seq_add_seq (orig_post_p, post);
3180 *expr_p = lhs;
3181 return GS_ALL_DONE;
3183 else
3185 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3186 return GS_OK;
3190 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3192 static void
3193 maybe_with_size_expr (tree *expr_p)
3195 tree expr = *expr_p;
3196 tree type = TREE_TYPE (expr);
3197 tree size;
3199 /* If we've already wrapped this or the type is error_mark_node, we can't do
3200 anything. */
3201 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3202 || type == error_mark_node)
3203 return;
3205 /* If the size isn't known or is a constant, we have nothing to do. */
3206 size = TYPE_SIZE_UNIT (type);
3207 if (!size || poly_int_tree_p (size))
3208 return;
3210 /* Otherwise, make a WITH_SIZE_EXPR. */
3211 size = unshare_expr (size);
3212 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3213 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3216 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3217 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3218 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3219 gimplified to an SSA name. */
3221 enum gimplify_status
3222 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3223 bool allow_ssa)
3225 bool (*test) (tree);
3226 fallback_t fb;
3228 /* In general, we allow lvalues for function arguments to avoid
3229 extra overhead of copying large aggregates out of even larger
3230 aggregates into temporaries only to copy the temporaries to
3231 the argument list. Make optimizers happy by pulling out to
3232 temporaries those types that fit in registers. */
3233 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3234 test = is_gimple_val, fb = fb_rvalue;
3235 else
3237 test = is_gimple_lvalue, fb = fb_either;
3238 /* Also strip a TARGET_EXPR that would force an extra copy. */
3239 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3241 tree init = TARGET_EXPR_INITIAL (*arg_p);
3242 if (init
3243 && !VOID_TYPE_P (TREE_TYPE (init)))
3244 *arg_p = init;
3248 /* If this is a variable sized type, we must remember the size. */
3249 maybe_with_size_expr (arg_p);
3251 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3252 /* Make sure arguments have the same location as the function call
3253 itself. */
3254 protected_set_expr_location (*arg_p, call_location);
3256 /* There is a sequence point before a function call. Side effects in
3257 the argument list must occur before the actual call. So, when
3258 gimplifying arguments, force gimplify_expr to use an internal
3259 post queue which is then appended to the end of PRE_P. */
3260 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3263 /* Don't fold inside offloading or taskreg regions: it can break code by
3264 adding decl references that weren't in the source. We'll do it during
3265 omplower pass instead. */
3267 static bool
3268 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3270 struct gimplify_omp_ctx *ctx;
3271 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3272 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3273 return false;
3274 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3275 return false;
3276 /* Delay folding of builtins until the IL is in consistent state
3277 so the diagnostic machinery can do a better job. */
3278 if (gimple_call_builtin_p (gsi_stmt (*gsi)))
3279 return false;
3280 return fold_stmt (gsi);
3283 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3284 WANT_VALUE is true if the result of the call is desired. */
3286 static enum gimplify_status
3287 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3289 tree fndecl, parms, p, fnptrtype;
3290 enum gimplify_status ret;
3291 int i, nargs;
3292 gcall *call;
3293 bool builtin_va_start_p = false;
3294 location_t loc = EXPR_LOCATION (*expr_p);
3296 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3298 /* For reliable diagnostics during inlining, it is necessary that
3299 every call_expr be annotated with file and line. */
3300 if (! EXPR_HAS_LOCATION (*expr_p))
3301 SET_EXPR_LOCATION (*expr_p, input_location);
3303 /* Gimplify internal functions created in the FEs. */
3304 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3306 if (want_value)
3307 return GS_ALL_DONE;
3309 nargs = call_expr_nargs (*expr_p);
3310 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3311 auto_vec<tree> vargs (nargs);
3313 for (i = 0; i < nargs; i++)
3315 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3316 EXPR_LOCATION (*expr_p));
3317 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3320 gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3321 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3322 gimplify_seq_add_stmt (pre_p, call);
3323 return GS_ALL_DONE;
3326 /* This may be a call to a builtin function.
3328 Builtin function calls may be transformed into different
3329 (and more efficient) builtin function calls under certain
3330 circumstances. Unfortunately, gimplification can muck things
3331 up enough that the builtin expanders are not aware that certain
3332 transformations are still valid.
3334 So we attempt transformation/gimplification of the call before
3335 we gimplify the CALL_EXPR. At this time we do not manage to
3336 transform all calls in the same manner as the expanders do, but
3337 we do transform most of them. */
3338 fndecl = get_callee_fndecl (*expr_p);
3339 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3340 switch (DECL_FUNCTION_CODE (fndecl))
3342 CASE_BUILT_IN_ALLOCA:
3343 /* If the call has been built for a variable-sized object, then we
3344 want to restore the stack level when the enclosing BIND_EXPR is
3345 exited to reclaim the allocated space; otherwise, we precisely
3346 need to do the opposite and preserve the latest stack level. */
3347 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3348 gimplify_ctxp->save_stack = true;
3349 else
3350 gimplify_ctxp->keep_stack = true;
3351 break;
3353 case BUILT_IN_VA_START:
3355 builtin_va_start_p = TRUE;
3356 if (call_expr_nargs (*expr_p) < 2)
3358 error ("too few arguments to function %<va_start%>");
3359 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3360 return GS_OK;
3363 if (fold_builtin_next_arg (*expr_p, true))
3365 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3366 return GS_OK;
3368 break;
3371 case BUILT_IN_EH_RETURN:
3372 cfun->calls_eh_return = true;
3373 break;
3375 default:
3378 if (fndecl && fndecl_built_in_p (fndecl))
3380 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3381 if (new_tree && new_tree != *expr_p)
3383 /* There was a transformation of this call which computes the
3384 same value, but in a more efficient way. Return and try
3385 again. */
3386 *expr_p = new_tree;
3387 return GS_OK;
3391 /* Remember the original function pointer type. */
3392 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3394 if (flag_openmp
3395 && fndecl
3396 && cfun
3397 && (cfun->curr_properties & PROP_gimple_any) == 0)
3399 tree variant = omp_resolve_declare_variant (fndecl);
3400 if (variant != fndecl)
3401 CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
3404 /* There is a sequence point before the call, so any side effects in
3405 the calling expression must occur before the actual call. Force
3406 gimplify_expr to use an internal post queue. */
3407 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3408 is_gimple_call_addr, fb_rvalue);
3410 nargs = call_expr_nargs (*expr_p);
3412 /* Get argument types for verification. */
3413 fndecl = get_callee_fndecl (*expr_p);
3414 parms = NULL_TREE;
3415 if (fndecl)
3416 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3417 else
3418 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3420 if (fndecl && DECL_ARGUMENTS (fndecl))
3421 p = DECL_ARGUMENTS (fndecl);
3422 else if (parms)
3423 p = parms;
3424 else
3425 p = NULL_TREE;
3426 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3429 /* If the last argument is __builtin_va_arg_pack () and it is not
3430 passed as a named argument, decrease the number of CALL_EXPR
3431 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3432 if (!p
3433 && i < nargs
3434 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3436 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3437 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3439 if (last_arg_fndecl
3440 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3442 tree call = *expr_p;
3444 --nargs;
3445 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3446 CALL_EXPR_FN (call),
3447 nargs, CALL_EXPR_ARGP (call));
3449 /* Copy all CALL_EXPR flags, location and block, except
3450 CALL_EXPR_VA_ARG_PACK flag. */
3451 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3452 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3453 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3454 = CALL_EXPR_RETURN_SLOT_OPT (call);
3455 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3456 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3458 /* Set CALL_EXPR_VA_ARG_PACK. */
3459 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3463 /* If the call returns twice then after building the CFG the call
3464 argument computations will no longer dominate the call because
3465 we add an abnormal incoming edge to the call. So do not use SSA
3466 vars there. */
3467 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3469 /* Gimplify the function arguments. */
3470 if (nargs > 0)
3472 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3473 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3474 PUSH_ARGS_REVERSED ? i-- : i++)
3476 enum gimplify_status t;
3478 /* Avoid gimplifying the second argument to va_start, which needs to
3479 be the plain PARM_DECL. */
3480 if ((i != 1) || !builtin_va_start_p)
3482 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3483 EXPR_LOCATION (*expr_p), ! returns_twice);
3485 if (t == GS_ERROR)
3486 ret = GS_ERROR;
3491 /* Gimplify the static chain. */
3492 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3494 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3495 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3496 else
3498 enum gimplify_status t;
3499 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3500 EXPR_LOCATION (*expr_p), ! returns_twice);
3501 if (t == GS_ERROR)
3502 ret = GS_ERROR;
3506 /* Verify the function result. */
3507 if (want_value && fndecl
3508 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3510 error_at (loc, "using result of function returning %<void%>");
3511 ret = GS_ERROR;
3514 /* Try this again in case gimplification exposed something. */
3515 if (ret != GS_ERROR)
3517 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3519 if (new_tree && new_tree != *expr_p)
3521 /* There was a transformation of this call which computes the
3522 same value, but in a more efficient way. Return and try
3523 again. */
3524 *expr_p = new_tree;
3525 return GS_OK;
3528 else
3530 *expr_p = error_mark_node;
3531 return GS_ERROR;
3534 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3535 decl. This allows us to eliminate redundant or useless
3536 calls to "const" functions. */
3537 if (TREE_CODE (*expr_p) == CALL_EXPR)
3539 int flags = call_expr_flags (*expr_p);
3540 if (flags & (ECF_CONST | ECF_PURE)
3541 /* An infinite loop is considered a side effect. */
3542 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3543 TREE_SIDE_EFFECTS (*expr_p) = 0;
3546 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3547 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3548 form and delegate the creation of a GIMPLE_CALL to
3549 gimplify_modify_expr. This is always possible because when
3550 WANT_VALUE is true, the caller wants the result of this call into
3551 a temporary, which means that we will emit an INIT_EXPR in
3552 internal_get_tmp_var which will then be handled by
3553 gimplify_modify_expr. */
3554 if (!want_value)
3556 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3557 have to do is replicate it as a GIMPLE_CALL tuple. */
3558 gimple_stmt_iterator gsi;
3559 call = gimple_build_call_from_tree (*expr_p, fnptrtype);
3560 notice_special_calls (call);
3561 gimplify_seq_add_stmt (pre_p, call);
3562 gsi = gsi_last (*pre_p);
3563 maybe_fold_stmt (&gsi);
3564 *expr_p = NULL_TREE;
3566 else
3567 /* Remember the original function type. */
3568 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3569 CALL_EXPR_FN (*expr_p));
3571 return ret;
3574 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3575 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3577 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3578 condition is true or false, respectively. If null, we should generate
3579 our own to skip over the evaluation of this specific expression.
3581 LOCUS is the source location of the COND_EXPR.
3583 This function is the tree equivalent of do_jump.
3585 shortcut_cond_r should only be called by shortcut_cond_expr. */
3587 static tree
3588 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3589 location_t locus)
3591 tree local_label = NULL_TREE;
3592 tree t, expr = NULL;
3594 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3595 retain the shortcut semantics. Just insert the gotos here;
3596 shortcut_cond_expr will append the real blocks later. */
3597 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3599 location_t new_locus;
3601 /* Turn if (a && b) into
3603 if (a); else goto no;
3604 if (b) goto yes; else goto no;
3605 (no:) */
3607 if (false_label_p == NULL)
3608 false_label_p = &local_label;
3610 /* Keep the original source location on the first 'if'. */
3611 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3612 append_to_statement_list (t, &expr);
3614 /* Set the source location of the && on the second 'if'. */
3615 new_locus = rexpr_location (pred, locus);
3616 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3617 new_locus);
3618 append_to_statement_list (t, &expr);
3620 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3622 location_t new_locus;
3624 /* Turn if (a || b) into
3626 if (a) goto yes;
3627 if (b) goto yes; else goto no;
3628 (yes:) */
3630 if (true_label_p == NULL)
3631 true_label_p = &local_label;
3633 /* Keep the original source location on the first 'if'. */
3634 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3635 append_to_statement_list (t, &expr);
3637 /* Set the source location of the || on the second 'if'. */
3638 new_locus = rexpr_location (pred, locus);
3639 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3640 new_locus);
3641 append_to_statement_list (t, &expr);
3643 else if (TREE_CODE (pred) == COND_EXPR
3644 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3645 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3647 location_t new_locus;
3649 /* As long as we're messing with gotos, turn if (a ? b : c) into
3650 if (a)
3651 if (b) goto yes; else goto no;
3652 else
3653 if (c) goto yes; else goto no;
3655 Don't do this if one of the arms has void type, which can happen
3656 in C++ when the arm is throw. */
3658 /* Keep the original source location on the first 'if'. Set the source
3659 location of the ? on the second 'if'. */
3660 new_locus = rexpr_location (pred, locus);
3661 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3662 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3663 false_label_p, locus),
3664 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3665 false_label_p, new_locus));
3667 else
3669 expr = build3 (COND_EXPR, void_type_node, pred,
3670 build_and_jump (true_label_p),
3671 build_and_jump (false_label_p));
3672 SET_EXPR_LOCATION (expr, locus);
3675 if (local_label)
3677 t = build1 (LABEL_EXPR, void_type_node, local_label);
3678 append_to_statement_list (t, &expr);
3681 return expr;
3684 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3685 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3686 statement, if it is the last one. Otherwise, return NULL. */
3688 static tree
3689 find_goto (tree expr)
3691 if (!expr)
3692 return NULL_TREE;
3694 if (TREE_CODE (expr) == GOTO_EXPR)
3695 return expr;
3697 if (TREE_CODE (expr) != STATEMENT_LIST)
3698 return NULL_TREE;
3700 tree_stmt_iterator i = tsi_start (expr);
3702 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
3703 tsi_next (&i);
3705 if (!tsi_one_before_end_p (i))
3706 return NULL_TREE;
3708 return find_goto (tsi_stmt (i));
3711 /* Same as find_goto, except that it returns NULL if the destination
3712 is not a LABEL_DECL. */
3714 static inline tree
3715 find_goto_label (tree expr)
3717 tree dest = find_goto (expr);
3718 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
3719 return dest;
3720 return NULL_TREE;
3723 /* Given a conditional expression EXPR with short-circuit boolean
3724 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3725 predicate apart into the equivalent sequence of conditionals. */
3727 static tree
3728 shortcut_cond_expr (tree expr)
3730 tree pred = TREE_OPERAND (expr, 0);
3731 tree then_ = TREE_OPERAND (expr, 1);
3732 tree else_ = TREE_OPERAND (expr, 2);
3733 tree true_label, false_label, end_label, t;
3734 tree *true_label_p;
3735 tree *false_label_p;
3736 bool emit_end, emit_false, jump_over_else;
3737 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3738 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3740 /* First do simple transformations. */
3741 if (!else_se)
3743 /* If there is no 'else', turn
3744 if (a && b) then c
3745 into
3746 if (a) if (b) then c. */
3747 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3749 /* Keep the original source location on the first 'if'. */
3750 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3751 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3752 /* Set the source location of the && on the second 'if'. */
3753 if (rexpr_has_location (pred))
3754 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3755 then_ = shortcut_cond_expr (expr);
3756 then_se = then_ && TREE_SIDE_EFFECTS (then_);
3757 pred = TREE_OPERAND (pred, 0);
3758 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
3759 SET_EXPR_LOCATION (expr, locus);
3763 if (!then_se)
3765 /* If there is no 'then', turn
3766 if (a || b); else d
3767 into
3768 if (a); else if (b); else d. */
3769 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3771 /* Keep the original source location on the first 'if'. */
3772 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3773 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3774 /* Set the source location of the || on the second 'if'. */
3775 if (rexpr_has_location (pred))
3776 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3777 else_ = shortcut_cond_expr (expr);
3778 else_se = else_ && TREE_SIDE_EFFECTS (else_);
3779 pred = TREE_OPERAND (pred, 0);
3780 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
3781 SET_EXPR_LOCATION (expr, locus);
3785 /* If we're done, great. */
3786 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
3787 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
3788 return expr;
3790 /* Otherwise we need to mess with gotos. Change
3791 if (a) c; else d;
3793 if (a); else goto no;
3794 c; goto end;
3795 no: d; end:
3796 and recursively gimplify the condition. */
3798 true_label = false_label = end_label = NULL_TREE;
3800 /* If our arms just jump somewhere, hijack those labels so we don't
3801 generate jumps to jumps. */
3803 if (tree then_goto = find_goto_label (then_))
3805 true_label = GOTO_DESTINATION (then_goto);
3806 then_ = NULL;
3807 then_se = false;
3810 if (tree else_goto = find_goto_label (else_))
3812 false_label = GOTO_DESTINATION (else_goto);
3813 else_ = NULL;
3814 else_se = false;
3817 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3818 if (true_label)
3819 true_label_p = &true_label;
3820 else
3821 true_label_p = NULL;
3823 /* The 'else' branch also needs a label if it contains interesting code. */
3824 if (false_label || else_se)
3825 false_label_p = &false_label;
3826 else
3827 false_label_p = NULL;
3829 /* If there was nothing else in our arms, just forward the label(s). */
3830 if (!then_se && !else_se)
3831 return shortcut_cond_r (pred, true_label_p, false_label_p,
3832 EXPR_LOC_OR_LOC (expr, input_location));
3834 /* If our last subexpression already has a terminal label, reuse it. */
3835 if (else_se)
3836 t = expr_last (else_);
3837 else if (then_se)
3838 t = expr_last (then_);
3839 else
3840 t = NULL;
3841 if (t && TREE_CODE (t) == LABEL_EXPR)
3842 end_label = LABEL_EXPR_LABEL (t);
3844 /* If we don't care about jumping to the 'else' branch, jump to the end
3845 if the condition is false. */
3846 if (!false_label_p)
3847 false_label_p = &end_label;
3849 /* We only want to emit these labels if we aren't hijacking them. */
3850 emit_end = (end_label == NULL_TREE);
3851 emit_false = (false_label == NULL_TREE);
3853 /* We only emit the jump over the else clause if we have to--if the
3854 then clause may fall through. Otherwise we can wind up with a
3855 useless jump and a useless label at the end of gimplified code,
3856 which will cause us to think that this conditional as a whole
3857 falls through even if it doesn't. If we then inline a function
3858 which ends with such a condition, that can cause us to issue an
3859 inappropriate warning about control reaching the end of a
3860 non-void function. */
3861 jump_over_else = block_may_fallthru (then_);
3863 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
3864 EXPR_LOC_OR_LOC (expr, input_location));
3866 expr = NULL;
3867 append_to_statement_list (pred, &expr);
3869 append_to_statement_list (then_, &expr);
3870 if (else_se)
3872 if (jump_over_else)
3874 tree last = expr_last (expr);
3875 t = build_and_jump (&end_label);
3876 if (rexpr_has_location (last))
3877 SET_EXPR_LOCATION (t, rexpr_location (last));
3878 append_to_statement_list (t, &expr);
3880 if (emit_false)
3882 t = build1 (LABEL_EXPR, void_type_node, false_label);
3883 append_to_statement_list (t, &expr);
3885 append_to_statement_list (else_, &expr);
3887 if (emit_end && end_label)
3889 t = build1 (LABEL_EXPR, void_type_node, end_label);
3890 append_to_statement_list (t, &expr);
3893 return expr;
3896 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
3898 tree
3899 gimple_boolify (tree expr)
3901 tree type = TREE_TYPE (expr);
3902 location_t loc = EXPR_LOCATION (expr);
3904 if (TREE_CODE (expr) == NE_EXPR
3905 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
3906 && integer_zerop (TREE_OPERAND (expr, 1)))
3908 tree call = TREE_OPERAND (expr, 0);
3909 tree fn = get_callee_fndecl (call);
3911 /* For __builtin_expect ((long) (x), y) recurse into x as well
3912 if x is truth_value_p. */
3913 if (fn
3914 && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
3915 && call_expr_nargs (call) == 2)
3917 tree arg = CALL_EXPR_ARG (call, 0);
3918 if (arg)
3920 if (TREE_CODE (arg) == NOP_EXPR
3921 && TREE_TYPE (arg) == TREE_TYPE (call))
3922 arg = TREE_OPERAND (arg, 0);
3923 if (truth_value_p (TREE_CODE (arg)))
3925 arg = gimple_boolify (arg);
3926 CALL_EXPR_ARG (call, 0)
3927 = fold_convert_loc (loc, TREE_TYPE (call), arg);
3933 switch (TREE_CODE (expr))
3935 case TRUTH_AND_EXPR:
3936 case TRUTH_OR_EXPR:
3937 case TRUTH_XOR_EXPR:
3938 case TRUTH_ANDIF_EXPR:
3939 case TRUTH_ORIF_EXPR:
3940 /* Also boolify the arguments of truth exprs. */
3941 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
3942 /* FALLTHRU */
3944 case TRUTH_NOT_EXPR:
3945 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3947 /* These expressions always produce boolean results. */
3948 if (TREE_CODE (type) != BOOLEAN_TYPE)
3949 TREE_TYPE (expr) = boolean_type_node;
3950 return expr;
3952 case ANNOTATE_EXPR:
3953 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
3955 case annot_expr_ivdep_kind:
3956 case annot_expr_unroll_kind:
3957 case annot_expr_no_vector_kind:
3958 case annot_expr_vector_kind:
3959 case annot_expr_parallel_kind:
3960 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3961 if (TREE_CODE (type) != BOOLEAN_TYPE)
3962 TREE_TYPE (expr) = boolean_type_node;
3963 return expr;
3964 default:
3965 gcc_unreachable ();
3968 default:
3969 if (COMPARISON_CLASS_P (expr))
3971 /* There expressions always prduce boolean results. */
3972 if (TREE_CODE (type) != BOOLEAN_TYPE)
3973 TREE_TYPE (expr) = boolean_type_node;
3974 return expr;
3976 /* Other expressions that get here must have boolean values, but
3977 might need to be converted to the appropriate mode. */
3978 if (TREE_CODE (type) == BOOLEAN_TYPE)
3979 return expr;
3980 return fold_convert_loc (loc, boolean_type_node, expr);
3984 /* Given a conditional expression *EXPR_P without side effects, gimplify
3985 its operands. New statements are inserted to PRE_P. */
3987 static enum gimplify_status
3988 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
3990 tree expr = *expr_p, cond;
3991 enum gimplify_status ret, tret;
3992 enum tree_code code;
3994 cond = gimple_boolify (COND_EXPR_COND (expr));
3996 /* We need to handle && and || specially, as their gimplification
3997 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
3998 code = TREE_CODE (cond);
3999 if (code == TRUTH_ANDIF_EXPR)
4000 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
4001 else if (code == TRUTH_ORIF_EXPR)
4002 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
4003 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
4004 COND_EXPR_COND (*expr_p) = cond;
4006 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
4007 is_gimple_val, fb_rvalue);
4008 ret = MIN (ret, tret);
4009 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
4010 is_gimple_val, fb_rvalue);
4012 return MIN (ret, tret);
4015 /* Return true if evaluating EXPR could trap.
4016 EXPR is GENERIC, while tree_could_trap_p can be called
4017 only on GIMPLE. */
4019 bool
4020 generic_expr_could_trap_p (tree expr)
4022 unsigned i, n;
4024 if (!expr || is_gimple_val (expr))
4025 return false;
4027 if (!EXPR_P (expr) || tree_could_trap_p (expr))
4028 return true;
4030 n = TREE_OPERAND_LENGTH (expr);
4031 for (i = 0; i < n; i++)
4032 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
4033 return true;
4035 return false;
4038 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4039 into
4041 if (p) if (p)
4042 t1 = a; a;
4043 else or else
4044 t1 = b; b;
4047 The second form is used when *EXPR_P is of type void.
4049 PRE_P points to the list where side effects that must happen before
4050 *EXPR_P should be stored. */
4052 static enum gimplify_status
4053 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
4055 tree expr = *expr_p;
4056 tree type = TREE_TYPE (expr);
4057 location_t loc = EXPR_LOCATION (expr);
4058 tree tmp, arm1, arm2;
4059 enum gimplify_status ret;
4060 tree label_true, label_false, label_cont;
4061 bool have_then_clause_p, have_else_clause_p;
4062 gcond *cond_stmt;
4063 enum tree_code pred_code;
4064 gimple_seq seq = NULL;
4066 /* If this COND_EXPR has a value, copy the values into a temporary within
4067 the arms. */
4068 if (!VOID_TYPE_P (type))
4070 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
4071 tree result;
4073 /* If either an rvalue is ok or we do not require an lvalue, create the
4074 temporary. But we cannot do that if the type is addressable. */
4075 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
4076 && !TREE_ADDRESSABLE (type))
4078 if (gimplify_ctxp->allow_rhs_cond_expr
4079 /* If either branch has side effects or could trap, it can't be
4080 evaluated unconditionally. */
4081 && !TREE_SIDE_EFFECTS (then_)
4082 && !generic_expr_could_trap_p (then_)
4083 && !TREE_SIDE_EFFECTS (else_)
4084 && !generic_expr_could_trap_p (else_))
4085 return gimplify_pure_cond_expr (expr_p, pre_p);
4087 tmp = create_tmp_var (type, "iftmp");
4088 result = tmp;
4091 /* Otherwise, only create and copy references to the values. */
4092 else
4094 type = build_pointer_type (type);
4096 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4097 then_ = build_fold_addr_expr_loc (loc, then_);
4099 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4100 else_ = build_fold_addr_expr_loc (loc, else_);
4102 expr
4103 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
4105 tmp = create_tmp_var (type, "iftmp");
4106 result = build_simple_mem_ref_loc (loc, tmp);
4109 /* Build the new then clause, `tmp = then_;'. But don't build the
4110 assignment if the value is void; in C++ it can be if it's a throw. */
4111 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4112 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
4114 /* Similarly, build the new else clause, `tmp = else_;'. */
4115 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4116 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
4118 TREE_TYPE (expr) = void_type_node;
4119 recalculate_side_effects (expr);
4121 /* Move the COND_EXPR to the prequeue. */
4122 gimplify_stmt (&expr, pre_p);
4124 *expr_p = result;
4125 return GS_ALL_DONE;
4128 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4129 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4130 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4131 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4133 /* Make sure the condition has BOOLEAN_TYPE. */
4134 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4136 /* Break apart && and || conditions. */
4137 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4138 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4140 expr = shortcut_cond_expr (expr);
4142 if (expr != *expr_p)
4144 *expr_p = expr;
4146 /* We can't rely on gimplify_expr to re-gimplify the expanded
4147 form properly, as cleanups might cause the target labels to be
4148 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4149 set up a conditional context. */
4150 gimple_push_condition ();
4151 gimplify_stmt (expr_p, &seq);
4152 gimple_pop_condition (pre_p);
4153 gimple_seq_add_seq (pre_p, seq);
4155 return GS_ALL_DONE;
4159 /* Now do the normal gimplification. */
4161 /* Gimplify condition. */
4162 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
4163 is_gimple_condexpr_for_cond, fb_rvalue);
4164 if (ret == GS_ERROR)
4165 return GS_ERROR;
4166 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4168 gimple_push_condition ();
4170 have_then_clause_p = have_else_clause_p = false;
4171 label_true = find_goto_label (TREE_OPERAND (expr, 1));
4172 if (label_true
4173 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4174 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4175 have different locations, otherwise we end up with incorrect
4176 location information on the branches. */
4177 && (optimize
4178 || !EXPR_HAS_LOCATION (expr)
4179 || !rexpr_has_location (label_true)
4180 || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4182 have_then_clause_p = true;
4183 label_true = GOTO_DESTINATION (label_true);
4185 else
4186 label_true = create_artificial_label (UNKNOWN_LOCATION);
4187 label_false = find_goto_label (TREE_OPERAND (expr, 2));
4188 if (label_false
4189 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4190 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4191 have different locations, otherwise we end up with incorrect
4192 location information on the branches. */
4193 && (optimize
4194 || !EXPR_HAS_LOCATION (expr)
4195 || !rexpr_has_location (label_false)
4196 || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4198 have_else_clause_p = true;
4199 label_false = GOTO_DESTINATION (label_false);
4201 else
4202 label_false = create_artificial_label (UNKNOWN_LOCATION);
4204 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4205 &arm2);
4206 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4207 label_false);
4208 gimple_set_no_warning (cond_stmt, TREE_NO_WARNING (COND_EXPR_COND (expr)));
4209 gimplify_seq_add_stmt (&seq, cond_stmt);
4210 gimple_stmt_iterator gsi = gsi_last (seq);
4211 maybe_fold_stmt (&gsi);
4213 label_cont = NULL_TREE;
4214 if (!have_then_clause_p)
4216 /* For if (...) {} else { code; } put label_true after
4217 the else block. */
4218 if (TREE_OPERAND (expr, 1) == NULL_TREE
4219 && !have_else_clause_p
4220 && TREE_OPERAND (expr, 2) != NULL_TREE)
4221 label_cont = label_true;
4222 else
4224 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4225 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4226 /* For if (...) { code; } else {} or
4227 if (...) { code; } else goto label; or
4228 if (...) { code; return; } else { ... }
4229 label_cont isn't needed. */
4230 if (!have_else_clause_p
4231 && TREE_OPERAND (expr, 2) != NULL_TREE
4232 && gimple_seq_may_fallthru (seq))
4234 gimple *g;
4235 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4237 g = gimple_build_goto (label_cont);
4239 /* GIMPLE_COND's are very low level; they have embedded
4240 gotos. This particular embedded goto should not be marked
4241 with the location of the original COND_EXPR, as it would
4242 correspond to the COND_EXPR's condition, not the ELSE or the
4243 THEN arms. To avoid marking it with the wrong location, flag
4244 it as "no location". */
4245 gimple_set_do_not_emit_location (g);
4247 gimplify_seq_add_stmt (&seq, g);
4251 if (!have_else_clause_p)
4253 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4254 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4256 if (label_cont)
4257 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4259 gimple_pop_condition (pre_p);
4260 gimple_seq_add_seq (pre_p, seq);
4262 if (ret == GS_ERROR)
4263 ; /* Do nothing. */
4264 else if (have_then_clause_p || have_else_clause_p)
4265 ret = GS_ALL_DONE;
4266 else
4268 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4269 expr = TREE_OPERAND (expr, 0);
4270 gimplify_stmt (&expr, pre_p);
4273 *expr_p = NULL;
4274 return ret;
4277 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4278 to be marked addressable.
4280 We cannot rely on such an expression being directly markable if a temporary
4281 has been created by the gimplification. In this case, we create another
4282 temporary and initialize it with a copy, which will become a store after we
4283 mark it addressable. This can happen if the front-end passed us something
4284 that it could not mark addressable yet, like a Fortran pass-by-reference
4285 parameter (int) floatvar. */
4287 static void
4288 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4290 while (handled_component_p (*expr_p))
4291 expr_p = &TREE_OPERAND (*expr_p, 0);
4292 if (is_gimple_reg (*expr_p))
4294 /* Do not allow an SSA name as the temporary. */
4295 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
4296 DECL_GIMPLE_REG_P (var) = 0;
4297 *expr_p = var;
4301 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4302 a call to __builtin_memcpy. */
4304 static enum gimplify_status
4305 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4306 gimple_seq *seq_p)
4308 tree t, to, to_ptr, from, from_ptr;
4309 gcall *gs;
4310 location_t loc = EXPR_LOCATION (*expr_p);
4312 to = TREE_OPERAND (*expr_p, 0);
4313 from = TREE_OPERAND (*expr_p, 1);
4315 /* Mark the RHS addressable. Beware that it may not be possible to do so
4316 directly if a temporary has been created by the gimplification. */
4317 prepare_gimple_addressable (&from, seq_p);
4319 mark_addressable (from);
4320 from_ptr = build_fold_addr_expr_loc (loc, from);
4321 gimplify_arg (&from_ptr, seq_p, loc);
4323 mark_addressable (to);
4324 to_ptr = build_fold_addr_expr_loc (loc, to);
4325 gimplify_arg (&to_ptr, seq_p, loc);
4327 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4329 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4331 if (want_value)
4333 /* tmp = memcpy() */
4334 t = create_tmp_var (TREE_TYPE (to_ptr));
4335 gimple_call_set_lhs (gs, t);
4336 gimplify_seq_add_stmt (seq_p, gs);
4338 *expr_p = build_simple_mem_ref (t);
4339 return GS_ALL_DONE;
4342 gimplify_seq_add_stmt (seq_p, gs);
4343 *expr_p = NULL;
4344 return GS_ALL_DONE;
4347 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4348 a call to __builtin_memset. In this case we know that the RHS is
4349 a CONSTRUCTOR with an empty element list. */
4351 static enum gimplify_status
4352 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4353 gimple_seq *seq_p)
4355 tree t, from, to, to_ptr;
4356 gcall *gs;
4357 location_t loc = EXPR_LOCATION (*expr_p);
4359 /* Assert our assumptions, to abort instead of producing wrong code
4360 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4361 not be immediately exposed. */
4362 from = TREE_OPERAND (*expr_p, 1);
4363 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4364 from = TREE_OPERAND (from, 0);
4366 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4367 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4369 /* Now proceed. */
4370 to = TREE_OPERAND (*expr_p, 0);
4372 to_ptr = build_fold_addr_expr_loc (loc, to);
4373 gimplify_arg (&to_ptr, seq_p, loc);
4374 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4376 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4378 if (want_value)
4380 /* tmp = memset() */
4381 t = create_tmp_var (TREE_TYPE (to_ptr));
4382 gimple_call_set_lhs (gs, t);
4383 gimplify_seq_add_stmt (seq_p, gs);
4385 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4386 return GS_ALL_DONE;
4389 gimplify_seq_add_stmt (seq_p, gs);
4390 *expr_p = NULL;
4391 return GS_ALL_DONE;
4394 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4395 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4396 assignment. Return non-null if we detect a potential overlap. */
4398 struct gimplify_init_ctor_preeval_data
4400 /* The base decl of the lhs object. May be NULL, in which case we
4401 have to assume the lhs is indirect. */
4402 tree lhs_base_decl;
4404 /* The alias set of the lhs object. */
4405 alias_set_type lhs_alias_set;
4408 static tree
4409 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4411 struct gimplify_init_ctor_preeval_data *data
4412 = (struct gimplify_init_ctor_preeval_data *) xdata;
4413 tree t = *tp;
4415 /* If we find the base object, obviously we have overlap. */
4416 if (data->lhs_base_decl == t)
4417 return t;
4419 /* If the constructor component is indirect, determine if we have a
4420 potential overlap with the lhs. The only bits of information we
4421 have to go on at this point are addressability and alias sets. */
4422 if ((INDIRECT_REF_P (t)
4423 || TREE_CODE (t) == MEM_REF)
4424 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4425 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4426 return t;
4428 /* If the constructor component is a call, determine if it can hide a
4429 potential overlap with the lhs through an INDIRECT_REF like above.
4430 ??? Ugh - this is completely broken. In fact this whole analysis
4431 doesn't look conservative. */
4432 if (TREE_CODE (t) == CALL_EXPR)
4434 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4436 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4437 if (POINTER_TYPE_P (TREE_VALUE (type))
4438 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4439 && alias_sets_conflict_p (data->lhs_alias_set,
4440 get_alias_set
4441 (TREE_TYPE (TREE_VALUE (type)))))
4442 return t;
4445 if (IS_TYPE_OR_DECL_P (t))
4446 *walk_subtrees = 0;
4447 return NULL;
4450 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4451 force values that overlap with the lhs (as described by *DATA)
4452 into temporaries. */
4454 static void
4455 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4456 struct gimplify_init_ctor_preeval_data *data)
4458 enum gimplify_status one;
4460 /* If the value is constant, then there's nothing to pre-evaluate. */
4461 if (TREE_CONSTANT (*expr_p))
4463 /* Ensure it does not have side effects, it might contain a reference to
4464 the object we're initializing. */
4465 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4466 return;
4469 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4470 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4471 return;
4473 /* Recurse for nested constructors. */
4474 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4476 unsigned HOST_WIDE_INT ix;
4477 constructor_elt *ce;
4478 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4480 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4481 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4483 return;
4486 /* If this is a variable sized type, we must remember the size. */
4487 maybe_with_size_expr (expr_p);
4489 /* Gimplify the constructor element to something appropriate for the rhs
4490 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4491 the gimplifier will consider this a store to memory. Doing this
4492 gimplification now means that we won't have to deal with complicated
4493 language-specific trees, nor trees like SAVE_EXPR that can induce
4494 exponential search behavior. */
4495 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4496 if (one == GS_ERROR)
4498 *expr_p = NULL;
4499 return;
4502 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4503 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4504 always be true for all scalars, since is_gimple_mem_rhs insists on a
4505 temporary variable for them. */
4506 if (DECL_P (*expr_p))
4507 return;
4509 /* If this is of variable size, we have no choice but to assume it doesn't
4510 overlap since we can't make a temporary for it. */
4511 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4512 return;
4514 /* Otherwise, we must search for overlap ... */
4515 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4516 return;
4518 /* ... and if found, force the value into a temporary. */
4519 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4522 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4523 a RANGE_EXPR in a CONSTRUCTOR for an array.
4525 var = lower;
4526 loop_entry:
4527 object[var] = value;
4528 if (var == upper)
4529 goto loop_exit;
4530 var = var + 1;
4531 goto loop_entry;
4532 loop_exit:
4534 We increment var _after_ the loop exit check because we might otherwise
4535 fail if upper == TYPE_MAX_VALUE (type for upper).
4537 Note that we never have to deal with SAVE_EXPRs here, because this has
4538 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4540 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4541 gimple_seq *, bool);
4543 static void
4544 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4545 tree value, tree array_elt_type,
4546 gimple_seq *pre_p, bool cleared)
4548 tree loop_entry_label, loop_exit_label, fall_thru_label;
4549 tree var, var_type, cref, tmp;
4551 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4552 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4553 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4555 /* Create and initialize the index variable. */
4556 var_type = TREE_TYPE (upper);
4557 var = create_tmp_var (var_type);
4558 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4560 /* Add the loop entry label. */
4561 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4563 /* Build the reference. */
4564 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4565 var, NULL_TREE, NULL_TREE);
4567 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4568 the store. Otherwise just assign value to the reference. */
4570 if (TREE_CODE (value) == CONSTRUCTOR)
4571 /* NB we might have to call ourself recursively through
4572 gimplify_init_ctor_eval if the value is a constructor. */
4573 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4574 pre_p, cleared);
4575 else
4576 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4578 /* We exit the loop when the index var is equal to the upper bound. */
4579 gimplify_seq_add_stmt (pre_p,
4580 gimple_build_cond (EQ_EXPR, var, upper,
4581 loop_exit_label, fall_thru_label));
4583 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4585 /* Otherwise, increment the index var... */
4586 tmp = build2 (PLUS_EXPR, var_type, var,
4587 fold_convert (var_type, integer_one_node));
4588 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4590 /* ...and jump back to the loop entry. */
4591 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4593 /* Add the loop exit label. */
4594 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4597 /* Return true if FDECL is accessing a field that is zero sized. */
4599 static bool
4600 zero_sized_field_decl (const_tree fdecl)
4602 if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl)
4603 && integer_zerop (DECL_SIZE (fdecl)))
4604 return true;
4605 return false;
4608 /* Return true if TYPE is zero sized. */
4610 static bool
4611 zero_sized_type (const_tree type)
4613 if (AGGREGATE_TYPE_P (type) && TYPE_SIZE (type)
4614 && integer_zerop (TYPE_SIZE (type)))
4615 return true;
4616 return false;
4619 /* A subroutine of gimplify_init_constructor. Generate individual
4620 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4621 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4622 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4623 zeroed first. */
4625 static void
4626 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4627 gimple_seq *pre_p, bool cleared)
4629 tree array_elt_type = NULL;
4630 unsigned HOST_WIDE_INT ix;
4631 tree purpose, value;
4633 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4634 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4636 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4638 tree cref;
4640 /* NULL values are created above for gimplification errors. */
4641 if (value == NULL)
4642 continue;
4644 if (cleared && initializer_zerop (value))
4645 continue;
4647 /* ??? Here's to hoping the front end fills in all of the indices,
4648 so we don't have to figure out what's missing ourselves. */
4649 gcc_assert (purpose);
4651 /* Skip zero-sized fields, unless value has side-effects. This can
4652 happen with calls to functions returning a zero-sized type, which
4653 we shouldn't discard. As a number of downstream passes don't
4654 expect sets of zero-sized fields, we rely on the gimplification of
4655 the MODIFY_EXPR we make below to drop the assignment statement. */
4656 if (! TREE_SIDE_EFFECTS (value) && zero_sized_field_decl (purpose))
4657 continue;
4659 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4660 whole range. */
4661 if (TREE_CODE (purpose) == RANGE_EXPR)
4663 tree lower = TREE_OPERAND (purpose, 0);
4664 tree upper = TREE_OPERAND (purpose, 1);
4666 /* If the lower bound is equal to upper, just treat it as if
4667 upper was the index. */
4668 if (simple_cst_equal (lower, upper))
4669 purpose = upper;
4670 else
4672 gimplify_init_ctor_eval_range (object, lower, upper, value,
4673 array_elt_type, pre_p, cleared);
4674 continue;
4678 if (array_elt_type)
4680 /* Do not use bitsizetype for ARRAY_REF indices. */
4681 if (TYPE_DOMAIN (TREE_TYPE (object)))
4682 purpose
4683 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4684 purpose);
4685 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4686 purpose, NULL_TREE, NULL_TREE);
4688 else
4690 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4691 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4692 unshare_expr (object), purpose, NULL_TREE);
4695 if (TREE_CODE (value) == CONSTRUCTOR
4696 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4697 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4698 pre_p, cleared);
4699 else
4701 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4702 gimplify_and_add (init, pre_p);
4703 ggc_free (init);
4708 /* Return the appropriate RHS predicate for this LHS. */
4710 gimple_predicate
4711 rhs_predicate_for (tree lhs)
4713 if (is_gimple_reg (lhs))
4714 return is_gimple_reg_rhs_or_call;
4715 else
4716 return is_gimple_mem_rhs_or_call;
4719 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4720 before the LHS has been gimplified. */
4722 static gimple_predicate
4723 initial_rhs_predicate_for (tree lhs)
4725 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4726 return is_gimple_reg_rhs_or_call;
4727 else
4728 return is_gimple_mem_rhs_or_call;
4731 /* Gimplify a C99 compound literal expression. This just means adding
4732 the DECL_EXPR before the current statement and using its anonymous
4733 decl instead. */
4735 static enum gimplify_status
4736 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
4737 bool (*gimple_test_f) (tree),
4738 fallback_t fallback)
4740 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
4741 tree decl = DECL_EXPR_DECL (decl_s);
4742 tree init = DECL_INITIAL (decl);
4743 /* Mark the decl as addressable if the compound literal
4744 expression is addressable now, otherwise it is marked too late
4745 after we gimplify the initialization expression. */
4746 if (TREE_ADDRESSABLE (*expr_p))
4747 TREE_ADDRESSABLE (decl) = 1;
4748 /* Otherwise, if we don't need an lvalue and have a literal directly
4749 substitute it. Check if it matches the gimple predicate, as
4750 otherwise we'd generate a new temporary, and we can as well just
4751 use the decl we already have. */
4752 else if (!TREE_ADDRESSABLE (decl)
4753 && !TREE_THIS_VOLATILE (decl)
4754 && init
4755 && (fallback & fb_lvalue) == 0
4756 && gimple_test_f (init))
4758 *expr_p = init;
4759 return GS_OK;
4762 /* Preliminarily mark non-addressed complex variables as eligible
4763 for promotion to gimple registers. We'll transform their uses
4764 as we find them. */
4765 if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE
4766 || TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE)
4767 && !TREE_THIS_VOLATILE (decl)
4768 && !needs_to_live_in_memory (decl))
4769 DECL_GIMPLE_REG_P (decl) = 1;
4771 /* If the decl is not addressable, then it is being used in some
4772 expression or on the right hand side of a statement, and it can
4773 be put into a readonly data section. */
4774 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
4775 TREE_READONLY (decl) = 1;
4777 /* This decl isn't mentioned in the enclosing block, so add it to the
4778 list of temps. FIXME it seems a bit of a kludge to say that
4779 anonymous artificial vars aren't pushed, but everything else is. */
4780 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
4781 gimple_add_tmp_var (decl);
4783 gimplify_and_add (decl_s, pre_p);
4784 *expr_p = decl;
4785 return GS_OK;
4788 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4789 return a new CONSTRUCTOR if something changed. */
4791 static tree
4792 optimize_compound_literals_in_ctor (tree orig_ctor)
4794 tree ctor = orig_ctor;
4795 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
4796 unsigned int idx, num = vec_safe_length (elts);
4798 for (idx = 0; idx < num; idx++)
4800 tree value = (*elts)[idx].value;
4801 tree newval = value;
4802 if (TREE_CODE (value) == CONSTRUCTOR)
4803 newval = optimize_compound_literals_in_ctor (value);
4804 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
4806 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
4807 tree decl = DECL_EXPR_DECL (decl_s);
4808 tree init = DECL_INITIAL (decl);
4810 if (!TREE_ADDRESSABLE (value)
4811 && !TREE_ADDRESSABLE (decl)
4812 && init
4813 && TREE_CODE (init) == CONSTRUCTOR)
4814 newval = optimize_compound_literals_in_ctor (init);
4816 if (newval == value)
4817 continue;
4819 if (ctor == orig_ctor)
4821 ctor = copy_node (orig_ctor);
4822 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
4823 elts = CONSTRUCTOR_ELTS (ctor);
4825 (*elts)[idx].value = newval;
4827 return ctor;
4830 /* A subroutine of gimplify_modify_expr. Break out elements of a
4831 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4833 Note that we still need to clear any elements that don't have explicit
4834 initializers, so if not all elements are initialized we keep the
4835 original MODIFY_EXPR, we just remove all of the constructor elements.
4837 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4838 GS_ERROR if we would have to create a temporary when gimplifying
4839 this constructor. Otherwise, return GS_OK.
4841 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4843 static enum gimplify_status
4844 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4845 bool want_value, bool notify_temp_creation)
4847 tree object, ctor, type;
4848 enum gimplify_status ret;
4849 vec<constructor_elt, va_gc> *elts;
4851 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
4853 if (!notify_temp_creation)
4855 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
4856 is_gimple_lvalue, fb_lvalue);
4857 if (ret == GS_ERROR)
4858 return ret;
4861 object = TREE_OPERAND (*expr_p, 0);
4862 ctor = TREE_OPERAND (*expr_p, 1)
4863 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
4864 type = TREE_TYPE (ctor);
4865 elts = CONSTRUCTOR_ELTS (ctor);
4866 ret = GS_ALL_DONE;
4868 switch (TREE_CODE (type))
4870 case RECORD_TYPE:
4871 case UNION_TYPE:
4872 case QUAL_UNION_TYPE:
4873 case ARRAY_TYPE:
4875 struct gimplify_init_ctor_preeval_data preeval_data;
4876 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
4877 HOST_WIDE_INT num_unique_nonzero_elements;
4878 bool cleared, complete_p, valid_const_initializer;
4879 /* Use readonly data for initializers of this or smaller size
4880 regardless of the num_nonzero_elements / num_unique_nonzero_elements
4881 ratio. */
4882 const HOST_WIDE_INT min_unique_size = 64;
4883 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
4884 is smaller than this, use readonly data. */
4885 const int unique_nonzero_ratio = 8;
4887 /* Aggregate types must lower constructors to initialization of
4888 individual elements. The exception is that a CONSTRUCTOR node
4889 with no elements indicates zero-initialization of the whole. */
4890 if (vec_safe_is_empty (elts))
4892 if (notify_temp_creation)
4893 return GS_OK;
4894 break;
4897 /* Fetch information about the constructor to direct later processing.
4898 We might want to make static versions of it in various cases, and
4899 can only do so if it known to be a valid constant initializer. */
4900 valid_const_initializer
4901 = categorize_ctor_elements (ctor, &num_nonzero_elements,
4902 &num_unique_nonzero_elements,
4903 &num_ctor_elements, &complete_p);
4905 /* If a const aggregate variable is being initialized, then it
4906 should never be a lose to promote the variable to be static. */
4907 if (valid_const_initializer
4908 && num_nonzero_elements > 1
4909 && TREE_READONLY (object)
4910 && VAR_P (object)
4911 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))
4912 /* For ctors that have many repeated nonzero elements
4913 represented through RANGE_EXPRs, prefer initializing
4914 those through runtime loops over copies of large amounts
4915 of data from readonly data section. */
4916 && (num_unique_nonzero_elements
4917 > num_nonzero_elements / unique_nonzero_ratio
4918 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
4919 <= (unsigned HOST_WIDE_INT) min_unique_size)))
4921 if (notify_temp_creation)
4922 return GS_ERROR;
4923 DECL_INITIAL (object) = ctor;
4924 TREE_STATIC (object) = 1;
4925 if (!DECL_NAME (object))
4926 DECL_NAME (object) = create_tmp_var_name ("C");
4927 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
4929 /* ??? C++ doesn't automatically append a .<number> to the
4930 assembler name, and even when it does, it looks at FE private
4931 data structures to figure out what that number should be,
4932 which are not set for this variable. I suppose this is
4933 important for local statics for inline functions, which aren't
4934 "local" in the object file sense. So in order to get a unique
4935 TU-local symbol, we must invoke the lhd version now. */
4936 lhd_set_decl_assembler_name (object);
4938 *expr_p = NULL_TREE;
4939 break;
4942 /* If there are "lots" of initialized elements, even discounting
4943 those that are not address constants (and thus *must* be
4944 computed at runtime), then partition the constructor into
4945 constant and non-constant parts. Block copy the constant
4946 parts in, then generate code for the non-constant parts. */
4947 /* TODO. There's code in cp/typeck.c to do this. */
4949 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
4950 /* store_constructor will ignore the clearing of variable-sized
4951 objects. Initializers for such objects must explicitly set
4952 every field that needs to be set. */
4953 cleared = false;
4954 else if (!complete_p)
4955 /* If the constructor isn't complete, clear the whole object
4956 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
4958 ??? This ought not to be needed. For any element not present
4959 in the initializer, we should simply set them to zero. Except
4960 we'd need to *find* the elements that are not present, and that
4961 requires trickery to avoid quadratic compile-time behavior in
4962 large cases or excessive memory use in small cases. */
4963 cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
4964 else if (num_ctor_elements - num_nonzero_elements
4965 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
4966 && num_nonzero_elements < num_ctor_elements / 4)
4967 /* If there are "lots" of zeros, it's more efficient to clear
4968 the memory and then set the nonzero elements. */
4969 cleared = true;
4970 else
4971 cleared = false;
4973 /* If there are "lots" of initialized elements, and all of them
4974 are valid address constants, then the entire initializer can
4975 be dropped to memory, and then memcpy'd out. Don't do this
4976 for sparse arrays, though, as it's more efficient to follow
4977 the standard CONSTRUCTOR behavior of memset followed by
4978 individual element initialization. Also don't do this for small
4979 all-zero initializers (which aren't big enough to merit
4980 clearing), and don't try to make bitwise copies of
4981 TREE_ADDRESSABLE types. */
4983 if (valid_const_initializer
4984 && !(cleared || num_nonzero_elements == 0)
4985 && !TREE_ADDRESSABLE (type))
4987 HOST_WIDE_INT size = int_size_in_bytes (type);
4988 unsigned int align;
4990 /* ??? We can still get unbounded array types, at least
4991 from the C++ front end. This seems wrong, but attempt
4992 to work around it for now. */
4993 if (size < 0)
4995 size = int_size_in_bytes (TREE_TYPE (object));
4996 if (size >= 0)
4997 TREE_TYPE (ctor) = type = TREE_TYPE (object);
5000 /* Find the maximum alignment we can assume for the object. */
5001 /* ??? Make use of DECL_OFFSET_ALIGN. */
5002 if (DECL_P (object))
5003 align = DECL_ALIGN (object);
5004 else
5005 align = TYPE_ALIGN (type);
5007 /* Do a block move either if the size is so small as to make
5008 each individual move a sub-unit move on average, or if it
5009 is so large as to make individual moves inefficient. */
5010 if (size > 0
5011 && num_nonzero_elements > 1
5012 /* For ctors that have many repeated nonzero elements
5013 represented through RANGE_EXPRs, prefer initializing
5014 those through runtime loops over copies of large amounts
5015 of data from readonly data section. */
5016 && (num_unique_nonzero_elements
5017 > num_nonzero_elements / unique_nonzero_ratio
5018 || size <= min_unique_size)
5019 && (size < num_nonzero_elements
5020 || !can_move_by_pieces (size, align)))
5022 if (notify_temp_creation)
5023 return GS_ERROR;
5025 walk_tree (&ctor, force_labels_r, NULL, NULL);
5026 ctor = tree_output_constant_def (ctor);
5027 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
5028 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
5029 TREE_OPERAND (*expr_p, 1) = ctor;
5031 /* This is no longer an assignment of a CONSTRUCTOR, but
5032 we still may have processing to do on the LHS. So
5033 pretend we didn't do anything here to let that happen. */
5034 return GS_UNHANDLED;
5038 /* If the target is volatile, we have non-zero elements and more than
5039 one field to assign, initialize the target from a temporary. */
5040 if (TREE_THIS_VOLATILE (object)
5041 && !TREE_ADDRESSABLE (type)
5042 && (num_nonzero_elements > 0 || !cleared)
5043 && vec_safe_length (elts) > 1)
5045 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
5046 TREE_OPERAND (*expr_p, 0) = temp;
5047 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
5048 *expr_p,
5049 build2 (MODIFY_EXPR, void_type_node,
5050 object, temp));
5051 return GS_OK;
5054 if (notify_temp_creation)
5055 return GS_OK;
5057 /* If there are nonzero elements and if needed, pre-evaluate to capture
5058 elements overlapping with the lhs into temporaries. We must do this
5059 before clearing to fetch the values before they are zeroed-out. */
5060 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
5062 preeval_data.lhs_base_decl = get_base_address (object);
5063 if (!DECL_P (preeval_data.lhs_base_decl))
5064 preeval_data.lhs_base_decl = NULL;
5065 preeval_data.lhs_alias_set = get_alias_set (object);
5067 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
5068 pre_p, post_p, &preeval_data);
5071 bool ctor_has_side_effects_p
5072 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
5074 if (cleared)
5076 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5077 Note that we still have to gimplify, in order to handle the
5078 case of variable sized types. Avoid shared tree structures. */
5079 CONSTRUCTOR_ELTS (ctor) = NULL;
5080 TREE_SIDE_EFFECTS (ctor) = 0;
5081 object = unshare_expr (object);
5082 gimplify_stmt (expr_p, pre_p);
5085 /* If we have not block cleared the object, or if there are nonzero
5086 elements in the constructor, or if the constructor has side effects,
5087 add assignments to the individual scalar fields of the object. */
5088 if (!cleared
5089 || num_nonzero_elements > 0
5090 || ctor_has_side_effects_p)
5091 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
5093 *expr_p = NULL_TREE;
5095 break;
5097 case COMPLEX_TYPE:
5099 tree r, i;
5101 if (notify_temp_creation)
5102 return GS_OK;
5104 /* Extract the real and imaginary parts out of the ctor. */
5105 gcc_assert (elts->length () == 2);
5106 r = (*elts)[0].value;
5107 i = (*elts)[1].value;
5108 if (r == NULL || i == NULL)
5110 tree zero = build_zero_cst (TREE_TYPE (type));
5111 if (r == NULL)
5112 r = zero;
5113 if (i == NULL)
5114 i = zero;
5117 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5118 represent creation of a complex value. */
5119 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
5121 ctor = build_complex (type, r, i);
5122 TREE_OPERAND (*expr_p, 1) = ctor;
5124 else
5126 ctor = build2 (COMPLEX_EXPR, type, r, i);
5127 TREE_OPERAND (*expr_p, 1) = ctor;
5128 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
5129 pre_p,
5130 post_p,
5131 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
5132 fb_rvalue);
5135 break;
5137 case VECTOR_TYPE:
5139 unsigned HOST_WIDE_INT ix;
5140 constructor_elt *ce;
5142 if (notify_temp_creation)
5143 return GS_OK;
5145 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5146 if (TREE_CONSTANT (ctor))
5148 bool constant_p = true;
5149 tree value;
5151 /* Even when ctor is constant, it might contain non-*_CST
5152 elements, such as addresses or trapping values like
5153 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5154 in VECTOR_CST nodes. */
5155 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5156 if (!CONSTANT_CLASS_P (value))
5158 constant_p = false;
5159 break;
5162 if (constant_p)
5164 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5165 break;
5168 TREE_CONSTANT (ctor) = 0;
5171 /* Vector types use CONSTRUCTOR all the way through gimple
5172 compilation as a general initializer. */
5173 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5175 enum gimplify_status tret;
5176 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5177 fb_rvalue);
5178 if (tret == GS_ERROR)
5179 ret = GS_ERROR;
5180 else if (TREE_STATIC (ctor)
5181 && !initializer_constant_valid_p (ce->value,
5182 TREE_TYPE (ce->value)))
5183 TREE_STATIC (ctor) = 0;
5185 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5186 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5188 break;
5190 default:
5191 /* So how did we get a CONSTRUCTOR for a scalar type? */
5192 gcc_unreachable ();
5195 if (ret == GS_ERROR)
5196 return GS_ERROR;
5197 /* If we have gimplified both sides of the initializer but have
5198 not emitted an assignment, do so now. */
5199 if (*expr_p)
5201 tree lhs = TREE_OPERAND (*expr_p, 0);
5202 tree rhs = TREE_OPERAND (*expr_p, 1);
5203 if (want_value && object == lhs)
5204 lhs = unshare_expr (lhs);
5205 gassign *init = gimple_build_assign (lhs, rhs);
5206 gimplify_seq_add_stmt (pre_p, init);
5208 if (want_value)
5210 *expr_p = object;
5211 return GS_OK;
5213 else
5215 *expr_p = NULL;
5216 return GS_ALL_DONE;
5220 /* Given a pointer value OP0, return a simplified version of an
5221 indirection through OP0, or NULL_TREE if no simplification is
5222 possible. This may only be applied to a rhs of an expression.
5223 Note that the resulting type may be different from the type pointed
5224 to in the sense that it is still compatible from the langhooks
5225 point of view. */
5227 static tree
5228 gimple_fold_indirect_ref_rhs (tree t)
5230 return gimple_fold_indirect_ref (t);
5233 /* Subroutine of gimplify_modify_expr to do simplifications of
5234 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5235 something changes. */
5237 static enum gimplify_status
5238 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5239 gimple_seq *pre_p, gimple_seq *post_p,
5240 bool want_value)
5242 enum gimplify_status ret = GS_UNHANDLED;
5243 bool changed;
5247 changed = false;
5248 switch (TREE_CODE (*from_p))
5250 case VAR_DECL:
5251 /* If we're assigning from a read-only variable initialized with
5252 a constructor, do the direct assignment from the constructor,
5253 but only if neither source nor target are volatile since this
5254 latter assignment might end up being done on a per-field basis. */
5255 if (DECL_INITIAL (*from_p)
5256 && TREE_READONLY (*from_p)
5257 && !TREE_THIS_VOLATILE (*from_p)
5258 && !TREE_THIS_VOLATILE (*to_p)
5259 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR)
5261 tree old_from = *from_p;
5262 enum gimplify_status subret;
5264 /* Move the constructor into the RHS. */
5265 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5267 /* Let's see if gimplify_init_constructor will need to put
5268 it in memory. */
5269 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5270 false, true);
5271 if (subret == GS_ERROR)
5273 /* If so, revert the change. */
5274 *from_p = old_from;
5276 else
5278 ret = GS_OK;
5279 changed = true;
5282 break;
5283 case INDIRECT_REF:
5285 /* If we have code like
5287 *(const A*)(A*)&x
5289 where the type of "x" is a (possibly cv-qualified variant
5290 of "A"), treat the entire expression as identical to "x".
5291 This kind of code arises in C++ when an object is bound
5292 to a const reference, and if "x" is a TARGET_EXPR we want
5293 to take advantage of the optimization below. */
5294 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5295 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5296 if (t)
5298 if (TREE_THIS_VOLATILE (t) != volatile_p)
5300 if (DECL_P (t))
5301 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5302 build_fold_addr_expr (t));
5303 if (REFERENCE_CLASS_P (t))
5304 TREE_THIS_VOLATILE (t) = volatile_p;
5306 *from_p = t;
5307 ret = GS_OK;
5308 changed = true;
5310 break;
5313 case TARGET_EXPR:
5315 /* If we are initializing something from a TARGET_EXPR, strip the
5316 TARGET_EXPR and initialize it directly, if possible. This can't
5317 be done if the initializer is void, since that implies that the
5318 temporary is set in some non-trivial way.
5320 ??? What about code that pulls out the temp and uses it
5321 elsewhere? I think that such code never uses the TARGET_EXPR as
5322 an initializer. If I'm wrong, we'll die because the temp won't
5323 have any RTL. In that case, I guess we'll need to replace
5324 references somehow. */
5325 tree init = TARGET_EXPR_INITIAL (*from_p);
5327 if (init
5328 && (TREE_CODE (*expr_p) != MODIFY_EXPR
5329 || !TARGET_EXPR_NO_ELIDE (*from_p))
5330 && !VOID_TYPE_P (TREE_TYPE (init)))
5332 *from_p = init;
5333 ret = GS_OK;
5334 changed = true;
5337 break;
5339 case COMPOUND_EXPR:
5340 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5341 caught. */
5342 gimplify_compound_expr (from_p, pre_p, true);
5343 ret = GS_OK;
5344 changed = true;
5345 break;
5347 case CONSTRUCTOR:
5348 /* If we already made some changes, let the front end have a
5349 crack at this before we break it down. */
5350 if (ret != GS_UNHANDLED)
5351 break;
5352 /* If we're initializing from a CONSTRUCTOR, break this into
5353 individual MODIFY_EXPRs. */
5354 return gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5355 false);
5357 case COND_EXPR:
5358 /* If we're assigning to a non-register type, push the assignment
5359 down into the branches. This is mandatory for ADDRESSABLE types,
5360 since we cannot generate temporaries for such, but it saves a
5361 copy in other cases as well. */
5362 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5364 /* This code should mirror the code in gimplify_cond_expr. */
5365 enum tree_code code = TREE_CODE (*expr_p);
5366 tree cond = *from_p;
5367 tree result = *to_p;
5369 ret = gimplify_expr (&result, pre_p, post_p,
5370 is_gimple_lvalue, fb_lvalue);
5371 if (ret != GS_ERROR)
5372 ret = GS_OK;
5374 /* If we are going to write RESULT more than once, clear
5375 TREE_READONLY flag, otherwise we might incorrectly promote
5376 the variable to static const and initialize it at compile
5377 time in one of the branches. */
5378 if (VAR_P (result)
5379 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5380 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5381 TREE_READONLY (result) = 0;
5382 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5383 TREE_OPERAND (cond, 1)
5384 = build2 (code, void_type_node, result,
5385 TREE_OPERAND (cond, 1));
5386 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5387 TREE_OPERAND (cond, 2)
5388 = build2 (code, void_type_node, unshare_expr (result),
5389 TREE_OPERAND (cond, 2));
5391 TREE_TYPE (cond) = void_type_node;
5392 recalculate_side_effects (cond);
5394 if (want_value)
5396 gimplify_and_add (cond, pre_p);
5397 *expr_p = unshare_expr (result);
5399 else
5400 *expr_p = cond;
5401 return ret;
5403 break;
5405 case CALL_EXPR:
5406 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5407 return slot so that we don't generate a temporary. */
5408 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5409 && aggregate_value_p (*from_p, *from_p))
5411 bool use_target;
5413 if (!(rhs_predicate_for (*to_p))(*from_p))
5414 /* If we need a temporary, *to_p isn't accurate. */
5415 use_target = false;
5416 /* It's OK to use the return slot directly unless it's an NRV. */
5417 else if (TREE_CODE (*to_p) == RESULT_DECL
5418 && DECL_NAME (*to_p) == NULL_TREE
5419 && needs_to_live_in_memory (*to_p))
5420 use_target = true;
5421 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5422 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5423 /* Don't force regs into memory. */
5424 use_target = false;
5425 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5426 /* It's OK to use the target directly if it's being
5427 initialized. */
5428 use_target = true;
5429 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5430 != INTEGER_CST)
5431 /* Always use the target and thus RSO for variable-sized types.
5432 GIMPLE cannot deal with a variable-sized assignment
5433 embedded in a call statement. */
5434 use_target = true;
5435 else if (TREE_CODE (*to_p) != SSA_NAME
5436 && (!is_gimple_variable (*to_p)
5437 || needs_to_live_in_memory (*to_p)))
5438 /* Don't use the original target if it's already addressable;
5439 if its address escapes, and the called function uses the
5440 NRV optimization, a conforming program could see *to_p
5441 change before the called function returns; see c++/19317.
5442 When optimizing, the return_slot pass marks more functions
5443 as safe after we have escape info. */
5444 use_target = false;
5445 else
5446 use_target = true;
5448 if (use_target)
5450 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5451 mark_addressable (*to_p);
5454 break;
5456 case WITH_SIZE_EXPR:
5457 /* Likewise for calls that return an aggregate of non-constant size,
5458 since we would not be able to generate a temporary at all. */
5459 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5461 *from_p = TREE_OPERAND (*from_p, 0);
5462 /* We don't change ret in this case because the
5463 WITH_SIZE_EXPR might have been added in
5464 gimplify_modify_expr, so returning GS_OK would lead to an
5465 infinite loop. */
5466 changed = true;
5468 break;
5470 /* If we're initializing from a container, push the initialization
5471 inside it. */
5472 case CLEANUP_POINT_EXPR:
5473 case BIND_EXPR:
5474 case STATEMENT_LIST:
5476 tree wrap = *from_p;
5477 tree t;
5479 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5480 fb_lvalue);
5481 if (ret != GS_ERROR)
5482 ret = GS_OK;
5484 t = voidify_wrapper_expr (wrap, *expr_p);
5485 gcc_assert (t == *expr_p);
5487 if (want_value)
5489 gimplify_and_add (wrap, pre_p);
5490 *expr_p = unshare_expr (*to_p);
5492 else
5493 *expr_p = wrap;
5494 return GS_OK;
5497 case COMPOUND_LITERAL_EXPR:
5499 tree complit = TREE_OPERAND (*expr_p, 1);
5500 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5501 tree decl = DECL_EXPR_DECL (decl_s);
5502 tree init = DECL_INITIAL (decl);
5504 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5505 into struct T x = { 0, 1, 2 } if the address of the
5506 compound literal has never been taken. */
5507 if (!TREE_ADDRESSABLE (complit)
5508 && !TREE_ADDRESSABLE (decl)
5509 && init)
5511 *expr_p = copy_node (*expr_p);
5512 TREE_OPERAND (*expr_p, 1) = init;
5513 return GS_OK;
5517 default:
5518 break;
5521 while (changed);
5523 return ret;
5527 /* Return true if T looks like a valid GIMPLE statement. */
5529 static bool
5530 is_gimple_stmt (tree t)
5532 const enum tree_code code = TREE_CODE (t);
5534 switch (code)
5536 case NOP_EXPR:
5537 /* The only valid NOP_EXPR is the empty statement. */
5538 return IS_EMPTY_STMT (t);
5540 case BIND_EXPR:
5541 case COND_EXPR:
5542 /* These are only valid if they're void. */
5543 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5545 case SWITCH_EXPR:
5546 case GOTO_EXPR:
5547 case RETURN_EXPR:
5548 case LABEL_EXPR:
5549 case CASE_LABEL_EXPR:
5550 case TRY_CATCH_EXPR:
5551 case TRY_FINALLY_EXPR:
5552 case EH_FILTER_EXPR:
5553 case CATCH_EXPR:
5554 case ASM_EXPR:
5555 case STATEMENT_LIST:
5556 case OACC_PARALLEL:
5557 case OACC_KERNELS:
5558 case OACC_SERIAL:
5559 case OACC_DATA:
5560 case OACC_HOST_DATA:
5561 case OACC_DECLARE:
5562 case OACC_UPDATE:
5563 case OACC_ENTER_DATA:
5564 case OACC_EXIT_DATA:
5565 case OACC_CACHE:
5566 case OMP_PARALLEL:
5567 case OMP_FOR:
5568 case OMP_SIMD:
5569 case OMP_DISTRIBUTE:
5570 case OMP_LOOP:
5571 case OACC_LOOP:
5572 case OMP_SCAN:
5573 case OMP_SECTIONS:
5574 case OMP_SECTION:
5575 case OMP_SINGLE:
5576 case OMP_MASTER:
5577 case OMP_TASKGROUP:
5578 case OMP_ORDERED:
5579 case OMP_CRITICAL:
5580 case OMP_TASK:
5581 case OMP_TARGET:
5582 case OMP_TARGET_DATA:
5583 case OMP_TARGET_UPDATE:
5584 case OMP_TARGET_ENTER_DATA:
5585 case OMP_TARGET_EXIT_DATA:
5586 case OMP_TASKLOOP:
5587 case OMP_TEAMS:
5588 /* These are always void. */
5589 return true;
5591 case CALL_EXPR:
5592 case MODIFY_EXPR:
5593 case PREDICT_EXPR:
5594 /* These are valid regardless of their type. */
5595 return true;
5597 default:
5598 return false;
5603 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5604 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with
5605 DECL_GIMPLE_REG_P set.
5607 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5608 other, unmodified part of the complex object just before the total store.
5609 As a consequence, if the object is still uninitialized, an undefined value
5610 will be loaded into a register, which may result in a spurious exception
5611 if the register is floating-point and the value happens to be a signaling
5612 NaN for example. Then the fully-fledged complex operations lowering pass
5613 followed by a DCE pass are necessary in order to fix things up. */
5615 static enum gimplify_status
5616 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5617 bool want_value)
5619 enum tree_code code, ocode;
5620 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5622 lhs = TREE_OPERAND (*expr_p, 0);
5623 rhs = TREE_OPERAND (*expr_p, 1);
5624 code = TREE_CODE (lhs);
5625 lhs = TREE_OPERAND (lhs, 0);
5627 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5628 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5629 TREE_NO_WARNING (other) = 1;
5630 other = get_formal_tmp_var (other, pre_p);
5632 realpart = code == REALPART_EXPR ? rhs : other;
5633 imagpart = code == REALPART_EXPR ? other : rhs;
5635 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5636 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5637 else
5638 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5640 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5641 *expr_p = (want_value) ? rhs : NULL_TREE;
5643 return GS_ALL_DONE;
5646 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5648 modify_expr
5649 : varname '=' rhs
5650 | '*' ID '=' rhs
5652 PRE_P points to the list where side effects that must happen before
5653 *EXPR_P should be stored.
5655 POST_P points to the list where side effects that must happen after
5656 *EXPR_P should be stored.
5658 WANT_VALUE is nonzero iff we want to use the value of this expression
5659 in another expression. */
5661 static enum gimplify_status
5662 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5663 bool want_value)
5665 tree *from_p = &TREE_OPERAND (*expr_p, 1);
5666 tree *to_p = &TREE_OPERAND (*expr_p, 0);
5667 enum gimplify_status ret = GS_UNHANDLED;
5668 gimple *assign;
5669 location_t loc = EXPR_LOCATION (*expr_p);
5670 gimple_stmt_iterator gsi;
5672 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
5673 || TREE_CODE (*expr_p) == INIT_EXPR);
5675 /* Trying to simplify a clobber using normal logic doesn't work,
5676 so handle it here. */
5677 if (TREE_CLOBBER_P (*from_p))
5679 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5680 if (ret == GS_ERROR)
5681 return ret;
5682 gcc_assert (!want_value);
5683 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
5685 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
5686 pre_p, post_p);
5687 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
5689 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
5690 *expr_p = NULL;
5691 return GS_ALL_DONE;
5694 /* Insert pointer conversions required by the middle-end that are not
5695 required by the frontend. This fixes middle-end type checking for
5696 for example gcc.dg/redecl-6.c. */
5697 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
5699 STRIP_USELESS_TYPE_CONVERSION (*from_p);
5700 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
5701 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
5704 /* See if any simplifications can be done based on what the RHS is. */
5705 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5706 want_value);
5707 if (ret != GS_UNHANDLED)
5708 return ret;
5710 /* For zero sized types only gimplify the left hand side and right hand
5711 side as statements and throw away the assignment. Do this after
5712 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5713 types properly. */
5714 if (zero_sized_type (TREE_TYPE (*from_p))
5715 && !want_value
5716 /* Don't do this for calls that return addressable types, expand_call
5717 relies on those having a lhs. */
5718 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
5719 && TREE_CODE (*from_p) == CALL_EXPR))
5721 gimplify_stmt (from_p, pre_p);
5722 gimplify_stmt (to_p, pre_p);
5723 *expr_p = NULL_TREE;
5724 return GS_ALL_DONE;
5727 /* If the value being copied is of variable width, compute the length
5728 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5729 before gimplifying any of the operands so that we can resolve any
5730 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5731 the size of the expression to be copied, not of the destination, so
5732 that is what we must do here. */
5733 maybe_with_size_expr (from_p);
5735 /* As a special case, we have to temporarily allow for assignments
5736 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5737 a toplevel statement, when gimplifying the GENERIC expression
5738 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5739 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5741 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5742 prevent gimplify_expr from trying to create a new temporary for
5743 foo's LHS, we tell it that it should only gimplify until it
5744 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5745 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5746 and all we need to do here is set 'a' to be its LHS. */
5748 /* Gimplify the RHS first for C++17 and bug 71104. */
5749 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
5750 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
5751 if (ret == GS_ERROR)
5752 return ret;
5754 /* Then gimplify the LHS. */
5755 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5756 twice we have to make sure to gimplify into non-SSA as otherwise
5757 the abnormal edge added later will make those defs not dominate
5758 their uses.
5759 ??? Technically this applies only to the registers used in the
5760 resulting non-register *TO_P. */
5761 bool saved_into_ssa = gimplify_ctxp->into_ssa;
5762 if (saved_into_ssa
5763 && TREE_CODE (*from_p) == CALL_EXPR
5764 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
5765 gimplify_ctxp->into_ssa = false;
5766 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5767 gimplify_ctxp->into_ssa = saved_into_ssa;
5768 if (ret == GS_ERROR)
5769 return ret;
5771 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5772 guess for the predicate was wrong. */
5773 gimple_predicate final_pred = rhs_predicate_for (*to_p);
5774 if (final_pred != initial_pred)
5776 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
5777 if (ret == GS_ERROR)
5778 return ret;
5781 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5782 size as argument to the call. */
5783 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5785 tree call = TREE_OPERAND (*from_p, 0);
5786 tree vlasize = TREE_OPERAND (*from_p, 1);
5788 if (TREE_CODE (call) == CALL_EXPR
5789 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
5791 int nargs = call_expr_nargs (call);
5792 tree type = TREE_TYPE (call);
5793 tree ap = CALL_EXPR_ARG (call, 0);
5794 tree tag = CALL_EXPR_ARG (call, 1);
5795 tree aptag = CALL_EXPR_ARG (call, 2);
5796 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
5797 IFN_VA_ARG, type,
5798 nargs + 1, ap, tag,
5799 aptag, vlasize);
5800 TREE_OPERAND (*from_p, 0) = newcall;
5804 /* Now see if the above changed *from_p to something we handle specially. */
5805 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5806 want_value);
5807 if (ret != GS_UNHANDLED)
5808 return ret;
5810 /* If we've got a variable sized assignment between two lvalues (i.e. does
5811 not involve a call), then we can make things a bit more straightforward
5812 by converting the assignment to memcpy or memset. */
5813 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5815 tree from = TREE_OPERAND (*from_p, 0);
5816 tree size = TREE_OPERAND (*from_p, 1);
5818 if (TREE_CODE (from) == CONSTRUCTOR)
5819 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
5821 if (is_gimple_addressable (from))
5823 *from_p = from;
5824 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
5825 pre_p);
5829 /* Transform partial stores to non-addressable complex variables into
5830 total stores. This allows us to use real instead of virtual operands
5831 for these variables, which improves optimization. */
5832 if ((TREE_CODE (*to_p) == REALPART_EXPR
5833 || TREE_CODE (*to_p) == IMAGPART_EXPR)
5834 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
5835 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
5837 /* Try to alleviate the effects of the gimplification creating artificial
5838 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
5839 make sure not to create DECL_DEBUG_EXPR links across functions. */
5840 if (!gimplify_ctxp->into_ssa
5841 && VAR_P (*from_p)
5842 && DECL_IGNORED_P (*from_p)
5843 && DECL_P (*to_p)
5844 && !DECL_IGNORED_P (*to_p)
5845 && decl_function_context (*to_p) == current_function_decl
5846 && decl_function_context (*from_p) == current_function_decl)
5848 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
5849 DECL_NAME (*from_p)
5850 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
5851 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
5852 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
5855 if (want_value && TREE_THIS_VOLATILE (*to_p))
5856 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
5858 if (TREE_CODE (*from_p) == CALL_EXPR)
5860 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
5861 instead of a GIMPLE_ASSIGN. */
5862 gcall *call_stmt;
5863 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
5865 /* Gimplify internal functions created in the FEs. */
5866 int nargs = call_expr_nargs (*from_p), i;
5867 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
5868 auto_vec<tree> vargs (nargs);
5870 for (i = 0; i < nargs; i++)
5872 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
5873 EXPR_LOCATION (*from_p));
5874 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
5876 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
5877 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
5878 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
5880 else
5882 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
5883 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
5884 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
5885 tree fndecl = get_callee_fndecl (*from_p);
5886 if (fndecl
5887 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
5888 && call_expr_nargs (*from_p) == 3)
5889 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
5890 CALL_EXPR_ARG (*from_p, 0),
5891 CALL_EXPR_ARG (*from_p, 1),
5892 CALL_EXPR_ARG (*from_p, 2));
5893 else
5895 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
5898 notice_special_calls (call_stmt);
5899 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
5900 gimple_call_set_lhs (call_stmt, *to_p);
5901 else if (TREE_CODE (*to_p) == SSA_NAME)
5902 /* The above is somewhat premature, avoid ICEing later for a
5903 SSA name w/o a definition. We may have uses in the GIMPLE IL.
5904 ??? This doesn't make it a default-def. */
5905 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
5907 assign = call_stmt;
5909 else
5911 assign = gimple_build_assign (*to_p, *from_p);
5912 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
5913 if (COMPARISON_CLASS_P (*from_p))
5914 gimple_set_no_warning (assign, TREE_NO_WARNING (*from_p));
5917 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
5919 /* We should have got an SSA name from the start. */
5920 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
5921 || ! gimple_in_ssa_p (cfun));
5924 gimplify_seq_add_stmt (pre_p, assign);
5925 gsi = gsi_last (*pre_p);
5926 maybe_fold_stmt (&gsi);
5928 if (want_value)
5930 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
5931 return GS_OK;
5933 else
5934 *expr_p = NULL;
5936 return GS_ALL_DONE;
5939 /* Gimplify a comparison between two variable-sized objects. Do this
5940 with a call to BUILT_IN_MEMCMP. */
5942 static enum gimplify_status
5943 gimplify_variable_sized_compare (tree *expr_p)
5945 location_t loc = EXPR_LOCATION (*expr_p);
5946 tree op0 = TREE_OPERAND (*expr_p, 0);
5947 tree op1 = TREE_OPERAND (*expr_p, 1);
5948 tree t, arg, dest, src, expr;
5950 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
5951 arg = unshare_expr (arg);
5952 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
5953 src = build_fold_addr_expr_loc (loc, op1);
5954 dest = build_fold_addr_expr_loc (loc, op0);
5955 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
5956 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
5958 expr
5959 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
5960 SET_EXPR_LOCATION (expr, loc);
5961 *expr_p = expr;
5963 return GS_OK;
5966 /* Gimplify a comparison between two aggregate objects of integral scalar
5967 mode as a comparison between the bitwise equivalent scalar values. */
5969 static enum gimplify_status
5970 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
5972 location_t loc = EXPR_LOCATION (*expr_p);
5973 tree op0 = TREE_OPERAND (*expr_p, 0);
5974 tree op1 = TREE_OPERAND (*expr_p, 1);
5976 tree type = TREE_TYPE (op0);
5977 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
5979 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
5980 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
5982 *expr_p
5983 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
5985 return GS_OK;
5988 /* Gimplify an expression sequence. This function gimplifies each
5989 expression and rewrites the original expression with the last
5990 expression of the sequence in GIMPLE form.
5992 PRE_P points to the list where the side effects for all the
5993 expressions in the sequence will be emitted.
5995 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
5997 static enum gimplify_status
5998 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
6000 tree t = *expr_p;
6004 tree *sub_p = &TREE_OPERAND (t, 0);
6006 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
6007 gimplify_compound_expr (sub_p, pre_p, false);
6008 else
6009 gimplify_stmt (sub_p, pre_p);
6011 t = TREE_OPERAND (t, 1);
6013 while (TREE_CODE (t) == COMPOUND_EXPR);
6015 *expr_p = t;
6016 if (want_value)
6017 return GS_OK;
6018 else
6020 gimplify_stmt (expr_p, pre_p);
6021 return GS_ALL_DONE;
6025 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6026 gimplify. After gimplification, EXPR_P will point to a new temporary
6027 that holds the original value of the SAVE_EXPR node.
6029 PRE_P points to the list where side effects that must happen before
6030 *EXPR_P should be stored. */
6032 static enum gimplify_status
6033 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6035 enum gimplify_status ret = GS_ALL_DONE;
6036 tree val;
6038 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
6039 val = TREE_OPERAND (*expr_p, 0);
6041 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6042 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
6044 /* The operand may be a void-valued expression. It is
6045 being executed only for its side-effects. */
6046 if (TREE_TYPE (val) == void_type_node)
6048 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
6049 is_gimple_stmt, fb_none);
6050 val = NULL;
6052 else
6053 /* The temporary may not be an SSA name as later abnormal and EH
6054 control flow may invalidate use/def domination. When in SSA
6055 form then assume there are no such issues and SAVE_EXPRs only
6056 appear via GENERIC foldings. */
6057 val = get_initialized_tmp_var (val, pre_p, post_p,
6058 gimple_in_ssa_p (cfun));
6060 TREE_OPERAND (*expr_p, 0) = val;
6061 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
6064 *expr_p = val;
6066 return ret;
6069 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6071 unary_expr
6072 : ...
6073 | '&' varname
6076 PRE_P points to the list where side effects that must happen before
6077 *EXPR_P should be stored.
6079 POST_P points to the list where side effects that must happen after
6080 *EXPR_P should be stored. */
6082 static enum gimplify_status
6083 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6085 tree expr = *expr_p;
6086 tree op0 = TREE_OPERAND (expr, 0);
6087 enum gimplify_status ret;
6088 location_t loc = EXPR_LOCATION (*expr_p);
6090 switch (TREE_CODE (op0))
6092 case INDIRECT_REF:
6093 do_indirect_ref:
6094 /* Check if we are dealing with an expression of the form '&*ptr'.
6095 While the front end folds away '&*ptr' into 'ptr', these
6096 expressions may be generated internally by the compiler (e.g.,
6097 builtins like __builtin_va_end). */
6098 /* Caution: the silent array decomposition semantics we allow for
6099 ADDR_EXPR means we can't always discard the pair. */
6100 /* Gimplification of the ADDR_EXPR operand may drop
6101 cv-qualification conversions, so make sure we add them if
6102 needed. */
6104 tree op00 = TREE_OPERAND (op0, 0);
6105 tree t_expr = TREE_TYPE (expr);
6106 tree t_op00 = TREE_TYPE (op00);
6108 if (!useless_type_conversion_p (t_expr, t_op00))
6109 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
6110 *expr_p = op00;
6111 ret = GS_OK;
6113 break;
6115 case VIEW_CONVERT_EXPR:
6116 /* Take the address of our operand and then convert it to the type of
6117 this ADDR_EXPR.
6119 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6120 all clear. The impact of this transformation is even less clear. */
6122 /* If the operand is a useless conversion, look through it. Doing so
6123 guarantees that the ADDR_EXPR and its operand will remain of the
6124 same type. */
6125 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
6126 op0 = TREE_OPERAND (op0, 0);
6128 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
6129 build_fold_addr_expr_loc (loc,
6130 TREE_OPERAND (op0, 0)));
6131 ret = GS_OK;
6132 break;
6134 case MEM_REF:
6135 if (integer_zerop (TREE_OPERAND (op0, 1)))
6136 goto do_indirect_ref;
6138 /* fall through */
6140 default:
6141 /* If we see a call to a declared builtin or see its address
6142 being taken (we can unify those cases here) then we can mark
6143 the builtin for implicit generation by GCC. */
6144 if (TREE_CODE (op0) == FUNCTION_DECL
6145 && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6146 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6147 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6149 /* We use fb_either here because the C frontend sometimes takes
6150 the address of a call that returns a struct; see
6151 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6152 the implied temporary explicit. */
6154 /* Make the operand addressable. */
6155 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6156 is_gimple_addressable, fb_either);
6157 if (ret == GS_ERROR)
6158 break;
6160 /* Then mark it. Beware that it may not be possible to do so directly
6161 if a temporary has been created by the gimplification. */
6162 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6164 op0 = TREE_OPERAND (expr, 0);
6166 /* For various reasons, the gimplification of the expression
6167 may have made a new INDIRECT_REF. */
6168 if (TREE_CODE (op0) == INDIRECT_REF)
6169 goto do_indirect_ref;
6171 mark_addressable (TREE_OPERAND (expr, 0));
6173 /* The FEs may end up building ADDR_EXPRs early on a decl with
6174 an incomplete type. Re-build ADDR_EXPRs in canonical form
6175 here. */
6176 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6177 *expr_p = build_fold_addr_expr (op0);
6179 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6180 recompute_tree_invariant_for_addr_expr (*expr_p);
6182 /* If we re-built the ADDR_EXPR add a conversion to the original type
6183 if required. */
6184 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6185 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6187 break;
6190 return ret;
6193 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6194 value; output operands should be a gimple lvalue. */
6196 static enum gimplify_status
6197 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6199 tree expr;
6200 int noutputs;
6201 const char **oconstraints;
6202 int i;
6203 tree link;
6204 const char *constraint;
6205 bool allows_mem, allows_reg, is_inout;
6206 enum gimplify_status ret, tret;
6207 gasm *stmt;
6208 vec<tree, va_gc> *inputs;
6209 vec<tree, va_gc> *outputs;
6210 vec<tree, va_gc> *clobbers;
6211 vec<tree, va_gc> *labels;
6212 tree link_next;
6214 expr = *expr_p;
6215 noutputs = list_length (ASM_OUTPUTS (expr));
6216 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6218 inputs = NULL;
6219 outputs = NULL;
6220 clobbers = NULL;
6221 labels = NULL;
6223 ret = GS_ALL_DONE;
6224 link_next = NULL_TREE;
6225 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6227 bool ok;
6228 size_t constraint_len;
6230 link_next = TREE_CHAIN (link);
6232 oconstraints[i]
6233 = constraint
6234 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6235 constraint_len = strlen (constraint);
6236 if (constraint_len == 0)
6237 continue;
6239 ok = parse_output_constraint (&constraint, i, 0, 0,
6240 &allows_mem, &allows_reg, &is_inout);
6241 if (!ok)
6243 ret = GS_ERROR;
6244 is_inout = false;
6247 /* If we can't make copies, we can only accept memory.
6248 Similarly for VLAs. */
6249 tree outtype = TREE_TYPE (TREE_VALUE (link));
6250 if (outtype != error_mark_node
6251 && (TREE_ADDRESSABLE (outtype)
6252 || !COMPLETE_TYPE_P (outtype)
6253 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
6255 if (allows_mem)
6256 allows_reg = 0;
6257 else
6259 error ("impossible constraint in %<asm%>");
6260 error ("non-memory output %d must stay in memory", i);
6261 return GS_ERROR;
6265 if (!allows_reg && allows_mem)
6266 mark_addressable (TREE_VALUE (link));
6268 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6269 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6270 fb_lvalue | fb_mayfail);
6271 if (tret == GS_ERROR)
6273 error ("invalid lvalue in %<asm%> output %d", i);
6274 ret = tret;
6277 /* If the constraint does not allow memory make sure we gimplify
6278 it to a register if it is not already but its base is. This
6279 happens for complex and vector components. */
6280 if (!allows_mem)
6282 tree op = TREE_VALUE (link);
6283 if (! is_gimple_val (op)
6284 && is_gimple_reg_type (TREE_TYPE (op))
6285 && is_gimple_reg (get_base_address (op)))
6287 tree tem = create_tmp_reg (TREE_TYPE (op));
6288 tree ass;
6289 if (is_inout)
6291 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6292 tem, unshare_expr (op));
6293 gimplify_and_add (ass, pre_p);
6295 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6296 gimplify_and_add (ass, post_p);
6298 TREE_VALUE (link) = tem;
6299 tret = GS_OK;
6303 vec_safe_push (outputs, link);
6304 TREE_CHAIN (link) = NULL_TREE;
6306 if (is_inout)
6308 /* An input/output operand. To give the optimizers more
6309 flexibility, split it into separate input and output
6310 operands. */
6311 tree input;
6312 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6313 char buf[11];
6315 /* Turn the in/out constraint into an output constraint. */
6316 char *p = xstrdup (constraint);
6317 p[0] = '=';
6318 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6320 /* And add a matching input constraint. */
6321 if (allows_reg)
6323 sprintf (buf, "%u", i);
6325 /* If there are multiple alternatives in the constraint,
6326 handle each of them individually. Those that allow register
6327 will be replaced with operand number, the others will stay
6328 unchanged. */
6329 if (strchr (p, ',') != NULL)
6331 size_t len = 0, buflen = strlen (buf);
6332 char *beg, *end, *str, *dst;
6334 for (beg = p + 1;;)
6336 end = strchr (beg, ',');
6337 if (end == NULL)
6338 end = strchr (beg, '\0');
6339 if ((size_t) (end - beg) < buflen)
6340 len += buflen + 1;
6341 else
6342 len += end - beg + 1;
6343 if (*end)
6344 beg = end + 1;
6345 else
6346 break;
6349 str = (char *) alloca (len);
6350 for (beg = p + 1, dst = str;;)
6352 const char *tem;
6353 bool mem_p, reg_p, inout_p;
6355 end = strchr (beg, ',');
6356 if (end)
6357 *end = '\0';
6358 beg[-1] = '=';
6359 tem = beg - 1;
6360 parse_output_constraint (&tem, i, 0, 0,
6361 &mem_p, &reg_p, &inout_p);
6362 if (dst != str)
6363 *dst++ = ',';
6364 if (reg_p)
6366 memcpy (dst, buf, buflen);
6367 dst += buflen;
6369 else
6371 if (end)
6372 len = end - beg;
6373 else
6374 len = strlen (beg);
6375 memcpy (dst, beg, len);
6376 dst += len;
6378 if (end)
6379 beg = end + 1;
6380 else
6381 break;
6383 *dst = '\0';
6384 input = build_string (dst - str, str);
6386 else
6387 input = build_string (strlen (buf), buf);
6389 else
6390 input = build_string (constraint_len - 1, constraint + 1);
6392 free (p);
6394 input = build_tree_list (build_tree_list (NULL_TREE, input),
6395 unshare_expr (TREE_VALUE (link)));
6396 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6400 link_next = NULL_TREE;
6401 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6403 link_next = TREE_CHAIN (link);
6404 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6405 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6406 oconstraints, &allows_mem, &allows_reg);
6408 /* If we can't make copies, we can only accept memory. */
6409 tree intype = TREE_TYPE (TREE_VALUE (link));
6410 if (intype != error_mark_node
6411 && (TREE_ADDRESSABLE (intype)
6412 || !COMPLETE_TYPE_P (intype)
6413 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
6415 if (allows_mem)
6416 allows_reg = 0;
6417 else
6419 error ("impossible constraint in %<asm%>");
6420 error ("non-memory input %d must stay in memory", i);
6421 return GS_ERROR;
6425 /* If the operand is a memory input, it should be an lvalue. */
6426 if (!allows_reg && allows_mem)
6428 tree inputv = TREE_VALUE (link);
6429 STRIP_NOPS (inputv);
6430 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6431 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6432 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6433 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6434 || TREE_CODE (inputv) == MODIFY_EXPR)
6435 TREE_VALUE (link) = error_mark_node;
6436 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6437 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6438 if (tret != GS_ERROR)
6440 /* Unlike output operands, memory inputs are not guaranteed
6441 to be lvalues by the FE, and while the expressions are
6442 marked addressable there, if it is e.g. a statement
6443 expression, temporaries in it might not end up being
6444 addressable. They might be already used in the IL and thus
6445 it is too late to make them addressable now though. */
6446 tree x = TREE_VALUE (link);
6447 while (handled_component_p (x))
6448 x = TREE_OPERAND (x, 0);
6449 if (TREE_CODE (x) == MEM_REF
6450 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6451 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6452 if ((VAR_P (x)
6453 || TREE_CODE (x) == PARM_DECL
6454 || TREE_CODE (x) == RESULT_DECL)
6455 && !TREE_ADDRESSABLE (x)
6456 && is_gimple_reg (x))
6458 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6459 input_location), 0,
6460 "memory input %d is not directly addressable",
6462 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6465 mark_addressable (TREE_VALUE (link));
6466 if (tret == GS_ERROR)
6468 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6469 "memory input %d is not directly addressable", i);
6470 ret = tret;
6473 else
6475 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6476 is_gimple_asm_val, fb_rvalue);
6477 if (tret == GS_ERROR)
6478 ret = tret;
6481 TREE_CHAIN (link) = NULL_TREE;
6482 vec_safe_push (inputs, link);
6485 link_next = NULL_TREE;
6486 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6488 link_next = TREE_CHAIN (link);
6489 TREE_CHAIN (link) = NULL_TREE;
6490 vec_safe_push (clobbers, link);
6493 link_next = NULL_TREE;
6494 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6496 link_next = TREE_CHAIN (link);
6497 TREE_CHAIN (link) = NULL_TREE;
6498 vec_safe_push (labels, link);
6501 /* Do not add ASMs with errors to the gimple IL stream. */
6502 if (ret != GS_ERROR)
6504 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6505 inputs, outputs, clobbers, labels);
6507 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
6508 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6509 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
6511 gimplify_seq_add_stmt (pre_p, stmt);
6514 return ret;
6517 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6518 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6519 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6520 return to this function.
6522 FIXME should we complexify the prequeue handling instead? Or use flags
6523 for all the cleanups and let the optimizer tighten them up? The current
6524 code seems pretty fragile; it will break on a cleanup within any
6525 non-conditional nesting. But any such nesting would be broken, anyway;
6526 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6527 and continues out of it. We can do that at the RTL level, though, so
6528 having an optimizer to tighten up try/finally regions would be a Good
6529 Thing. */
6531 static enum gimplify_status
6532 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6534 gimple_stmt_iterator iter;
6535 gimple_seq body_sequence = NULL;
6537 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6539 /* We only care about the number of conditions between the innermost
6540 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6541 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6542 int old_conds = gimplify_ctxp->conditions;
6543 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6544 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6545 gimplify_ctxp->conditions = 0;
6546 gimplify_ctxp->conditional_cleanups = NULL;
6547 gimplify_ctxp->in_cleanup_point_expr = true;
6549 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6551 gimplify_ctxp->conditions = old_conds;
6552 gimplify_ctxp->conditional_cleanups = old_cleanups;
6553 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6555 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6557 gimple *wce = gsi_stmt (iter);
6559 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6561 if (gsi_one_before_end_p (iter))
6563 /* Note that gsi_insert_seq_before and gsi_remove do not
6564 scan operands, unlike some other sequence mutators. */
6565 if (!gimple_wce_cleanup_eh_only (wce))
6566 gsi_insert_seq_before_without_update (&iter,
6567 gimple_wce_cleanup (wce),
6568 GSI_SAME_STMT);
6569 gsi_remove (&iter, true);
6570 break;
6572 else
6574 gtry *gtry;
6575 gimple_seq seq;
6576 enum gimple_try_flags kind;
6578 if (gimple_wce_cleanup_eh_only (wce))
6579 kind = GIMPLE_TRY_CATCH;
6580 else
6581 kind = GIMPLE_TRY_FINALLY;
6582 seq = gsi_split_seq_after (iter);
6584 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6585 /* Do not use gsi_replace here, as it may scan operands.
6586 We want to do a simple structural modification only. */
6587 gsi_set_stmt (&iter, gtry);
6588 iter = gsi_start (gtry->eval);
6591 else
6592 gsi_next (&iter);
6595 gimplify_seq_add_seq (pre_p, body_sequence);
6596 if (temp)
6598 *expr_p = temp;
6599 return GS_OK;
6601 else
6603 *expr_p = NULL;
6604 return GS_ALL_DONE;
6608 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6609 is the cleanup action required. EH_ONLY is true if the cleanup should
6610 only be executed if an exception is thrown, not on normal exit.
6611 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6612 only valid for clobbers. */
6614 static void
6615 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6616 bool force_uncond = false)
6618 gimple *wce;
6619 gimple_seq cleanup_stmts = NULL;
6621 /* Errors can result in improperly nested cleanups. Which results in
6622 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6623 if (seen_error ())
6624 return;
6626 if (gimple_conditional_context ())
6628 /* If we're in a conditional context, this is more complex. We only
6629 want to run the cleanup if we actually ran the initialization that
6630 necessitates it, but we want to run it after the end of the
6631 conditional context. So we wrap the try/finally around the
6632 condition and use a flag to determine whether or not to actually
6633 run the destructor. Thus
6635 test ? f(A()) : 0
6637 becomes (approximately)
6639 flag = 0;
6640 try {
6641 if (test) { A::A(temp); flag = 1; val = f(temp); }
6642 else { val = 0; }
6643 } finally {
6644 if (flag) A::~A(temp);
6648 if (force_uncond)
6650 gimplify_stmt (&cleanup, &cleanup_stmts);
6651 wce = gimple_build_wce (cleanup_stmts);
6652 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6654 else
6656 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6657 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
6658 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
6660 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
6661 gimplify_stmt (&cleanup, &cleanup_stmts);
6662 wce = gimple_build_wce (cleanup_stmts);
6664 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
6665 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6666 gimplify_seq_add_stmt (pre_p, ftrue);
6668 /* Because of this manipulation, and the EH edges that jump
6669 threading cannot redirect, the temporary (VAR) will appear
6670 to be used uninitialized. Don't warn. */
6671 TREE_NO_WARNING (var) = 1;
6674 else
6676 gimplify_stmt (&cleanup, &cleanup_stmts);
6677 wce = gimple_build_wce (cleanup_stmts);
6678 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6679 gimplify_seq_add_stmt (pre_p, wce);
6683 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6685 static enum gimplify_status
6686 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6688 tree targ = *expr_p;
6689 tree temp = TARGET_EXPR_SLOT (targ);
6690 tree init = TARGET_EXPR_INITIAL (targ);
6691 enum gimplify_status ret;
6693 bool unpoison_empty_seq = false;
6694 gimple_stmt_iterator unpoison_it;
6696 if (init)
6698 tree cleanup = NULL_TREE;
6700 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6701 to the temps list. Handle also variable length TARGET_EXPRs. */
6702 if (TREE_CODE (DECL_SIZE (temp)) != INTEGER_CST)
6704 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
6705 gimplify_type_sizes (TREE_TYPE (temp), pre_p);
6706 gimplify_vla_decl (temp, pre_p);
6708 else
6710 /* Save location where we need to place unpoisoning. It's possible
6711 that a variable will be converted to needs_to_live_in_memory. */
6712 unpoison_it = gsi_last (*pre_p);
6713 unpoison_empty_seq = gsi_end_p (unpoison_it);
6715 gimple_add_tmp_var (temp);
6718 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6719 expression is supposed to initialize the slot. */
6720 if (VOID_TYPE_P (TREE_TYPE (init)))
6721 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6722 else
6724 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
6725 init = init_expr;
6726 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6727 init = NULL;
6728 ggc_free (init_expr);
6730 if (ret == GS_ERROR)
6732 /* PR c++/28266 Make sure this is expanded only once. */
6733 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6734 return GS_ERROR;
6736 if (init)
6737 gimplify_and_add (init, pre_p);
6739 /* If needed, push the cleanup for the temp. */
6740 if (TARGET_EXPR_CLEANUP (targ))
6742 if (CLEANUP_EH_ONLY (targ))
6743 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
6744 CLEANUP_EH_ONLY (targ), pre_p);
6745 else
6746 cleanup = TARGET_EXPR_CLEANUP (targ);
6749 /* Add a clobber for the temporary going out of scope, like
6750 gimplify_bind_expr. */
6751 if (gimplify_ctxp->in_cleanup_point_expr
6752 && needs_to_live_in_memory (temp))
6754 if (flag_stack_reuse == SR_ALL)
6756 tree clobber = build_clobber (TREE_TYPE (temp));
6757 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
6758 gimple_push_cleanup (temp, clobber, false, pre_p, true);
6760 if (asan_poisoned_variables
6761 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
6762 && !TREE_STATIC (temp)
6763 && dbg_cnt (asan_use_after_scope)
6764 && !gimplify_omp_ctxp)
6766 tree asan_cleanup = build_asan_poison_call_expr (temp);
6767 if (asan_cleanup)
6769 if (unpoison_empty_seq)
6770 unpoison_it = gsi_start (*pre_p);
6772 asan_poison_variable (temp, false, &unpoison_it,
6773 unpoison_empty_seq);
6774 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
6778 if (cleanup)
6779 gimple_push_cleanup (temp, cleanup, false, pre_p);
6781 /* Only expand this once. */
6782 TREE_OPERAND (targ, 3) = init;
6783 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6785 else
6786 /* We should have expanded this before. */
6787 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
6789 *expr_p = temp;
6790 return GS_OK;
6793 /* Gimplification of expression trees. */
6795 /* Gimplify an expression which appears at statement context. The
6796 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
6797 NULL, a new sequence is allocated.
6799 Return true if we actually added a statement to the queue. */
6801 bool
6802 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
6804 gimple_seq_node last;
6806 last = gimple_seq_last (*seq_p);
6807 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
6808 return last != gimple_seq_last (*seq_p);
6811 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
6812 to CTX. If entries already exist, force them to be some flavor of private.
6813 If there is no enclosing parallel, do nothing. */
6815 void
6816 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
6818 splay_tree_node n;
6820 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
6821 return;
6825 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6826 if (n != NULL)
6828 if (n->value & GOVD_SHARED)
6829 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
6830 else if (n->value & GOVD_MAP)
6831 n->value |= GOVD_MAP_TO_ONLY;
6832 else
6833 return;
6835 else if ((ctx->region_type & ORT_TARGET) != 0)
6837 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
6838 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6839 else
6840 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
6842 else if (ctx->region_type != ORT_WORKSHARE
6843 && ctx->region_type != ORT_TASKGROUP
6844 && ctx->region_type != ORT_SIMD
6845 && ctx->region_type != ORT_ACC
6846 && !(ctx->region_type & ORT_TARGET_DATA))
6847 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6849 ctx = ctx->outer_context;
6851 while (ctx);
6854 /* Similarly for each of the type sizes of TYPE. */
6856 static void
6857 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
6859 if (type == NULL || type == error_mark_node)
6860 return;
6861 type = TYPE_MAIN_VARIANT (type);
6863 if (ctx->privatized_types->add (type))
6864 return;
6866 switch (TREE_CODE (type))
6868 case INTEGER_TYPE:
6869 case ENUMERAL_TYPE:
6870 case BOOLEAN_TYPE:
6871 case REAL_TYPE:
6872 case FIXED_POINT_TYPE:
6873 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
6874 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
6875 break;
6877 case ARRAY_TYPE:
6878 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6879 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
6880 break;
6882 case RECORD_TYPE:
6883 case UNION_TYPE:
6884 case QUAL_UNION_TYPE:
6886 tree field;
6887 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
6888 if (TREE_CODE (field) == FIELD_DECL)
6890 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
6891 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
6894 break;
6896 case POINTER_TYPE:
6897 case REFERENCE_TYPE:
6898 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6899 break;
6901 default:
6902 break;
6905 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
6906 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
6907 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
6910 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
6912 static void
6913 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
6915 splay_tree_node n;
6916 unsigned int nflags;
6917 tree t;
6919 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
6920 return;
6922 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
6923 there are constructors involved somewhere. Exception is a shared clause,
6924 there is nothing privatized in that case. */
6925 if ((flags & GOVD_SHARED) == 0
6926 && (TREE_ADDRESSABLE (TREE_TYPE (decl))
6927 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
6928 flags |= GOVD_SEEN;
6930 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6931 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
6933 /* We shouldn't be re-adding the decl with the same data
6934 sharing class. */
6935 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
6936 nflags = n->value | flags;
6937 /* The only combination of data sharing classes we should see is
6938 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
6939 reduction variables to be used in data sharing clauses. */
6940 gcc_assert ((ctx->region_type & ORT_ACC) != 0
6941 || ((nflags & GOVD_DATA_SHARE_CLASS)
6942 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
6943 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
6944 n->value = nflags;
6945 return;
6948 /* When adding a variable-sized variable, we have to handle all sorts
6949 of additional bits of data: the pointer replacement variable, and
6950 the parameters of the type. */
6951 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
6953 /* Add the pointer replacement variable as PRIVATE if the variable
6954 replacement is private, else FIRSTPRIVATE since we'll need the
6955 address of the original variable either for SHARED, or for the
6956 copy into or out of the context. */
6957 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
6959 if (flags & GOVD_MAP)
6960 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
6961 else if (flags & GOVD_PRIVATE)
6962 nflags = GOVD_PRIVATE;
6963 else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
6964 && (flags & GOVD_FIRSTPRIVATE))
6965 || (ctx->region_type == ORT_TARGET_DATA
6966 && (flags & GOVD_DATA_SHARE_CLASS) == 0))
6967 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
6968 else
6969 nflags = GOVD_FIRSTPRIVATE;
6970 nflags |= flags & GOVD_SEEN;
6971 t = DECL_VALUE_EXPR (decl);
6972 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
6973 t = TREE_OPERAND (t, 0);
6974 gcc_assert (DECL_P (t));
6975 omp_add_variable (ctx, t, nflags);
6978 /* Add all of the variable and type parameters (which should have
6979 been gimplified to a formal temporary) as FIRSTPRIVATE. */
6980 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
6981 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
6982 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
6984 /* The variable-sized variable itself is never SHARED, only some form
6985 of PRIVATE. The sharing would take place via the pointer variable
6986 which we remapped above. */
6987 if (flags & GOVD_SHARED)
6988 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
6989 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
6991 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
6992 alloca statement we generate for the variable, so make sure it
6993 is available. This isn't automatically needed for the SHARED
6994 case, since we won't be allocating local storage then.
6995 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
6996 in this case omp_notice_variable will be called later
6997 on when it is gimplified. */
6998 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
6999 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
7000 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
7002 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
7003 && lang_hooks.decls.omp_privatize_by_reference (decl))
7005 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7007 /* Similar to the direct variable sized case above, we'll need the
7008 size of references being privatized. */
7009 if ((flags & GOVD_SHARED) == 0)
7011 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7012 if (DECL_P (t))
7013 omp_notice_variable (ctx, t, true);
7017 if (n != NULL)
7018 n->value |= flags;
7019 else
7020 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
7022 /* For reductions clauses in OpenACC loop directives, by default create a
7023 copy clause on the enclosing parallel construct for carrying back the
7024 results. */
7025 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
7027 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
7028 while (outer_ctx)
7030 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
7031 if (n != NULL)
7033 /* Ignore local variables and explicitly declared clauses. */
7034 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
7035 break;
7036 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
7038 /* According to the OpenACC spec, such a reduction variable
7039 should already have a copy map on a kernels construct,
7040 verify that here. */
7041 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
7042 && (n->value & GOVD_MAP));
7044 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7046 /* Remove firstprivate and make it a copy map. */
7047 n->value &= ~GOVD_FIRSTPRIVATE;
7048 n->value |= GOVD_MAP;
7051 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7053 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
7054 GOVD_MAP | GOVD_SEEN);
7055 break;
7057 outer_ctx = outer_ctx->outer_context;
7062 /* Notice a threadprivate variable DECL used in OMP context CTX.
7063 This just prints out diagnostics about threadprivate variable uses
7064 in untied tasks. If DECL2 is non-NULL, prevent this warning
7065 on that variable. */
7067 static bool
7068 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
7069 tree decl2)
7071 splay_tree_node n;
7072 struct gimplify_omp_ctx *octx;
7074 for (octx = ctx; octx; octx = octx->outer_context)
7075 if ((octx->region_type & ORT_TARGET) != 0
7076 || octx->order_concurrent)
7078 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
7079 if (n == NULL)
7081 if (octx->order_concurrent)
7083 error ("threadprivate variable %qE used in a region with"
7084 " %<order(concurrent)%> clause", DECL_NAME (decl));
7085 error_at (octx->location, "enclosing region");
7087 else
7089 error ("threadprivate variable %qE used in target region",
7090 DECL_NAME (decl));
7091 error_at (octx->location, "enclosing target region");
7093 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
7095 if (decl2)
7096 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
7099 if (ctx->region_type != ORT_UNTIED_TASK)
7100 return false;
7101 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7102 if (n == NULL)
7104 error ("threadprivate variable %qE used in untied task",
7105 DECL_NAME (decl));
7106 error_at (ctx->location, "enclosing task");
7107 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
7109 if (decl2)
7110 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
7111 return false;
7114 /* Return true if global var DECL is device resident. */
7116 static bool
7117 device_resident_p (tree decl)
7119 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
7121 if (!attr)
7122 return false;
7124 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
7126 tree c = TREE_VALUE (t);
7127 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
7128 return true;
7131 return false;
7134 /* Return true if DECL has an ACC DECLARE attribute. */
7136 static bool
7137 is_oacc_declared (tree decl)
7139 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
7140 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
7141 return declared != NULL_TREE;
7144 /* Determine outer default flags for DECL mentioned in an OMP region
7145 but not declared in an enclosing clause.
7147 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7148 remapped firstprivate instead of shared. To some extent this is
7149 addressed in omp_firstprivatize_type_sizes, but not
7150 effectively. */
7152 static unsigned
7153 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
7154 bool in_code, unsigned flags)
7156 enum omp_clause_default_kind default_kind = ctx->default_kind;
7157 enum omp_clause_default_kind kind;
7159 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
7160 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7161 default_kind = kind;
7162 else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
7163 default_kind = OMP_CLAUSE_DEFAULT_SHARED;
7165 switch (default_kind)
7167 case OMP_CLAUSE_DEFAULT_NONE:
7169 const char *rtype;
7171 if (ctx->region_type & ORT_PARALLEL)
7172 rtype = "parallel";
7173 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
7174 rtype = "taskloop";
7175 else if (ctx->region_type & ORT_TASK)
7176 rtype = "task";
7177 else if (ctx->region_type & ORT_TEAMS)
7178 rtype = "teams";
7179 else
7180 gcc_unreachable ();
7182 error ("%qE not specified in enclosing %qs",
7183 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7184 error_at (ctx->location, "enclosing %qs", rtype);
7186 /* FALLTHRU */
7187 case OMP_CLAUSE_DEFAULT_SHARED:
7188 flags |= GOVD_SHARED;
7189 break;
7190 case OMP_CLAUSE_DEFAULT_PRIVATE:
7191 flags |= GOVD_PRIVATE;
7192 break;
7193 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7194 flags |= GOVD_FIRSTPRIVATE;
7195 break;
7196 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7197 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7198 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7199 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7201 omp_notice_variable (octx, decl, in_code);
7202 for (; octx; octx = octx->outer_context)
7204 splay_tree_node n2;
7206 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7207 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7208 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7209 continue;
7210 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7212 flags |= GOVD_FIRSTPRIVATE;
7213 goto found_outer;
7215 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7217 flags |= GOVD_SHARED;
7218 goto found_outer;
7223 if (TREE_CODE (decl) == PARM_DECL
7224 || (!is_global_var (decl)
7225 && DECL_CONTEXT (decl) == current_function_decl))
7226 flags |= GOVD_FIRSTPRIVATE;
7227 else
7228 flags |= GOVD_SHARED;
7229 found_outer:
7230 break;
7232 default:
7233 gcc_unreachable ();
7236 return flags;
7240 /* Determine outer default flags for DECL mentioned in an OACC region
7241 but not declared in an enclosing clause. */
7243 static unsigned
7244 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7246 const char *rkind;
7247 bool on_device = false;
7248 bool is_private = false;
7249 bool declared = is_oacc_declared (decl);
7250 tree type = TREE_TYPE (decl);
7252 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7253 type = TREE_TYPE (type);
7255 /* For Fortran COMMON blocks, only used variables in those blocks are
7256 transfered and remapped. The block itself will have a private clause to
7257 avoid transfering the data twice.
7258 The hook evaluates to false by default. For a variable in Fortran's COMMON
7259 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7260 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7261 the whole block. For C++ and Fortran, it can also be true under certain
7262 other conditions, if DECL_HAS_VALUE_EXPR. */
7263 if (RECORD_OR_UNION_TYPE_P (type))
7264 is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
7266 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7267 && is_global_var (decl)
7268 && device_resident_p (decl)
7269 && !is_private)
7271 on_device = true;
7272 flags |= GOVD_MAP_TO_ONLY;
7275 switch (ctx->region_type)
7277 case ORT_ACC_KERNELS:
7278 rkind = "kernels";
7280 if (is_private)
7281 flags |= GOVD_FIRSTPRIVATE;
7282 else if (AGGREGATE_TYPE_P (type))
7284 /* Aggregates default to 'present_or_copy', or 'present'. */
7285 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7286 flags |= GOVD_MAP;
7287 else
7288 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7290 else
7291 /* Scalars default to 'copy'. */
7292 flags |= GOVD_MAP | GOVD_MAP_FORCE;
7294 break;
7296 case ORT_ACC_PARALLEL:
7297 case ORT_ACC_SERIAL:
7298 rkind = ctx->region_type == ORT_ACC_PARALLEL ? "parallel" : "serial";
7300 if (is_private)
7301 flags |= GOVD_FIRSTPRIVATE;
7302 else if (on_device || declared)
7303 flags |= GOVD_MAP;
7304 else if (AGGREGATE_TYPE_P (type))
7306 /* Aggregates default to 'present_or_copy', or 'present'. */
7307 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7308 flags |= GOVD_MAP;
7309 else
7310 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7312 else
7313 /* Scalars default to 'firstprivate'. */
7314 flags |= GOVD_FIRSTPRIVATE;
7316 break;
7318 default:
7319 gcc_unreachable ();
7322 if (DECL_ARTIFICIAL (decl))
7323 ; /* We can get compiler-generated decls, and should not complain
7324 about them. */
7325 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7327 error ("%qE not specified in enclosing OpenACC %qs construct",
7328 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
7329 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
7331 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7332 ; /* Handled above. */
7333 else
7334 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7336 return flags;
7339 /* Record the fact that DECL was used within the OMP context CTX.
7340 IN_CODE is true when real code uses DECL, and false when we should
7341 merely emit default(none) errors. Return true if DECL is going to
7342 be remapped and thus DECL shouldn't be gimplified into its
7343 DECL_VALUE_EXPR (if any). */
7345 static bool
7346 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7348 splay_tree_node n;
7349 unsigned flags = in_code ? GOVD_SEEN : 0;
7350 bool ret = false, shared;
7352 if (error_operand_p (decl))
7353 return false;
7355 if (ctx->region_type == ORT_NONE)
7356 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7358 if (is_global_var (decl))
7360 /* Threadprivate variables are predetermined. */
7361 if (DECL_THREAD_LOCAL_P (decl))
7362 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7364 if (DECL_HAS_VALUE_EXPR_P (decl))
7366 if (ctx->region_type & ORT_ACC)
7367 /* For OpenACC, defer expansion of value to avoid transfering
7368 privatized common block data instead of im-/explicitly transfered
7369 variables which are in common blocks. */
7371 else
7373 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7375 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7376 return omp_notice_threadprivate_variable (ctx, decl, value);
7380 if (gimplify_omp_ctxp->outer_context == NULL
7381 && VAR_P (decl)
7382 && oacc_get_fn_attrib (current_function_decl))
7384 location_t loc = DECL_SOURCE_LOCATION (decl);
7386 if (lookup_attribute ("omp declare target link",
7387 DECL_ATTRIBUTES (decl)))
7389 error_at (loc,
7390 "%qE with %<link%> clause used in %<routine%> function",
7391 DECL_NAME (decl));
7392 return false;
7394 else if (!lookup_attribute ("omp declare target",
7395 DECL_ATTRIBUTES (decl)))
7397 error_at (loc,
7398 "%qE requires a %<declare%> directive for use "
7399 "in a %<routine%> function", DECL_NAME (decl));
7400 return false;
7405 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7406 if ((ctx->region_type & ORT_TARGET) != 0)
7408 if (ctx->region_type & ORT_ACC)
7409 /* For OpenACC, as remarked above, defer expansion. */
7410 shared = false;
7411 else
7412 shared = true;
7414 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7415 if (n == NULL)
7417 unsigned nflags = flags;
7418 if ((ctx->region_type & ORT_ACC) == 0)
7420 bool is_declare_target = false;
7421 if (is_global_var (decl)
7422 && varpool_node::get_create (decl)->offloadable)
7424 struct gimplify_omp_ctx *octx;
7425 for (octx = ctx->outer_context;
7426 octx; octx = octx->outer_context)
7428 n = splay_tree_lookup (octx->variables,
7429 (splay_tree_key)decl);
7430 if (n
7431 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7432 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7433 break;
7435 is_declare_target = octx == NULL;
7437 if (!is_declare_target)
7439 int gdmk;
7440 if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7441 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7442 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7443 == POINTER_TYPE)))
7444 gdmk = GDMK_POINTER;
7445 else if (lang_hooks.decls.omp_scalar_p (decl))
7446 gdmk = GDMK_SCALAR;
7447 else
7448 gdmk = GDMK_AGGREGATE;
7449 if (ctx->defaultmap[gdmk] == 0)
7451 tree d = lang_hooks.decls.omp_report_decl (decl);
7452 error ("%qE not specified in enclosing %<target%>",
7453 DECL_NAME (d));
7454 error_at (ctx->location, "enclosing %<target%>");
7456 else if (ctx->defaultmap[gdmk]
7457 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
7458 nflags |= ctx->defaultmap[gdmk];
7459 else
7461 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
7462 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
7467 struct gimplify_omp_ctx *octx = ctx->outer_context;
7468 if ((ctx->region_type & ORT_ACC) && octx)
7470 /* Look in outer OpenACC contexts, to see if there's a
7471 data attribute for this variable. */
7472 omp_notice_variable (octx, decl, in_code);
7474 for (; octx; octx = octx->outer_context)
7476 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7477 break;
7478 splay_tree_node n2
7479 = splay_tree_lookup (octx->variables,
7480 (splay_tree_key) decl);
7481 if (n2)
7483 if (octx->region_type == ORT_ACC_HOST_DATA)
7484 error ("variable %qE declared in enclosing "
7485 "%<host_data%> region", DECL_NAME (decl));
7486 nflags |= GOVD_MAP;
7487 if (octx->region_type == ORT_ACC_DATA
7488 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7489 nflags |= GOVD_MAP_0LEN_ARRAY;
7490 goto found_outer;
7495 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
7496 | GOVD_MAP_ALLOC_ONLY)) == flags)
7498 tree type = TREE_TYPE (decl);
7500 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
7501 && lang_hooks.decls.omp_privatize_by_reference (decl))
7502 type = TREE_TYPE (type);
7503 if (!lang_hooks.types.omp_mappable_type (type))
7505 error ("%qD referenced in target region does not have "
7506 "a mappable type", decl);
7507 nflags |= GOVD_MAP | GOVD_EXPLICIT;
7509 else
7511 if ((ctx->region_type & ORT_ACC) != 0)
7512 nflags = oacc_default_clause (ctx, decl, flags);
7513 else
7514 nflags |= GOVD_MAP;
7517 found_outer:
7518 omp_add_variable (ctx, decl, nflags);
7520 else
7522 /* If nothing changed, there's nothing left to do. */
7523 if ((n->value & flags) == flags)
7524 return ret;
7525 flags |= n->value;
7526 n->value = flags;
7528 goto do_outer;
7531 if (n == NULL)
7533 if (ctx->region_type == ORT_WORKSHARE
7534 || ctx->region_type == ORT_TASKGROUP
7535 || ctx->region_type == ORT_SIMD
7536 || ctx->region_type == ORT_ACC
7537 || (ctx->region_type & ORT_TARGET_DATA) != 0)
7538 goto do_outer;
7540 flags = omp_default_clause (ctx, decl, in_code, flags);
7542 if ((flags & GOVD_PRIVATE)
7543 && lang_hooks.decls.omp_private_outer_ref (decl))
7544 flags |= GOVD_PRIVATE_OUTER_REF;
7546 omp_add_variable (ctx, decl, flags);
7548 shared = (flags & GOVD_SHARED) != 0;
7549 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7550 goto do_outer;
7553 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7554 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7555 && DECL_SIZE (decl))
7557 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7559 splay_tree_node n2;
7560 tree t = DECL_VALUE_EXPR (decl);
7561 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7562 t = TREE_OPERAND (t, 0);
7563 gcc_assert (DECL_P (t));
7564 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7565 n2->value |= GOVD_SEEN;
7567 else if (lang_hooks.decls.omp_privatize_by_reference (decl)
7568 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7569 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7570 != INTEGER_CST))
7572 splay_tree_node n2;
7573 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7574 gcc_assert (DECL_P (t));
7575 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7576 if (n2)
7577 omp_notice_variable (ctx, t, true);
7581 if (ctx->region_type & ORT_ACC)
7582 /* For OpenACC, as remarked above, defer expansion. */
7583 shared = false;
7584 else
7585 shared = ((flags | n->value) & GOVD_SHARED) != 0;
7586 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7588 /* If nothing changed, there's nothing left to do. */
7589 if ((n->value & flags) == flags)
7590 return ret;
7591 flags |= n->value;
7592 n->value = flags;
7594 do_outer:
7595 /* If the variable is private in the current context, then we don't
7596 need to propagate anything to an outer context. */
7597 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7598 return ret;
7599 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7600 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7601 return ret;
7602 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7603 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7604 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7605 return ret;
7606 if (ctx->outer_context
7607 && omp_notice_variable (ctx->outer_context, decl, in_code))
7608 return true;
7609 return ret;
7612 /* Verify that DECL is private within CTX. If there's specific information
7613 to the contrary in the innermost scope, generate an error. */
7615 static bool
7616 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
7618 splay_tree_node n;
7620 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7621 if (n != NULL)
7623 if (n->value & GOVD_SHARED)
7625 if (ctx == gimplify_omp_ctxp)
7627 if (simd)
7628 error ("iteration variable %qE is predetermined linear",
7629 DECL_NAME (decl));
7630 else
7631 error ("iteration variable %qE should be private",
7632 DECL_NAME (decl));
7633 n->value = GOVD_PRIVATE;
7634 return true;
7636 else
7637 return false;
7639 else if ((n->value & GOVD_EXPLICIT) != 0
7640 && (ctx == gimplify_omp_ctxp
7641 || (ctx->region_type == ORT_COMBINED_PARALLEL
7642 && gimplify_omp_ctxp->outer_context == ctx)))
7644 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
7645 error ("iteration variable %qE should not be firstprivate",
7646 DECL_NAME (decl));
7647 else if ((n->value & GOVD_REDUCTION) != 0)
7648 error ("iteration variable %qE should not be reduction",
7649 DECL_NAME (decl));
7650 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
7651 error ("iteration variable %qE should not be linear",
7652 DECL_NAME (decl));
7654 return (ctx == gimplify_omp_ctxp
7655 || (ctx->region_type == ORT_COMBINED_PARALLEL
7656 && gimplify_omp_ctxp->outer_context == ctx));
7659 if (ctx->region_type != ORT_WORKSHARE
7660 && ctx->region_type != ORT_TASKGROUP
7661 && ctx->region_type != ORT_SIMD
7662 && ctx->region_type != ORT_ACC)
7663 return false;
7664 else if (ctx->outer_context)
7665 return omp_is_private (ctx->outer_context, decl, simd);
7666 return false;
7669 /* Return true if DECL is private within a parallel region
7670 that binds to the current construct's context or in parallel
7671 region's REDUCTION clause. */
7673 static bool
7674 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
7676 splay_tree_node n;
7680 ctx = ctx->outer_context;
7681 if (ctx == NULL)
7683 if (is_global_var (decl))
7684 return false;
7686 /* References might be private, but might be shared too,
7687 when checking for copyprivate, assume they might be
7688 private, otherwise assume they might be shared. */
7689 if (copyprivate)
7690 return true;
7692 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7693 return false;
7695 /* Treat C++ privatized non-static data members outside
7696 of the privatization the same. */
7697 if (omp_member_access_dummy_var (decl))
7698 return false;
7700 return true;
7703 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
7705 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7706 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
7707 continue;
7709 if (n != NULL)
7711 if ((n->value & GOVD_LOCAL) != 0
7712 && omp_member_access_dummy_var (decl))
7713 return false;
7714 return (n->value & GOVD_SHARED) == 0;
7717 while (ctx->region_type == ORT_WORKSHARE
7718 || ctx->region_type == ORT_TASKGROUP
7719 || ctx->region_type == ORT_SIMD
7720 || ctx->region_type == ORT_ACC);
7721 return false;
7724 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7726 static tree
7727 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
7729 tree t = *tp;
7731 /* If this node has been visited, unmark it and keep looking. */
7732 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
7733 return t;
7735 if (IS_TYPE_OR_DECL_P (t))
7736 *walk_subtrees = 0;
7737 return NULL_TREE;
7740 /* If *LIST_P contains any OpenMP depend clauses with iterators,
7741 lower all the depend clauses by populating corresponding depend
7742 array. Returns 0 if there are no such depend clauses, or
7743 2 if all depend clauses should be removed, 1 otherwise. */
7745 static int
7746 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
7748 tree c;
7749 gimple *g;
7750 size_t n[4] = { 0, 0, 0, 0 };
7751 bool unused[4];
7752 tree counts[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
7753 tree last_iter = NULL_TREE, last_count = NULL_TREE;
7754 size_t i, j;
7755 location_t first_loc = UNKNOWN_LOCATION;
7757 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
7758 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
7760 switch (OMP_CLAUSE_DEPEND_KIND (c))
7762 case OMP_CLAUSE_DEPEND_IN:
7763 i = 2;
7764 break;
7765 case OMP_CLAUSE_DEPEND_OUT:
7766 case OMP_CLAUSE_DEPEND_INOUT:
7767 i = 0;
7768 break;
7769 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
7770 i = 1;
7771 break;
7772 case OMP_CLAUSE_DEPEND_DEPOBJ:
7773 i = 3;
7774 break;
7775 case OMP_CLAUSE_DEPEND_SOURCE:
7776 case OMP_CLAUSE_DEPEND_SINK:
7777 continue;
7778 default:
7779 gcc_unreachable ();
7781 tree t = OMP_CLAUSE_DECL (c);
7782 if (first_loc == UNKNOWN_LOCATION)
7783 first_loc = OMP_CLAUSE_LOCATION (c);
7784 if (TREE_CODE (t) == TREE_LIST
7785 && TREE_PURPOSE (t)
7786 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
7788 if (TREE_PURPOSE (t) != last_iter)
7790 tree tcnt = size_one_node;
7791 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
7793 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
7794 is_gimple_val, fb_rvalue) == GS_ERROR
7795 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
7796 is_gimple_val, fb_rvalue) == GS_ERROR
7797 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
7798 is_gimple_val, fb_rvalue) == GS_ERROR
7799 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
7800 is_gimple_val, fb_rvalue)
7801 == GS_ERROR))
7802 return 2;
7803 tree var = TREE_VEC_ELT (it, 0);
7804 tree begin = TREE_VEC_ELT (it, 1);
7805 tree end = TREE_VEC_ELT (it, 2);
7806 tree step = TREE_VEC_ELT (it, 3);
7807 tree orig_step = TREE_VEC_ELT (it, 4);
7808 tree type = TREE_TYPE (var);
7809 tree stype = TREE_TYPE (step);
7810 location_t loc = DECL_SOURCE_LOCATION (var);
7811 tree endmbegin;
7812 /* Compute count for this iterator as
7813 orig_step > 0
7814 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
7815 : (begin > end ? (end - begin + (step + 1)) / step : 0)
7816 and compute product of those for the entire depend
7817 clause. */
7818 if (POINTER_TYPE_P (type))
7819 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
7820 stype, end, begin);
7821 else
7822 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
7823 end, begin);
7824 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
7825 step,
7826 build_int_cst (stype, 1));
7827 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
7828 build_int_cst (stype, 1));
7829 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
7830 unshare_expr (endmbegin),
7831 stepm1);
7832 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
7833 pos, step);
7834 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
7835 endmbegin, stepp1);
7836 if (TYPE_UNSIGNED (stype))
7838 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
7839 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
7841 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
7842 neg, step);
7843 step = NULL_TREE;
7844 tree cond = fold_build2_loc (loc, LT_EXPR,
7845 boolean_type_node,
7846 begin, end);
7847 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
7848 build_int_cst (stype, 0));
7849 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
7850 end, begin);
7851 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
7852 build_int_cst (stype, 0));
7853 tree osteptype = TREE_TYPE (orig_step);
7854 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
7855 orig_step,
7856 build_int_cst (osteptype, 0));
7857 tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
7858 cond, pos, neg);
7859 cnt = fold_convert_loc (loc, sizetype, cnt);
7860 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
7861 fb_rvalue) == GS_ERROR)
7862 return 2;
7863 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
7865 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
7866 fb_rvalue) == GS_ERROR)
7867 return 2;
7868 last_iter = TREE_PURPOSE (t);
7869 last_count = tcnt;
7871 if (counts[i] == NULL_TREE)
7872 counts[i] = last_count;
7873 else
7874 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
7875 PLUS_EXPR, counts[i], last_count);
7877 else
7878 n[i]++;
7880 for (i = 0; i < 4; i++)
7881 if (counts[i])
7882 break;
7883 if (i == 4)
7884 return 0;
7886 tree total = size_zero_node;
7887 for (i = 0; i < 4; i++)
7889 unused[i] = counts[i] == NULL_TREE && n[i] == 0;
7890 if (counts[i] == NULL_TREE)
7891 counts[i] = size_zero_node;
7892 if (n[i])
7893 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
7894 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
7895 fb_rvalue) == GS_ERROR)
7896 return 2;
7897 total = size_binop (PLUS_EXPR, total, counts[i]);
7900 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
7901 == GS_ERROR)
7902 return 2;
7903 bool is_old = unused[1] && unused[3];
7904 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
7905 size_int (is_old ? 1 : 4));
7906 tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
7907 tree array = create_tmp_var_raw (type);
7908 TREE_ADDRESSABLE (array) = 1;
7909 if (TREE_CODE (totalpx) != INTEGER_CST)
7911 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
7912 gimplify_type_sizes (TREE_TYPE (array), pre_p);
7913 if (gimplify_omp_ctxp)
7915 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
7916 while (ctx
7917 && (ctx->region_type == ORT_WORKSHARE
7918 || ctx->region_type == ORT_TASKGROUP
7919 || ctx->region_type == ORT_SIMD
7920 || ctx->region_type == ORT_ACC))
7921 ctx = ctx->outer_context;
7922 if (ctx)
7923 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
7925 gimplify_vla_decl (array, pre_p);
7927 else
7928 gimple_add_tmp_var (array);
7929 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
7930 NULL_TREE);
7931 tree tem;
7932 if (!is_old)
7934 tem = build2 (MODIFY_EXPR, void_type_node, r,
7935 build_int_cst (ptr_type_node, 0));
7936 gimplify_and_add (tem, pre_p);
7937 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
7938 NULL_TREE);
7940 tem = build2 (MODIFY_EXPR, void_type_node, r,
7941 fold_convert (ptr_type_node, total));
7942 gimplify_and_add (tem, pre_p);
7943 for (i = 1; i < (is_old ? 2 : 4); i++)
7945 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
7946 NULL_TREE, NULL_TREE);
7947 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
7948 gimplify_and_add (tem, pre_p);
7951 tree cnts[4];
7952 for (j = 4; j; j--)
7953 if (!unused[j - 1])
7954 break;
7955 for (i = 0; i < 4; i++)
7957 if (i && (i >= j || unused[i - 1]))
7959 cnts[i] = cnts[i - 1];
7960 continue;
7962 cnts[i] = create_tmp_var (sizetype);
7963 if (i == 0)
7964 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
7965 else
7967 tree t;
7968 if (is_old)
7969 t = size_binop (PLUS_EXPR, counts[0], size_int (2));
7970 else
7971 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
7972 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
7973 == GS_ERROR)
7974 return 2;
7975 g = gimple_build_assign (cnts[i], t);
7977 gimple_seq_add_stmt (pre_p, g);
7980 last_iter = NULL_TREE;
7981 tree last_bind = NULL_TREE;
7982 tree *last_body = NULL;
7983 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
7984 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
7986 switch (OMP_CLAUSE_DEPEND_KIND (c))
7988 case OMP_CLAUSE_DEPEND_IN:
7989 i = 2;
7990 break;
7991 case OMP_CLAUSE_DEPEND_OUT:
7992 case OMP_CLAUSE_DEPEND_INOUT:
7993 i = 0;
7994 break;
7995 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
7996 i = 1;
7997 break;
7998 case OMP_CLAUSE_DEPEND_DEPOBJ:
7999 i = 3;
8000 break;
8001 case OMP_CLAUSE_DEPEND_SOURCE:
8002 case OMP_CLAUSE_DEPEND_SINK:
8003 continue;
8004 default:
8005 gcc_unreachable ();
8007 tree t = OMP_CLAUSE_DECL (c);
8008 if (TREE_CODE (t) == TREE_LIST
8009 && TREE_PURPOSE (t)
8010 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8012 if (TREE_PURPOSE (t) != last_iter)
8014 if (last_bind)
8015 gimplify_and_add (last_bind, pre_p);
8016 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8017 last_bind = build3 (BIND_EXPR, void_type_node,
8018 BLOCK_VARS (block), NULL, block);
8019 TREE_SIDE_EFFECTS (last_bind) = 1;
8020 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
8021 tree *p = &BIND_EXPR_BODY (last_bind);
8022 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8024 tree var = TREE_VEC_ELT (it, 0);
8025 tree begin = TREE_VEC_ELT (it, 1);
8026 tree end = TREE_VEC_ELT (it, 2);
8027 tree step = TREE_VEC_ELT (it, 3);
8028 tree orig_step = TREE_VEC_ELT (it, 4);
8029 tree type = TREE_TYPE (var);
8030 location_t loc = DECL_SOURCE_LOCATION (var);
8031 /* Emit:
8032 var = begin;
8033 goto cond_label;
8034 beg_label:
8036 var = var + step;
8037 cond_label:
8038 if (orig_step > 0) {
8039 if (var < end) goto beg_label;
8040 } else {
8041 if (var > end) goto beg_label;
8043 for each iterator, with inner iterators added to
8044 the ... above. */
8045 tree beg_label = create_artificial_label (loc);
8046 tree cond_label = NULL_TREE;
8047 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8048 var, begin);
8049 append_to_statement_list_force (tem, p);
8050 tem = build_and_jump (&cond_label);
8051 append_to_statement_list_force (tem, p);
8052 tem = build1 (LABEL_EXPR, void_type_node, beg_label);
8053 append_to_statement_list (tem, p);
8054 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
8055 NULL_TREE, NULL_TREE);
8056 TREE_SIDE_EFFECTS (bind) = 1;
8057 SET_EXPR_LOCATION (bind, loc);
8058 append_to_statement_list_force (bind, p);
8059 if (POINTER_TYPE_P (type))
8060 tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
8061 var, fold_convert_loc (loc, sizetype,
8062 step));
8063 else
8064 tem = build2_loc (loc, PLUS_EXPR, type, var, step);
8065 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8066 var, tem);
8067 append_to_statement_list_force (tem, p);
8068 tem = build1 (LABEL_EXPR, void_type_node, cond_label);
8069 append_to_statement_list (tem, p);
8070 tree cond = fold_build2_loc (loc, LT_EXPR,
8071 boolean_type_node,
8072 var, end);
8073 tree pos
8074 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8075 cond, build_and_jump (&beg_label),
8076 void_node);
8077 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8078 var, end);
8079 tree neg
8080 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8081 cond, build_and_jump (&beg_label),
8082 void_node);
8083 tree osteptype = TREE_TYPE (orig_step);
8084 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8085 orig_step,
8086 build_int_cst (osteptype, 0));
8087 tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
8088 cond, pos, neg);
8089 append_to_statement_list_force (tem, p);
8090 p = &BIND_EXPR_BODY (bind);
8092 last_body = p;
8094 last_iter = TREE_PURPOSE (t);
8095 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8097 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
8098 0), last_body);
8099 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8101 if (error_operand_p (TREE_VALUE (t)))
8102 return 2;
8103 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
8104 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8105 NULL_TREE, NULL_TREE);
8106 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8107 void_type_node, r, TREE_VALUE (t));
8108 append_to_statement_list_force (tem, last_body);
8109 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8110 void_type_node, cnts[i],
8111 size_binop (PLUS_EXPR, cnts[i], size_int (1)));
8112 append_to_statement_list_force (tem, last_body);
8113 TREE_VALUE (t) = null_pointer_node;
8115 else
8117 if (last_bind)
8119 gimplify_and_add (last_bind, pre_p);
8120 last_bind = NULL_TREE;
8122 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8124 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8125 NULL, is_gimple_val, fb_rvalue);
8126 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8128 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8129 return 2;
8130 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8131 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8132 is_gimple_val, fb_rvalue) == GS_ERROR)
8133 return 2;
8134 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8135 NULL_TREE, NULL_TREE);
8136 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
8137 gimplify_and_add (tem, pre_p);
8138 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, cnts[i],
8139 size_int (1)));
8140 gimple_seq_add_stmt (pre_p, g);
8143 if (last_bind)
8144 gimplify_and_add (last_bind, pre_p);
8145 tree cond = boolean_false_node;
8146 if (is_old)
8148 if (!unused[0])
8149 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
8150 size_binop_loc (first_loc, PLUS_EXPR, counts[0],
8151 size_int (2)));
8152 if (!unused[2])
8153 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8154 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8155 cnts[2],
8156 size_binop_loc (first_loc, PLUS_EXPR,
8157 totalpx,
8158 size_int (1))));
8160 else
8162 tree prev = size_int (5);
8163 for (i = 0; i < 4; i++)
8165 if (unused[i])
8166 continue;
8167 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
8168 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8169 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8170 cnts[i], unshare_expr (prev)));
8173 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
8174 build_call_expr_loc (first_loc,
8175 builtin_decl_explicit (BUILT_IN_TRAP),
8176 0), void_node);
8177 gimplify_and_add (tem, pre_p);
8178 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
8179 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
8180 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
8181 OMP_CLAUSE_CHAIN (c) = *list_p;
8182 *list_p = c;
8183 return 1;
8186 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
8187 and previous omp contexts. */
8189 static void
8190 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
8191 enum omp_region_type region_type,
8192 enum tree_code code)
8194 struct gimplify_omp_ctx *ctx, *outer_ctx;
8195 tree c;
8196 hash_map<tree, tree> *struct_map_to_clause = NULL;
8197 tree *prev_list_p = NULL, *orig_list_p = list_p;
8198 int handled_depend_iterators = -1;
8199 int nowait = -1;
8201 ctx = new_omp_context (region_type);
8202 ctx->code = code;
8203 outer_ctx = ctx->outer_context;
8204 if (code == OMP_TARGET)
8206 if (!lang_GNU_Fortran ())
8207 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
8208 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
8210 if (!lang_GNU_Fortran ())
8211 switch (code)
8213 case OMP_TARGET:
8214 case OMP_TARGET_DATA:
8215 case OMP_TARGET_ENTER_DATA:
8216 case OMP_TARGET_EXIT_DATA:
8217 case OACC_DECLARE:
8218 case OACC_HOST_DATA:
8219 case OACC_PARALLEL:
8220 case OACC_KERNELS:
8221 ctx->target_firstprivatize_array_bases = true;
8222 default:
8223 break;
8226 while ((c = *list_p) != NULL)
8228 bool remove = false;
8229 bool notice_outer = true;
8230 const char *check_non_private = NULL;
8231 unsigned int flags;
8232 tree decl;
8234 switch (OMP_CLAUSE_CODE (c))
8236 case OMP_CLAUSE_PRIVATE:
8237 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
8238 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
8240 flags |= GOVD_PRIVATE_OUTER_REF;
8241 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
8243 else
8244 notice_outer = false;
8245 goto do_add;
8246 case OMP_CLAUSE_SHARED:
8247 flags = GOVD_SHARED | GOVD_EXPLICIT;
8248 goto do_add;
8249 case OMP_CLAUSE_FIRSTPRIVATE:
8250 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8251 check_non_private = "firstprivate";
8252 goto do_add;
8253 case OMP_CLAUSE_LASTPRIVATE:
8254 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
8255 switch (code)
8257 case OMP_DISTRIBUTE:
8258 error_at (OMP_CLAUSE_LOCATION (c),
8259 "conditional %<lastprivate%> clause on "
8260 "%qs construct", "distribute");
8261 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8262 break;
8263 case OMP_TASKLOOP:
8264 error_at (OMP_CLAUSE_LOCATION (c),
8265 "conditional %<lastprivate%> clause on "
8266 "%qs construct", "taskloop");
8267 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8268 break;
8269 default:
8270 break;
8272 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
8273 if (code != OMP_LOOP)
8274 check_non_private = "lastprivate";
8275 decl = OMP_CLAUSE_DECL (c);
8276 if (error_operand_p (decl))
8277 goto do_add;
8278 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
8279 && !lang_hooks.decls.omp_scalar_p (decl))
8281 error_at (OMP_CLAUSE_LOCATION (c),
8282 "non-scalar variable %qD in conditional "
8283 "%<lastprivate%> clause", decl);
8284 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8286 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
8287 flags |= GOVD_LASTPRIVATE_CONDITIONAL;
8288 if (outer_ctx
8289 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
8290 || ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
8291 == ORT_COMBINED_TEAMS))
8292 && splay_tree_lookup (outer_ctx->variables,
8293 (splay_tree_key) decl) == NULL)
8295 omp_add_variable (outer_ctx, decl, GOVD_SHARED | GOVD_SEEN);
8296 if (outer_ctx->outer_context)
8297 omp_notice_variable (outer_ctx->outer_context, decl, true);
8299 else if (outer_ctx
8300 && (outer_ctx->region_type & ORT_TASK) != 0
8301 && outer_ctx->combined_loop
8302 && splay_tree_lookup (outer_ctx->variables,
8303 (splay_tree_key) decl) == NULL)
8305 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8306 if (outer_ctx->outer_context)
8307 omp_notice_variable (outer_ctx->outer_context, decl, true);
8309 else if (outer_ctx
8310 && (outer_ctx->region_type == ORT_WORKSHARE
8311 || outer_ctx->region_type == ORT_ACC)
8312 && outer_ctx->combined_loop
8313 && splay_tree_lookup (outer_ctx->variables,
8314 (splay_tree_key) decl) == NULL
8315 && !omp_check_private (outer_ctx, decl, false))
8317 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8318 if (outer_ctx->outer_context
8319 && (outer_ctx->outer_context->region_type
8320 == ORT_COMBINED_PARALLEL)
8321 && splay_tree_lookup (outer_ctx->outer_context->variables,
8322 (splay_tree_key) decl) == NULL)
8324 struct gimplify_omp_ctx *octx = outer_ctx->outer_context;
8325 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
8326 if (octx->outer_context)
8328 octx = octx->outer_context;
8329 if (octx->region_type == ORT_WORKSHARE
8330 && octx->combined_loop
8331 && splay_tree_lookup (octx->variables,
8332 (splay_tree_key) decl) == NULL
8333 && !omp_check_private (octx, decl, false))
8335 omp_add_variable (octx, decl,
8336 GOVD_LASTPRIVATE | GOVD_SEEN);
8337 octx = octx->outer_context;
8338 if (octx
8339 && ((octx->region_type & ORT_COMBINED_TEAMS)
8340 == ORT_COMBINED_TEAMS)
8341 && (splay_tree_lookup (octx->variables,
8342 (splay_tree_key) decl)
8343 == NULL))
8345 omp_add_variable (octx, decl,
8346 GOVD_SHARED | GOVD_SEEN);
8347 octx = octx->outer_context;
8350 if (octx)
8351 omp_notice_variable (octx, decl, true);
8354 else if (outer_ctx->outer_context)
8355 omp_notice_variable (outer_ctx->outer_context, decl, true);
8357 goto do_add;
8358 case OMP_CLAUSE_REDUCTION:
8359 if (OMP_CLAUSE_REDUCTION_TASK (c))
8361 if (region_type == ORT_WORKSHARE)
8363 if (nowait == -1)
8364 nowait = omp_find_clause (*list_p,
8365 OMP_CLAUSE_NOWAIT) != NULL_TREE;
8366 if (nowait
8367 && (outer_ctx == NULL
8368 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
8370 error_at (OMP_CLAUSE_LOCATION (c),
8371 "%<task%> reduction modifier on a construct "
8372 "with a %<nowait%> clause");
8373 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
8376 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
8378 error_at (OMP_CLAUSE_LOCATION (c),
8379 "invalid %<task%> reduction modifier on construct "
8380 "other than %<parallel%>, %<for%> or %<sections%>");
8381 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
8384 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
8385 switch (code)
8387 case OMP_SECTIONS:
8388 error_at (OMP_CLAUSE_LOCATION (c),
8389 "%<inscan%> %<reduction%> clause on "
8390 "%qs construct", "sections");
8391 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8392 break;
8393 case OMP_PARALLEL:
8394 error_at (OMP_CLAUSE_LOCATION (c),
8395 "%<inscan%> %<reduction%> clause on "
8396 "%qs construct", "parallel");
8397 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8398 break;
8399 case OMP_TEAMS:
8400 error_at (OMP_CLAUSE_LOCATION (c),
8401 "%<inscan%> %<reduction%> clause on "
8402 "%qs construct", "teams");
8403 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8404 break;
8405 case OMP_TASKLOOP:
8406 error_at (OMP_CLAUSE_LOCATION (c),
8407 "%<inscan%> %<reduction%> clause on "
8408 "%qs construct", "taskloop");
8409 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8410 break;
8411 default:
8412 break;
8414 /* FALLTHRU */
8415 case OMP_CLAUSE_IN_REDUCTION:
8416 case OMP_CLAUSE_TASK_REDUCTION:
8417 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
8418 /* OpenACC permits reductions on private variables. */
8419 if (!(region_type & ORT_ACC)
8420 /* taskgroup is actually not a worksharing region. */
8421 && code != OMP_TASKGROUP)
8422 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
8423 decl = OMP_CLAUSE_DECL (c);
8424 if (TREE_CODE (decl) == MEM_REF)
8426 tree type = TREE_TYPE (decl);
8427 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
8428 NULL, is_gimple_val, fb_rvalue, false)
8429 == GS_ERROR)
8431 remove = true;
8432 break;
8434 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
8435 if (DECL_P (v))
8437 omp_firstprivatize_variable (ctx, v);
8438 omp_notice_variable (ctx, v, true);
8440 decl = TREE_OPERAND (decl, 0);
8441 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
8443 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
8444 NULL, is_gimple_val, fb_rvalue, false)
8445 == GS_ERROR)
8447 remove = true;
8448 break;
8450 v = TREE_OPERAND (decl, 1);
8451 if (DECL_P (v))
8453 omp_firstprivatize_variable (ctx, v);
8454 omp_notice_variable (ctx, v, true);
8456 decl = TREE_OPERAND (decl, 0);
8458 if (TREE_CODE (decl) == ADDR_EXPR
8459 || TREE_CODE (decl) == INDIRECT_REF)
8460 decl = TREE_OPERAND (decl, 0);
8462 goto do_add_decl;
8463 case OMP_CLAUSE_LINEAR:
8464 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
8465 is_gimple_val, fb_rvalue) == GS_ERROR)
8467 remove = true;
8468 break;
8470 else
8472 if (code == OMP_SIMD
8473 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
8475 struct gimplify_omp_ctx *octx = outer_ctx;
8476 if (octx
8477 && octx->region_type == ORT_WORKSHARE
8478 && octx->combined_loop
8479 && !octx->distribute)
8481 if (octx->outer_context
8482 && (octx->outer_context->region_type
8483 == ORT_COMBINED_PARALLEL))
8484 octx = octx->outer_context->outer_context;
8485 else
8486 octx = octx->outer_context;
8488 if (octx
8489 && octx->region_type == ORT_WORKSHARE
8490 && octx->combined_loop
8491 && octx->distribute)
8493 error_at (OMP_CLAUSE_LOCATION (c),
8494 "%<linear%> clause for variable other than "
8495 "loop iterator specified on construct "
8496 "combined with %<distribute%>");
8497 remove = true;
8498 break;
8501 /* For combined #pragma omp parallel for simd, need to put
8502 lastprivate and perhaps firstprivate too on the
8503 parallel. Similarly for #pragma omp for simd. */
8504 struct gimplify_omp_ctx *octx = outer_ctx;
8505 decl = NULL_TREE;
8508 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8509 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8510 break;
8511 decl = OMP_CLAUSE_DECL (c);
8512 if (error_operand_p (decl))
8514 decl = NULL_TREE;
8515 break;
8517 flags = GOVD_SEEN;
8518 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
8519 flags |= GOVD_FIRSTPRIVATE;
8520 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8521 flags |= GOVD_LASTPRIVATE;
8522 if (octx
8523 && octx->region_type == ORT_WORKSHARE
8524 && octx->combined_loop)
8526 if (octx->outer_context
8527 && (octx->outer_context->region_type
8528 == ORT_COMBINED_PARALLEL))
8529 octx = octx->outer_context;
8530 else if (omp_check_private (octx, decl, false))
8531 break;
8533 else if (octx
8534 && (octx->region_type & ORT_TASK) != 0
8535 && octx->combined_loop)
8537 else if (octx
8538 && octx->region_type == ORT_COMBINED_PARALLEL
8539 && ctx->region_type == ORT_WORKSHARE
8540 && octx == outer_ctx)
8541 flags = GOVD_SEEN | GOVD_SHARED;
8542 else if (octx
8543 && ((octx->region_type & ORT_COMBINED_TEAMS)
8544 == ORT_COMBINED_TEAMS))
8545 flags = GOVD_SEEN | GOVD_SHARED;
8546 else if (octx
8547 && octx->region_type == ORT_COMBINED_TARGET)
8549 flags &= ~GOVD_LASTPRIVATE;
8550 if (flags == GOVD_SEEN)
8551 break;
8553 else
8554 break;
8555 splay_tree_node on
8556 = splay_tree_lookup (octx->variables,
8557 (splay_tree_key) decl);
8558 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
8560 octx = NULL;
8561 break;
8563 omp_add_variable (octx, decl, flags);
8564 if (octx->outer_context == NULL)
8565 break;
8566 octx = octx->outer_context;
8568 while (1);
8569 if (octx
8570 && decl
8571 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8572 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
8573 omp_notice_variable (octx, decl, true);
8575 flags = GOVD_LINEAR | GOVD_EXPLICIT;
8576 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8577 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8579 notice_outer = false;
8580 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
8582 goto do_add;
8584 case OMP_CLAUSE_MAP:
8585 decl = OMP_CLAUSE_DECL (c);
8586 if (error_operand_p (decl))
8587 remove = true;
8588 switch (code)
8590 case OMP_TARGET:
8591 break;
8592 case OACC_DATA:
8593 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
8594 break;
8595 /* FALLTHRU */
8596 case OMP_TARGET_DATA:
8597 case OMP_TARGET_ENTER_DATA:
8598 case OMP_TARGET_EXIT_DATA:
8599 case OACC_ENTER_DATA:
8600 case OACC_EXIT_DATA:
8601 case OACC_HOST_DATA:
8602 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
8603 || (OMP_CLAUSE_MAP_KIND (c)
8604 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8605 /* For target {,enter ,exit }data only the array slice is
8606 mapped, but not the pointer to it. */
8607 remove = true;
8608 break;
8609 default:
8610 break;
8612 /* For Fortran, not only the pointer to the data is mapped but also
8613 the address of the pointer, the array descriptor etc.; for
8614 'exit data' - and in particular for 'delete:' - having an 'alloc:'
8615 does not make sense. Likewise, for 'update' only transferring the
8616 data itself is needed as the rest has been handled in previous
8617 directives. */
8618 if ((code == OMP_TARGET_EXIT_DATA || code == OMP_TARGET_UPDATE)
8619 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
8620 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET))
8621 remove = true;
8623 if (remove)
8624 break;
8625 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
8627 struct gimplify_omp_ctx *octx;
8628 for (octx = outer_ctx; octx; octx = octx->outer_context)
8630 if (octx->region_type != ORT_ACC_HOST_DATA)
8631 break;
8632 splay_tree_node n2
8633 = splay_tree_lookup (octx->variables,
8634 (splay_tree_key) decl);
8635 if (n2)
8636 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
8637 "declared in enclosing %<host_data%> region",
8638 DECL_NAME (decl));
8641 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
8642 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
8643 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
8644 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
8645 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
8647 remove = true;
8648 break;
8650 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
8651 || (OMP_CLAUSE_MAP_KIND (c)
8652 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8653 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
8655 OMP_CLAUSE_SIZE (c)
8656 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
8657 false);
8658 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
8659 GOVD_FIRSTPRIVATE | GOVD_SEEN);
8661 if (!DECL_P (decl))
8663 tree d = decl, *pd;
8664 if (TREE_CODE (d) == ARRAY_REF)
8666 while (TREE_CODE (d) == ARRAY_REF)
8667 d = TREE_OPERAND (d, 0);
8668 if (TREE_CODE (d) == COMPONENT_REF
8669 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
8670 decl = d;
8672 pd = &OMP_CLAUSE_DECL (c);
8673 if (d == decl
8674 && TREE_CODE (decl) == INDIRECT_REF
8675 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
8676 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8677 == REFERENCE_TYPE))
8679 pd = &TREE_OPERAND (decl, 0);
8680 decl = TREE_OPERAND (decl, 0);
8682 if (TREE_CODE (decl) == COMPONENT_REF)
8684 while (TREE_CODE (decl) == COMPONENT_REF)
8685 decl = TREE_OPERAND (decl, 0);
8686 if (TREE_CODE (decl) == INDIRECT_REF
8687 && DECL_P (TREE_OPERAND (decl, 0))
8688 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8689 == REFERENCE_TYPE))
8690 decl = TREE_OPERAND (decl, 0);
8692 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, fb_lvalue)
8693 == GS_ERROR)
8695 remove = true;
8696 break;
8698 if (DECL_P (decl))
8700 if (error_operand_p (decl))
8702 remove = true;
8703 break;
8706 tree stype = TREE_TYPE (decl);
8707 if (TREE_CODE (stype) == REFERENCE_TYPE)
8708 stype = TREE_TYPE (stype);
8709 if (TYPE_SIZE_UNIT (stype) == NULL
8710 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
8712 error_at (OMP_CLAUSE_LOCATION (c),
8713 "mapping field %qE of variable length "
8714 "structure", OMP_CLAUSE_DECL (c));
8715 remove = true;
8716 break;
8719 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
8721 /* Error recovery. */
8722 if (prev_list_p == NULL)
8724 remove = true;
8725 break;
8727 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
8729 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
8730 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
8732 remove = true;
8733 break;
8738 tree offset;
8739 poly_int64 bitsize, bitpos;
8740 machine_mode mode;
8741 int unsignedp, reversep, volatilep = 0;
8742 tree base = OMP_CLAUSE_DECL (c);
8743 while (TREE_CODE (base) == ARRAY_REF)
8744 base = TREE_OPERAND (base, 0);
8745 if (TREE_CODE (base) == INDIRECT_REF)
8746 base = TREE_OPERAND (base, 0);
8747 base = get_inner_reference (base, &bitsize, &bitpos, &offset,
8748 &mode, &unsignedp, &reversep,
8749 &volatilep);
8750 tree orig_base = base;
8751 if ((TREE_CODE (base) == INDIRECT_REF
8752 || (TREE_CODE (base) == MEM_REF
8753 && integer_zerop (TREE_OPERAND (base, 1))))
8754 && DECL_P (TREE_OPERAND (base, 0))
8755 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
8756 == REFERENCE_TYPE))
8757 base = TREE_OPERAND (base, 0);
8758 gcc_assert (base == decl
8759 && (offset == NULL_TREE
8760 || poly_int_tree_p (offset)));
8762 splay_tree_node n
8763 = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
8764 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
8765 == GOMP_MAP_ALWAYS_POINTER);
8766 if (n == NULL || (n->value & GOVD_MAP) == 0)
8768 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8769 OMP_CLAUSE_MAP);
8770 OMP_CLAUSE_SET_MAP_KIND (l, GOMP_MAP_STRUCT);
8771 if (orig_base != base)
8772 OMP_CLAUSE_DECL (l) = unshare_expr (orig_base);
8773 else
8774 OMP_CLAUSE_DECL (l) = decl;
8775 OMP_CLAUSE_SIZE (l) = size_int (1);
8776 if (struct_map_to_clause == NULL)
8777 struct_map_to_clause = new hash_map<tree, tree>;
8778 struct_map_to_clause->put (decl, l);
8779 if (ptr)
8781 enum gomp_map_kind mkind
8782 = code == OMP_TARGET_EXIT_DATA
8783 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8784 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8785 OMP_CLAUSE_MAP);
8786 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8787 OMP_CLAUSE_DECL (c2)
8788 = unshare_expr (OMP_CLAUSE_DECL (c));
8789 OMP_CLAUSE_CHAIN (c2) = *prev_list_p;
8790 OMP_CLAUSE_SIZE (c2)
8791 = TYPE_SIZE_UNIT (ptr_type_node);
8792 OMP_CLAUSE_CHAIN (l) = c2;
8793 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
8795 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
8796 tree c3
8797 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8798 OMP_CLAUSE_MAP);
8799 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8800 OMP_CLAUSE_DECL (c3)
8801 = unshare_expr (OMP_CLAUSE_DECL (c4));
8802 OMP_CLAUSE_SIZE (c3)
8803 = TYPE_SIZE_UNIT (ptr_type_node);
8804 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
8805 OMP_CLAUSE_CHAIN (c2) = c3;
8807 *prev_list_p = l;
8808 prev_list_p = NULL;
8810 else
8812 OMP_CLAUSE_CHAIN (l) = c;
8813 *list_p = l;
8814 list_p = &OMP_CLAUSE_CHAIN (l);
8816 if (orig_base != base && code == OMP_TARGET)
8818 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8819 OMP_CLAUSE_MAP);
8820 enum gomp_map_kind mkind
8821 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
8822 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8823 OMP_CLAUSE_DECL (c2) = decl;
8824 OMP_CLAUSE_SIZE (c2) = size_zero_node;
8825 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
8826 OMP_CLAUSE_CHAIN (l) = c2;
8828 flags = GOVD_MAP | GOVD_EXPLICIT;
8829 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
8830 flags |= GOVD_SEEN;
8831 goto do_add_decl;
8833 else
8835 tree *osc = struct_map_to_clause->get (decl);
8836 tree *sc = NULL, *scp = NULL;
8837 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
8838 n->value |= GOVD_SEEN;
8839 poly_offset_int o1, o2;
8840 if (offset)
8841 o1 = wi::to_poly_offset (offset);
8842 else
8843 o1 = 0;
8844 if (maybe_ne (bitpos, 0))
8845 o1 += bits_to_bytes_round_down (bitpos);
8846 sc = &OMP_CLAUSE_CHAIN (*osc);
8847 if (*sc != c
8848 && (OMP_CLAUSE_MAP_KIND (*sc)
8849 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8850 sc = &OMP_CLAUSE_CHAIN (*sc);
8851 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
8852 if (ptr && sc == prev_list_p)
8853 break;
8854 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
8855 != COMPONENT_REF
8856 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
8857 != INDIRECT_REF)
8858 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
8859 != ARRAY_REF))
8860 break;
8861 else
8863 tree offset2;
8864 poly_int64 bitsize2, bitpos2;
8865 base = OMP_CLAUSE_DECL (*sc);
8866 if (TREE_CODE (base) == ARRAY_REF)
8868 while (TREE_CODE (base) == ARRAY_REF)
8869 base = TREE_OPERAND (base, 0);
8870 if (TREE_CODE (base) != COMPONENT_REF
8871 || (TREE_CODE (TREE_TYPE (base))
8872 != ARRAY_TYPE))
8873 break;
8875 else if (TREE_CODE (base) == INDIRECT_REF
8876 && (TREE_CODE (TREE_OPERAND (base, 0))
8877 == COMPONENT_REF)
8878 && (TREE_CODE (TREE_TYPE
8879 (TREE_OPERAND (base, 0)))
8880 == REFERENCE_TYPE))
8881 base = TREE_OPERAND (base, 0);
8882 base = get_inner_reference (base, &bitsize2,
8883 &bitpos2, &offset2,
8884 &mode, &unsignedp,
8885 &reversep, &volatilep);
8886 if ((TREE_CODE (base) == INDIRECT_REF
8887 || (TREE_CODE (base) == MEM_REF
8888 && integer_zerop (TREE_OPERAND (base,
8889 1))))
8890 && DECL_P (TREE_OPERAND (base, 0))
8891 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base,
8892 0)))
8893 == REFERENCE_TYPE))
8894 base = TREE_OPERAND (base, 0);
8895 if (base != decl)
8896 break;
8897 if (scp)
8898 continue;
8899 gcc_assert (offset2 == NULL_TREE
8900 || poly_int_tree_p (offset2));
8901 tree d1 = OMP_CLAUSE_DECL (*sc);
8902 tree d2 = OMP_CLAUSE_DECL (c);
8903 while (TREE_CODE (d1) == ARRAY_REF)
8904 d1 = TREE_OPERAND (d1, 0);
8905 while (TREE_CODE (d2) == ARRAY_REF)
8906 d2 = TREE_OPERAND (d2, 0);
8907 if (TREE_CODE (d1) == INDIRECT_REF)
8908 d1 = TREE_OPERAND (d1, 0);
8909 if (TREE_CODE (d2) == INDIRECT_REF)
8910 d2 = TREE_OPERAND (d2, 0);
8911 while (TREE_CODE (d1) == COMPONENT_REF)
8912 if (TREE_CODE (d2) == COMPONENT_REF
8913 && TREE_OPERAND (d1, 1)
8914 == TREE_OPERAND (d2, 1))
8916 d1 = TREE_OPERAND (d1, 0);
8917 d2 = TREE_OPERAND (d2, 0);
8919 else
8920 break;
8921 if (d1 == d2)
8923 error_at (OMP_CLAUSE_LOCATION (c),
8924 "%qE appears more than once in map "
8925 "clauses", OMP_CLAUSE_DECL (c));
8926 remove = true;
8927 break;
8929 if (offset2)
8930 o2 = wi::to_poly_offset (offset2);
8931 else
8932 o2 = 0;
8933 o2 += bits_to_bytes_round_down (bitpos2);
8934 if (maybe_lt (o1, o2)
8935 || (known_eq (o1, o2)
8936 && maybe_lt (bitpos, bitpos2)))
8938 if (ptr)
8939 scp = sc;
8940 else
8941 break;
8944 if (remove)
8945 break;
8946 OMP_CLAUSE_SIZE (*osc)
8947 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
8948 size_one_node);
8949 if (ptr)
8951 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8952 OMP_CLAUSE_MAP);
8953 tree cl = NULL_TREE;
8954 enum gomp_map_kind mkind
8955 = code == OMP_TARGET_EXIT_DATA
8956 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8957 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8958 OMP_CLAUSE_DECL (c2)
8959 = unshare_expr (OMP_CLAUSE_DECL (c));
8960 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : *prev_list_p;
8961 OMP_CLAUSE_SIZE (c2)
8962 = TYPE_SIZE_UNIT (ptr_type_node);
8963 cl = scp ? *prev_list_p : c2;
8964 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
8966 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
8967 tree c3
8968 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8969 OMP_CLAUSE_MAP);
8970 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8971 OMP_CLAUSE_DECL (c3)
8972 = unshare_expr (OMP_CLAUSE_DECL (c4));
8973 OMP_CLAUSE_SIZE (c3)
8974 = TYPE_SIZE_UNIT (ptr_type_node);
8975 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
8976 if (!scp)
8977 OMP_CLAUSE_CHAIN (c2) = c3;
8978 else
8979 cl = c3;
8981 if (scp)
8982 *scp = c2;
8983 if (sc == prev_list_p)
8985 *sc = cl;
8986 prev_list_p = NULL;
8988 else
8990 *prev_list_p = OMP_CLAUSE_CHAIN (c);
8991 list_p = prev_list_p;
8992 prev_list_p = NULL;
8993 OMP_CLAUSE_CHAIN (c) = *sc;
8994 *sc = cl;
8995 continue;
8998 else if (*sc != c)
9000 *list_p = OMP_CLAUSE_CHAIN (c);
9001 OMP_CLAUSE_CHAIN (c) = *sc;
9002 *sc = c;
9003 continue;
9007 if (!remove
9008 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
9009 && OMP_CLAUSE_CHAIN (c)
9010 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
9011 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9012 == GOMP_MAP_ALWAYS_POINTER))
9013 prev_list_p = list_p;
9014 break;
9016 flags = GOVD_MAP | GOVD_EXPLICIT;
9017 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
9018 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
9019 flags |= GOVD_MAP_ALWAYS_TO;
9020 goto do_add;
9022 case OMP_CLAUSE_DEPEND:
9023 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
9025 tree deps = OMP_CLAUSE_DECL (c);
9026 while (deps && TREE_CODE (deps) == TREE_LIST)
9028 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
9029 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
9030 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
9031 pre_p, NULL, is_gimple_val, fb_rvalue);
9032 deps = TREE_CHAIN (deps);
9034 break;
9036 else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
9037 break;
9038 if (handled_depend_iterators == -1)
9039 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
9040 if (handled_depend_iterators)
9042 if (handled_depend_iterators == 2)
9043 remove = true;
9044 break;
9046 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
9048 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
9049 NULL, is_gimple_val, fb_rvalue);
9050 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
9052 if (error_operand_p (OMP_CLAUSE_DECL (c)))
9054 remove = true;
9055 break;
9057 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
9058 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
9059 is_gimple_val, fb_rvalue) == GS_ERROR)
9061 remove = true;
9062 break;
9064 break;
9066 case OMP_CLAUSE_TO:
9067 case OMP_CLAUSE_FROM:
9068 case OMP_CLAUSE__CACHE_:
9069 decl = OMP_CLAUSE_DECL (c);
9070 if (error_operand_p (decl))
9072 remove = true;
9073 break;
9075 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9076 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
9077 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
9078 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
9079 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
9081 remove = true;
9082 break;
9084 if (!DECL_P (decl))
9086 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
9087 NULL, is_gimple_lvalue, fb_lvalue)
9088 == GS_ERROR)
9090 remove = true;
9091 break;
9093 break;
9095 goto do_notice;
9097 case OMP_CLAUSE_USE_DEVICE_PTR:
9098 case OMP_CLAUSE_USE_DEVICE_ADDR:
9099 flags = GOVD_EXPLICIT;
9100 goto do_add;
9102 case OMP_CLAUSE_IS_DEVICE_PTR:
9103 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
9104 goto do_add;
9106 do_add:
9107 decl = OMP_CLAUSE_DECL (c);
9108 do_add_decl:
9109 if (error_operand_p (decl))
9111 remove = true;
9112 break;
9114 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
9116 tree t = omp_member_access_dummy_var (decl);
9117 if (t)
9119 tree v = DECL_VALUE_EXPR (decl);
9120 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
9121 if (outer_ctx)
9122 omp_notice_variable (outer_ctx, t, true);
9125 if (code == OACC_DATA
9126 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9127 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
9128 flags |= GOVD_MAP_0LEN_ARRAY;
9129 omp_add_variable (ctx, decl, flags);
9130 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9131 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
9132 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
9133 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
9135 omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
9136 GOVD_LOCAL | GOVD_SEEN);
9137 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
9138 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
9139 find_decl_expr,
9140 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
9141 NULL) == NULL_TREE)
9142 omp_add_variable (ctx,
9143 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
9144 GOVD_LOCAL | GOVD_SEEN);
9145 gimplify_omp_ctxp = ctx;
9146 push_gimplify_context ();
9148 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
9149 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
9151 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
9152 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
9153 pop_gimplify_context
9154 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
9155 push_gimplify_context ();
9156 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
9157 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
9158 pop_gimplify_context
9159 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
9160 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
9161 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
9163 gimplify_omp_ctxp = outer_ctx;
9165 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
9166 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
9168 gimplify_omp_ctxp = ctx;
9169 push_gimplify_context ();
9170 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
9172 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
9173 NULL, NULL);
9174 TREE_SIDE_EFFECTS (bind) = 1;
9175 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
9176 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
9178 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
9179 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
9180 pop_gimplify_context
9181 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
9182 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
9184 gimplify_omp_ctxp = outer_ctx;
9186 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9187 && OMP_CLAUSE_LINEAR_STMT (c))
9189 gimplify_omp_ctxp = ctx;
9190 push_gimplify_context ();
9191 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
9193 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
9194 NULL, NULL);
9195 TREE_SIDE_EFFECTS (bind) = 1;
9196 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
9197 OMP_CLAUSE_LINEAR_STMT (c) = bind;
9199 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
9200 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
9201 pop_gimplify_context
9202 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
9203 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
9205 gimplify_omp_ctxp = outer_ctx;
9207 if (notice_outer)
9208 goto do_notice;
9209 break;
9211 case OMP_CLAUSE_COPYIN:
9212 case OMP_CLAUSE_COPYPRIVATE:
9213 decl = OMP_CLAUSE_DECL (c);
9214 if (error_operand_p (decl))
9216 remove = true;
9217 break;
9219 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
9220 && !remove
9221 && !omp_check_private (ctx, decl, true))
9223 remove = true;
9224 if (is_global_var (decl))
9226 if (DECL_THREAD_LOCAL_P (decl))
9227 remove = false;
9228 else if (DECL_HAS_VALUE_EXPR_P (decl))
9230 tree value = get_base_address (DECL_VALUE_EXPR (decl));
9232 if (value
9233 && DECL_P (value)
9234 && DECL_THREAD_LOCAL_P (value))
9235 remove = false;
9238 if (remove)
9239 error_at (OMP_CLAUSE_LOCATION (c),
9240 "copyprivate variable %qE is not threadprivate"
9241 " or private in outer context", DECL_NAME (decl));
9243 do_notice:
9244 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9245 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
9246 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
9247 && outer_ctx
9248 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
9249 || (region_type == ORT_WORKSHARE
9250 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9251 && (OMP_CLAUSE_REDUCTION_INSCAN (c)
9252 || code == OMP_LOOP)))
9253 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
9254 || (code == OMP_LOOP
9255 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9256 && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
9257 == ORT_COMBINED_TEAMS))))
9259 splay_tree_node on
9260 = splay_tree_lookup (outer_ctx->variables,
9261 (splay_tree_key)decl);
9262 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
9264 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9265 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
9266 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
9267 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
9268 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
9269 == POINTER_TYPE))))
9270 omp_firstprivatize_variable (outer_ctx, decl);
9271 else
9272 omp_add_variable (outer_ctx, decl,
9273 GOVD_SEEN | GOVD_SHARED);
9274 omp_notice_variable (outer_ctx, decl, true);
9277 if (outer_ctx)
9278 omp_notice_variable (outer_ctx, decl, true);
9279 if (check_non_private
9280 && region_type == ORT_WORKSHARE
9281 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
9282 || decl == OMP_CLAUSE_DECL (c)
9283 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
9284 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
9285 == ADDR_EXPR
9286 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
9287 == POINTER_PLUS_EXPR
9288 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
9289 (OMP_CLAUSE_DECL (c), 0), 0))
9290 == ADDR_EXPR)))))
9291 && omp_check_private (ctx, decl, false))
9293 error ("%s variable %qE is private in outer context",
9294 check_non_private, DECL_NAME (decl));
9295 remove = true;
9297 break;
9299 case OMP_CLAUSE_IF:
9300 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
9301 && OMP_CLAUSE_IF_MODIFIER (c) != code)
9303 const char *p[2];
9304 for (int i = 0; i < 2; i++)
9305 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
9307 case VOID_CST: p[i] = "cancel"; break;
9308 case OMP_PARALLEL: p[i] = "parallel"; break;
9309 case OMP_SIMD: p[i] = "simd"; break;
9310 case OMP_TASK: p[i] = "task"; break;
9311 case OMP_TASKLOOP: p[i] = "taskloop"; break;
9312 case OMP_TARGET_DATA: p[i] = "target data"; break;
9313 case OMP_TARGET: p[i] = "target"; break;
9314 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
9315 case OMP_TARGET_ENTER_DATA:
9316 p[i] = "target enter data"; break;
9317 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
9318 default: gcc_unreachable ();
9320 error_at (OMP_CLAUSE_LOCATION (c),
9321 "expected %qs %<if%> clause modifier rather than %qs",
9322 p[0], p[1]);
9323 remove = true;
9325 /* Fall through. */
9327 case OMP_CLAUSE_FINAL:
9328 OMP_CLAUSE_OPERAND (c, 0)
9329 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
9330 /* Fall through. */
9332 case OMP_CLAUSE_SCHEDULE:
9333 case OMP_CLAUSE_NUM_THREADS:
9334 case OMP_CLAUSE_NUM_TEAMS:
9335 case OMP_CLAUSE_THREAD_LIMIT:
9336 case OMP_CLAUSE_DIST_SCHEDULE:
9337 case OMP_CLAUSE_DEVICE:
9338 case OMP_CLAUSE_PRIORITY:
9339 case OMP_CLAUSE_GRAINSIZE:
9340 case OMP_CLAUSE_NUM_TASKS:
9341 case OMP_CLAUSE_HINT:
9342 case OMP_CLAUSE_ASYNC:
9343 case OMP_CLAUSE_WAIT:
9344 case OMP_CLAUSE_NUM_GANGS:
9345 case OMP_CLAUSE_NUM_WORKERS:
9346 case OMP_CLAUSE_VECTOR_LENGTH:
9347 case OMP_CLAUSE_WORKER:
9348 case OMP_CLAUSE_VECTOR:
9349 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
9350 is_gimple_val, fb_rvalue) == GS_ERROR)
9351 remove = true;
9352 break;
9354 case OMP_CLAUSE_GANG:
9355 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
9356 is_gimple_val, fb_rvalue) == GS_ERROR)
9357 remove = true;
9358 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
9359 is_gimple_val, fb_rvalue) == GS_ERROR)
9360 remove = true;
9361 break;
9363 case OMP_CLAUSE_NOWAIT:
9364 nowait = 1;
9365 break;
9367 case OMP_CLAUSE_ORDERED:
9368 case OMP_CLAUSE_UNTIED:
9369 case OMP_CLAUSE_COLLAPSE:
9370 case OMP_CLAUSE_TILE:
9371 case OMP_CLAUSE_AUTO:
9372 case OMP_CLAUSE_SEQ:
9373 case OMP_CLAUSE_INDEPENDENT:
9374 case OMP_CLAUSE_MERGEABLE:
9375 case OMP_CLAUSE_PROC_BIND:
9376 case OMP_CLAUSE_SAFELEN:
9377 case OMP_CLAUSE_SIMDLEN:
9378 case OMP_CLAUSE_NOGROUP:
9379 case OMP_CLAUSE_THREADS:
9380 case OMP_CLAUSE_SIMD:
9381 case OMP_CLAUSE_BIND:
9382 case OMP_CLAUSE_IF_PRESENT:
9383 case OMP_CLAUSE_FINALIZE:
9384 break;
9386 case OMP_CLAUSE_ORDER:
9387 ctx->order_concurrent = true;
9388 break;
9390 case OMP_CLAUSE_DEFAULTMAP:
9391 enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
9392 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
9394 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
9395 gdmkmin = GDMK_SCALAR;
9396 gdmkmax = GDMK_POINTER;
9397 break;
9398 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
9399 gdmkmin = gdmkmax = GDMK_SCALAR;
9400 break;
9401 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
9402 gdmkmin = gdmkmax = GDMK_AGGREGATE;
9403 break;
9404 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
9405 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
9406 break;
9407 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
9408 gdmkmin = gdmkmax = GDMK_POINTER;
9409 break;
9410 default:
9411 gcc_unreachable ();
9413 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
9414 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
9416 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
9417 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
9418 break;
9419 case OMP_CLAUSE_DEFAULTMAP_TO:
9420 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
9421 break;
9422 case OMP_CLAUSE_DEFAULTMAP_FROM:
9423 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
9424 break;
9425 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
9426 ctx->defaultmap[gdmk] = GOVD_MAP;
9427 break;
9428 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
9429 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
9430 break;
9431 case OMP_CLAUSE_DEFAULTMAP_NONE:
9432 ctx->defaultmap[gdmk] = 0;
9433 break;
9434 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
9435 switch (gdmk)
9437 case GDMK_SCALAR:
9438 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
9439 break;
9440 case GDMK_AGGREGATE:
9441 case GDMK_ALLOCATABLE:
9442 ctx->defaultmap[gdmk] = GOVD_MAP;
9443 break;
9444 case GDMK_POINTER:
9445 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
9446 break;
9447 default:
9448 gcc_unreachable ();
9450 break;
9451 default:
9452 gcc_unreachable ();
9454 break;
9456 case OMP_CLAUSE_ALIGNED:
9457 decl = OMP_CLAUSE_DECL (c);
9458 if (error_operand_p (decl))
9460 remove = true;
9461 break;
9463 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
9464 is_gimple_val, fb_rvalue) == GS_ERROR)
9466 remove = true;
9467 break;
9469 if (!is_global_var (decl)
9470 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
9471 omp_add_variable (ctx, decl, GOVD_ALIGNED);
9472 break;
9474 case OMP_CLAUSE_NONTEMPORAL:
9475 decl = OMP_CLAUSE_DECL (c);
9476 if (error_operand_p (decl))
9478 remove = true;
9479 break;
9481 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
9482 break;
9484 case OMP_CLAUSE_DEFAULT:
9485 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
9486 break;
9488 case OMP_CLAUSE_INCLUSIVE:
9489 case OMP_CLAUSE_EXCLUSIVE:
9490 decl = OMP_CLAUSE_DECL (c);
9492 splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
9493 (splay_tree_key) decl);
9494 if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
9496 error_at (OMP_CLAUSE_LOCATION (c),
9497 "%qD specified in %qs clause but not in %<inscan%> "
9498 "%<reduction%> clause on the containing construct",
9499 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9500 remove = true;
9502 else
9504 n->value |= GOVD_REDUCTION_INSCAN;
9505 if (outer_ctx->region_type == ORT_SIMD
9506 && outer_ctx->outer_context
9507 && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
9509 n = splay_tree_lookup (outer_ctx->outer_context->variables,
9510 (splay_tree_key) decl);
9511 if (n && (n->value & GOVD_REDUCTION) != 0)
9512 n->value |= GOVD_REDUCTION_INSCAN;
9516 break;
9518 default:
9519 gcc_unreachable ();
9522 if (code == OACC_DATA
9523 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9524 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9525 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9526 remove = true;
9527 if (remove)
9528 *list_p = OMP_CLAUSE_CHAIN (c);
9529 else
9530 list_p = &OMP_CLAUSE_CHAIN (c);
9533 ctx->clauses = *orig_list_p;
9534 gimplify_omp_ctxp = ctx;
9535 if (struct_map_to_clause)
9536 delete struct_map_to_clause;
9539 /* Return true if DECL is a candidate for shared to firstprivate
9540 optimization. We only consider non-addressable scalars, not
9541 too big, and not references. */
9543 static bool
9544 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
9546 if (TREE_ADDRESSABLE (decl))
9547 return false;
9548 tree type = TREE_TYPE (decl);
9549 if (!is_gimple_reg_type (type)
9550 || TREE_CODE (type) == REFERENCE_TYPE
9551 || TREE_ADDRESSABLE (type))
9552 return false;
9553 /* Don't optimize too large decls, as each thread/task will have
9554 its own. */
9555 HOST_WIDE_INT len = int_size_in_bytes (type);
9556 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
9557 return false;
9558 if (lang_hooks.decls.omp_privatize_by_reference (decl))
9559 return false;
9560 return true;
9563 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
9564 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
9565 GOVD_WRITTEN in outer contexts. */
9567 static void
9568 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
9570 for (; ctx; ctx = ctx->outer_context)
9572 splay_tree_node n = splay_tree_lookup (ctx->variables,
9573 (splay_tree_key) decl);
9574 if (n == NULL)
9575 continue;
9576 else if (n->value & GOVD_SHARED)
9578 n->value |= GOVD_WRITTEN;
9579 return;
9581 else if (n->value & GOVD_DATA_SHARE_CLASS)
9582 return;
9586 /* Helper callback for walk_gimple_seq to discover possible stores
9587 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
9588 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
9589 for those. */
9591 static tree
9592 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
9594 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
9596 *walk_subtrees = 0;
9597 if (!wi->is_lhs)
9598 return NULL_TREE;
9600 tree op = *tp;
9603 if (handled_component_p (op))
9604 op = TREE_OPERAND (op, 0);
9605 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
9606 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
9607 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
9608 else
9609 break;
9611 while (1);
9612 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
9613 return NULL_TREE;
9615 omp_mark_stores (gimplify_omp_ctxp, op);
9616 return NULL_TREE;
9619 /* Helper callback for walk_gimple_seq to discover possible stores
9620 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
9621 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
9622 for those. */
9624 static tree
9625 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
9626 bool *handled_ops_p,
9627 struct walk_stmt_info *wi)
9629 gimple *stmt = gsi_stmt (*gsi_p);
9630 switch (gimple_code (stmt))
9632 /* Don't recurse on OpenMP constructs for which
9633 gimplify_adjust_omp_clauses already handled the bodies,
9634 except handle gimple_omp_for_pre_body. */
9635 case GIMPLE_OMP_FOR:
9636 *handled_ops_p = true;
9637 if (gimple_omp_for_pre_body (stmt))
9638 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
9639 omp_find_stores_stmt, omp_find_stores_op, wi);
9640 break;
9641 case GIMPLE_OMP_PARALLEL:
9642 case GIMPLE_OMP_TASK:
9643 case GIMPLE_OMP_SECTIONS:
9644 case GIMPLE_OMP_SINGLE:
9645 case GIMPLE_OMP_TARGET:
9646 case GIMPLE_OMP_TEAMS:
9647 case GIMPLE_OMP_CRITICAL:
9648 *handled_ops_p = true;
9649 break;
9650 default:
9651 break;
9653 return NULL_TREE;
9656 struct gimplify_adjust_omp_clauses_data
9658 tree *list_p;
9659 gimple_seq *pre_p;
9662 /* For all variables that were not actually used within the context,
9663 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
9665 static int
9666 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
9668 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
9669 gimple_seq *pre_p
9670 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
9671 tree decl = (tree) n->key;
9672 unsigned flags = n->value;
9673 enum omp_clause_code code;
9674 tree clause;
9675 bool private_debug;
9677 if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
9678 && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
9679 flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
9680 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
9681 return 0;
9682 if ((flags & GOVD_SEEN) == 0)
9683 return 0;
9684 if (flags & GOVD_DEBUG_PRIVATE)
9686 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
9687 private_debug = true;
9689 else if (flags & GOVD_MAP)
9690 private_debug = false;
9691 else
9692 private_debug
9693 = lang_hooks.decls.omp_private_debug_clause (decl,
9694 !!(flags & GOVD_SHARED));
9695 if (private_debug)
9696 code = OMP_CLAUSE_PRIVATE;
9697 else if (flags & GOVD_MAP)
9699 code = OMP_CLAUSE_MAP;
9700 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
9701 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
9703 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
9704 return 0;
9707 else if (flags & GOVD_SHARED)
9709 if (is_global_var (decl))
9711 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
9712 while (ctx != NULL)
9714 splay_tree_node on
9715 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9716 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
9717 | GOVD_PRIVATE | GOVD_REDUCTION
9718 | GOVD_LINEAR | GOVD_MAP)) != 0)
9719 break;
9720 ctx = ctx->outer_context;
9722 if (ctx == NULL)
9723 return 0;
9725 code = OMP_CLAUSE_SHARED;
9727 else if (flags & GOVD_PRIVATE)
9728 code = OMP_CLAUSE_PRIVATE;
9729 else if (flags & GOVD_FIRSTPRIVATE)
9731 code = OMP_CLAUSE_FIRSTPRIVATE;
9732 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
9733 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
9734 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
9736 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
9737 "%<target%> construct", decl);
9738 return 0;
9741 else if (flags & GOVD_LASTPRIVATE)
9742 code = OMP_CLAUSE_LASTPRIVATE;
9743 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
9744 return 0;
9745 else if (flags & GOVD_CONDTEMP)
9747 code = OMP_CLAUSE__CONDTEMP_;
9748 gimple_add_tmp_var (decl);
9750 else
9751 gcc_unreachable ();
9753 if (((flags & GOVD_LASTPRIVATE)
9754 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
9755 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9756 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
9758 tree chain = *list_p;
9759 clause = build_omp_clause (input_location, code);
9760 OMP_CLAUSE_DECL (clause) = decl;
9761 OMP_CLAUSE_CHAIN (clause) = chain;
9762 if (private_debug)
9763 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
9764 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
9765 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
9766 else if (code == OMP_CLAUSE_SHARED
9767 && (flags & GOVD_WRITTEN) == 0
9768 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9769 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
9770 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
9771 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
9772 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
9774 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
9775 OMP_CLAUSE_DECL (nc) = decl;
9776 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
9777 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
9778 OMP_CLAUSE_DECL (clause)
9779 = build_simple_mem_ref_loc (input_location, decl);
9780 OMP_CLAUSE_DECL (clause)
9781 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
9782 build_int_cst (build_pointer_type (char_type_node), 0));
9783 OMP_CLAUSE_SIZE (clause) = size_zero_node;
9784 OMP_CLAUSE_SIZE (nc) = size_zero_node;
9785 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
9786 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
9787 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
9788 OMP_CLAUSE_CHAIN (nc) = chain;
9789 OMP_CLAUSE_CHAIN (clause) = nc;
9790 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9791 gimplify_omp_ctxp = ctx->outer_context;
9792 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
9793 pre_p, NULL, is_gimple_val, fb_rvalue);
9794 gimplify_omp_ctxp = ctx;
9796 else if (code == OMP_CLAUSE_MAP)
9798 int kind;
9799 /* Not all combinations of these GOVD_MAP flags are actually valid. */
9800 switch (flags & (GOVD_MAP_TO_ONLY
9801 | GOVD_MAP_FORCE
9802 | GOVD_MAP_FORCE_PRESENT
9803 | GOVD_MAP_ALLOC_ONLY
9804 | GOVD_MAP_FROM_ONLY))
9806 case 0:
9807 kind = GOMP_MAP_TOFROM;
9808 break;
9809 case GOVD_MAP_FORCE:
9810 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
9811 break;
9812 case GOVD_MAP_TO_ONLY:
9813 kind = GOMP_MAP_TO;
9814 break;
9815 case GOVD_MAP_FROM_ONLY:
9816 kind = GOMP_MAP_FROM;
9817 break;
9818 case GOVD_MAP_ALLOC_ONLY:
9819 kind = GOMP_MAP_ALLOC;
9820 break;
9821 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
9822 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
9823 break;
9824 case GOVD_MAP_FORCE_PRESENT:
9825 kind = GOMP_MAP_FORCE_PRESENT;
9826 break;
9827 default:
9828 gcc_unreachable ();
9830 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
9831 if (DECL_SIZE (decl)
9832 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
9834 tree decl2 = DECL_VALUE_EXPR (decl);
9835 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
9836 decl2 = TREE_OPERAND (decl2, 0);
9837 gcc_assert (DECL_P (decl2));
9838 tree mem = build_simple_mem_ref (decl2);
9839 OMP_CLAUSE_DECL (clause) = mem;
9840 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
9841 if (gimplify_omp_ctxp->outer_context)
9843 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
9844 omp_notice_variable (ctx, decl2, true);
9845 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
9847 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
9848 OMP_CLAUSE_MAP);
9849 OMP_CLAUSE_DECL (nc) = decl;
9850 OMP_CLAUSE_SIZE (nc) = size_zero_node;
9851 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
9852 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
9853 else
9854 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
9855 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
9856 OMP_CLAUSE_CHAIN (clause) = nc;
9858 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
9859 && lang_hooks.decls.omp_privatize_by_reference (decl))
9861 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
9862 OMP_CLAUSE_SIZE (clause)
9863 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
9864 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9865 gimplify_omp_ctxp = ctx->outer_context;
9866 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
9867 pre_p, NULL, is_gimple_val, fb_rvalue);
9868 gimplify_omp_ctxp = ctx;
9869 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
9870 OMP_CLAUSE_MAP);
9871 OMP_CLAUSE_DECL (nc) = decl;
9872 OMP_CLAUSE_SIZE (nc) = size_zero_node;
9873 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
9874 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
9875 OMP_CLAUSE_CHAIN (clause) = nc;
9877 else
9878 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
9880 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
9882 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
9883 OMP_CLAUSE_DECL (nc) = decl;
9884 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
9885 OMP_CLAUSE_CHAIN (nc) = chain;
9886 OMP_CLAUSE_CHAIN (clause) = nc;
9887 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9888 gimplify_omp_ctxp = ctx->outer_context;
9889 lang_hooks.decls.omp_finish_clause (nc, pre_p);
9890 gimplify_omp_ctxp = ctx;
9892 *list_p = clause;
9893 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9894 gimplify_omp_ctxp = ctx->outer_context;
9895 lang_hooks.decls.omp_finish_clause (clause, pre_p);
9896 if (gimplify_omp_ctxp)
9897 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
9898 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
9899 && DECL_P (OMP_CLAUSE_SIZE (clause)))
9900 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
9901 true);
9902 gimplify_omp_ctxp = ctx;
9903 return 0;
9906 static void
9907 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
9908 enum tree_code code)
9910 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9911 tree *orig_list_p = list_p;
9912 tree c, decl;
9913 bool has_inscan_reductions = false;
9915 if (body)
9917 struct gimplify_omp_ctx *octx;
9918 for (octx = ctx; octx; octx = octx->outer_context)
9919 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
9920 break;
9921 if (octx)
9923 struct walk_stmt_info wi;
9924 memset (&wi, 0, sizeof (wi));
9925 walk_gimple_seq (body, omp_find_stores_stmt,
9926 omp_find_stores_op, &wi);
9930 if (ctx->add_safelen1)
9932 /* If there are VLAs in the body of simd loop, prevent
9933 vectorization. */
9934 gcc_assert (ctx->region_type == ORT_SIMD);
9935 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
9936 OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
9937 OMP_CLAUSE_CHAIN (c) = *list_p;
9938 *list_p = c;
9939 list_p = &OMP_CLAUSE_CHAIN (c);
9942 if (ctx->region_type == ORT_WORKSHARE
9943 && ctx->outer_context
9944 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
9946 for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
9947 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
9948 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
9950 decl = OMP_CLAUSE_DECL (c);
9951 splay_tree_node n
9952 = splay_tree_lookup (ctx->outer_context->variables,
9953 (splay_tree_key) decl);
9954 gcc_checking_assert (!splay_tree_lookup (ctx->variables,
9955 (splay_tree_key) decl));
9956 omp_add_variable (ctx, decl, n->value);
9957 tree c2 = copy_node (c);
9958 OMP_CLAUSE_CHAIN (c2) = *list_p;
9959 *list_p = c2;
9960 if ((n->value & GOVD_FIRSTPRIVATE) == 0)
9961 continue;
9962 c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9963 OMP_CLAUSE_FIRSTPRIVATE);
9964 OMP_CLAUSE_DECL (c2) = decl;
9965 OMP_CLAUSE_CHAIN (c2) = *list_p;
9966 *list_p = c2;
9969 while ((c = *list_p) != NULL)
9971 splay_tree_node n;
9972 bool remove = false;
9974 switch (OMP_CLAUSE_CODE (c))
9976 case OMP_CLAUSE_FIRSTPRIVATE:
9977 if ((ctx->region_type & ORT_TARGET)
9978 && (ctx->region_type & ORT_ACC) == 0
9979 && TYPE_ATOMIC (strip_array_types
9980 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
9982 error_at (OMP_CLAUSE_LOCATION (c),
9983 "%<_Atomic%> %qD in %<firstprivate%> clause on "
9984 "%<target%> construct", OMP_CLAUSE_DECL (c));
9985 remove = true;
9986 break;
9988 /* FALLTHRU */
9989 case OMP_CLAUSE_PRIVATE:
9990 case OMP_CLAUSE_SHARED:
9991 case OMP_CLAUSE_LINEAR:
9992 decl = OMP_CLAUSE_DECL (c);
9993 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9994 remove = !(n->value & GOVD_SEEN);
9995 if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
9996 && code == OMP_PARALLEL
9997 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
9998 remove = true;
9999 if (! remove)
10001 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
10002 if ((n->value & GOVD_DEBUG_PRIVATE)
10003 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
10005 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
10006 || ((n->value & GOVD_DATA_SHARE_CLASS)
10007 == GOVD_SHARED));
10008 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
10009 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
10011 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10012 && (n->value & GOVD_WRITTEN) == 0
10013 && DECL_P (decl)
10014 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10015 OMP_CLAUSE_SHARED_READONLY (c) = 1;
10016 else if (DECL_P (decl)
10017 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10018 && (n->value & GOVD_WRITTEN) != 0)
10019 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10020 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
10021 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10022 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10024 break;
10026 case OMP_CLAUSE_LASTPRIVATE:
10027 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
10028 accurately reflect the presence of a FIRSTPRIVATE clause. */
10029 decl = OMP_CLAUSE_DECL (c);
10030 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10031 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
10032 = (n->value & GOVD_FIRSTPRIVATE) != 0;
10033 if (code == OMP_DISTRIBUTE
10034 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
10036 remove = true;
10037 error_at (OMP_CLAUSE_LOCATION (c),
10038 "same variable used in %<firstprivate%> and "
10039 "%<lastprivate%> clauses on %<distribute%> "
10040 "construct");
10042 if (!remove
10043 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10044 && DECL_P (decl)
10045 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10046 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10047 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
10048 remove = true;
10049 break;
10051 case OMP_CLAUSE_ALIGNED:
10052 decl = OMP_CLAUSE_DECL (c);
10053 if (!is_global_var (decl))
10055 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10056 remove = n == NULL || !(n->value & GOVD_SEEN);
10057 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
10059 struct gimplify_omp_ctx *octx;
10060 if (n != NULL
10061 && (n->value & (GOVD_DATA_SHARE_CLASS
10062 & ~GOVD_FIRSTPRIVATE)))
10063 remove = true;
10064 else
10065 for (octx = ctx->outer_context; octx;
10066 octx = octx->outer_context)
10068 n = splay_tree_lookup (octx->variables,
10069 (splay_tree_key) decl);
10070 if (n == NULL)
10071 continue;
10072 if (n->value & GOVD_LOCAL)
10073 break;
10074 /* We have to avoid assigning a shared variable
10075 to itself when trying to add
10076 __builtin_assume_aligned. */
10077 if (n->value & GOVD_SHARED)
10079 remove = true;
10080 break;
10085 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
10087 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10088 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
10089 remove = true;
10091 break;
10093 case OMP_CLAUSE_NONTEMPORAL:
10094 decl = OMP_CLAUSE_DECL (c);
10095 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10096 remove = n == NULL || !(n->value & GOVD_SEEN);
10097 break;
10099 case OMP_CLAUSE_MAP:
10100 if (code == OMP_TARGET_EXIT_DATA
10101 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
10103 remove = true;
10104 break;
10106 decl = OMP_CLAUSE_DECL (c);
10107 /* Data clauses associated with reductions must be
10108 compatible with present_or_copy. Warn and adjust the clause
10109 if that is not the case. */
10110 if (ctx->region_type == ORT_ACC_PARALLEL
10111 || ctx->region_type == ORT_ACC_SERIAL)
10113 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
10114 n = NULL;
10116 if (DECL_P (t))
10117 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
10119 if (n && (n->value & GOVD_REDUCTION))
10121 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
10123 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
10124 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
10125 && kind != GOMP_MAP_FORCE_PRESENT
10126 && kind != GOMP_MAP_POINTER)
10128 warning_at (OMP_CLAUSE_LOCATION (c), 0,
10129 "incompatible data clause with reduction "
10130 "on %qE; promoting to %<present_or_copy%>",
10131 DECL_NAME (t));
10132 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
10136 if (!DECL_P (decl))
10138 if ((ctx->region_type & ORT_TARGET) != 0
10139 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
10141 if (TREE_CODE (decl) == INDIRECT_REF
10142 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
10143 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
10144 == REFERENCE_TYPE))
10145 decl = TREE_OPERAND (decl, 0);
10146 if (TREE_CODE (decl) == COMPONENT_REF)
10148 while (TREE_CODE (decl) == COMPONENT_REF)
10149 decl = TREE_OPERAND (decl, 0);
10150 if (DECL_P (decl))
10152 n = splay_tree_lookup (ctx->variables,
10153 (splay_tree_key) decl);
10154 if (!(n->value & GOVD_SEEN))
10155 remove = true;
10159 break;
10161 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10162 if ((ctx->region_type & ORT_TARGET) != 0
10163 && !(n->value & GOVD_SEEN)
10164 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
10165 && (!is_global_var (decl)
10166 || !lookup_attribute ("omp declare target link",
10167 DECL_ATTRIBUTES (decl))))
10169 remove = true;
10170 /* For struct element mapping, if struct is never referenced
10171 in target block and none of the mapping has always modifier,
10172 remove all the struct element mappings, which immediately
10173 follow the GOMP_MAP_STRUCT map clause. */
10174 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
10176 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
10177 while (cnt--)
10178 OMP_CLAUSE_CHAIN (c)
10179 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
10182 else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
10183 && code == OMP_TARGET_EXIT_DATA)
10184 remove = true;
10185 else if (DECL_SIZE (decl)
10186 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
10187 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
10188 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
10189 && (OMP_CLAUSE_MAP_KIND (c)
10190 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
10192 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
10193 for these, TREE_CODE (DECL_SIZE (decl)) will always be
10194 INTEGER_CST. */
10195 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
10197 tree decl2 = DECL_VALUE_EXPR (decl);
10198 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
10199 decl2 = TREE_OPERAND (decl2, 0);
10200 gcc_assert (DECL_P (decl2));
10201 tree mem = build_simple_mem_ref (decl2);
10202 OMP_CLAUSE_DECL (c) = mem;
10203 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
10204 if (ctx->outer_context)
10206 omp_notice_variable (ctx->outer_context, decl2, true);
10207 omp_notice_variable (ctx->outer_context,
10208 OMP_CLAUSE_SIZE (c), true);
10210 if (((ctx->region_type & ORT_TARGET) != 0
10211 || !ctx->target_firstprivatize_array_bases)
10212 && ((n->value & GOVD_SEEN) == 0
10213 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
10215 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10216 OMP_CLAUSE_MAP);
10217 OMP_CLAUSE_DECL (nc) = decl;
10218 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10219 if (ctx->target_firstprivatize_array_bases)
10220 OMP_CLAUSE_SET_MAP_KIND (nc,
10221 GOMP_MAP_FIRSTPRIVATE_POINTER);
10222 else
10223 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
10224 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
10225 OMP_CLAUSE_CHAIN (c) = nc;
10226 c = nc;
10229 else
10231 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10232 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
10233 gcc_assert ((n->value & GOVD_SEEN) == 0
10234 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
10235 == 0));
10237 break;
10239 case OMP_CLAUSE_TO:
10240 case OMP_CLAUSE_FROM:
10241 case OMP_CLAUSE__CACHE_:
10242 decl = OMP_CLAUSE_DECL (c);
10243 if (!DECL_P (decl))
10244 break;
10245 if (DECL_SIZE (decl)
10246 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
10248 tree decl2 = DECL_VALUE_EXPR (decl);
10249 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
10250 decl2 = TREE_OPERAND (decl2, 0);
10251 gcc_assert (DECL_P (decl2));
10252 tree mem = build_simple_mem_ref (decl2);
10253 OMP_CLAUSE_DECL (c) = mem;
10254 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
10255 if (ctx->outer_context)
10257 omp_notice_variable (ctx->outer_context, decl2, true);
10258 omp_notice_variable (ctx->outer_context,
10259 OMP_CLAUSE_SIZE (c), true);
10262 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10263 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
10264 break;
10266 case OMP_CLAUSE_REDUCTION:
10267 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
10269 decl = OMP_CLAUSE_DECL (c);
10270 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10271 if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
10273 remove = true;
10274 error_at (OMP_CLAUSE_LOCATION (c),
10275 "%qD specified in %<inscan%> %<reduction%> clause "
10276 "but not in %<scan%> directive clause", decl);
10277 break;
10279 has_inscan_reductions = true;
10281 /* FALLTHRU */
10282 case OMP_CLAUSE_IN_REDUCTION:
10283 case OMP_CLAUSE_TASK_REDUCTION:
10284 decl = OMP_CLAUSE_DECL (c);
10285 /* OpenACC reductions need a present_or_copy data clause.
10286 Add one if necessary. Emit error when the reduction is private. */
10287 if (ctx->region_type == ORT_ACC_PARALLEL
10288 || ctx->region_type == ORT_ACC_SERIAL)
10290 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10291 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
10293 remove = true;
10294 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
10295 "reduction on %qE", DECL_NAME (decl));
10297 else if ((n->value & GOVD_MAP) == 0)
10299 tree next = OMP_CLAUSE_CHAIN (c);
10300 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
10301 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
10302 OMP_CLAUSE_DECL (nc) = decl;
10303 OMP_CLAUSE_CHAIN (c) = nc;
10304 lang_hooks.decls.omp_finish_clause (nc, pre_p);
10305 while (1)
10307 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
10308 if (OMP_CLAUSE_CHAIN (nc) == NULL)
10309 break;
10310 nc = OMP_CLAUSE_CHAIN (nc);
10312 OMP_CLAUSE_CHAIN (nc) = next;
10313 n->value |= GOVD_MAP;
10316 if (DECL_P (decl)
10317 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10318 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10319 break;
10320 case OMP_CLAUSE_COPYIN:
10321 case OMP_CLAUSE_COPYPRIVATE:
10322 case OMP_CLAUSE_IF:
10323 case OMP_CLAUSE_NUM_THREADS:
10324 case OMP_CLAUSE_NUM_TEAMS:
10325 case OMP_CLAUSE_THREAD_LIMIT:
10326 case OMP_CLAUSE_DIST_SCHEDULE:
10327 case OMP_CLAUSE_DEVICE:
10328 case OMP_CLAUSE_SCHEDULE:
10329 case OMP_CLAUSE_NOWAIT:
10330 case OMP_CLAUSE_ORDERED:
10331 case OMP_CLAUSE_DEFAULT:
10332 case OMP_CLAUSE_UNTIED:
10333 case OMP_CLAUSE_COLLAPSE:
10334 case OMP_CLAUSE_FINAL:
10335 case OMP_CLAUSE_MERGEABLE:
10336 case OMP_CLAUSE_PROC_BIND:
10337 case OMP_CLAUSE_SAFELEN:
10338 case OMP_CLAUSE_SIMDLEN:
10339 case OMP_CLAUSE_DEPEND:
10340 case OMP_CLAUSE_PRIORITY:
10341 case OMP_CLAUSE_GRAINSIZE:
10342 case OMP_CLAUSE_NUM_TASKS:
10343 case OMP_CLAUSE_NOGROUP:
10344 case OMP_CLAUSE_THREADS:
10345 case OMP_CLAUSE_SIMD:
10346 case OMP_CLAUSE_HINT:
10347 case OMP_CLAUSE_DEFAULTMAP:
10348 case OMP_CLAUSE_ORDER:
10349 case OMP_CLAUSE_BIND:
10350 case OMP_CLAUSE_USE_DEVICE_PTR:
10351 case OMP_CLAUSE_USE_DEVICE_ADDR:
10352 case OMP_CLAUSE_IS_DEVICE_PTR:
10353 case OMP_CLAUSE_ASYNC:
10354 case OMP_CLAUSE_WAIT:
10355 case OMP_CLAUSE_INDEPENDENT:
10356 case OMP_CLAUSE_NUM_GANGS:
10357 case OMP_CLAUSE_NUM_WORKERS:
10358 case OMP_CLAUSE_VECTOR_LENGTH:
10359 case OMP_CLAUSE_GANG:
10360 case OMP_CLAUSE_WORKER:
10361 case OMP_CLAUSE_VECTOR:
10362 case OMP_CLAUSE_AUTO:
10363 case OMP_CLAUSE_SEQ:
10364 case OMP_CLAUSE_TILE:
10365 case OMP_CLAUSE_IF_PRESENT:
10366 case OMP_CLAUSE_FINALIZE:
10367 case OMP_CLAUSE_INCLUSIVE:
10368 case OMP_CLAUSE_EXCLUSIVE:
10369 break;
10371 default:
10372 gcc_unreachable ();
10375 if (remove)
10376 *list_p = OMP_CLAUSE_CHAIN (c);
10377 else
10378 list_p = &OMP_CLAUSE_CHAIN (c);
10381 /* Add in any implicit data sharing. */
10382 struct gimplify_adjust_omp_clauses_data data;
10383 data.list_p = list_p;
10384 data.pre_p = pre_p;
10385 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
10387 if (has_inscan_reductions)
10388 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
10389 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10390 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
10392 error_at (OMP_CLAUSE_LOCATION (c),
10393 "%<inscan%> %<reduction%> clause used together with "
10394 "%<linear%> clause for a variable other than loop "
10395 "iterator");
10396 break;
10399 gimplify_omp_ctxp = ctx->outer_context;
10400 delete_omp_context (ctx);
10403 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
10404 -1 if unknown yet (simd is involved, won't be known until vectorization)
10405 and 1 if they do. If SCORES is non-NULL, it should point to an array
10406 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
10407 of the CONSTRUCTS (position -1 if it will never match) followed by
10408 number of constructs in the OpenMP context construct trait. If the
10409 score depends on whether it will be in a declare simd clone or not,
10410 the function returns 2 and there will be two sets of the scores, the first
10411 one for the case that it is not in a declare simd clone, the other
10412 that it is in a declare simd clone. */
10415 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
10416 int *scores)
10418 int matched = 0, cnt = 0;
10419 bool simd_seen = false;
10420 bool target_seen = false;
10421 int declare_simd_cnt = -1;
10422 auto_vec<enum tree_code, 16> codes;
10423 for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
10425 if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
10426 || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
10427 == ORT_TARGET && ctx->code == OMP_TARGET)
10428 || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
10429 || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
10430 || (ctx->region_type == ORT_SIMD
10431 && ctx->code == OMP_SIMD
10432 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
10434 ++cnt;
10435 if (scores)
10436 codes.safe_push (ctx->code);
10437 else if (matched < nconstructs && ctx->code == constructs[matched])
10439 if (ctx->code == OMP_SIMD)
10441 if (matched)
10442 return 0;
10443 simd_seen = true;
10445 ++matched;
10447 if (ctx->code == OMP_TARGET)
10449 if (scores == NULL)
10450 return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
10451 target_seen = true;
10452 break;
10455 else if (ctx->region_type == ORT_WORKSHARE
10456 && ctx->code == OMP_LOOP
10457 && ctx->outer_context
10458 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
10459 && ctx->outer_context->outer_context
10460 && ctx->outer_context->outer_context->code == OMP_LOOP
10461 && ctx->outer_context->outer_context->distribute)
10462 ctx = ctx->outer_context->outer_context;
10463 ctx = ctx->outer_context;
10465 if (!target_seen
10466 && lookup_attribute ("omp declare simd",
10467 DECL_ATTRIBUTES (current_function_decl)))
10469 /* Declare simd is a maybe case, it is supposed to be added only to the
10470 omp-simd-clone.c added clones and not to the base function. */
10471 declare_simd_cnt = cnt++;
10472 if (scores)
10473 codes.safe_push (OMP_SIMD);
10474 else if (cnt == 0
10475 && constructs[0] == OMP_SIMD)
10477 gcc_assert (matched == 0);
10478 simd_seen = true;
10479 if (++matched == nconstructs)
10480 return -1;
10483 if (tree attr = lookup_attribute ("omp declare variant variant",
10484 DECL_ATTRIBUTES (current_function_decl)))
10486 enum tree_code variant_constructs[5];
10487 int variant_nconstructs = 0;
10488 if (!target_seen)
10489 variant_nconstructs
10490 = omp_constructor_traits_to_codes (TREE_VALUE (attr),
10491 variant_constructs);
10492 for (int i = 0; i < variant_nconstructs; i++)
10494 ++cnt;
10495 if (scores)
10496 codes.safe_push (variant_constructs[i]);
10497 else if (matched < nconstructs
10498 && variant_constructs[i] == constructs[matched])
10500 if (variant_constructs[i] == OMP_SIMD)
10502 if (matched)
10503 return 0;
10504 simd_seen = true;
10506 ++matched;
10510 if (!target_seen
10511 && lookup_attribute ("omp declare target block",
10512 DECL_ATTRIBUTES (current_function_decl)))
10514 if (scores)
10515 codes.safe_push (OMP_TARGET);
10516 else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
10517 ++matched;
10519 if (scores)
10521 for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
10523 int j = codes.length () - 1;
10524 for (int i = nconstructs - 1; i >= 0; i--)
10526 while (j >= 0
10527 && (pass != 0 || declare_simd_cnt != j)
10528 && constructs[i] != codes[j])
10529 --j;
10530 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
10531 *scores++ = j - 1;
10532 else
10533 *scores++ = j;
10535 *scores++ = ((pass == 0 && declare_simd_cnt != -1)
10536 ? codes.length () - 1 : codes.length ());
10538 return declare_simd_cnt == -1 ? 1 : 2;
10540 if (matched == nconstructs)
10541 return simd_seen ? -1 : 1;
10542 return 0;
10545 /* Gimplify OACC_CACHE. */
10547 static void
10548 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
10550 tree expr = *expr_p;
10552 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
10553 OACC_CACHE);
10554 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
10555 OACC_CACHE);
10557 /* TODO: Do something sensible with this information. */
10559 *expr_p = NULL_TREE;
10562 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
10563 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
10564 kind. The entry kind will replace the one in CLAUSE, while the exit
10565 kind will be used in a new omp_clause and returned to the caller. */
10567 static tree
10568 gimplify_oacc_declare_1 (tree clause)
10570 HOST_WIDE_INT kind, new_op;
10571 bool ret = false;
10572 tree c = NULL;
10574 kind = OMP_CLAUSE_MAP_KIND (clause);
10576 switch (kind)
10578 case GOMP_MAP_ALLOC:
10579 new_op = GOMP_MAP_RELEASE;
10580 ret = true;
10581 break;
10583 case GOMP_MAP_FROM:
10584 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
10585 new_op = GOMP_MAP_FROM;
10586 ret = true;
10587 break;
10589 case GOMP_MAP_TOFROM:
10590 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
10591 new_op = GOMP_MAP_FROM;
10592 ret = true;
10593 break;
10595 case GOMP_MAP_DEVICE_RESIDENT:
10596 case GOMP_MAP_FORCE_DEVICEPTR:
10597 case GOMP_MAP_FORCE_PRESENT:
10598 case GOMP_MAP_LINK:
10599 case GOMP_MAP_POINTER:
10600 case GOMP_MAP_TO:
10601 break;
10603 default:
10604 gcc_unreachable ();
10605 break;
10608 if (ret)
10610 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
10611 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
10612 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
10615 return c;
10618 /* Gimplify OACC_DECLARE. */
10620 static void
10621 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
10623 tree expr = *expr_p;
10624 gomp_target *stmt;
10625 tree clauses, t, decl;
10627 clauses = OACC_DECLARE_CLAUSES (expr);
10629 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
10630 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
10632 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
10634 decl = OMP_CLAUSE_DECL (t);
10636 if (TREE_CODE (decl) == MEM_REF)
10637 decl = TREE_OPERAND (decl, 0);
10639 if (VAR_P (decl) && !is_oacc_declared (decl))
10641 tree attr = get_identifier ("oacc declare target");
10642 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
10643 DECL_ATTRIBUTES (decl));
10646 if (VAR_P (decl)
10647 && !is_global_var (decl)
10648 && DECL_CONTEXT (decl) == current_function_decl)
10650 tree c = gimplify_oacc_declare_1 (t);
10651 if (c)
10653 if (oacc_declare_returns == NULL)
10654 oacc_declare_returns = new hash_map<tree, tree>;
10656 oacc_declare_returns->put (decl, c);
10660 if (gimplify_omp_ctxp)
10661 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
10664 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
10665 clauses);
10667 gimplify_seq_add_stmt (pre_p, stmt);
10669 *expr_p = NULL_TREE;
10672 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
10673 gimplification of the body, as well as scanning the body for used
10674 variables. We need to do this scan now, because variable-sized
10675 decls will be decomposed during gimplification. */
10677 static void
10678 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
10680 tree expr = *expr_p;
10681 gimple *g;
10682 gimple_seq body = NULL;
10684 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
10685 OMP_PARALLEL_COMBINED (expr)
10686 ? ORT_COMBINED_PARALLEL
10687 : ORT_PARALLEL, OMP_PARALLEL);
10689 push_gimplify_context ();
10691 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
10692 if (gimple_code (g) == GIMPLE_BIND)
10693 pop_gimplify_context (g);
10694 else
10695 pop_gimplify_context (NULL);
10697 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
10698 OMP_PARALLEL);
10700 g = gimple_build_omp_parallel (body,
10701 OMP_PARALLEL_CLAUSES (expr),
10702 NULL_TREE, NULL_TREE);
10703 if (OMP_PARALLEL_COMBINED (expr))
10704 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
10705 gimplify_seq_add_stmt (pre_p, g);
10706 *expr_p = NULL_TREE;
10709 /* Gimplify the contents of an OMP_TASK statement. This involves
10710 gimplification of the body, as well as scanning the body for used
10711 variables. We need to do this scan now, because variable-sized
10712 decls will be decomposed during gimplification. */
10714 static void
10715 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
10717 tree expr = *expr_p;
10718 gimple *g;
10719 gimple_seq body = NULL;
10721 if (OMP_TASK_BODY (expr) == NULL_TREE)
10722 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
10723 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10724 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
10726 error_at (OMP_CLAUSE_LOCATION (c),
10727 "%<mutexinoutset%> kind in %<depend%> clause on a "
10728 "%<taskwait%> construct");
10729 break;
10732 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
10733 omp_find_clause (OMP_TASK_CLAUSES (expr),
10734 OMP_CLAUSE_UNTIED)
10735 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
10737 if (OMP_TASK_BODY (expr))
10739 push_gimplify_context ();
10741 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
10742 if (gimple_code (g) == GIMPLE_BIND)
10743 pop_gimplify_context (g);
10744 else
10745 pop_gimplify_context (NULL);
10748 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
10749 OMP_TASK);
10751 g = gimple_build_omp_task (body,
10752 OMP_TASK_CLAUSES (expr),
10753 NULL_TREE, NULL_TREE,
10754 NULL_TREE, NULL_TREE, NULL_TREE);
10755 if (OMP_TASK_BODY (expr) == NULL_TREE)
10756 gimple_omp_task_set_taskwait_p (g, true);
10757 gimplify_seq_add_stmt (pre_p, g);
10758 *expr_p = NULL_TREE;
10761 /* Helper function of gimplify_omp_for, find OMP_FOR resp. OMP_SIMD
10762 with non-NULL OMP_FOR_INIT. Also, fill in pdata array,
10763 pdata[0] non-NULL if there is anything non-trivial in between, pdata[1]
10764 is address of OMP_PARALLEL in between if any, pdata[2] is address of
10765 OMP_FOR in between if any and pdata[3] is address of the inner
10766 OMP_FOR/OMP_SIMD. */
10768 static tree
10769 find_combined_omp_for (tree *tp, int *walk_subtrees, void *data)
10771 tree **pdata = (tree **) data;
10772 *walk_subtrees = 0;
10773 switch (TREE_CODE (*tp))
10775 case OMP_FOR:
10776 if (OMP_FOR_INIT (*tp) != NULL_TREE)
10778 pdata[3] = tp;
10779 return *tp;
10781 pdata[2] = tp;
10782 *walk_subtrees = 1;
10783 break;
10784 case OMP_SIMD:
10785 if (OMP_FOR_INIT (*tp) != NULL_TREE)
10787 pdata[3] = tp;
10788 return *tp;
10790 break;
10791 case BIND_EXPR:
10792 if (BIND_EXPR_VARS (*tp)
10793 || (BIND_EXPR_BLOCK (*tp)
10794 && BLOCK_VARS (BIND_EXPR_BLOCK (*tp))))
10795 pdata[0] = tp;
10796 *walk_subtrees = 1;
10797 break;
10798 case STATEMENT_LIST:
10799 if (!tsi_one_before_end_p (tsi_start (*tp)))
10800 pdata[0] = tp;
10801 *walk_subtrees = 1;
10802 break;
10803 case TRY_FINALLY_EXPR:
10804 pdata[0] = tp;
10805 *walk_subtrees = 1;
10806 break;
10807 case OMP_PARALLEL:
10808 pdata[1] = tp;
10809 *walk_subtrees = 1;
10810 break;
10811 default:
10812 break;
10814 return NULL_TREE;
10817 /* Gimplify the gross structure of an OMP_FOR statement. */
10819 static enum gimplify_status
10820 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
10822 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
10823 enum gimplify_status ret = GS_ALL_DONE;
10824 enum gimplify_status tret;
10825 gomp_for *gfor;
10826 gimple_seq for_body, for_pre_body;
10827 int i;
10828 bitmap has_decl_expr = NULL;
10829 enum omp_region_type ort = ORT_WORKSHARE;
10831 orig_for_stmt = for_stmt = *expr_p;
10833 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
10834 != NULL_TREE);
10835 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
10837 tree *data[4] = { NULL, NULL, NULL, NULL };
10838 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
10839 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
10840 find_combined_omp_for, data, NULL);
10841 if (inner_for_stmt == NULL_TREE)
10843 gcc_assert (seen_error ());
10844 *expr_p = NULL_TREE;
10845 return GS_ERROR;
10847 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
10849 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
10850 &OMP_FOR_PRE_BODY (for_stmt));
10851 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
10853 if (OMP_FOR_PRE_BODY (inner_for_stmt))
10855 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
10856 &OMP_FOR_PRE_BODY (for_stmt));
10857 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
10860 if (data[0])
10862 /* We have some statements or variable declarations in between
10863 the composite construct directives. Move them around the
10864 inner_for_stmt. */
10865 data[0] = expr_p;
10866 for (i = 0; i < 3; i++)
10867 if (data[i])
10869 tree t = *data[i];
10870 if (i < 2 && data[i + 1] == &OMP_BODY (t))
10871 data[i + 1] = data[i];
10872 *data[i] = OMP_BODY (t);
10873 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
10874 NULL_TREE, make_node (BLOCK));
10875 OMP_BODY (t) = body;
10876 append_to_statement_list_force (inner_for_stmt,
10877 &BIND_EXPR_BODY (body));
10878 *data[3] = t;
10879 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
10880 gcc_assert (*data[3] == inner_for_stmt);
10882 return GS_OK;
10885 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
10886 if (!loop_p
10887 && OMP_FOR_ORIG_DECLS (inner_for_stmt)
10888 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
10889 i)) == TREE_LIST
10890 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
10891 i)))
10893 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
10894 /* Class iterators aren't allowed on OMP_SIMD, so the only
10895 case we need to solve is distribute parallel for. They are
10896 allowed on the loop construct, but that is already handled
10897 in gimplify_omp_loop. */
10898 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
10899 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
10900 && data[1]);
10901 tree orig_decl = TREE_PURPOSE (orig);
10902 tree last = TREE_VALUE (orig);
10903 tree *pc;
10904 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
10905 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
10906 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
10907 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
10908 && OMP_CLAUSE_DECL (*pc) == orig_decl)
10909 break;
10910 if (*pc == NULL_TREE)
10912 tree *spc;
10913 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
10914 *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
10915 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
10916 && OMP_CLAUSE_DECL (*spc) == orig_decl)
10917 break;
10918 if (*spc)
10920 tree c = *spc;
10921 *spc = OMP_CLAUSE_CHAIN (c);
10922 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
10923 *pc = c;
10926 if (*pc == NULL_TREE)
10928 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
10930 /* private clause will appear only on inner_for_stmt.
10931 Change it into firstprivate, and add private clause
10932 on for_stmt. */
10933 tree c = copy_node (*pc);
10934 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
10935 OMP_FOR_CLAUSES (for_stmt) = c;
10936 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
10937 lang_hooks.decls.omp_finish_clause (*pc, pre_p);
10939 else
10941 /* lastprivate clause will appear on both inner_for_stmt
10942 and for_stmt. Add firstprivate clause to
10943 inner_for_stmt. */
10944 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
10945 OMP_CLAUSE_FIRSTPRIVATE);
10946 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
10947 OMP_CLAUSE_CHAIN (c) = *pc;
10948 *pc = c;
10949 lang_hooks.decls.omp_finish_clause (*pc, pre_p);
10951 tree c = build_omp_clause (UNKNOWN_LOCATION,
10952 OMP_CLAUSE_FIRSTPRIVATE);
10953 OMP_CLAUSE_DECL (c) = last;
10954 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
10955 OMP_PARALLEL_CLAUSES (*data[1]) = c;
10956 c = build_omp_clause (UNKNOWN_LOCATION,
10957 *pc ? OMP_CLAUSE_SHARED
10958 : OMP_CLAUSE_FIRSTPRIVATE);
10959 OMP_CLAUSE_DECL (c) = orig_decl;
10960 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
10961 OMP_PARALLEL_CLAUSES (*data[1]) = c;
10963 /* Similarly, take care of C++ range for temporaries, those should
10964 be firstprivate on OMP_PARALLEL if any. */
10965 if (data[1])
10966 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
10967 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
10968 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
10969 i)) == TREE_LIST
10970 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
10971 i)))
10973 tree orig
10974 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
10975 tree v = TREE_CHAIN (orig);
10976 tree c = build_omp_clause (UNKNOWN_LOCATION,
10977 OMP_CLAUSE_FIRSTPRIVATE);
10978 /* First add firstprivate clause for the __for_end artificial
10979 decl. */
10980 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
10981 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
10982 == REFERENCE_TYPE)
10983 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
10984 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
10985 OMP_PARALLEL_CLAUSES (*data[1]) = c;
10986 if (TREE_VEC_ELT (v, 0))
10988 /* And now the same for __for_range artificial decl if it
10989 exists. */
10990 c = build_omp_clause (UNKNOWN_LOCATION,
10991 OMP_CLAUSE_FIRSTPRIVATE);
10992 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
10993 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
10994 == REFERENCE_TYPE)
10995 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
10996 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
10997 OMP_PARALLEL_CLAUSES (*data[1]) = c;
11002 switch (TREE_CODE (for_stmt))
11004 case OMP_FOR:
11005 case OMP_DISTRIBUTE:
11006 break;
11007 case OACC_LOOP:
11008 ort = ORT_ACC;
11009 break;
11010 case OMP_TASKLOOP:
11011 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
11012 ort = ORT_UNTIED_TASKLOOP;
11013 else
11014 ort = ORT_TASKLOOP;
11015 break;
11016 case OMP_SIMD:
11017 ort = ORT_SIMD;
11018 break;
11019 default:
11020 gcc_unreachable ();
11023 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
11024 clause for the IV. */
11025 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
11027 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
11028 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
11029 decl = TREE_OPERAND (t, 0);
11030 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
11031 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11032 && OMP_CLAUSE_DECL (c) == decl)
11034 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
11035 break;
11039 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
11040 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
11041 loop_p && TREE_CODE (for_stmt) != OMP_SIMD
11042 ? OMP_LOOP : TREE_CODE (for_stmt));
11044 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
11045 gimplify_omp_ctxp->distribute = true;
11047 /* Handle OMP_FOR_INIT. */
11048 for_pre_body = NULL;
11049 if ((ort == ORT_SIMD
11050 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
11051 && OMP_FOR_PRE_BODY (for_stmt))
11053 has_decl_expr = BITMAP_ALLOC (NULL);
11054 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
11055 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
11056 == VAR_DECL)
11058 t = OMP_FOR_PRE_BODY (for_stmt);
11059 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
11061 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
11063 tree_stmt_iterator si;
11064 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
11065 tsi_next (&si))
11067 t = tsi_stmt (si);
11068 if (TREE_CODE (t) == DECL_EXPR
11069 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
11070 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
11074 if (OMP_FOR_PRE_BODY (for_stmt))
11076 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
11077 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
11078 else
11080 struct gimplify_omp_ctx ctx;
11081 memset (&ctx, 0, sizeof (ctx));
11082 ctx.region_type = ORT_NONE;
11083 gimplify_omp_ctxp = &ctx;
11084 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
11085 gimplify_omp_ctxp = NULL;
11088 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
11090 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
11091 for_stmt = inner_for_stmt;
11093 /* For taskloop, need to gimplify the start, end and step before the
11094 taskloop, outside of the taskloop omp context. */
11095 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11097 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11099 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11100 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
11102 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
11103 TREE_OPERAND (t, 1)
11104 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
11105 gimple_seq_empty_p (for_pre_body)
11106 ? pre_p : &for_pre_body, NULL,
11107 false);
11108 /* Reference to pointer conversion is considered useless,
11109 but is significant for firstprivate clause. Force it
11110 here. */
11111 if (TREE_CODE (type) == POINTER_TYPE
11112 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1)))
11113 == REFERENCE_TYPE))
11115 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
11116 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v,
11117 TREE_OPERAND (t, 1));
11118 gimplify_and_add (m, gimple_seq_empty_p (for_pre_body)
11119 ? pre_p : &for_pre_body);
11120 TREE_OPERAND (t, 1) = v;
11122 tree c = build_omp_clause (input_location,
11123 OMP_CLAUSE_FIRSTPRIVATE);
11124 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
11125 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
11126 OMP_FOR_CLAUSES (orig_for_stmt) = c;
11129 /* Handle OMP_FOR_COND. */
11130 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
11131 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
11133 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
11134 TREE_OPERAND (t, 1)
11135 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
11136 gimple_seq_empty_p (for_pre_body)
11137 ? pre_p : &for_pre_body, NULL,
11138 false);
11139 /* Reference to pointer conversion is considered useless,
11140 but is significant for firstprivate clause. Force it
11141 here. */
11142 if (TREE_CODE (type) == POINTER_TYPE
11143 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1)))
11144 == REFERENCE_TYPE))
11146 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
11147 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v,
11148 TREE_OPERAND (t, 1));
11149 gimplify_and_add (m, gimple_seq_empty_p (for_pre_body)
11150 ? pre_p : &for_pre_body);
11151 TREE_OPERAND (t, 1) = v;
11153 tree c = build_omp_clause (input_location,
11154 OMP_CLAUSE_FIRSTPRIVATE);
11155 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
11156 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
11157 OMP_FOR_CLAUSES (orig_for_stmt) = c;
11160 /* Handle OMP_FOR_INCR. */
11161 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11162 if (TREE_CODE (t) == MODIFY_EXPR)
11164 decl = TREE_OPERAND (t, 0);
11165 t = TREE_OPERAND (t, 1);
11166 tree *tp = &TREE_OPERAND (t, 1);
11167 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
11168 tp = &TREE_OPERAND (t, 0);
11170 if (!is_gimple_constant (*tp))
11172 gimple_seq *seq = gimple_seq_empty_p (for_pre_body)
11173 ? pre_p : &for_pre_body;
11174 *tp = get_initialized_tmp_var (*tp, seq, NULL, false);
11175 tree c = build_omp_clause (input_location,
11176 OMP_CLAUSE_FIRSTPRIVATE);
11177 OMP_CLAUSE_DECL (c) = *tp;
11178 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
11179 OMP_FOR_CLAUSES (orig_for_stmt) = c;
11184 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
11185 OMP_TASKLOOP);
11188 if (orig_for_stmt != for_stmt)
11189 gimplify_omp_ctxp->combined_loop = true;
11191 for_body = NULL;
11192 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
11193 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
11194 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
11195 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
11197 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
11198 bool is_doacross = false;
11199 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
11201 is_doacross = true;
11202 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
11203 (OMP_FOR_INIT (for_stmt))
11204 * 2);
11206 int collapse = 1, tile = 0;
11207 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
11208 if (c)
11209 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
11210 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
11211 if (c)
11212 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
11213 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11215 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11216 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
11217 decl = TREE_OPERAND (t, 0);
11218 gcc_assert (DECL_P (decl));
11219 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
11220 || POINTER_TYPE_P (TREE_TYPE (decl)));
11221 if (is_doacross)
11223 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
11225 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
11226 if (TREE_CODE (orig_decl) == TREE_LIST)
11228 orig_decl = TREE_PURPOSE (orig_decl);
11229 if (!orig_decl)
11230 orig_decl = decl;
11232 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
11234 else
11235 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
11236 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
11239 /* Make sure the iteration variable is private. */
11240 tree c = NULL_TREE;
11241 tree c2 = NULL_TREE;
11242 if (orig_for_stmt != for_stmt)
11244 /* Preserve this information until we gimplify the inner simd. */
11245 if (has_decl_expr
11246 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
11247 TREE_PRIVATE (t) = 1;
11249 else if (ort == ORT_SIMD)
11251 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
11252 (splay_tree_key) decl);
11253 omp_is_private (gimplify_omp_ctxp, decl,
11254 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
11255 != 1));
11256 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
11258 omp_notice_variable (gimplify_omp_ctxp, decl, true);
11259 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
11260 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
11261 OMP_CLAUSE_LASTPRIVATE);
11262 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
11263 OMP_CLAUSE_LASTPRIVATE))
11264 if (OMP_CLAUSE_DECL (c3) == decl)
11266 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
11267 "conditional %<lastprivate%> on loop "
11268 "iterator %qD ignored", decl);
11269 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
11270 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
11273 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
11275 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
11276 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
11277 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
11278 if ((has_decl_expr
11279 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
11280 || TREE_PRIVATE (t))
11282 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
11283 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
11285 struct gimplify_omp_ctx *outer
11286 = gimplify_omp_ctxp->outer_context;
11287 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
11289 if (outer->region_type == ORT_WORKSHARE
11290 && outer->combined_loop)
11292 n = splay_tree_lookup (outer->variables,
11293 (splay_tree_key)decl);
11294 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
11296 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
11297 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
11299 else
11301 struct gimplify_omp_ctx *octx = outer->outer_context;
11302 if (octx
11303 && octx->region_type == ORT_COMBINED_PARALLEL
11304 && octx->outer_context
11305 && (octx->outer_context->region_type
11306 == ORT_WORKSHARE)
11307 && octx->outer_context->combined_loop)
11309 octx = octx->outer_context;
11310 n = splay_tree_lookup (octx->variables,
11311 (splay_tree_key)decl);
11312 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
11314 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
11315 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
11322 OMP_CLAUSE_DECL (c) = decl;
11323 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
11324 OMP_FOR_CLAUSES (for_stmt) = c;
11325 omp_add_variable (gimplify_omp_ctxp, decl, flags);
11326 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
11328 if (outer->region_type == ORT_WORKSHARE
11329 && outer->combined_loop)
11331 if (outer->outer_context
11332 && (outer->outer_context->region_type
11333 == ORT_COMBINED_PARALLEL))
11334 outer = outer->outer_context;
11335 else if (omp_check_private (outer, decl, false))
11336 outer = NULL;
11338 else if (((outer->region_type & ORT_TASKLOOP)
11339 == ORT_TASKLOOP)
11340 && outer->combined_loop
11341 && !omp_check_private (gimplify_omp_ctxp,
11342 decl, false))
11344 else if (outer->region_type != ORT_COMBINED_PARALLEL)
11346 omp_notice_variable (outer, decl, true);
11347 outer = NULL;
11349 if (outer)
11351 n = splay_tree_lookup (outer->variables,
11352 (splay_tree_key)decl);
11353 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11355 omp_add_variable (outer, decl,
11356 GOVD_LASTPRIVATE | GOVD_SEEN);
11357 if (outer->region_type == ORT_COMBINED_PARALLEL
11358 && outer->outer_context
11359 && (outer->outer_context->region_type
11360 == ORT_WORKSHARE)
11361 && outer->outer_context->combined_loop)
11363 outer = outer->outer_context;
11364 n = splay_tree_lookup (outer->variables,
11365 (splay_tree_key)decl);
11366 if (omp_check_private (outer, decl, false))
11367 outer = NULL;
11368 else if (n == NULL
11369 || ((n->value & GOVD_DATA_SHARE_CLASS)
11370 == 0))
11371 omp_add_variable (outer, decl,
11372 GOVD_LASTPRIVATE
11373 | GOVD_SEEN);
11374 else
11375 outer = NULL;
11377 if (outer && outer->outer_context
11378 && ((outer->outer_context->region_type
11379 & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS
11380 || (((outer->region_type & ORT_TASKLOOP)
11381 == ORT_TASKLOOP)
11382 && (outer->outer_context->region_type
11383 == ORT_COMBINED_PARALLEL))))
11385 outer = outer->outer_context;
11386 n = splay_tree_lookup (outer->variables,
11387 (splay_tree_key)decl);
11388 if (n == NULL
11389 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11390 omp_add_variable (outer, decl,
11391 GOVD_SHARED | GOVD_SEEN);
11392 else
11393 outer = NULL;
11395 if (outer && outer->outer_context)
11396 omp_notice_variable (outer->outer_context, decl,
11397 true);
11402 else
11404 bool lastprivate
11405 = (!has_decl_expr
11406 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
11407 if (TREE_PRIVATE (t))
11408 lastprivate = false;
11409 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
11411 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
11412 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
11413 lastprivate = false;
11416 struct gimplify_omp_ctx *outer
11417 = gimplify_omp_ctxp->outer_context;
11418 if (outer && lastprivate)
11420 if (outer->region_type == ORT_WORKSHARE
11421 && outer->combined_loop)
11423 n = splay_tree_lookup (outer->variables,
11424 (splay_tree_key)decl);
11425 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
11427 lastprivate = false;
11428 outer = NULL;
11430 else if (outer->outer_context
11431 && (outer->outer_context->region_type
11432 == ORT_COMBINED_PARALLEL))
11433 outer = outer->outer_context;
11434 else if (omp_check_private (outer, decl, false))
11435 outer = NULL;
11437 else if (((outer->region_type & ORT_TASKLOOP)
11438 == ORT_TASKLOOP)
11439 && outer->combined_loop
11440 && !omp_check_private (gimplify_omp_ctxp,
11441 decl, false))
11443 else if (outer->region_type != ORT_COMBINED_PARALLEL)
11445 omp_notice_variable (outer, decl, true);
11446 outer = NULL;
11448 if (outer)
11450 n = splay_tree_lookup (outer->variables,
11451 (splay_tree_key)decl);
11452 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11454 omp_add_variable (outer, decl,
11455 GOVD_LASTPRIVATE | GOVD_SEEN);
11456 if (outer->region_type == ORT_COMBINED_PARALLEL
11457 && outer->outer_context
11458 && (outer->outer_context->region_type
11459 == ORT_WORKSHARE)
11460 && outer->outer_context->combined_loop)
11462 outer = outer->outer_context;
11463 n = splay_tree_lookup (outer->variables,
11464 (splay_tree_key)decl);
11465 if (omp_check_private (outer, decl, false))
11466 outer = NULL;
11467 else if (n == NULL
11468 || ((n->value & GOVD_DATA_SHARE_CLASS)
11469 == 0))
11470 omp_add_variable (outer, decl,
11471 GOVD_LASTPRIVATE
11472 | GOVD_SEEN);
11473 else
11474 outer = NULL;
11476 if (outer && outer->outer_context
11477 && ((outer->outer_context->region_type
11478 & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS
11479 || (((outer->region_type & ORT_TASKLOOP)
11480 == ORT_TASKLOOP)
11481 && (outer->outer_context->region_type
11482 == ORT_COMBINED_PARALLEL))))
11484 outer = outer->outer_context;
11485 n = splay_tree_lookup (outer->variables,
11486 (splay_tree_key)decl);
11487 if (n == NULL
11488 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11489 omp_add_variable (outer, decl,
11490 GOVD_SHARED | GOVD_SEEN);
11491 else
11492 outer = NULL;
11494 if (outer && outer->outer_context)
11495 omp_notice_variable (outer->outer_context, decl,
11496 true);
11501 c = build_omp_clause (input_location,
11502 lastprivate ? OMP_CLAUSE_LASTPRIVATE
11503 : OMP_CLAUSE_PRIVATE);
11504 OMP_CLAUSE_DECL (c) = decl;
11505 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
11506 OMP_FOR_CLAUSES (for_stmt) = c;
11507 omp_add_variable (gimplify_omp_ctxp, decl,
11508 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
11509 | GOVD_EXPLICIT | GOVD_SEEN);
11510 c = NULL_TREE;
11513 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
11515 omp_notice_variable (gimplify_omp_ctxp, decl, true);
11516 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
11517 (splay_tree_key) decl);
11518 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
11519 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
11520 OMP_CLAUSE_LASTPRIVATE);
11521 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
11522 OMP_CLAUSE_LASTPRIVATE))
11523 if (OMP_CLAUSE_DECL (c3) == decl)
11525 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
11526 "conditional %<lastprivate%> on loop "
11527 "iterator %qD ignored", decl);
11528 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
11529 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
11532 else
11533 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
11535 /* If DECL is not a gimple register, create a temporary variable to act
11536 as an iteration counter. This is valid, since DECL cannot be
11537 modified in the body of the loop. Similarly for any iteration vars
11538 in simd with collapse > 1 where the iterator vars must be
11539 lastprivate. */
11540 if (orig_for_stmt != for_stmt)
11541 var = decl;
11542 else if (!is_gimple_reg (decl)
11543 || (ort == ORT_SIMD
11544 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1))
11546 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11547 /* Make sure omp_add_variable is not called on it prematurely.
11548 We call it ourselves a few lines later. */
11549 gimplify_omp_ctxp = NULL;
11550 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
11551 gimplify_omp_ctxp = ctx;
11552 TREE_OPERAND (t, 0) = var;
11554 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
11556 if (ort == ORT_SIMD
11557 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
11559 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
11560 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
11561 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
11562 OMP_CLAUSE_DECL (c2) = var;
11563 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
11564 OMP_FOR_CLAUSES (for_stmt) = c2;
11565 omp_add_variable (gimplify_omp_ctxp, var,
11566 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
11567 if (c == NULL_TREE)
11569 c = c2;
11570 c2 = NULL_TREE;
11573 else
11574 omp_add_variable (gimplify_omp_ctxp, var,
11575 GOVD_PRIVATE | GOVD_SEEN);
11577 else
11578 var = decl;
11580 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
11581 is_gimple_val, fb_rvalue, false);
11582 ret = MIN (ret, tret);
11583 if (ret == GS_ERROR)
11584 return ret;
11586 /* Handle OMP_FOR_COND. */
11587 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
11588 gcc_assert (COMPARISON_CLASS_P (t));
11589 gcc_assert (TREE_OPERAND (t, 0) == decl);
11591 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
11592 is_gimple_val, fb_rvalue, false);
11593 ret = MIN (ret, tret);
11595 /* Handle OMP_FOR_INCR. */
11596 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11597 switch (TREE_CODE (t))
11599 case PREINCREMENT_EXPR:
11600 case POSTINCREMENT_EXPR:
11602 tree decl = TREE_OPERAND (t, 0);
11603 /* c_omp_for_incr_canonicalize_ptr() should have been
11604 called to massage things appropriately. */
11605 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
11607 if (orig_for_stmt != for_stmt)
11608 break;
11609 t = build_int_cst (TREE_TYPE (decl), 1);
11610 if (c)
11611 OMP_CLAUSE_LINEAR_STEP (c) = t;
11612 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
11613 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
11614 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
11615 break;
11618 case PREDECREMENT_EXPR:
11619 case POSTDECREMENT_EXPR:
11620 /* c_omp_for_incr_canonicalize_ptr() should have been
11621 called to massage things appropriately. */
11622 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
11623 if (orig_for_stmt != for_stmt)
11624 break;
11625 t = build_int_cst (TREE_TYPE (decl), -1);
11626 if (c)
11627 OMP_CLAUSE_LINEAR_STEP (c) = t;
11628 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
11629 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
11630 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
11631 break;
11633 case MODIFY_EXPR:
11634 gcc_assert (TREE_OPERAND (t, 0) == decl);
11635 TREE_OPERAND (t, 0) = var;
11637 t = TREE_OPERAND (t, 1);
11638 switch (TREE_CODE (t))
11640 case PLUS_EXPR:
11641 if (TREE_OPERAND (t, 1) == decl)
11643 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
11644 TREE_OPERAND (t, 0) = var;
11645 break;
11648 /* Fallthru. */
11649 case MINUS_EXPR:
11650 case POINTER_PLUS_EXPR:
11651 gcc_assert (TREE_OPERAND (t, 0) == decl);
11652 TREE_OPERAND (t, 0) = var;
11653 break;
11654 default:
11655 gcc_unreachable ();
11658 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
11659 is_gimple_val, fb_rvalue, false);
11660 ret = MIN (ret, tret);
11661 if (c)
11663 tree step = TREE_OPERAND (t, 1);
11664 tree stept = TREE_TYPE (decl);
11665 if (POINTER_TYPE_P (stept))
11666 stept = sizetype;
11667 step = fold_convert (stept, step);
11668 if (TREE_CODE (t) == MINUS_EXPR)
11669 step = fold_build1 (NEGATE_EXPR, stept, step);
11670 OMP_CLAUSE_LINEAR_STEP (c) = step;
11671 if (step != TREE_OPERAND (t, 1))
11673 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
11674 &for_pre_body, NULL,
11675 is_gimple_val, fb_rvalue, false);
11676 ret = MIN (ret, tret);
11679 break;
11681 default:
11682 gcc_unreachable ();
11685 if (c2)
11687 gcc_assert (c);
11688 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
11691 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
11693 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
11694 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11695 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
11696 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11697 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
11698 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
11699 && OMP_CLAUSE_DECL (c) == decl)
11701 if (is_doacross && (collapse == 1 || i >= collapse))
11702 t = var;
11703 else
11705 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11706 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
11707 gcc_assert (TREE_OPERAND (t, 0) == var);
11708 t = TREE_OPERAND (t, 1);
11709 gcc_assert (TREE_CODE (t) == PLUS_EXPR
11710 || TREE_CODE (t) == MINUS_EXPR
11711 || TREE_CODE (t) == POINTER_PLUS_EXPR);
11712 gcc_assert (TREE_OPERAND (t, 0) == var);
11713 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
11714 is_doacross ? var : decl,
11715 TREE_OPERAND (t, 1));
11717 gimple_seq *seq;
11718 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
11719 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
11720 else
11721 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
11722 push_gimplify_context ();
11723 gimplify_assign (decl, t, seq);
11724 gimple *bind = NULL;
11725 if (gimplify_ctxp->temps)
11727 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
11728 *seq = NULL;
11729 gimplify_seq_add_stmt (seq, bind);
11731 pop_gimplify_context (bind);
11736 BITMAP_FREE (has_decl_expr);
11738 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
11739 || (loop_p && orig_for_stmt == for_stmt))
11741 push_gimplify_context ();
11742 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
11744 OMP_FOR_BODY (orig_for_stmt)
11745 = build3 (BIND_EXPR, void_type_node, NULL,
11746 OMP_FOR_BODY (orig_for_stmt), NULL);
11747 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
11751 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
11752 &for_body);
11754 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
11755 || (loop_p && orig_for_stmt == for_stmt))
11757 if (gimple_code (g) == GIMPLE_BIND)
11758 pop_gimplify_context (g);
11759 else
11760 pop_gimplify_context (NULL);
11763 if (orig_for_stmt != for_stmt)
11764 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11766 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11767 decl = TREE_OPERAND (t, 0);
11768 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11769 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11770 gimplify_omp_ctxp = ctx->outer_context;
11771 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
11772 gimplify_omp_ctxp = ctx;
11773 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
11774 TREE_OPERAND (t, 0) = var;
11775 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11776 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
11777 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
11780 gimplify_adjust_omp_clauses (pre_p, for_body,
11781 &OMP_FOR_CLAUSES (orig_for_stmt),
11782 TREE_CODE (orig_for_stmt));
11784 int kind;
11785 switch (TREE_CODE (orig_for_stmt))
11787 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
11788 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
11789 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
11790 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
11791 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
11792 default:
11793 gcc_unreachable ();
11795 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
11797 gimplify_seq_add_seq (pre_p, for_pre_body);
11798 for_pre_body = NULL;
11800 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
11801 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
11802 for_pre_body);
11803 if (orig_for_stmt != for_stmt)
11804 gimple_omp_for_set_combined_p (gfor, true);
11805 if (gimplify_omp_ctxp
11806 && (gimplify_omp_ctxp->combined_loop
11807 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
11808 && gimplify_omp_ctxp->outer_context
11809 && gimplify_omp_ctxp->outer_context->combined_loop)))
11811 gimple_omp_for_set_combined_into_p (gfor, true);
11812 if (gimplify_omp_ctxp->combined_loop)
11813 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
11814 else
11815 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
11818 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11820 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11821 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
11822 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
11823 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
11824 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
11825 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
11826 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11827 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
11830 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
11831 constructs with GIMPLE_OMP_TASK sandwiched in between them.
11832 The outer taskloop stands for computing the number of iterations,
11833 counts for collapsed loops and holding taskloop specific clauses.
11834 The task construct stands for the effect of data sharing on the
11835 explicit task it creates and the inner taskloop stands for expansion
11836 of the static loop inside of the explicit task construct. */
11837 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11839 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
11840 tree task_clauses = NULL_TREE;
11841 tree c = *gfor_clauses_ptr;
11842 tree *gtask_clauses_ptr = &task_clauses;
11843 tree outer_for_clauses = NULL_TREE;
11844 tree *gforo_clauses_ptr = &outer_for_clauses;
11845 for (; c; c = OMP_CLAUSE_CHAIN (c))
11846 switch (OMP_CLAUSE_CODE (c))
11848 /* These clauses are allowed on task, move them there. */
11849 case OMP_CLAUSE_SHARED:
11850 case OMP_CLAUSE_FIRSTPRIVATE:
11851 case OMP_CLAUSE_DEFAULT:
11852 case OMP_CLAUSE_IF:
11853 case OMP_CLAUSE_UNTIED:
11854 case OMP_CLAUSE_FINAL:
11855 case OMP_CLAUSE_MERGEABLE:
11856 case OMP_CLAUSE_PRIORITY:
11857 case OMP_CLAUSE_REDUCTION:
11858 case OMP_CLAUSE_IN_REDUCTION:
11859 *gtask_clauses_ptr = c;
11860 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11861 break;
11862 case OMP_CLAUSE_PRIVATE:
11863 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
11865 /* We want private on outer for and firstprivate
11866 on task. */
11867 *gtask_clauses_ptr
11868 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11869 OMP_CLAUSE_FIRSTPRIVATE);
11870 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
11871 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
11872 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
11873 *gforo_clauses_ptr = c;
11874 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11876 else
11878 *gtask_clauses_ptr = c;
11879 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11881 break;
11882 /* These clauses go into outer taskloop clauses. */
11883 case OMP_CLAUSE_GRAINSIZE:
11884 case OMP_CLAUSE_NUM_TASKS:
11885 case OMP_CLAUSE_NOGROUP:
11886 *gforo_clauses_ptr = c;
11887 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11888 break;
11889 /* Taskloop clause we duplicate on both taskloops. */
11890 case OMP_CLAUSE_COLLAPSE:
11891 *gfor_clauses_ptr = c;
11892 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11893 *gforo_clauses_ptr = copy_node (c);
11894 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
11895 break;
11896 /* For lastprivate, keep the clause on inner taskloop, and add
11897 a shared clause on task. If the same decl is also firstprivate,
11898 add also firstprivate clause on the inner taskloop. */
11899 case OMP_CLAUSE_LASTPRIVATE:
11900 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
11902 /* For taskloop C++ lastprivate IVs, we want:
11903 1) private on outer taskloop
11904 2) firstprivate and shared on task
11905 3) lastprivate on inner taskloop */
11906 *gtask_clauses_ptr
11907 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11908 OMP_CLAUSE_FIRSTPRIVATE);
11909 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
11910 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
11911 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
11912 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
11913 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11914 OMP_CLAUSE_PRIVATE);
11915 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
11916 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
11917 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
11918 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
11920 *gfor_clauses_ptr = c;
11921 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11922 *gtask_clauses_ptr
11923 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
11924 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
11925 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
11926 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
11927 gtask_clauses_ptr
11928 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
11929 break;
11930 default:
11931 gcc_unreachable ();
11933 *gfor_clauses_ptr = NULL_TREE;
11934 *gtask_clauses_ptr = NULL_TREE;
11935 *gforo_clauses_ptr = NULL_TREE;
11936 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
11937 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
11938 NULL_TREE, NULL_TREE, NULL_TREE);
11939 gimple_omp_task_set_taskloop_p (g, true);
11940 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
11941 gomp_for *gforo
11942 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
11943 gimple_omp_for_collapse (gfor),
11944 gimple_omp_for_pre_body (gfor));
11945 gimple_omp_for_set_pre_body (gfor, NULL);
11946 gimple_omp_for_set_combined_p (gforo, true);
11947 gimple_omp_for_set_combined_into_p (gfor, true);
11948 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
11950 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
11951 tree v = create_tmp_var (type);
11952 gimple_omp_for_set_index (gforo, i, v);
11953 t = unshare_expr (gimple_omp_for_initial (gfor, i));
11954 gimple_omp_for_set_initial (gforo, i, t);
11955 gimple_omp_for_set_cond (gforo, i,
11956 gimple_omp_for_cond (gfor, i));
11957 t = unshare_expr (gimple_omp_for_final (gfor, i));
11958 gimple_omp_for_set_final (gforo, i, t);
11959 t = unshare_expr (gimple_omp_for_incr (gfor, i));
11960 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
11961 TREE_OPERAND (t, 0) = v;
11962 gimple_omp_for_set_incr (gforo, i, t);
11963 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
11964 OMP_CLAUSE_DECL (t) = v;
11965 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
11966 gimple_omp_for_set_clauses (gforo, t);
11968 gimplify_seq_add_stmt (pre_p, gforo);
11970 else
11971 gimplify_seq_add_stmt (pre_p, gfor);
11973 if (TREE_CODE (orig_for_stmt) == OMP_FOR)
11975 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11976 unsigned lastprivate_conditional = 0;
11977 while (ctx
11978 && (ctx->region_type == ORT_TARGET_DATA
11979 || ctx->region_type == ORT_TASKGROUP))
11980 ctx = ctx->outer_context;
11981 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
11982 for (tree c = gimple_omp_for_clauses (gfor);
11983 c; c = OMP_CLAUSE_CHAIN (c))
11984 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11985 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
11986 ++lastprivate_conditional;
11987 if (lastprivate_conditional)
11989 struct omp_for_data fd;
11990 omp_extract_for_data (gfor, &fd, NULL);
11991 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
11992 lastprivate_conditional);
11993 tree var = create_tmp_var_raw (type);
11994 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
11995 OMP_CLAUSE_DECL (c) = var;
11996 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
11997 gimple_omp_for_set_clauses (gfor, c);
11998 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
12001 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
12003 unsigned lastprivate_conditional = 0;
12004 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
12005 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12006 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
12007 ++lastprivate_conditional;
12008 if (lastprivate_conditional)
12010 struct omp_for_data fd;
12011 omp_extract_for_data (gfor, &fd, NULL);
12012 tree type = unsigned_type_for (fd.iter_type);
12013 while (lastprivate_conditional--)
12015 tree c = build_omp_clause (UNKNOWN_LOCATION,
12016 OMP_CLAUSE__CONDTEMP_);
12017 OMP_CLAUSE_DECL (c) = create_tmp_var (type);
12018 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
12019 gimple_omp_for_set_clauses (gfor, c);
12024 if (ret != GS_ALL_DONE)
12025 return GS_ERROR;
12026 *expr_p = NULL_TREE;
12027 return GS_ALL_DONE;
12030 /* Helper for gimplify_omp_loop, called through walk_tree. */
12032 static tree
12033 replace_reduction_placeholders (tree *tp, int *walk_subtrees, void *data)
12035 if (DECL_P (*tp))
12037 tree *d = (tree *) data;
12038 if (*tp == OMP_CLAUSE_REDUCTION_PLACEHOLDER (d[0]))
12040 *tp = OMP_CLAUSE_REDUCTION_PLACEHOLDER (d[1]);
12041 *walk_subtrees = 0;
12043 else if (*tp == OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d[0]))
12045 *tp = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d[1]);
12046 *walk_subtrees = 0;
12049 return NULL_TREE;
12052 /* Gimplify the gross structure of an OMP_LOOP statement. */
12054 static enum gimplify_status
12055 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
12057 tree for_stmt = *expr_p;
12058 tree clauses = OMP_FOR_CLAUSES (for_stmt);
12059 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
12060 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
12061 int i;
12063 /* If order is not present, the behavior is as if order(concurrent)
12064 appeared. */
12065 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
12066 if (order == NULL_TREE)
12068 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
12069 OMP_CLAUSE_CHAIN (order) = clauses;
12070 OMP_FOR_CLAUSES (for_stmt) = clauses = order;
12073 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
12074 if (bind == NULL_TREE)
12076 if (!flag_openmp) /* flag_openmp_simd */
12078 else if (octx && (octx->region_type & ORT_TEAMS) != 0)
12079 kind = OMP_CLAUSE_BIND_TEAMS;
12080 else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
12081 kind = OMP_CLAUSE_BIND_PARALLEL;
12082 else
12084 for (; octx; octx = octx->outer_context)
12086 if ((octx->region_type & ORT_ACC) != 0
12087 || octx->region_type == ORT_NONE
12088 || octx->region_type == ORT_IMPLICIT_TARGET)
12089 continue;
12090 break;
12092 if (octx == NULL && !in_omp_construct)
12093 error_at (EXPR_LOCATION (for_stmt),
12094 "%<bind%> clause not specified on a %<loop%> "
12095 "construct not nested inside another OpenMP construct");
12097 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
12098 OMP_CLAUSE_CHAIN (bind) = clauses;
12099 OMP_CLAUSE_BIND_KIND (bind) = kind;
12100 OMP_FOR_CLAUSES (for_stmt) = bind;
12102 else
12103 switch (OMP_CLAUSE_BIND_KIND (bind))
12105 case OMP_CLAUSE_BIND_THREAD:
12106 break;
12107 case OMP_CLAUSE_BIND_PARALLEL:
12108 if (!flag_openmp) /* flag_openmp_simd */
12110 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12111 break;
12113 for (; octx; octx = octx->outer_context)
12114 if (octx->region_type == ORT_SIMD
12115 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
12117 error_at (EXPR_LOCATION (for_stmt),
12118 "%<bind(parallel)%> on a %<loop%> construct nested "
12119 "inside %<simd%> construct");
12120 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12121 break;
12123 kind = OMP_CLAUSE_BIND_PARALLEL;
12124 break;
12125 case OMP_CLAUSE_BIND_TEAMS:
12126 if (!flag_openmp) /* flag_openmp_simd */
12128 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12129 break;
12131 if ((octx
12132 && octx->region_type != ORT_IMPLICIT_TARGET
12133 && octx->region_type != ORT_NONE
12134 && (octx->region_type & ORT_TEAMS) == 0)
12135 || in_omp_construct)
12137 error_at (EXPR_LOCATION (for_stmt),
12138 "%<bind(teams)%> on a %<loop%> region not strictly "
12139 "nested inside of a %<teams%> region");
12140 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12141 break;
12143 kind = OMP_CLAUSE_BIND_TEAMS;
12144 break;
12145 default:
12146 gcc_unreachable ();
12149 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
12150 switch (OMP_CLAUSE_CODE (*pc))
12152 case OMP_CLAUSE_REDUCTION:
12153 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
12155 error_at (OMP_CLAUSE_LOCATION (*pc),
12156 "%<inscan%> %<reduction%> clause on "
12157 "%qs construct", "loop");
12158 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
12160 if (OMP_CLAUSE_REDUCTION_TASK (*pc))
12162 error_at (OMP_CLAUSE_LOCATION (*pc),
12163 "invalid %<task%> reduction modifier on construct "
12164 "other than %<parallel%>, %<for%> or %<sections%>");
12165 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
12167 pc = &OMP_CLAUSE_CHAIN (*pc);
12168 break;
12169 case OMP_CLAUSE_LASTPRIVATE:
12170 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12172 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12173 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12174 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
12175 break;
12176 if (OMP_FOR_ORIG_DECLS (for_stmt)
12177 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
12178 i)) == TREE_LIST
12179 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
12180 i)))
12182 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12183 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
12184 break;
12187 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
12189 error_at (OMP_CLAUSE_LOCATION (*pc),
12190 "%<lastprivate%> clause on a %<loop%> construct refers "
12191 "to a variable %qD which is not the loop iterator",
12192 OMP_CLAUSE_DECL (*pc));
12193 *pc = OMP_CLAUSE_CHAIN (*pc);
12194 break;
12196 pc = &OMP_CLAUSE_CHAIN (*pc);
12197 break;
12198 default:
12199 pc = &OMP_CLAUSE_CHAIN (*pc);
12200 break;
12203 TREE_SET_CODE (for_stmt, OMP_SIMD);
12205 int last;
12206 switch (kind)
12208 case OMP_CLAUSE_BIND_THREAD: last = 0; break;
12209 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
12210 case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
12212 for (int pass = 1; pass <= last; pass++)
12214 if (pass == 2)
12216 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
12217 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
12218 *expr_p = make_node (OMP_PARALLEL);
12219 TREE_TYPE (*expr_p) = void_type_node;
12220 OMP_PARALLEL_BODY (*expr_p) = bind;
12221 OMP_PARALLEL_COMBINED (*expr_p) = 1;
12222 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
12223 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
12224 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12225 if (OMP_FOR_ORIG_DECLS (for_stmt)
12226 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
12227 == TREE_LIST))
12229 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12230 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
12232 *pc = build_omp_clause (UNKNOWN_LOCATION,
12233 OMP_CLAUSE_FIRSTPRIVATE);
12234 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
12235 pc = &OMP_CLAUSE_CHAIN (*pc);
12239 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
12240 tree *pc = &OMP_FOR_CLAUSES (t);
12241 TREE_TYPE (t) = void_type_node;
12242 OMP_FOR_BODY (t) = *expr_p;
12243 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
12244 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
12245 switch (OMP_CLAUSE_CODE (c))
12247 case OMP_CLAUSE_BIND:
12248 case OMP_CLAUSE_ORDER:
12249 case OMP_CLAUSE_COLLAPSE:
12250 *pc = copy_node (c);
12251 pc = &OMP_CLAUSE_CHAIN (*pc);
12252 break;
12253 case OMP_CLAUSE_PRIVATE:
12254 case OMP_CLAUSE_FIRSTPRIVATE:
12255 /* Only needed on innermost. */
12256 break;
12257 case OMP_CLAUSE_LASTPRIVATE:
12258 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
12260 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12261 OMP_CLAUSE_FIRSTPRIVATE);
12262 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
12263 lang_hooks.decls.omp_finish_clause (*pc, NULL);
12264 pc = &OMP_CLAUSE_CHAIN (*pc);
12266 *pc = copy_node (c);
12267 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
12268 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
12269 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
12271 if (pass != last)
12272 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
12273 else
12274 lang_hooks.decls.omp_finish_clause (*pc, NULL);
12275 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
12277 pc = &OMP_CLAUSE_CHAIN (*pc);
12278 break;
12279 case OMP_CLAUSE_REDUCTION:
12280 *pc = copy_node (c);
12281 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
12282 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
12283 OMP_CLAUSE_REDUCTION_INIT (*pc)
12284 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
12285 OMP_CLAUSE_REDUCTION_MERGE (*pc)
12286 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
12287 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
12289 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
12290 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
12291 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
12292 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
12293 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
12294 tree nc = *pc;
12295 tree data[2] = { c, nc };
12296 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (nc),
12297 replace_reduction_placeholders,
12298 data);
12299 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (nc),
12300 replace_reduction_placeholders,
12301 data);
12303 pc = &OMP_CLAUSE_CHAIN (*pc);
12304 break;
12305 default:
12306 gcc_unreachable ();
12308 *pc = NULL_TREE;
12309 *expr_p = t;
12311 return gimplify_omp_for (expr_p, pre_p);
12315 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
12316 of OMP_TARGET's body. */
12318 static tree
12319 find_omp_teams (tree *tp, int *walk_subtrees, void *)
12321 *walk_subtrees = 0;
12322 switch (TREE_CODE (*tp))
12324 case OMP_TEAMS:
12325 return *tp;
12326 case BIND_EXPR:
12327 case STATEMENT_LIST:
12328 *walk_subtrees = 1;
12329 break;
12330 default:
12331 break;
12333 return NULL_TREE;
12336 /* Helper function of optimize_target_teams, determine if the expression
12337 can be computed safely before the target construct on the host. */
12339 static tree
12340 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
12342 splay_tree_node n;
12344 if (TYPE_P (*tp))
12346 *walk_subtrees = 0;
12347 return NULL_TREE;
12349 switch (TREE_CODE (*tp))
12351 case VAR_DECL:
12352 case PARM_DECL:
12353 case RESULT_DECL:
12354 *walk_subtrees = 0;
12355 if (error_operand_p (*tp)
12356 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
12357 || DECL_HAS_VALUE_EXPR_P (*tp)
12358 || DECL_THREAD_LOCAL_P (*tp)
12359 || TREE_SIDE_EFFECTS (*tp)
12360 || TREE_THIS_VOLATILE (*tp))
12361 return *tp;
12362 if (is_global_var (*tp)
12363 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
12364 || lookup_attribute ("omp declare target link",
12365 DECL_ATTRIBUTES (*tp))))
12366 return *tp;
12367 if (VAR_P (*tp)
12368 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
12369 && !is_global_var (*tp)
12370 && decl_function_context (*tp) == current_function_decl)
12371 return *tp;
12372 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12373 (splay_tree_key) *tp);
12374 if (n == NULL)
12376 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
12377 return NULL_TREE;
12378 return *tp;
12380 else if (n->value & GOVD_LOCAL)
12381 return *tp;
12382 else if (n->value & GOVD_FIRSTPRIVATE)
12383 return NULL_TREE;
12384 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
12385 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
12386 return NULL_TREE;
12387 return *tp;
12388 case INTEGER_CST:
12389 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
12390 return *tp;
12391 return NULL_TREE;
12392 case TARGET_EXPR:
12393 if (TARGET_EXPR_INITIAL (*tp)
12394 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
12395 return *tp;
12396 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
12397 walk_subtrees, NULL);
12398 /* Allow some reasonable subset of integral arithmetics. */
12399 case PLUS_EXPR:
12400 case MINUS_EXPR:
12401 case MULT_EXPR:
12402 case TRUNC_DIV_EXPR:
12403 case CEIL_DIV_EXPR:
12404 case FLOOR_DIV_EXPR:
12405 case ROUND_DIV_EXPR:
12406 case TRUNC_MOD_EXPR:
12407 case CEIL_MOD_EXPR:
12408 case FLOOR_MOD_EXPR:
12409 case ROUND_MOD_EXPR:
12410 case RDIV_EXPR:
12411 case EXACT_DIV_EXPR:
12412 case MIN_EXPR:
12413 case MAX_EXPR:
12414 case LSHIFT_EXPR:
12415 case RSHIFT_EXPR:
12416 case BIT_IOR_EXPR:
12417 case BIT_XOR_EXPR:
12418 case BIT_AND_EXPR:
12419 case NEGATE_EXPR:
12420 case ABS_EXPR:
12421 case BIT_NOT_EXPR:
12422 case NON_LVALUE_EXPR:
12423 CASE_CONVERT:
12424 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
12425 return *tp;
12426 return NULL_TREE;
12427 /* And disallow anything else, except for comparisons. */
12428 default:
12429 if (COMPARISON_CLASS_P (*tp))
12430 return NULL_TREE;
12431 return *tp;
12435 /* Try to determine if the num_teams and/or thread_limit expressions
12436 can have their values determined already before entering the
12437 target construct.
12438 INTEGER_CSTs trivially are,
12439 integral decls that are firstprivate (explicitly or implicitly)
12440 or explicitly map(always, to:) or map(always, tofrom:) on the target
12441 region too, and expressions involving simple arithmetics on those
12442 too, function calls are not ok, dereferencing something neither etc.
12443 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
12444 EXPR based on what we find:
12445 0 stands for clause not specified at all, use implementation default
12446 -1 stands for value that can't be determined easily before entering
12447 the target construct.
12448 If teams construct is not present at all, use 1 for num_teams
12449 and 0 for thread_limit (only one team is involved, and the thread
12450 limit is implementation defined. */
12452 static void
12453 optimize_target_teams (tree target, gimple_seq *pre_p)
12455 tree body = OMP_BODY (target);
12456 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
12457 tree num_teams = integer_zero_node;
12458 tree thread_limit = integer_zero_node;
12459 location_t num_teams_loc = EXPR_LOCATION (target);
12460 location_t thread_limit_loc = EXPR_LOCATION (target);
12461 tree c, *p, expr;
12462 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
12464 if (teams == NULL_TREE)
12465 num_teams = integer_one_node;
12466 else
12467 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
12469 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
12471 p = &num_teams;
12472 num_teams_loc = OMP_CLAUSE_LOCATION (c);
12474 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
12476 p = &thread_limit;
12477 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
12479 else
12480 continue;
12481 expr = OMP_CLAUSE_OPERAND (c, 0);
12482 if (TREE_CODE (expr) == INTEGER_CST)
12484 *p = expr;
12485 continue;
12487 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
12489 *p = integer_minus_one_node;
12490 continue;
12492 *p = expr;
12493 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
12494 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
12495 == GS_ERROR)
12497 gimplify_omp_ctxp = target_ctx;
12498 *p = integer_minus_one_node;
12499 continue;
12501 gimplify_omp_ctxp = target_ctx;
12502 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
12503 OMP_CLAUSE_OPERAND (c, 0) = *p;
12505 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
12506 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
12507 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
12508 OMP_TARGET_CLAUSES (target) = c;
12509 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
12510 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
12511 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
12512 OMP_TARGET_CLAUSES (target) = c;
12515 /* Gimplify the gross structure of several OMP constructs. */
12517 static void
12518 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
12520 tree expr = *expr_p;
12521 gimple *stmt;
12522 gimple_seq body = NULL;
12523 enum omp_region_type ort;
12525 switch (TREE_CODE (expr))
12527 case OMP_SECTIONS:
12528 case OMP_SINGLE:
12529 ort = ORT_WORKSHARE;
12530 break;
12531 case OMP_TARGET:
12532 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
12533 break;
12534 case OACC_KERNELS:
12535 ort = ORT_ACC_KERNELS;
12536 break;
12537 case OACC_PARALLEL:
12538 ort = ORT_ACC_PARALLEL;
12539 break;
12540 case OACC_SERIAL:
12541 ort = ORT_ACC_SERIAL;
12542 break;
12543 case OACC_DATA:
12544 ort = ORT_ACC_DATA;
12545 break;
12546 case OMP_TARGET_DATA:
12547 ort = ORT_TARGET_DATA;
12548 break;
12549 case OMP_TEAMS:
12550 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
12551 if (gimplify_omp_ctxp == NULL
12552 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
12553 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
12554 break;
12555 case OACC_HOST_DATA:
12556 ort = ORT_ACC_HOST_DATA;
12557 break;
12558 default:
12559 gcc_unreachable ();
12562 bool save_in_omp_construct = in_omp_construct;
12563 if ((ort & ORT_ACC) == 0)
12564 in_omp_construct = false;
12565 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
12566 TREE_CODE (expr));
12567 if (TREE_CODE (expr) == OMP_TARGET)
12568 optimize_target_teams (expr, pre_p);
12569 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
12570 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
12572 push_gimplify_context ();
12573 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
12574 if (gimple_code (g) == GIMPLE_BIND)
12575 pop_gimplify_context (g);
12576 else
12577 pop_gimplify_context (NULL);
12578 if ((ort & ORT_TARGET_DATA) != 0)
12580 enum built_in_function end_ix;
12581 switch (TREE_CODE (expr))
12583 case OACC_DATA:
12584 case OACC_HOST_DATA:
12585 end_ix = BUILT_IN_GOACC_DATA_END;
12586 break;
12587 case OMP_TARGET_DATA:
12588 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
12589 break;
12590 default:
12591 gcc_unreachable ();
12593 tree fn = builtin_decl_explicit (end_ix);
12594 g = gimple_build_call (fn, 0);
12595 gimple_seq cleanup = NULL;
12596 gimple_seq_add_stmt (&cleanup, g);
12597 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
12598 body = NULL;
12599 gimple_seq_add_stmt (&body, g);
12602 else
12603 gimplify_and_add (OMP_BODY (expr), &body);
12604 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
12605 TREE_CODE (expr));
12606 in_omp_construct = save_in_omp_construct;
12608 switch (TREE_CODE (expr))
12610 case OACC_DATA:
12611 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
12612 OMP_CLAUSES (expr));
12613 break;
12614 case OACC_KERNELS:
12615 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
12616 OMP_CLAUSES (expr));
12617 break;
12618 case OACC_HOST_DATA:
12619 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
12620 OMP_CLAUSES (expr));
12621 break;
12622 case OACC_PARALLEL:
12623 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
12624 OMP_CLAUSES (expr));
12625 break;
12626 case OACC_SERIAL:
12627 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
12628 OMP_CLAUSES (expr));
12629 break;
12630 case OMP_SECTIONS:
12631 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
12632 break;
12633 case OMP_SINGLE:
12634 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
12635 break;
12636 case OMP_TARGET:
12637 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
12638 OMP_CLAUSES (expr));
12639 break;
12640 case OMP_TARGET_DATA:
12641 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
12642 to be evaluated before the use_device_{ptr,addr} clauses if they
12643 refer to the same variables. */
12645 tree use_device_clauses;
12646 tree *pc, *uc = &use_device_clauses;
12647 for (pc = &OMP_CLAUSES (expr); *pc; )
12648 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
12649 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
12651 *uc = *pc;
12652 *pc = OMP_CLAUSE_CHAIN (*pc);
12653 uc = &OMP_CLAUSE_CHAIN (*uc);
12655 else
12656 pc = &OMP_CLAUSE_CHAIN (*pc);
12657 *uc = NULL_TREE;
12658 *pc = use_device_clauses;
12659 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
12660 OMP_CLAUSES (expr));
12662 break;
12663 case OMP_TEAMS:
12664 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
12665 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
12666 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
12667 break;
12668 default:
12669 gcc_unreachable ();
12672 gimplify_seq_add_stmt (pre_p, stmt);
12673 *expr_p = NULL_TREE;
12676 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
12677 target update constructs. */
12679 static void
12680 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
12682 tree expr = *expr_p;
12683 int kind;
12684 gomp_target *stmt;
12685 enum omp_region_type ort = ORT_WORKSHARE;
12687 switch (TREE_CODE (expr))
12689 case OACC_ENTER_DATA:
12690 case OACC_EXIT_DATA:
12691 kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
12692 ort = ORT_ACC;
12693 break;
12694 case OACC_UPDATE:
12695 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
12696 ort = ORT_ACC;
12697 break;
12698 case OMP_TARGET_UPDATE:
12699 kind = GF_OMP_TARGET_KIND_UPDATE;
12700 break;
12701 case OMP_TARGET_ENTER_DATA:
12702 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
12703 break;
12704 case OMP_TARGET_EXIT_DATA:
12705 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
12706 break;
12707 default:
12708 gcc_unreachable ();
12710 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
12711 ort, TREE_CODE (expr));
12712 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
12713 TREE_CODE (expr));
12714 if (TREE_CODE (expr) == OACC_UPDATE
12715 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
12716 OMP_CLAUSE_IF_PRESENT))
12718 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
12719 clause. */
12720 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
12721 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
12722 switch (OMP_CLAUSE_MAP_KIND (c))
12724 case GOMP_MAP_FORCE_TO:
12725 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
12726 break;
12727 case GOMP_MAP_FORCE_FROM:
12728 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
12729 break;
12730 default:
12731 break;
12734 else if (TREE_CODE (expr) == OACC_EXIT_DATA
12735 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
12736 OMP_CLAUSE_FINALIZE))
12738 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote that "finalize"
12739 semantics apply to all mappings of this OpenACC directive. */
12740 bool finalize_marked = false;
12741 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
12742 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
12743 switch (OMP_CLAUSE_MAP_KIND (c))
12745 case GOMP_MAP_FROM:
12746 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
12747 finalize_marked = true;
12748 break;
12749 case GOMP_MAP_RELEASE:
12750 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
12751 finalize_marked = true;
12752 break;
12753 default:
12754 /* Check consistency: libgomp relies on the very first data
12755 mapping clause being marked, so make sure we did that before
12756 any other mapping clauses. */
12757 gcc_assert (finalize_marked);
12758 break;
12761 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
12763 gimplify_seq_add_stmt (pre_p, stmt);
12764 *expr_p = NULL_TREE;
12767 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
12768 stabilized the lhs of the atomic operation as *ADDR. Return true if
12769 EXPR is this stabilized form. */
12771 static bool
12772 goa_lhs_expr_p (tree expr, tree addr)
12774 /* Also include casts to other type variants. The C front end is fond
12775 of adding these for e.g. volatile variables. This is like
12776 STRIP_TYPE_NOPS but includes the main variant lookup. */
12777 STRIP_USELESS_TYPE_CONVERSION (expr);
12779 if (TREE_CODE (expr) == INDIRECT_REF)
12781 expr = TREE_OPERAND (expr, 0);
12782 while (expr != addr
12783 && (CONVERT_EXPR_P (expr)
12784 || TREE_CODE (expr) == NON_LVALUE_EXPR)
12785 && TREE_CODE (expr) == TREE_CODE (addr)
12786 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
12788 expr = TREE_OPERAND (expr, 0);
12789 addr = TREE_OPERAND (addr, 0);
12791 if (expr == addr)
12792 return true;
12793 return (TREE_CODE (addr) == ADDR_EXPR
12794 && TREE_CODE (expr) == ADDR_EXPR
12795 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
12797 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
12798 return true;
12799 return false;
12802 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
12803 expression does not involve the lhs, evaluate it into a temporary.
12804 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
12805 or -1 if an error was encountered. */
12807 static int
12808 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
12809 tree lhs_var)
12811 tree expr = *expr_p;
12812 int saw_lhs;
12814 if (goa_lhs_expr_p (expr, lhs_addr))
12816 *expr_p = lhs_var;
12817 return 1;
12819 if (is_gimple_val (expr))
12820 return 0;
12822 saw_lhs = 0;
12823 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
12825 case tcc_binary:
12826 case tcc_comparison:
12827 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
12828 lhs_var);
12829 /* FALLTHRU */
12830 case tcc_unary:
12831 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
12832 lhs_var);
12833 break;
12834 case tcc_expression:
12835 switch (TREE_CODE (expr))
12837 case TRUTH_ANDIF_EXPR:
12838 case TRUTH_ORIF_EXPR:
12839 case TRUTH_AND_EXPR:
12840 case TRUTH_OR_EXPR:
12841 case TRUTH_XOR_EXPR:
12842 case BIT_INSERT_EXPR:
12843 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
12844 lhs_addr, lhs_var);
12845 /* FALLTHRU */
12846 case TRUTH_NOT_EXPR:
12847 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
12848 lhs_addr, lhs_var);
12849 break;
12850 case COMPOUND_EXPR:
12851 /* Break out any preevaluations from cp_build_modify_expr. */
12852 for (; TREE_CODE (expr) == COMPOUND_EXPR;
12853 expr = TREE_OPERAND (expr, 1))
12854 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
12855 *expr_p = expr;
12856 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var);
12857 default:
12858 break;
12860 break;
12861 case tcc_reference:
12862 if (TREE_CODE (expr) == BIT_FIELD_REF)
12863 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
12864 lhs_addr, lhs_var);
12865 break;
12866 default:
12867 break;
12870 if (saw_lhs == 0)
12872 enum gimplify_status gs;
12873 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
12874 if (gs != GS_ALL_DONE)
12875 saw_lhs = -1;
12878 return saw_lhs;
12881 /* Gimplify an OMP_ATOMIC statement. */
12883 static enum gimplify_status
12884 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
12886 tree addr = TREE_OPERAND (*expr_p, 0);
12887 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
12888 ? NULL : TREE_OPERAND (*expr_p, 1);
12889 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
12890 tree tmp_load;
12891 gomp_atomic_load *loadstmt;
12892 gomp_atomic_store *storestmt;
12894 tmp_load = create_tmp_reg (type);
12895 if (rhs && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load) < 0)
12896 return GS_ERROR;
12898 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
12899 != GS_ALL_DONE)
12900 return GS_ERROR;
12902 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
12903 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
12904 gimplify_seq_add_stmt (pre_p, loadstmt);
12905 if (rhs)
12907 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
12908 representatives. Use BIT_FIELD_REF on the lhs instead. */
12909 if (TREE_CODE (rhs) == BIT_INSERT_EXPR
12910 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
12912 tree bitpos = TREE_OPERAND (rhs, 2);
12913 tree op1 = TREE_OPERAND (rhs, 1);
12914 tree bitsize;
12915 tree tmp_store = tmp_load;
12916 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
12917 tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
12918 if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
12919 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
12920 else
12921 bitsize = TYPE_SIZE (TREE_TYPE (op1));
12922 gcc_assert (TREE_OPERAND (rhs, 0) == tmp_load);
12923 tree t = build2_loc (EXPR_LOCATION (rhs),
12924 MODIFY_EXPR, void_type_node,
12925 build3_loc (EXPR_LOCATION (rhs), BIT_FIELD_REF,
12926 TREE_TYPE (op1), tmp_store, bitsize,
12927 bitpos), op1);
12928 gimplify_and_add (t, pre_p);
12929 rhs = tmp_store;
12931 if (gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
12932 != GS_ALL_DONE)
12933 return GS_ERROR;
12936 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
12937 rhs = tmp_load;
12938 storestmt
12939 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
12940 gimplify_seq_add_stmt (pre_p, storestmt);
12941 switch (TREE_CODE (*expr_p))
12943 case OMP_ATOMIC_READ:
12944 case OMP_ATOMIC_CAPTURE_OLD:
12945 *expr_p = tmp_load;
12946 gimple_omp_atomic_set_need_value (loadstmt);
12947 break;
12948 case OMP_ATOMIC_CAPTURE_NEW:
12949 *expr_p = rhs;
12950 gimple_omp_atomic_set_need_value (storestmt);
12951 break;
12952 default:
12953 *expr_p = NULL;
12954 break;
12957 return GS_ALL_DONE;
12960 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
12961 body, and adding some EH bits. */
12963 static enum gimplify_status
12964 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
12966 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
12967 gimple *body_stmt;
12968 gtransaction *trans_stmt;
12969 gimple_seq body = NULL;
12970 int subcode = 0;
12972 /* Wrap the transaction body in a BIND_EXPR so we have a context
12973 where to put decls for OMP. */
12974 if (TREE_CODE (tbody) != BIND_EXPR)
12976 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
12977 TREE_SIDE_EFFECTS (bind) = 1;
12978 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
12979 TRANSACTION_EXPR_BODY (expr) = bind;
12982 push_gimplify_context ();
12983 temp = voidify_wrapper_expr (*expr_p, NULL);
12985 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
12986 pop_gimplify_context (body_stmt);
12988 trans_stmt = gimple_build_transaction (body);
12989 if (TRANSACTION_EXPR_OUTER (expr))
12990 subcode = GTMA_IS_OUTER;
12991 else if (TRANSACTION_EXPR_RELAXED (expr))
12992 subcode = GTMA_IS_RELAXED;
12993 gimple_transaction_set_subcode (trans_stmt, subcode);
12995 gimplify_seq_add_stmt (pre_p, trans_stmt);
12997 if (temp)
12999 *expr_p = temp;
13000 return GS_OK;
13003 *expr_p = NULL_TREE;
13004 return GS_ALL_DONE;
13007 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
13008 is the OMP_BODY of the original EXPR (which has already been
13009 gimplified so it's not present in the EXPR).
13011 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
13013 static gimple *
13014 gimplify_omp_ordered (tree expr, gimple_seq body)
13016 tree c, decls;
13017 int failures = 0;
13018 unsigned int i;
13019 tree source_c = NULL_TREE;
13020 tree sink_c = NULL_TREE;
13022 if (gimplify_omp_ctxp)
13024 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13025 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
13026 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
13027 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
13028 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
13030 error_at (OMP_CLAUSE_LOCATION (c),
13031 "%<ordered%> construct with %<depend%> clause must be "
13032 "closely nested inside a loop with %<ordered%> clause "
13033 "with a parameter");
13034 failures++;
13036 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
13037 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
13039 bool fail = false;
13040 for (decls = OMP_CLAUSE_DECL (c), i = 0;
13041 decls && TREE_CODE (decls) == TREE_LIST;
13042 decls = TREE_CHAIN (decls), ++i)
13043 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
13044 continue;
13045 else if (TREE_VALUE (decls)
13046 != gimplify_omp_ctxp->loop_iter_var[2 * i])
13048 error_at (OMP_CLAUSE_LOCATION (c),
13049 "variable %qE is not an iteration "
13050 "of outermost loop %d, expected %qE",
13051 TREE_VALUE (decls), i + 1,
13052 gimplify_omp_ctxp->loop_iter_var[2 * i]);
13053 fail = true;
13054 failures++;
13056 else
13057 TREE_VALUE (decls)
13058 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
13059 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
13061 error_at (OMP_CLAUSE_LOCATION (c),
13062 "number of variables in %<depend%> clause with "
13063 "%<sink%> modifier does not match number of "
13064 "iteration variables");
13065 failures++;
13067 sink_c = c;
13069 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
13070 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
13072 if (source_c)
13074 error_at (OMP_CLAUSE_LOCATION (c),
13075 "more than one %<depend%> clause with %<source%> "
13076 "modifier on an %<ordered%> construct");
13077 failures++;
13079 else
13080 source_c = c;
13083 if (source_c && sink_c)
13085 error_at (OMP_CLAUSE_LOCATION (source_c),
13086 "%<depend%> clause with %<source%> modifier specified "
13087 "together with %<depend%> clauses with %<sink%> modifier "
13088 "on the same construct");
13089 failures++;
13092 if (failures)
13093 return gimple_build_nop ();
13094 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
13097 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
13098 expression produces a value to be used as an operand inside a GIMPLE
13099 statement, the value will be stored back in *EXPR_P. This value will
13100 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
13101 an SSA_NAME. The corresponding sequence of GIMPLE statements is
13102 emitted in PRE_P and POST_P.
13104 Additionally, this process may overwrite parts of the input
13105 expression during gimplification. Ideally, it should be
13106 possible to do non-destructive gimplification.
13108 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
13109 the expression needs to evaluate to a value to be used as
13110 an operand in a GIMPLE statement, this value will be stored in
13111 *EXPR_P on exit. This happens when the caller specifies one
13112 of fb_lvalue or fb_rvalue fallback flags.
13114 PRE_P will contain the sequence of GIMPLE statements corresponding
13115 to the evaluation of EXPR and all the side-effects that must
13116 be executed before the main expression. On exit, the last
13117 statement of PRE_P is the core statement being gimplified. For
13118 instance, when gimplifying 'if (++a)' the last statement in
13119 PRE_P will be 'if (t.1)' where t.1 is the result of
13120 pre-incrementing 'a'.
13122 POST_P will contain the sequence of GIMPLE statements corresponding
13123 to the evaluation of all the side-effects that must be executed
13124 after the main expression. If this is NULL, the post
13125 side-effects are stored at the end of PRE_P.
13127 The reason why the output is split in two is to handle post
13128 side-effects explicitly. In some cases, an expression may have
13129 inner and outer post side-effects which need to be emitted in
13130 an order different from the one given by the recursive
13131 traversal. For instance, for the expression (*p--)++ the post
13132 side-effects of '--' must actually occur *after* the post
13133 side-effects of '++'. However, gimplification will first visit
13134 the inner expression, so if a separate POST sequence was not
13135 used, the resulting sequence would be:
13137 1 t.1 = *p
13138 2 p = p - 1
13139 3 t.2 = t.1 + 1
13140 4 *p = t.2
13142 However, the post-decrement operation in line #2 must not be
13143 evaluated until after the store to *p at line #4, so the
13144 correct sequence should be:
13146 1 t.1 = *p
13147 2 t.2 = t.1 + 1
13148 3 *p = t.2
13149 4 p = p - 1
13151 So, by specifying a separate post queue, it is possible
13152 to emit the post side-effects in the correct order.
13153 If POST_P is NULL, an internal queue will be used. Before
13154 returning to the caller, the sequence POST_P is appended to
13155 the main output sequence PRE_P.
13157 GIMPLE_TEST_F points to a function that takes a tree T and
13158 returns nonzero if T is in the GIMPLE form requested by the
13159 caller. The GIMPLE predicates are in gimple.c.
13161 FALLBACK tells the function what sort of a temporary we want if
13162 gimplification cannot produce an expression that complies with
13163 GIMPLE_TEST_F.
13165 fb_none means that no temporary should be generated
13166 fb_rvalue means that an rvalue is OK to generate
13167 fb_lvalue means that an lvalue is OK to generate
13168 fb_either means that either is OK, but an lvalue is preferable.
13169 fb_mayfail means that gimplification may fail (in which case
13170 GS_ERROR will be returned)
13172 The return value is either GS_ERROR or GS_ALL_DONE, since this
13173 function iterates until EXPR is completely gimplified or an error
13174 occurs. */
13176 enum gimplify_status
13177 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
13178 bool (*gimple_test_f) (tree), fallback_t fallback)
13180 tree tmp;
13181 gimple_seq internal_pre = NULL;
13182 gimple_seq internal_post = NULL;
13183 tree save_expr;
13184 bool is_statement;
13185 location_t saved_location;
13186 enum gimplify_status ret;
13187 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
13188 tree label;
13190 save_expr = *expr_p;
13191 if (save_expr == NULL_TREE)
13192 return GS_ALL_DONE;
13194 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
13195 is_statement = gimple_test_f == is_gimple_stmt;
13196 if (is_statement)
13197 gcc_assert (pre_p);
13199 /* Consistency checks. */
13200 if (gimple_test_f == is_gimple_reg)
13201 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
13202 else if (gimple_test_f == is_gimple_val
13203 || gimple_test_f == is_gimple_call_addr
13204 || gimple_test_f == is_gimple_condexpr
13205 || gimple_test_f == is_gimple_condexpr_for_cond
13206 || gimple_test_f == is_gimple_mem_rhs
13207 || gimple_test_f == is_gimple_mem_rhs_or_call
13208 || gimple_test_f == is_gimple_reg_rhs
13209 || gimple_test_f == is_gimple_reg_rhs_or_call
13210 || gimple_test_f == is_gimple_asm_val
13211 || gimple_test_f == is_gimple_mem_ref_addr)
13212 gcc_assert (fallback & fb_rvalue);
13213 else if (gimple_test_f == is_gimple_min_lval
13214 || gimple_test_f == is_gimple_lvalue)
13215 gcc_assert (fallback & fb_lvalue);
13216 else if (gimple_test_f == is_gimple_addressable)
13217 gcc_assert (fallback & fb_either);
13218 else if (gimple_test_f == is_gimple_stmt)
13219 gcc_assert (fallback == fb_none);
13220 else
13222 /* We should have recognized the GIMPLE_TEST_F predicate to
13223 know what kind of fallback to use in case a temporary is
13224 needed to hold the value or address of *EXPR_P. */
13225 gcc_unreachable ();
13228 /* We used to check the predicate here and return immediately if it
13229 succeeds. This is wrong; the design is for gimplification to be
13230 idempotent, and for the predicates to only test for valid forms, not
13231 whether they are fully simplified. */
13232 if (pre_p == NULL)
13233 pre_p = &internal_pre;
13235 if (post_p == NULL)
13236 post_p = &internal_post;
13238 /* Remember the last statements added to PRE_P and POST_P. Every
13239 new statement added by the gimplification helpers needs to be
13240 annotated with location information. To centralize the
13241 responsibility, we remember the last statement that had been
13242 added to both queues before gimplifying *EXPR_P. If
13243 gimplification produces new statements in PRE_P and POST_P, those
13244 statements will be annotated with the same location information
13245 as *EXPR_P. */
13246 pre_last_gsi = gsi_last (*pre_p);
13247 post_last_gsi = gsi_last (*post_p);
13249 saved_location = input_location;
13250 if (save_expr != error_mark_node
13251 && EXPR_HAS_LOCATION (*expr_p))
13252 input_location = EXPR_LOCATION (*expr_p);
13254 /* Loop over the specific gimplifiers until the toplevel node
13255 remains the same. */
13258 /* Strip away as many useless type conversions as possible
13259 at the toplevel. */
13260 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
13262 /* Remember the expr. */
13263 save_expr = *expr_p;
13265 /* Die, die, die, my darling. */
13266 if (error_operand_p (save_expr))
13268 ret = GS_ERROR;
13269 break;
13272 /* Do any language-specific gimplification. */
13273 ret = ((enum gimplify_status)
13274 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
13275 if (ret == GS_OK)
13277 if (*expr_p == NULL_TREE)
13278 break;
13279 if (*expr_p != save_expr)
13280 continue;
13282 else if (ret != GS_UNHANDLED)
13283 break;
13285 /* Make sure that all the cases set 'ret' appropriately. */
13286 ret = GS_UNHANDLED;
13287 switch (TREE_CODE (*expr_p))
13289 /* First deal with the special cases. */
13291 case POSTINCREMENT_EXPR:
13292 case POSTDECREMENT_EXPR:
13293 case PREINCREMENT_EXPR:
13294 case PREDECREMENT_EXPR:
13295 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
13296 fallback != fb_none,
13297 TREE_TYPE (*expr_p));
13298 break;
13300 case VIEW_CONVERT_EXPR:
13301 if ((fallback & fb_rvalue)
13302 && is_gimple_reg_type (TREE_TYPE (*expr_p))
13303 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
13305 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13306 post_p, is_gimple_val, fb_rvalue);
13307 recalculate_side_effects (*expr_p);
13308 break;
13310 /* Fallthru. */
13312 case ARRAY_REF:
13313 case ARRAY_RANGE_REF:
13314 case REALPART_EXPR:
13315 case IMAGPART_EXPR:
13316 case COMPONENT_REF:
13317 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
13318 fallback ? fallback : fb_rvalue);
13319 break;
13321 case COND_EXPR:
13322 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
13324 /* C99 code may assign to an array in a structure value of a
13325 conditional expression, and this has undefined behavior
13326 only on execution, so create a temporary if an lvalue is
13327 required. */
13328 if (fallback == fb_lvalue)
13330 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
13331 mark_addressable (*expr_p);
13332 ret = GS_OK;
13334 break;
13336 case CALL_EXPR:
13337 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
13339 /* C99 code may assign to an array in a structure returned
13340 from a function, and this has undefined behavior only on
13341 execution, so create a temporary if an lvalue is
13342 required. */
13343 if (fallback == fb_lvalue)
13345 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
13346 mark_addressable (*expr_p);
13347 ret = GS_OK;
13349 break;
13351 case TREE_LIST:
13352 gcc_unreachable ();
13354 case COMPOUND_EXPR:
13355 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
13356 break;
13358 case COMPOUND_LITERAL_EXPR:
13359 ret = gimplify_compound_literal_expr (expr_p, pre_p,
13360 gimple_test_f, fallback);
13361 break;
13363 case MODIFY_EXPR:
13364 case INIT_EXPR:
13365 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
13366 fallback != fb_none);
13367 break;
13369 case TRUTH_ANDIF_EXPR:
13370 case TRUTH_ORIF_EXPR:
13372 /* Preserve the original type of the expression and the
13373 source location of the outer expression. */
13374 tree org_type = TREE_TYPE (*expr_p);
13375 *expr_p = gimple_boolify (*expr_p);
13376 *expr_p = build3_loc (input_location, COND_EXPR,
13377 org_type, *expr_p,
13378 fold_convert_loc
13379 (input_location,
13380 org_type, boolean_true_node),
13381 fold_convert_loc
13382 (input_location,
13383 org_type, boolean_false_node));
13384 ret = GS_OK;
13385 break;
13388 case TRUTH_NOT_EXPR:
13390 tree type = TREE_TYPE (*expr_p);
13391 /* The parsers are careful to generate TRUTH_NOT_EXPR
13392 only with operands that are always zero or one.
13393 We do not fold here but handle the only interesting case
13394 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
13395 *expr_p = gimple_boolify (*expr_p);
13396 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
13397 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
13398 TREE_TYPE (*expr_p),
13399 TREE_OPERAND (*expr_p, 0));
13400 else
13401 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
13402 TREE_TYPE (*expr_p),
13403 TREE_OPERAND (*expr_p, 0),
13404 build_int_cst (TREE_TYPE (*expr_p), 1));
13405 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
13406 *expr_p = fold_convert_loc (input_location, type, *expr_p);
13407 ret = GS_OK;
13408 break;
13411 case ADDR_EXPR:
13412 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
13413 break;
13415 case ANNOTATE_EXPR:
13417 tree cond = TREE_OPERAND (*expr_p, 0);
13418 tree kind = TREE_OPERAND (*expr_p, 1);
13419 tree data = TREE_OPERAND (*expr_p, 2);
13420 tree type = TREE_TYPE (cond);
13421 if (!INTEGRAL_TYPE_P (type))
13423 *expr_p = cond;
13424 ret = GS_OK;
13425 break;
13427 tree tmp = create_tmp_var (type);
13428 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
13429 gcall *call
13430 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
13431 gimple_call_set_lhs (call, tmp);
13432 gimplify_seq_add_stmt (pre_p, call);
13433 *expr_p = tmp;
13434 ret = GS_ALL_DONE;
13435 break;
13438 case VA_ARG_EXPR:
13439 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
13440 break;
13442 CASE_CONVERT:
13443 if (IS_EMPTY_STMT (*expr_p))
13445 ret = GS_ALL_DONE;
13446 break;
13449 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
13450 || fallback == fb_none)
13452 /* Just strip a conversion to void (or in void context) and
13453 try again. */
13454 *expr_p = TREE_OPERAND (*expr_p, 0);
13455 ret = GS_OK;
13456 break;
13459 ret = gimplify_conversion (expr_p);
13460 if (ret == GS_ERROR)
13461 break;
13462 if (*expr_p != save_expr)
13463 break;
13464 /* FALLTHRU */
13466 case FIX_TRUNC_EXPR:
13467 /* unary_expr: ... | '(' cast ')' val | ... */
13468 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13469 is_gimple_val, fb_rvalue);
13470 recalculate_side_effects (*expr_p);
13471 break;
13473 case INDIRECT_REF:
13475 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
13476 bool notrap = TREE_THIS_NOTRAP (*expr_p);
13477 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
13479 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
13480 if (*expr_p != save_expr)
13482 ret = GS_OK;
13483 break;
13486 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13487 is_gimple_reg, fb_rvalue);
13488 if (ret == GS_ERROR)
13489 break;
13491 recalculate_side_effects (*expr_p);
13492 *expr_p = fold_build2_loc (input_location, MEM_REF,
13493 TREE_TYPE (*expr_p),
13494 TREE_OPERAND (*expr_p, 0),
13495 build_int_cst (saved_ptr_type, 0));
13496 TREE_THIS_VOLATILE (*expr_p) = volatilep;
13497 TREE_THIS_NOTRAP (*expr_p) = notrap;
13498 ret = GS_OK;
13499 break;
13502 /* We arrive here through the various re-gimplifcation paths. */
13503 case MEM_REF:
13504 /* First try re-folding the whole thing. */
13505 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
13506 TREE_OPERAND (*expr_p, 0),
13507 TREE_OPERAND (*expr_p, 1));
13508 if (tmp)
13510 REF_REVERSE_STORAGE_ORDER (tmp)
13511 = REF_REVERSE_STORAGE_ORDER (*expr_p);
13512 *expr_p = tmp;
13513 recalculate_side_effects (*expr_p);
13514 ret = GS_OK;
13515 break;
13517 /* Avoid re-gimplifying the address operand if it is already
13518 in suitable form. Re-gimplifying would mark the address
13519 operand addressable. Always gimplify when not in SSA form
13520 as we still may have to gimplify decls with value-exprs. */
13521 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
13522 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
13524 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13525 is_gimple_mem_ref_addr, fb_rvalue);
13526 if (ret == GS_ERROR)
13527 break;
13529 recalculate_side_effects (*expr_p);
13530 ret = GS_ALL_DONE;
13531 break;
13533 /* Constants need not be gimplified. */
13534 case INTEGER_CST:
13535 case REAL_CST:
13536 case FIXED_CST:
13537 case STRING_CST:
13538 case COMPLEX_CST:
13539 case VECTOR_CST:
13540 /* Drop the overflow flag on constants, we do not want
13541 that in the GIMPLE IL. */
13542 if (TREE_OVERFLOW_P (*expr_p))
13543 *expr_p = drop_tree_overflow (*expr_p);
13544 ret = GS_ALL_DONE;
13545 break;
13547 case CONST_DECL:
13548 /* If we require an lvalue, such as for ADDR_EXPR, retain the
13549 CONST_DECL node. Otherwise the decl is replaceable by its
13550 value. */
13551 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
13552 if (fallback & fb_lvalue)
13553 ret = GS_ALL_DONE;
13554 else
13556 *expr_p = DECL_INITIAL (*expr_p);
13557 ret = GS_OK;
13559 break;
13561 case DECL_EXPR:
13562 ret = gimplify_decl_expr (expr_p, pre_p);
13563 break;
13565 case BIND_EXPR:
13566 ret = gimplify_bind_expr (expr_p, pre_p);
13567 break;
13569 case LOOP_EXPR:
13570 ret = gimplify_loop_expr (expr_p, pre_p);
13571 break;
13573 case SWITCH_EXPR:
13574 ret = gimplify_switch_expr (expr_p, pre_p);
13575 break;
13577 case EXIT_EXPR:
13578 ret = gimplify_exit_expr (expr_p);
13579 break;
13581 case GOTO_EXPR:
13582 /* If the target is not LABEL, then it is a computed jump
13583 and the target needs to be gimplified. */
13584 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
13586 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
13587 NULL, is_gimple_val, fb_rvalue);
13588 if (ret == GS_ERROR)
13589 break;
13591 gimplify_seq_add_stmt (pre_p,
13592 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
13593 ret = GS_ALL_DONE;
13594 break;
13596 case PREDICT_EXPR:
13597 gimplify_seq_add_stmt (pre_p,
13598 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
13599 PREDICT_EXPR_OUTCOME (*expr_p)));
13600 ret = GS_ALL_DONE;
13601 break;
13603 case LABEL_EXPR:
13604 ret = gimplify_label_expr (expr_p, pre_p);
13605 label = LABEL_EXPR_LABEL (*expr_p);
13606 gcc_assert (decl_function_context (label) == current_function_decl);
13608 /* If the label is used in a goto statement, or address of the label
13609 is taken, we need to unpoison all variables that were seen so far.
13610 Doing so would prevent us from reporting a false positives. */
13611 if (asan_poisoned_variables
13612 && asan_used_labels != NULL
13613 && asan_used_labels->contains (label))
13614 asan_poison_variables (asan_poisoned_variables, false, pre_p);
13615 break;
13617 case CASE_LABEL_EXPR:
13618 ret = gimplify_case_label_expr (expr_p, pre_p);
13620 if (gimplify_ctxp->live_switch_vars)
13621 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
13622 pre_p);
13623 break;
13625 case RETURN_EXPR:
13626 ret = gimplify_return_expr (*expr_p, pre_p);
13627 break;
13629 case CONSTRUCTOR:
13630 /* Don't reduce this in place; let gimplify_init_constructor work its
13631 magic. Buf if we're just elaborating this for side effects, just
13632 gimplify any element that has side-effects. */
13633 if (fallback == fb_none)
13635 unsigned HOST_WIDE_INT ix;
13636 tree val;
13637 tree temp = NULL_TREE;
13638 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
13639 if (TREE_SIDE_EFFECTS (val))
13640 append_to_statement_list (val, &temp);
13642 *expr_p = temp;
13643 ret = temp ? GS_OK : GS_ALL_DONE;
13645 /* C99 code may assign to an array in a constructed
13646 structure or union, and this has undefined behavior only
13647 on execution, so create a temporary if an lvalue is
13648 required. */
13649 else if (fallback == fb_lvalue)
13651 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
13652 mark_addressable (*expr_p);
13653 ret = GS_OK;
13655 else
13656 ret = GS_ALL_DONE;
13657 break;
13659 /* The following are special cases that are not handled by the
13660 original GIMPLE grammar. */
13662 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
13663 eliminated. */
13664 case SAVE_EXPR:
13665 ret = gimplify_save_expr (expr_p, pre_p, post_p);
13666 break;
13668 case BIT_FIELD_REF:
13669 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13670 post_p, is_gimple_lvalue, fb_either);
13671 recalculate_side_effects (*expr_p);
13672 break;
13674 case TARGET_MEM_REF:
13676 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
13678 if (TMR_BASE (*expr_p))
13679 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
13680 post_p, is_gimple_mem_ref_addr, fb_either);
13681 if (TMR_INDEX (*expr_p))
13682 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
13683 post_p, is_gimple_val, fb_rvalue);
13684 if (TMR_INDEX2 (*expr_p))
13685 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
13686 post_p, is_gimple_val, fb_rvalue);
13687 /* TMR_STEP and TMR_OFFSET are always integer constants. */
13688 ret = MIN (r0, r1);
13690 break;
13692 case NON_LVALUE_EXPR:
13693 /* This should have been stripped above. */
13694 gcc_unreachable ();
13696 case ASM_EXPR:
13697 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
13698 break;
13700 case TRY_FINALLY_EXPR:
13701 case TRY_CATCH_EXPR:
13703 gimple_seq eval, cleanup;
13704 gtry *try_;
13706 /* Calls to destructors are generated automatically in FINALLY/CATCH
13707 block. They should have location as UNKNOWN_LOCATION. However,
13708 gimplify_call_expr will reset these call stmts to input_location
13709 if it finds stmt's location is unknown. To prevent resetting for
13710 destructors, we set the input_location to unknown.
13711 Note that this only affects the destructor calls in FINALLY/CATCH
13712 block, and will automatically reset to its original value by the
13713 end of gimplify_expr. */
13714 input_location = UNKNOWN_LOCATION;
13715 eval = cleanup = NULL;
13716 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
13717 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
13718 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
13720 gimple_seq n = NULL, e = NULL;
13721 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
13722 0), &n);
13723 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
13724 1), &e);
13725 if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
13727 geh_else *stmt = gimple_build_eh_else (n, e);
13728 gimple_seq_add_stmt (&cleanup, stmt);
13731 else
13732 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
13733 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
13734 if (gimple_seq_empty_p (cleanup))
13736 gimple_seq_add_seq (pre_p, eval);
13737 ret = GS_ALL_DONE;
13738 break;
13740 try_ = gimple_build_try (eval, cleanup,
13741 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
13742 ? GIMPLE_TRY_FINALLY
13743 : GIMPLE_TRY_CATCH);
13744 if (EXPR_HAS_LOCATION (save_expr))
13745 gimple_set_location (try_, EXPR_LOCATION (save_expr));
13746 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
13747 gimple_set_location (try_, saved_location);
13748 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
13749 gimple_try_set_catch_is_cleanup (try_,
13750 TRY_CATCH_IS_CLEANUP (*expr_p));
13751 gimplify_seq_add_stmt (pre_p, try_);
13752 ret = GS_ALL_DONE;
13753 break;
13756 case CLEANUP_POINT_EXPR:
13757 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
13758 break;
13760 case TARGET_EXPR:
13761 ret = gimplify_target_expr (expr_p, pre_p, post_p);
13762 break;
13764 case CATCH_EXPR:
13766 gimple *c;
13767 gimple_seq handler = NULL;
13768 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
13769 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
13770 gimplify_seq_add_stmt (pre_p, c);
13771 ret = GS_ALL_DONE;
13772 break;
13775 case EH_FILTER_EXPR:
13777 gimple *ehf;
13778 gimple_seq failure = NULL;
13780 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
13781 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
13782 gimple_set_no_warning (ehf, TREE_NO_WARNING (*expr_p));
13783 gimplify_seq_add_stmt (pre_p, ehf);
13784 ret = GS_ALL_DONE;
13785 break;
13788 case OBJ_TYPE_REF:
13790 enum gimplify_status r0, r1;
13791 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
13792 post_p, is_gimple_val, fb_rvalue);
13793 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
13794 post_p, is_gimple_val, fb_rvalue);
13795 TREE_SIDE_EFFECTS (*expr_p) = 0;
13796 ret = MIN (r0, r1);
13798 break;
13800 case LABEL_DECL:
13801 /* We get here when taking the address of a label. We mark
13802 the label as "forced"; meaning it can never be removed and
13803 it is a potential target for any computed goto. */
13804 FORCED_LABEL (*expr_p) = 1;
13805 ret = GS_ALL_DONE;
13806 break;
13808 case STATEMENT_LIST:
13809 ret = gimplify_statement_list (expr_p, pre_p);
13810 break;
13812 case WITH_SIZE_EXPR:
13814 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13815 post_p == &internal_post ? NULL : post_p,
13816 gimple_test_f, fallback);
13817 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
13818 is_gimple_val, fb_rvalue);
13819 ret = GS_ALL_DONE;
13821 break;
13823 case VAR_DECL:
13824 case PARM_DECL:
13825 ret = gimplify_var_or_parm_decl (expr_p);
13826 break;
13828 case RESULT_DECL:
13829 /* When within an OMP context, notice uses of variables. */
13830 if (gimplify_omp_ctxp)
13831 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
13832 ret = GS_ALL_DONE;
13833 break;
13835 case DEBUG_EXPR_DECL:
13836 gcc_unreachable ();
13838 case DEBUG_BEGIN_STMT:
13839 gimplify_seq_add_stmt (pre_p,
13840 gimple_build_debug_begin_stmt
13841 (TREE_BLOCK (*expr_p),
13842 EXPR_LOCATION (*expr_p)));
13843 ret = GS_ALL_DONE;
13844 *expr_p = NULL;
13845 break;
13847 case SSA_NAME:
13848 /* Allow callbacks into the gimplifier during optimization. */
13849 ret = GS_ALL_DONE;
13850 break;
13852 case OMP_PARALLEL:
13853 gimplify_omp_parallel (expr_p, pre_p);
13854 ret = GS_ALL_DONE;
13855 break;
13857 case OMP_TASK:
13858 gimplify_omp_task (expr_p, pre_p);
13859 ret = GS_ALL_DONE;
13860 break;
13862 case OMP_FOR:
13863 case OMP_SIMD:
13864 case OMP_DISTRIBUTE:
13865 case OMP_TASKLOOP:
13866 case OACC_LOOP:
13867 ret = gimplify_omp_for (expr_p, pre_p);
13868 break;
13870 case OMP_LOOP:
13871 ret = gimplify_omp_loop (expr_p, pre_p);
13872 break;
13874 case OACC_CACHE:
13875 gimplify_oacc_cache (expr_p, pre_p);
13876 ret = GS_ALL_DONE;
13877 break;
13879 case OACC_DECLARE:
13880 gimplify_oacc_declare (expr_p, pre_p);
13881 ret = GS_ALL_DONE;
13882 break;
13884 case OACC_HOST_DATA:
13885 case OACC_DATA:
13886 case OACC_KERNELS:
13887 case OACC_PARALLEL:
13888 case OACC_SERIAL:
13889 case OMP_SECTIONS:
13890 case OMP_SINGLE:
13891 case OMP_TARGET:
13892 case OMP_TARGET_DATA:
13893 case OMP_TEAMS:
13894 gimplify_omp_workshare (expr_p, pre_p);
13895 ret = GS_ALL_DONE;
13896 break;
13898 case OACC_ENTER_DATA:
13899 case OACC_EXIT_DATA:
13900 case OACC_UPDATE:
13901 case OMP_TARGET_UPDATE:
13902 case OMP_TARGET_ENTER_DATA:
13903 case OMP_TARGET_EXIT_DATA:
13904 gimplify_omp_target_update (expr_p, pre_p);
13905 ret = GS_ALL_DONE;
13906 break;
13908 case OMP_SECTION:
13909 case OMP_MASTER:
13910 case OMP_ORDERED:
13911 case OMP_CRITICAL:
13912 case OMP_SCAN:
13914 gimple_seq body = NULL;
13915 gimple *g;
13916 bool saved_in_omp_construct = in_omp_construct;
13918 in_omp_construct = true;
13919 gimplify_and_add (OMP_BODY (*expr_p), &body);
13920 in_omp_construct = saved_in_omp_construct;
13921 switch (TREE_CODE (*expr_p))
13923 case OMP_SECTION:
13924 g = gimple_build_omp_section (body);
13925 break;
13926 case OMP_MASTER:
13927 g = gimple_build_omp_master (body);
13928 break;
13929 case OMP_ORDERED:
13930 g = gimplify_omp_ordered (*expr_p, body);
13931 break;
13932 case OMP_CRITICAL:
13933 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
13934 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
13935 gimplify_adjust_omp_clauses (pre_p, body,
13936 &OMP_CRITICAL_CLAUSES (*expr_p),
13937 OMP_CRITICAL);
13938 g = gimple_build_omp_critical (body,
13939 OMP_CRITICAL_NAME (*expr_p),
13940 OMP_CRITICAL_CLAUSES (*expr_p));
13941 break;
13942 case OMP_SCAN:
13943 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
13944 pre_p, ORT_WORKSHARE, OMP_SCAN);
13945 gimplify_adjust_omp_clauses (pre_p, body,
13946 &OMP_SCAN_CLAUSES (*expr_p),
13947 OMP_SCAN);
13948 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
13949 break;
13950 default:
13951 gcc_unreachable ();
13953 gimplify_seq_add_stmt (pre_p, g);
13954 ret = GS_ALL_DONE;
13955 break;
13958 case OMP_TASKGROUP:
13960 gimple_seq body = NULL;
13962 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
13963 bool saved_in_omp_construct = in_omp_construct;
13964 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
13965 OMP_TASKGROUP);
13966 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
13968 in_omp_construct = true;
13969 gimplify_and_add (OMP_BODY (*expr_p), &body);
13970 in_omp_construct = saved_in_omp_construct;
13971 gimple_seq cleanup = NULL;
13972 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
13973 gimple *g = gimple_build_call (fn, 0);
13974 gimple_seq_add_stmt (&cleanup, g);
13975 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
13976 body = NULL;
13977 gimple_seq_add_stmt (&body, g);
13978 g = gimple_build_omp_taskgroup (body, *pclauses);
13979 gimplify_seq_add_stmt (pre_p, g);
13980 ret = GS_ALL_DONE;
13981 break;
13984 case OMP_ATOMIC:
13985 case OMP_ATOMIC_READ:
13986 case OMP_ATOMIC_CAPTURE_OLD:
13987 case OMP_ATOMIC_CAPTURE_NEW:
13988 ret = gimplify_omp_atomic (expr_p, pre_p);
13989 break;
13991 case TRANSACTION_EXPR:
13992 ret = gimplify_transaction (expr_p, pre_p);
13993 break;
13995 case TRUTH_AND_EXPR:
13996 case TRUTH_OR_EXPR:
13997 case TRUTH_XOR_EXPR:
13999 tree orig_type = TREE_TYPE (*expr_p);
14000 tree new_type, xop0, xop1;
14001 *expr_p = gimple_boolify (*expr_p);
14002 new_type = TREE_TYPE (*expr_p);
14003 if (!useless_type_conversion_p (orig_type, new_type))
14005 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
14006 ret = GS_OK;
14007 break;
14010 /* Boolified binary truth expressions are semantically equivalent
14011 to bitwise binary expressions. Canonicalize them to the
14012 bitwise variant. */
14013 switch (TREE_CODE (*expr_p))
14015 case TRUTH_AND_EXPR:
14016 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
14017 break;
14018 case TRUTH_OR_EXPR:
14019 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
14020 break;
14021 case TRUTH_XOR_EXPR:
14022 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
14023 break;
14024 default:
14025 break;
14027 /* Now make sure that operands have compatible type to
14028 expression's new_type. */
14029 xop0 = TREE_OPERAND (*expr_p, 0);
14030 xop1 = TREE_OPERAND (*expr_p, 1);
14031 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
14032 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
14033 new_type,
14034 xop0);
14035 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
14036 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
14037 new_type,
14038 xop1);
14039 /* Continue classified as tcc_binary. */
14040 goto expr_2;
14043 case VEC_COND_EXPR:
14045 enum gimplify_status r0, r1, r2;
14047 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14048 post_p, is_gimple_condexpr, fb_rvalue);
14049 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
14050 post_p, is_gimple_val, fb_rvalue);
14051 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
14052 post_p, is_gimple_val, fb_rvalue);
14054 ret = MIN (MIN (r0, r1), r2);
14055 recalculate_side_effects (*expr_p);
14057 break;
14059 case VEC_PERM_EXPR:
14060 /* Classified as tcc_expression. */
14061 goto expr_3;
14063 case BIT_INSERT_EXPR:
14064 /* Argument 3 is a constant. */
14065 goto expr_2;
14067 case POINTER_PLUS_EXPR:
14069 enum gimplify_status r0, r1;
14070 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14071 post_p, is_gimple_val, fb_rvalue);
14072 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
14073 post_p, is_gimple_val, fb_rvalue);
14074 recalculate_side_effects (*expr_p);
14075 ret = MIN (r0, r1);
14076 break;
14079 default:
14080 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
14082 case tcc_comparison:
14083 /* Handle comparison of objects of non scalar mode aggregates
14084 with a call to memcmp. It would be nice to only have to do
14085 this for variable-sized objects, but then we'd have to allow
14086 the same nest of reference nodes we allow for MODIFY_EXPR and
14087 that's too complex.
14089 Compare scalar mode aggregates as scalar mode values. Using
14090 memcmp for them would be very inefficient at best, and is
14091 plain wrong if bitfields are involved. */
14093 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
14095 /* Vector comparisons need no boolification. */
14096 if (TREE_CODE (type) == VECTOR_TYPE)
14097 goto expr_2;
14098 else if (!AGGREGATE_TYPE_P (type))
14100 tree org_type = TREE_TYPE (*expr_p);
14101 *expr_p = gimple_boolify (*expr_p);
14102 if (!useless_type_conversion_p (org_type,
14103 TREE_TYPE (*expr_p)))
14105 *expr_p = fold_convert_loc (input_location,
14106 org_type, *expr_p);
14107 ret = GS_OK;
14109 else
14110 goto expr_2;
14112 else if (TYPE_MODE (type) != BLKmode)
14113 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
14114 else
14115 ret = gimplify_variable_sized_compare (expr_p);
14117 break;
14120 /* If *EXPR_P does not need to be special-cased, handle it
14121 according to its class. */
14122 case tcc_unary:
14123 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14124 post_p, is_gimple_val, fb_rvalue);
14125 break;
14127 case tcc_binary:
14128 expr_2:
14130 enum gimplify_status r0, r1;
14132 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14133 post_p, is_gimple_val, fb_rvalue);
14134 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
14135 post_p, is_gimple_val, fb_rvalue);
14137 ret = MIN (r0, r1);
14138 break;
14141 expr_3:
14143 enum gimplify_status r0, r1, r2;
14145 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14146 post_p, is_gimple_val, fb_rvalue);
14147 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
14148 post_p, is_gimple_val, fb_rvalue);
14149 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
14150 post_p, is_gimple_val, fb_rvalue);
14152 ret = MIN (MIN (r0, r1), r2);
14153 break;
14156 case tcc_declaration:
14157 case tcc_constant:
14158 ret = GS_ALL_DONE;
14159 goto dont_recalculate;
14161 default:
14162 gcc_unreachable ();
14165 recalculate_side_effects (*expr_p);
14167 dont_recalculate:
14168 break;
14171 gcc_assert (*expr_p || ret != GS_OK);
14173 while (ret == GS_OK);
14175 /* If we encountered an error_mark somewhere nested inside, either
14176 stub out the statement or propagate the error back out. */
14177 if (ret == GS_ERROR)
14179 if (is_statement)
14180 *expr_p = NULL;
14181 goto out;
14184 /* This was only valid as a return value from the langhook, which
14185 we handled. Make sure it doesn't escape from any other context. */
14186 gcc_assert (ret != GS_UNHANDLED);
14188 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
14190 /* We aren't looking for a value, and we don't have a valid
14191 statement. If it doesn't have side-effects, throw it away.
14192 We can also get here with code such as "*&&L;", where L is
14193 a LABEL_DECL that is marked as FORCED_LABEL. */
14194 if (TREE_CODE (*expr_p) == LABEL_DECL
14195 || !TREE_SIDE_EFFECTS (*expr_p))
14196 *expr_p = NULL;
14197 else if (!TREE_THIS_VOLATILE (*expr_p))
14199 /* This is probably a _REF that contains something nested that
14200 has side effects. Recurse through the operands to find it. */
14201 enum tree_code code = TREE_CODE (*expr_p);
14203 switch (code)
14205 case COMPONENT_REF:
14206 case REALPART_EXPR:
14207 case IMAGPART_EXPR:
14208 case VIEW_CONVERT_EXPR:
14209 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14210 gimple_test_f, fallback);
14211 break;
14213 case ARRAY_REF:
14214 case ARRAY_RANGE_REF:
14215 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14216 gimple_test_f, fallback);
14217 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
14218 gimple_test_f, fallback);
14219 break;
14221 default:
14222 /* Anything else with side-effects must be converted to
14223 a valid statement before we get here. */
14224 gcc_unreachable ();
14227 *expr_p = NULL;
14229 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
14230 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode)
14232 /* Historically, the compiler has treated a bare reference
14233 to a non-BLKmode volatile lvalue as forcing a load. */
14234 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
14236 /* Normally, we do not want to create a temporary for a
14237 TREE_ADDRESSABLE type because such a type should not be
14238 copied by bitwise-assignment. However, we make an
14239 exception here, as all we are doing here is ensuring that
14240 we read the bytes that make up the type. We use
14241 create_tmp_var_raw because create_tmp_var will abort when
14242 given a TREE_ADDRESSABLE type. */
14243 tree tmp = create_tmp_var_raw (type, "vol");
14244 gimple_add_tmp_var (tmp);
14245 gimplify_assign (tmp, *expr_p, pre_p);
14246 *expr_p = NULL;
14248 else
14249 /* We can't do anything useful with a volatile reference to
14250 an incomplete type, so just throw it away. Likewise for
14251 a BLKmode type, since any implicit inner load should
14252 already have been turned into an explicit one by the
14253 gimplification process. */
14254 *expr_p = NULL;
14257 /* If we are gimplifying at the statement level, we're done. Tack
14258 everything together and return. */
14259 if (fallback == fb_none || is_statement)
14261 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
14262 it out for GC to reclaim it. */
14263 *expr_p = NULL_TREE;
14265 if (!gimple_seq_empty_p (internal_pre)
14266 || !gimple_seq_empty_p (internal_post))
14268 gimplify_seq_add_seq (&internal_pre, internal_post);
14269 gimplify_seq_add_seq (pre_p, internal_pre);
14272 /* The result of gimplifying *EXPR_P is going to be the last few
14273 statements in *PRE_P and *POST_P. Add location information
14274 to all the statements that were added by the gimplification
14275 helpers. */
14276 if (!gimple_seq_empty_p (*pre_p))
14277 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
14279 if (!gimple_seq_empty_p (*post_p))
14280 annotate_all_with_location_after (*post_p, post_last_gsi,
14281 input_location);
14283 goto out;
14286 #ifdef ENABLE_GIMPLE_CHECKING
14287 if (*expr_p)
14289 enum tree_code code = TREE_CODE (*expr_p);
14290 /* These expressions should already be in gimple IR form. */
14291 gcc_assert (code != MODIFY_EXPR
14292 && code != ASM_EXPR
14293 && code != BIND_EXPR
14294 && code != CATCH_EXPR
14295 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
14296 && code != EH_FILTER_EXPR
14297 && code != GOTO_EXPR
14298 && code != LABEL_EXPR
14299 && code != LOOP_EXPR
14300 && code != SWITCH_EXPR
14301 && code != TRY_FINALLY_EXPR
14302 && code != EH_ELSE_EXPR
14303 && code != OACC_PARALLEL
14304 && code != OACC_KERNELS
14305 && code != OACC_SERIAL
14306 && code != OACC_DATA
14307 && code != OACC_HOST_DATA
14308 && code != OACC_DECLARE
14309 && code != OACC_UPDATE
14310 && code != OACC_ENTER_DATA
14311 && code != OACC_EXIT_DATA
14312 && code != OACC_CACHE
14313 && code != OMP_CRITICAL
14314 && code != OMP_FOR
14315 && code != OACC_LOOP
14316 && code != OMP_MASTER
14317 && code != OMP_TASKGROUP
14318 && code != OMP_ORDERED
14319 && code != OMP_PARALLEL
14320 && code != OMP_SCAN
14321 && code != OMP_SECTIONS
14322 && code != OMP_SECTION
14323 && code != OMP_SINGLE);
14325 #endif
14327 /* Otherwise we're gimplifying a subexpression, so the resulting
14328 value is interesting. If it's a valid operand that matches
14329 GIMPLE_TEST_F, we're done. Unless we are handling some
14330 post-effects internally; if that's the case, we need to copy into
14331 a temporary before adding the post-effects to POST_P. */
14332 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
14333 goto out;
14335 /* Otherwise, we need to create a new temporary for the gimplified
14336 expression. */
14338 /* We can't return an lvalue if we have an internal postqueue. The
14339 object the lvalue refers to would (probably) be modified by the
14340 postqueue; we need to copy the value out first, which means an
14341 rvalue. */
14342 if ((fallback & fb_lvalue)
14343 && gimple_seq_empty_p (internal_post)
14344 && is_gimple_addressable (*expr_p))
14346 /* An lvalue will do. Take the address of the expression, store it
14347 in a temporary, and replace the expression with an INDIRECT_REF of
14348 that temporary. */
14349 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
14350 unsigned int ref_align = get_object_alignment (*expr_p);
14351 tree ref_type = TREE_TYPE (*expr_p);
14352 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
14353 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
14354 if (TYPE_ALIGN (ref_type) != ref_align)
14355 ref_type = build_aligned_type (ref_type, ref_align);
14356 *expr_p = build2 (MEM_REF, ref_type,
14357 tmp, build_zero_cst (ref_alias_type));
14359 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
14361 /* An rvalue will do. Assign the gimplified expression into a
14362 new temporary TMP and replace the original expression with
14363 TMP. First, make sure that the expression has a type so that
14364 it can be assigned into a temporary. */
14365 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
14366 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
14368 else
14370 #ifdef ENABLE_GIMPLE_CHECKING
14371 if (!(fallback & fb_mayfail))
14373 fprintf (stderr, "gimplification failed:\n");
14374 print_generic_expr (stderr, *expr_p);
14375 debug_tree (*expr_p);
14376 internal_error ("gimplification failed");
14378 #endif
14379 gcc_assert (fallback & fb_mayfail);
14381 /* If this is an asm statement, and the user asked for the
14382 impossible, don't die. Fail and let gimplify_asm_expr
14383 issue an error. */
14384 ret = GS_ERROR;
14385 goto out;
14388 /* Make sure the temporary matches our predicate. */
14389 gcc_assert ((*gimple_test_f) (*expr_p));
14391 if (!gimple_seq_empty_p (internal_post))
14393 annotate_all_with_location (internal_post, input_location);
14394 gimplify_seq_add_seq (pre_p, internal_post);
14397 out:
14398 input_location = saved_location;
14399 return ret;
14402 /* Like gimplify_expr but make sure the gimplified result is not itself
14403 a SSA name (but a decl if it were). Temporaries required by
14404 evaluating *EXPR_P may be still SSA names. */
14406 static enum gimplify_status
14407 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
14408 bool (*gimple_test_f) (tree), fallback_t fallback,
14409 bool allow_ssa)
14411 bool was_ssa_name_p = TREE_CODE (*expr_p) == SSA_NAME;
14412 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
14413 gimple_test_f, fallback);
14414 if (! allow_ssa
14415 && TREE_CODE (*expr_p) == SSA_NAME)
14417 tree name = *expr_p;
14418 if (was_ssa_name_p)
14419 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
14420 else
14422 /* Avoid the extra copy if possible. */
14423 *expr_p = create_tmp_reg (TREE_TYPE (name));
14424 gimple_set_lhs (SSA_NAME_DEF_STMT (name), *expr_p);
14425 release_ssa_name (name);
14428 return ret;
14431 /* Look through TYPE for variable-sized objects and gimplify each such
14432 size that we find. Add to LIST_P any statements generated. */
14434 void
14435 gimplify_type_sizes (tree type, gimple_seq *list_p)
14437 tree field, t;
14439 if (type == NULL || type == error_mark_node)
14440 return;
14442 /* We first do the main variant, then copy into any other variants. */
14443 type = TYPE_MAIN_VARIANT (type);
14445 /* Avoid infinite recursion. */
14446 if (TYPE_SIZES_GIMPLIFIED (type))
14447 return;
14449 TYPE_SIZES_GIMPLIFIED (type) = 1;
14451 switch (TREE_CODE (type))
14453 case INTEGER_TYPE:
14454 case ENUMERAL_TYPE:
14455 case BOOLEAN_TYPE:
14456 case REAL_TYPE:
14457 case FIXED_POINT_TYPE:
14458 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
14459 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
14461 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
14463 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
14464 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
14466 break;
14468 case ARRAY_TYPE:
14469 /* These types may not have declarations, so handle them here. */
14470 gimplify_type_sizes (TREE_TYPE (type), list_p);
14471 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
14472 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
14473 with assigned stack slots, for -O1+ -g they should be tracked
14474 by VTA. */
14475 if (!(TYPE_NAME (type)
14476 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
14477 && DECL_IGNORED_P (TYPE_NAME (type)))
14478 && TYPE_DOMAIN (type)
14479 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
14481 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
14482 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
14483 DECL_IGNORED_P (t) = 0;
14484 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
14485 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
14486 DECL_IGNORED_P (t) = 0;
14488 break;
14490 case RECORD_TYPE:
14491 case UNION_TYPE:
14492 case QUAL_UNION_TYPE:
14493 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
14494 if (TREE_CODE (field) == FIELD_DECL)
14496 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
14497 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
14498 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
14499 gimplify_type_sizes (TREE_TYPE (field), list_p);
14501 break;
14503 case POINTER_TYPE:
14504 case REFERENCE_TYPE:
14505 /* We used to recurse on the pointed-to type here, which turned out to
14506 be incorrect because its definition might refer to variables not
14507 yet initialized at this point if a forward declaration is involved.
14509 It was actually useful for anonymous pointed-to types to ensure
14510 that the sizes evaluation dominates every possible later use of the
14511 values. Restricting to such types here would be safe since there
14512 is no possible forward declaration around, but would introduce an
14513 undesirable middle-end semantic to anonymity. We then defer to
14514 front-ends the responsibility of ensuring that the sizes are
14515 evaluated both early and late enough, e.g. by attaching artificial
14516 type declarations to the tree. */
14517 break;
14519 default:
14520 break;
14523 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
14524 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
14526 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
14528 TYPE_SIZE (t) = TYPE_SIZE (type);
14529 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
14530 TYPE_SIZES_GIMPLIFIED (t) = 1;
14534 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
14535 a size or position, has had all of its SAVE_EXPRs evaluated.
14536 We add any required statements to *STMT_P. */
14538 void
14539 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
14541 tree expr = *expr_p;
14543 /* We don't do anything if the value isn't there, is constant, or contains
14544 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
14545 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
14546 will want to replace it with a new variable, but that will cause problems
14547 if this type is from outside the function. It's OK to have that here. */
14548 if (expr == NULL_TREE
14549 || is_gimple_constant (expr)
14550 || TREE_CODE (expr) == VAR_DECL
14551 || CONTAINS_PLACEHOLDER_P (expr))
14552 return;
14554 *expr_p = unshare_expr (expr);
14556 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
14557 if the def vanishes. */
14558 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
14560 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
14561 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
14562 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
14563 if (is_gimple_constant (*expr_p))
14564 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
14567 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
14568 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
14569 is true, also gimplify the parameters. */
14571 gbind *
14572 gimplify_body (tree fndecl, bool do_parms)
14574 location_t saved_location = input_location;
14575 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
14576 gimple *outer_stmt;
14577 gbind *outer_bind;
14579 timevar_push (TV_TREE_GIMPLIFY);
14581 init_tree_ssa (cfun);
14583 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
14584 gimplification. */
14585 default_rtl_profile ();
14587 gcc_assert (gimplify_ctxp == NULL);
14588 push_gimplify_context (true);
14590 if (flag_openacc || flag_openmp)
14592 gcc_assert (gimplify_omp_ctxp == NULL);
14593 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
14594 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
14597 /* Unshare most shared trees in the body and in that of any nested functions.
14598 It would seem we don't have to do this for nested functions because
14599 they are supposed to be output and then the outer function gimplified
14600 first, but the g++ front end doesn't always do it that way. */
14601 unshare_body (fndecl);
14602 unvisit_body (fndecl);
14604 /* Make sure input_location isn't set to something weird. */
14605 input_location = DECL_SOURCE_LOCATION (fndecl);
14607 /* Resolve callee-copies. This has to be done before processing
14608 the body so that DECL_VALUE_EXPR gets processed correctly. */
14609 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
14611 /* Gimplify the function's body. */
14612 seq = NULL;
14613 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
14614 outer_stmt = gimple_seq_first_stmt (seq);
14615 if (!outer_stmt)
14617 outer_stmt = gimple_build_nop ();
14618 gimplify_seq_add_stmt (&seq, outer_stmt);
14621 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
14622 not the case, wrap everything in a GIMPLE_BIND to make it so. */
14623 if (gimple_code (outer_stmt) == GIMPLE_BIND
14624 && gimple_seq_first (seq) == gimple_seq_last (seq))
14625 outer_bind = as_a <gbind *> (outer_stmt);
14626 else
14627 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
14629 DECL_SAVED_TREE (fndecl) = NULL_TREE;
14631 /* If we had callee-copies statements, insert them at the beginning
14632 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
14633 if (!gimple_seq_empty_p (parm_stmts))
14635 tree parm;
14637 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
14638 if (parm_cleanup)
14640 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
14641 GIMPLE_TRY_FINALLY);
14642 parm_stmts = NULL;
14643 gimple_seq_add_stmt (&parm_stmts, g);
14645 gimple_bind_set_body (outer_bind, parm_stmts);
14647 for (parm = DECL_ARGUMENTS (current_function_decl);
14648 parm; parm = DECL_CHAIN (parm))
14649 if (DECL_HAS_VALUE_EXPR_P (parm))
14651 DECL_HAS_VALUE_EXPR_P (parm) = 0;
14652 DECL_IGNORED_P (parm) = 0;
14656 if ((flag_openacc || flag_openmp || flag_openmp_simd)
14657 && gimplify_omp_ctxp)
14659 delete_omp_context (gimplify_omp_ctxp);
14660 gimplify_omp_ctxp = NULL;
14663 pop_gimplify_context (outer_bind);
14664 gcc_assert (gimplify_ctxp == NULL);
14666 if (flag_checking && !seen_error ())
14667 verify_gimple_in_seq (gimple_bind_body (outer_bind));
14669 timevar_pop (TV_TREE_GIMPLIFY);
14670 input_location = saved_location;
14672 return outer_bind;
14675 typedef char *char_p; /* For DEF_VEC_P. */
14677 /* Return whether we should exclude FNDECL from instrumentation. */
14679 static bool
14680 flag_instrument_functions_exclude_p (tree fndecl)
14682 vec<char_p> *v;
14684 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
14685 if (v && v->length () > 0)
14687 const char *name;
14688 int i;
14689 char *s;
14691 name = lang_hooks.decl_printable_name (fndecl, 1);
14692 FOR_EACH_VEC_ELT (*v, i, s)
14693 if (strstr (name, s) != NULL)
14694 return true;
14697 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
14698 if (v && v->length () > 0)
14700 const char *name;
14701 int i;
14702 char *s;
14704 name = DECL_SOURCE_FILE (fndecl);
14705 FOR_EACH_VEC_ELT (*v, i, s)
14706 if (strstr (name, s) != NULL)
14707 return true;
14710 return false;
14713 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
14714 node for the function we want to gimplify.
14716 Return the sequence of GIMPLE statements corresponding to the body
14717 of FNDECL. */
14719 void
14720 gimplify_function_tree (tree fndecl)
14722 tree parm, ret;
14723 gimple_seq seq;
14724 gbind *bind;
14726 gcc_assert (!gimple_body (fndecl));
14728 if (DECL_STRUCT_FUNCTION (fndecl))
14729 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
14730 else
14731 push_struct_function (fndecl);
14733 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
14734 if necessary. */
14735 cfun->curr_properties |= PROP_gimple_lva;
14737 for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = DECL_CHAIN (parm))
14739 /* Preliminarily mark non-addressed complex variables as eligible
14740 for promotion to gimple registers. We'll transform their uses
14741 as we find them. */
14742 if ((TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
14743 || TREE_CODE (TREE_TYPE (parm)) == VECTOR_TYPE)
14744 && !TREE_THIS_VOLATILE (parm)
14745 && !needs_to_live_in_memory (parm))
14746 DECL_GIMPLE_REG_P (parm) = 1;
14749 ret = DECL_RESULT (fndecl);
14750 if ((TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE
14751 || TREE_CODE (TREE_TYPE (ret)) == VECTOR_TYPE)
14752 && !needs_to_live_in_memory (ret))
14753 DECL_GIMPLE_REG_P (ret) = 1;
14755 if (asan_sanitize_use_after_scope () && sanitize_flags_p (SANITIZE_ADDRESS))
14756 asan_poisoned_variables = new hash_set<tree> ();
14757 bind = gimplify_body (fndecl, true);
14758 if (asan_poisoned_variables)
14760 delete asan_poisoned_variables;
14761 asan_poisoned_variables = NULL;
14764 /* The tree body of the function is no longer needed, replace it
14765 with the new GIMPLE body. */
14766 seq = NULL;
14767 gimple_seq_add_stmt (&seq, bind);
14768 gimple_set_body (fndecl, seq);
14770 /* If we're instrumenting function entry/exit, then prepend the call to
14771 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
14772 catch the exit hook. */
14773 /* ??? Add some way to ignore exceptions for this TFE. */
14774 if (flag_instrument_function_entry_exit
14775 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
14776 /* Do not instrument extern inline functions. */
14777 && !(DECL_DECLARED_INLINE_P (fndecl)
14778 && DECL_EXTERNAL (fndecl)
14779 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
14780 && !flag_instrument_functions_exclude_p (fndecl))
14782 tree x;
14783 gbind *new_bind;
14784 gimple *tf;
14785 gimple_seq cleanup = NULL, body = NULL;
14786 tree tmp_var, this_fn_addr;
14787 gcall *call;
14789 /* The instrumentation hooks aren't going to call the instrumented
14790 function and the address they receive is expected to be matchable
14791 against symbol addresses. Make sure we don't create a trampoline,
14792 in case the current function is nested. */
14793 this_fn_addr = build_fold_addr_expr (current_function_decl);
14794 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
14796 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
14797 call = gimple_build_call (x, 1, integer_zero_node);
14798 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
14799 gimple_call_set_lhs (call, tmp_var);
14800 gimplify_seq_add_stmt (&cleanup, call);
14801 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
14802 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
14803 gimplify_seq_add_stmt (&cleanup, call);
14804 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
14806 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
14807 call = gimple_build_call (x, 1, integer_zero_node);
14808 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
14809 gimple_call_set_lhs (call, tmp_var);
14810 gimplify_seq_add_stmt (&body, call);
14811 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
14812 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
14813 gimplify_seq_add_stmt (&body, call);
14814 gimplify_seq_add_stmt (&body, tf);
14815 new_bind = gimple_build_bind (NULL, body, NULL);
14817 /* Replace the current function body with the body
14818 wrapped in the try/finally TF. */
14819 seq = NULL;
14820 gimple_seq_add_stmt (&seq, new_bind);
14821 gimple_set_body (fndecl, seq);
14822 bind = new_bind;
14825 if (sanitize_flags_p (SANITIZE_THREAD))
14827 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
14828 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
14829 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
14830 /* Replace the current function body with the body
14831 wrapped in the try/finally TF. */
14832 seq = NULL;
14833 gimple_seq_add_stmt (&seq, new_bind);
14834 gimple_set_body (fndecl, seq);
14837 DECL_SAVED_TREE (fndecl) = NULL_TREE;
14838 cfun->curr_properties |= PROP_gimple_any;
14840 pop_cfun ();
14842 dump_function (TDI_gimple, fndecl);
14845 /* Return a dummy expression of type TYPE in order to keep going after an
14846 error. */
14848 static tree
14849 dummy_object (tree type)
14851 tree t = build_int_cst (build_pointer_type (type), 0);
14852 return build2 (MEM_REF, type, t, t);
14855 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
14856 builtin function, but a very special sort of operator. */
14858 enum gimplify_status
14859 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
14860 gimple_seq *post_p ATTRIBUTE_UNUSED)
14862 tree promoted_type, have_va_type;
14863 tree valist = TREE_OPERAND (*expr_p, 0);
14864 tree type = TREE_TYPE (*expr_p);
14865 tree t, tag, aptag;
14866 location_t loc = EXPR_LOCATION (*expr_p);
14868 /* Verify that valist is of the proper type. */
14869 have_va_type = TREE_TYPE (valist);
14870 if (have_va_type == error_mark_node)
14871 return GS_ERROR;
14872 have_va_type = targetm.canonical_va_list_type (have_va_type);
14873 if (have_va_type == NULL_TREE
14874 && POINTER_TYPE_P (TREE_TYPE (valist)))
14875 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
14876 have_va_type
14877 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
14878 gcc_assert (have_va_type != NULL_TREE);
14880 /* Generate a diagnostic for requesting data of a type that cannot
14881 be passed through `...' due to type promotion at the call site. */
14882 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
14883 != type)
14885 static bool gave_help;
14886 bool warned;
14887 /* Use the expansion point to handle cases such as passing bool (defined
14888 in a system header) through `...'. */
14889 location_t xloc
14890 = expansion_point_location_if_in_system_header (loc);
14892 /* Unfortunately, this is merely undefined, rather than a constraint
14893 violation, so we cannot make this an error. If this call is never
14894 executed, the program is still strictly conforming. */
14895 auto_diagnostic_group d;
14896 warned = warning_at (xloc, 0,
14897 "%qT is promoted to %qT when passed through %<...%>",
14898 type, promoted_type);
14899 if (!gave_help && warned)
14901 gave_help = true;
14902 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
14903 promoted_type, type);
14906 /* We can, however, treat "undefined" any way we please.
14907 Call abort to encourage the user to fix the program. */
14908 if (warned)
14909 inform (xloc, "if this code is reached, the program will abort");
14910 /* Before the abort, allow the evaluation of the va_list
14911 expression to exit or longjmp. */
14912 gimplify_and_add (valist, pre_p);
14913 t = build_call_expr_loc (loc,
14914 builtin_decl_implicit (BUILT_IN_TRAP), 0);
14915 gimplify_and_add (t, pre_p);
14917 /* This is dead code, but go ahead and finish so that the
14918 mode of the result comes out right. */
14919 *expr_p = dummy_object (type);
14920 return GS_ALL_DONE;
14923 tag = build_int_cst (build_pointer_type (type), 0);
14924 aptag = build_int_cst (TREE_TYPE (valist), 0);
14926 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
14927 valist, tag, aptag);
14929 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
14930 needs to be expanded. */
14931 cfun->curr_properties &= ~PROP_gimple_lva;
14933 return GS_OK;
14936 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
14938 DST/SRC are the destination and source respectively. You can pass
14939 ungimplified trees in DST or SRC, in which case they will be
14940 converted to a gimple operand if necessary.
14942 This function returns the newly created GIMPLE_ASSIGN tuple. */
14944 gimple *
14945 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
14947 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
14948 gimplify_and_add (t, seq_p);
14949 ggc_free (t);
14950 return gimple_seq_last_stmt (*seq_p);
14953 inline hashval_t
14954 gimplify_hasher::hash (const elt_t *p)
14956 tree t = p->val;
14957 return iterative_hash_expr (t, 0);
14960 inline bool
14961 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
14963 tree t1 = p1->val;
14964 tree t2 = p2->val;
14965 enum tree_code code = TREE_CODE (t1);
14967 if (TREE_CODE (t2) != code
14968 || TREE_TYPE (t1) != TREE_TYPE (t2))
14969 return false;
14971 if (!operand_equal_p (t1, t2, 0))
14972 return false;
14974 /* Only allow them to compare equal if they also hash equal; otherwise
14975 results are nondeterminate, and we fail bootstrap comparison. */
14976 gcc_checking_assert (hash (p1) == hash (p2));
14978 return true;