Add GCC support to ENQCMD.
[official-gcc.git] / gcc / gimplify.c
bloba0177b25f563160aa6f993ec218dc272523a9423
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"
69 /* Hash set of poisoned variables in a bind expr. */
70 static hash_set<tree> *asan_poisoned_variables = NULL;
72 enum gimplify_omp_var_data
74 GOVD_SEEN = 0x000001,
75 GOVD_EXPLICIT = 0x000002,
76 GOVD_SHARED = 0x000004,
77 GOVD_PRIVATE = 0x000008,
78 GOVD_FIRSTPRIVATE = 0x000010,
79 GOVD_LASTPRIVATE = 0x000020,
80 GOVD_REDUCTION = 0x000040,
81 GOVD_LOCAL = 0x00080,
82 GOVD_MAP = 0x000100,
83 GOVD_DEBUG_PRIVATE = 0x000200,
84 GOVD_PRIVATE_OUTER_REF = 0x000400,
85 GOVD_LINEAR = 0x000800,
86 GOVD_ALIGNED = 0x001000,
88 /* Flag for GOVD_MAP: don't copy back. */
89 GOVD_MAP_TO_ONLY = 0x002000,
91 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
92 GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 0x004000,
94 GOVD_MAP_0LEN_ARRAY = 0x008000,
96 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
97 GOVD_MAP_ALWAYS_TO = 0x010000,
99 /* Flag for shared vars that are or might be stored to in the region. */
100 GOVD_WRITTEN = 0x020000,
102 /* Flag for GOVD_MAP, if it is a forced mapping. */
103 GOVD_MAP_FORCE = 0x040000,
105 /* Flag for GOVD_MAP: must be present already. */
106 GOVD_MAP_FORCE_PRESENT = 0x080000,
108 /* Flag for GOVD_MAP: only allocate. */
109 GOVD_MAP_ALLOC_ONLY = 0x100000,
111 /* Flag for GOVD_MAP: only copy back. */
112 GOVD_MAP_FROM_ONLY = 0x200000,
114 GOVD_NONTEMPORAL = 0x400000,
116 /* Flag for GOVD_LASTPRIVATE: conditional modifier. */
117 GOVD_LASTPRIVATE_CONDITIONAL = 0x800000,
119 GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
120 | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
121 | GOVD_LOCAL)
125 enum omp_region_type
127 ORT_WORKSHARE = 0x00,
128 ORT_TASKGROUP = 0x01,
129 ORT_SIMD = 0x04,
131 ORT_PARALLEL = 0x08,
132 ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1,
134 ORT_TASK = 0x10,
135 ORT_UNTIED_TASK = ORT_TASK | 1,
136 ORT_TASKLOOP = ORT_TASK | 2,
137 ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2,
139 ORT_TEAMS = 0x20,
140 ORT_COMBINED_TEAMS = ORT_TEAMS | 1,
141 ORT_HOST_TEAMS = ORT_TEAMS | 2,
142 ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2,
144 /* Data region. */
145 ORT_TARGET_DATA = 0x40,
147 /* Data region with offloading. */
148 ORT_TARGET = 0x80,
149 ORT_COMBINED_TARGET = ORT_TARGET | 1,
151 /* OpenACC variants. */
152 ORT_ACC = 0x100, /* A generic OpenACC region. */
153 ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */
154 ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */
155 ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 2, /* Kernels construct. */
156 ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2, /* Host data. */
158 /* Dummy OpenMP region, used to disable expansion of
159 DECL_VALUE_EXPRs in taskloop pre body. */
160 ORT_NONE = 0x200
163 /* Gimplify hashtable helper. */
165 struct gimplify_hasher : free_ptr_hash <elt_t>
167 static inline hashval_t hash (const elt_t *);
168 static inline bool equal (const elt_t *, const elt_t *);
171 struct gimplify_ctx
173 struct gimplify_ctx *prev_context;
175 vec<gbind *> bind_expr_stack;
176 tree temps;
177 gimple_seq conditional_cleanups;
178 tree exit_label;
179 tree return_temp;
181 vec<tree> case_labels;
182 hash_set<tree> *live_switch_vars;
183 /* The formal temporary table. Should this be persistent? */
184 hash_table<gimplify_hasher> *temp_htab;
186 int conditions;
187 unsigned into_ssa : 1;
188 unsigned allow_rhs_cond_expr : 1;
189 unsigned in_cleanup_point_expr : 1;
190 unsigned keep_stack : 1;
191 unsigned save_stack : 1;
192 unsigned in_switch_expr : 1;
195 enum gimplify_defaultmap_kind
197 GDMK_SCALAR,
198 GDMK_AGGREGATE,
199 GDMK_ALLOCATABLE,
200 GDMK_POINTER
203 struct gimplify_omp_ctx
205 struct gimplify_omp_ctx *outer_context;
206 splay_tree variables;
207 hash_set<tree> *privatized_types;
208 /* Iteration variables in an OMP_FOR. */
209 vec<tree> loop_iter_var;
210 location_t location;
211 enum omp_clause_default_kind default_kind;
212 enum omp_region_type region_type;
213 bool combined_loop;
214 bool distribute;
215 bool target_firstprivatize_array_bases;
216 int defaultmap[4];
219 static struct gimplify_ctx *gimplify_ctxp;
220 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
222 /* Forward declaration. */
223 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
224 static hash_map<tree, tree> *oacc_declare_returns;
225 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
226 bool (*) (tree), fallback_t, bool);
228 /* Shorter alias name for the above function for use in gimplify.c
229 only. */
231 static inline void
232 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
234 gimple_seq_add_stmt_without_update (seq_p, gs);
237 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
238 NULL, a new sequence is allocated. This function is
239 similar to gimple_seq_add_seq, but does not scan the operands.
240 During gimplification, we need to manipulate statement sequences
241 before the def/use vectors have been constructed. */
243 static void
244 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
246 gimple_stmt_iterator si;
248 if (src == NULL)
249 return;
251 si = gsi_last (*dst_p);
252 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
256 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
257 and popping gimplify contexts. */
259 static struct gimplify_ctx *ctx_pool = NULL;
261 /* Return a gimplify context struct from the pool. */
263 static inline struct gimplify_ctx *
264 ctx_alloc (void)
266 struct gimplify_ctx * c = ctx_pool;
268 if (c)
269 ctx_pool = c->prev_context;
270 else
271 c = XNEW (struct gimplify_ctx);
273 memset (c, '\0', sizeof (*c));
274 return c;
277 /* Put gimplify context C back into the pool. */
279 static inline void
280 ctx_free (struct gimplify_ctx *c)
282 c->prev_context = ctx_pool;
283 ctx_pool = c;
286 /* Free allocated ctx stack memory. */
288 void
289 free_gimplify_stack (void)
291 struct gimplify_ctx *c;
293 while ((c = ctx_pool))
295 ctx_pool = c->prev_context;
296 free (c);
301 /* Set up a context for the gimplifier. */
303 void
304 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
306 struct gimplify_ctx *c = ctx_alloc ();
308 c->prev_context = gimplify_ctxp;
309 gimplify_ctxp = c;
310 gimplify_ctxp->into_ssa = in_ssa;
311 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
314 /* Tear down a context for the gimplifier. If BODY is non-null, then
315 put the temporaries into the outer BIND_EXPR. Otherwise, put them
316 in the local_decls.
318 BODY is not a sequence, but the first tuple in a sequence. */
320 void
321 pop_gimplify_context (gimple *body)
323 struct gimplify_ctx *c = gimplify_ctxp;
325 gcc_assert (c
326 && (!c->bind_expr_stack.exists ()
327 || c->bind_expr_stack.is_empty ()));
328 c->bind_expr_stack.release ();
329 gimplify_ctxp = c->prev_context;
331 if (body)
332 declare_vars (c->temps, body, false);
333 else
334 record_vars (c->temps);
336 delete c->temp_htab;
337 c->temp_htab = NULL;
338 ctx_free (c);
341 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
343 static void
344 gimple_push_bind_expr (gbind *bind_stmt)
346 gimplify_ctxp->bind_expr_stack.reserve (8);
347 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
350 /* Pop the first element off the stack of bindings. */
352 static void
353 gimple_pop_bind_expr (void)
355 gimplify_ctxp->bind_expr_stack.pop ();
358 /* Return the first element of the stack of bindings. */
360 gbind *
361 gimple_current_bind_expr (void)
363 return gimplify_ctxp->bind_expr_stack.last ();
366 /* Return the stack of bindings created during gimplification. */
368 vec<gbind *>
369 gimple_bind_expr_stack (void)
371 return gimplify_ctxp->bind_expr_stack;
374 /* Return true iff there is a COND_EXPR between us and the innermost
375 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
377 static bool
378 gimple_conditional_context (void)
380 return gimplify_ctxp->conditions > 0;
383 /* Note that we've entered a COND_EXPR. */
385 static void
386 gimple_push_condition (void)
388 #ifdef ENABLE_GIMPLE_CHECKING
389 if (gimplify_ctxp->conditions == 0)
390 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
391 #endif
392 ++(gimplify_ctxp->conditions);
395 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
396 now, add any conditional cleanups we've seen to the prequeue. */
398 static void
399 gimple_pop_condition (gimple_seq *pre_p)
401 int conds = --(gimplify_ctxp->conditions);
403 gcc_assert (conds >= 0);
404 if (conds == 0)
406 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
407 gimplify_ctxp->conditional_cleanups = NULL;
411 /* A stable comparison routine for use with splay trees and DECLs. */
413 static int
414 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
416 tree a = (tree) xa;
417 tree b = (tree) xb;
419 return DECL_UID (a) - DECL_UID (b);
422 /* Create a new omp construct that deals with variable remapping. */
424 static struct gimplify_omp_ctx *
425 new_omp_context (enum omp_region_type region_type)
427 struct gimplify_omp_ctx *c;
429 c = XCNEW (struct gimplify_omp_ctx);
430 c->outer_context = gimplify_omp_ctxp;
431 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
432 c->privatized_types = new hash_set<tree>;
433 c->location = input_location;
434 c->region_type = region_type;
435 if ((region_type & ORT_TASK) == 0)
436 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
437 else
438 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
439 c->defaultmap[GDMK_SCALAR] = GOVD_MAP;
440 c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
441 c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
442 c->defaultmap[GDMK_POINTER] = GOVD_MAP;
444 return c;
447 /* Destroy an omp construct that deals with variable remapping. */
449 static void
450 delete_omp_context (struct gimplify_omp_ctx *c)
452 splay_tree_delete (c->variables);
453 delete c->privatized_types;
454 c->loop_iter_var.release ();
455 XDELETE (c);
458 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
459 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
461 /* Both gimplify the statement T and append it to *SEQ_P. This function
462 behaves exactly as gimplify_stmt, but you don't have to pass T as a
463 reference. */
465 void
466 gimplify_and_add (tree t, gimple_seq *seq_p)
468 gimplify_stmt (&t, seq_p);
471 /* Gimplify statement T into sequence *SEQ_P, and return the first
472 tuple in the sequence of generated tuples for this statement.
473 Return NULL if gimplifying T produced no tuples. */
475 static gimple *
476 gimplify_and_return_first (tree t, gimple_seq *seq_p)
478 gimple_stmt_iterator last = gsi_last (*seq_p);
480 gimplify_and_add (t, seq_p);
482 if (!gsi_end_p (last))
484 gsi_next (&last);
485 return gsi_stmt (last);
487 else
488 return gimple_seq_first_stmt (*seq_p);
491 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
492 LHS, or for a call argument. */
494 static bool
495 is_gimple_mem_rhs (tree t)
497 /* If we're dealing with a renamable type, either source or dest must be
498 a renamed variable. */
499 if (is_gimple_reg_type (TREE_TYPE (t)))
500 return is_gimple_val (t);
501 else
502 return is_gimple_val (t) || is_gimple_lvalue (t);
505 /* Return true if T is a CALL_EXPR or an expression that can be
506 assigned to a temporary. Note that this predicate should only be
507 used during gimplification. See the rationale for this in
508 gimplify_modify_expr. */
510 static bool
511 is_gimple_reg_rhs_or_call (tree t)
513 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
514 || TREE_CODE (t) == CALL_EXPR);
517 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
518 this predicate should only be used during gimplification. See the
519 rationale for this in gimplify_modify_expr. */
521 static bool
522 is_gimple_mem_rhs_or_call (tree t)
524 /* If we're dealing with a renamable type, either source or dest must be
525 a renamed variable. */
526 if (is_gimple_reg_type (TREE_TYPE (t)))
527 return is_gimple_val (t);
528 else
529 return (is_gimple_val (t)
530 || is_gimple_lvalue (t)
531 || TREE_CLOBBER_P (t)
532 || TREE_CODE (t) == CALL_EXPR);
535 /* Create a temporary with a name derived from VAL. Subroutine of
536 lookup_tmp_var; nobody else should call this function. */
538 static inline tree
539 create_tmp_from_val (tree val)
541 /* Drop all qualifiers and address-space information from the value type. */
542 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
543 tree var = create_tmp_var (type, get_name (val));
544 if (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
545 || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
546 DECL_GIMPLE_REG_P (var) = 1;
547 return var;
550 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
551 an existing expression temporary. */
553 static tree
554 lookup_tmp_var (tree val, bool is_formal)
556 tree ret;
558 /* If not optimizing, never really reuse a temporary. local-alloc
559 won't allocate any variable that is used in more than one basic
560 block, which means it will go into memory, causing much extra
561 work in reload and final and poorer code generation, outweighing
562 the extra memory allocation here. */
563 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
564 ret = create_tmp_from_val (val);
565 else
567 elt_t elt, *elt_p;
568 elt_t **slot;
570 elt.val = val;
571 if (!gimplify_ctxp->temp_htab)
572 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
573 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
574 if (*slot == NULL)
576 elt_p = XNEW (elt_t);
577 elt_p->val = val;
578 elt_p->temp = ret = create_tmp_from_val (val);
579 *slot = elt_p;
581 else
583 elt_p = *slot;
584 ret = elt_p->temp;
588 return ret;
591 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
593 static tree
594 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
595 bool is_formal, bool allow_ssa)
597 tree t, mod;
599 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
600 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
601 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
602 fb_rvalue);
604 if (allow_ssa
605 && gimplify_ctxp->into_ssa
606 && is_gimple_reg_type (TREE_TYPE (val)))
608 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
609 if (! gimple_in_ssa_p (cfun))
611 const char *name = get_name (val);
612 if (name)
613 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
616 else
617 t = lookup_tmp_var (val, is_formal);
619 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
621 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
623 /* gimplify_modify_expr might want to reduce this further. */
624 gimplify_and_add (mod, pre_p);
625 ggc_free (mod);
627 return t;
630 /* Return a formal temporary variable initialized with VAL. PRE_P is as
631 in gimplify_expr. Only use this function if:
633 1) The value of the unfactored expression represented by VAL will not
634 change between the initialization and use of the temporary, and
635 2) The temporary will not be otherwise modified.
637 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
638 and #2 means it is inappropriate for && temps.
640 For other cases, use get_initialized_tmp_var instead. */
642 tree
643 get_formal_tmp_var (tree val, gimple_seq *pre_p)
645 return internal_get_tmp_var (val, pre_p, NULL, true, true);
648 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
649 are as in gimplify_expr. */
651 tree
652 get_initialized_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
653 bool allow_ssa)
655 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
658 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
659 generate debug info for them; otherwise don't. */
661 void
662 declare_vars (tree vars, gimple *gs, bool debug_info)
664 tree last = vars;
665 if (last)
667 tree temps, block;
669 gbind *scope = as_a <gbind *> (gs);
671 temps = nreverse (last);
673 block = gimple_bind_block (scope);
674 gcc_assert (!block || TREE_CODE (block) == BLOCK);
675 if (!block || !debug_info)
677 DECL_CHAIN (last) = gimple_bind_vars (scope);
678 gimple_bind_set_vars (scope, temps);
680 else
682 /* We need to attach the nodes both to the BIND_EXPR and to its
683 associated BLOCK for debugging purposes. The key point here
684 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
685 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
686 if (BLOCK_VARS (block))
687 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
688 else
690 gimple_bind_set_vars (scope,
691 chainon (gimple_bind_vars (scope), temps));
692 BLOCK_VARS (block) = temps;
698 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
699 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
700 no such upper bound can be obtained. */
702 static void
703 force_constant_size (tree var)
705 /* The only attempt we make is by querying the maximum size of objects
706 of the variable's type. */
708 HOST_WIDE_INT max_size;
710 gcc_assert (VAR_P (var));
712 max_size = max_int_size_in_bytes (TREE_TYPE (var));
714 gcc_assert (max_size >= 0);
716 DECL_SIZE_UNIT (var)
717 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
718 DECL_SIZE (var)
719 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
722 /* Push the temporary variable TMP into the current binding. */
724 void
725 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
727 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
729 /* Later processing assumes that the object size is constant, which might
730 not be true at this point. Force the use of a constant upper bound in
731 this case. */
732 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
733 force_constant_size (tmp);
735 DECL_CONTEXT (tmp) = fn->decl;
736 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
738 record_vars_into (tmp, fn->decl);
741 /* Push the temporary variable TMP into the current binding. */
743 void
744 gimple_add_tmp_var (tree tmp)
746 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
748 /* Later processing assumes that the object size is constant, which might
749 not be true at this point. Force the use of a constant upper bound in
750 this case. */
751 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
752 force_constant_size (tmp);
754 DECL_CONTEXT (tmp) = current_function_decl;
755 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
757 if (gimplify_ctxp)
759 DECL_CHAIN (tmp) = gimplify_ctxp->temps;
760 gimplify_ctxp->temps = tmp;
762 /* Mark temporaries local within the nearest enclosing parallel. */
763 if (gimplify_omp_ctxp)
765 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
766 while (ctx
767 && (ctx->region_type == ORT_WORKSHARE
768 || ctx->region_type == ORT_TASKGROUP
769 || ctx->region_type == ORT_SIMD
770 || ctx->region_type == ORT_ACC))
771 ctx = ctx->outer_context;
772 if (ctx)
773 omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN);
776 else if (cfun)
777 record_vars (tmp);
778 else
780 gimple_seq body_seq;
782 /* This case is for nested functions. We need to expose the locals
783 they create. */
784 body_seq = gimple_body (current_function_decl);
785 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
791 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
792 nodes that are referenced more than once in GENERIC functions. This is
793 necessary because gimplification (translation into GIMPLE) is performed
794 by modifying tree nodes in-place, so gimplication of a shared node in a
795 first context could generate an invalid GIMPLE form in a second context.
797 This is achieved with a simple mark/copy/unmark algorithm that walks the
798 GENERIC representation top-down, marks nodes with TREE_VISITED the first
799 time it encounters them, duplicates them if they already have TREE_VISITED
800 set, and finally removes the TREE_VISITED marks it has set.
802 The algorithm works only at the function level, i.e. it generates a GENERIC
803 representation of a function with no nodes shared within the function when
804 passed a GENERIC function (except for nodes that are allowed to be shared).
806 At the global level, it is also necessary to unshare tree nodes that are
807 referenced in more than one function, for the same aforementioned reason.
808 This requires some cooperation from the front-end. There are 2 strategies:
810 1. Manual unsharing. The front-end needs to call unshare_expr on every
811 expression that might end up being shared across functions.
813 2. Deep unsharing. This is an extension of regular unsharing. Instead
814 of calling unshare_expr on expressions that might be shared across
815 functions, the front-end pre-marks them with TREE_VISITED. This will
816 ensure that they are unshared on the first reference within functions
817 when the regular unsharing algorithm runs. The counterpart is that
818 this algorithm must look deeper than for manual unsharing, which is
819 specified by LANG_HOOKS_DEEP_UNSHARING.
821 If there are only few specific cases of node sharing across functions, it is
822 probably easier for a front-end to unshare the expressions manually. On the
823 contrary, if the expressions generated at the global level are as widespread
824 as expressions generated within functions, deep unsharing is very likely the
825 way to go. */
827 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
828 These nodes model computations that must be done once. If we were to
829 unshare something like SAVE_EXPR(i++), the gimplification process would
830 create wrong code. However, if DATA is non-null, it must hold a pointer
831 set that is used to unshare the subtrees of these nodes. */
833 static tree
834 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
836 tree t = *tp;
837 enum tree_code code = TREE_CODE (t);
839 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
840 copy their subtrees if we can make sure to do it only once. */
841 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
843 if (data && !((hash_set<tree> *)data)->add (t))
845 else
846 *walk_subtrees = 0;
849 /* Stop at types, decls, constants like copy_tree_r. */
850 else if (TREE_CODE_CLASS (code) == tcc_type
851 || TREE_CODE_CLASS (code) == tcc_declaration
852 || TREE_CODE_CLASS (code) == tcc_constant)
853 *walk_subtrees = 0;
855 /* Cope with the statement expression extension. */
856 else if (code == STATEMENT_LIST)
859 /* Leave the bulk of the work to copy_tree_r itself. */
860 else
861 copy_tree_r (tp, walk_subtrees, NULL);
863 return NULL_TREE;
866 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
867 If *TP has been visited already, then *TP is deeply copied by calling
868 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
870 static tree
871 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
873 tree t = *tp;
874 enum tree_code code = TREE_CODE (t);
876 /* Skip types, decls, and constants. But we do want to look at their
877 types and the bounds of types. Mark them as visited so we properly
878 unmark their subtrees on the unmark pass. If we've already seen them,
879 don't look down further. */
880 if (TREE_CODE_CLASS (code) == tcc_type
881 || TREE_CODE_CLASS (code) == tcc_declaration
882 || TREE_CODE_CLASS (code) == tcc_constant)
884 if (TREE_VISITED (t))
885 *walk_subtrees = 0;
886 else
887 TREE_VISITED (t) = 1;
890 /* If this node has been visited already, unshare it and don't look
891 any deeper. */
892 else if (TREE_VISITED (t))
894 walk_tree (tp, mostly_copy_tree_r, data, NULL);
895 *walk_subtrees = 0;
898 /* Otherwise, mark the node as visited and keep looking. */
899 else
900 TREE_VISITED (t) = 1;
902 return NULL_TREE;
905 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
906 copy_if_shared_r callback unmodified. */
908 static inline void
909 copy_if_shared (tree *tp, void *data)
911 walk_tree (tp, copy_if_shared_r, data, NULL);
914 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
915 any nested functions. */
917 static void
918 unshare_body (tree fndecl)
920 struct cgraph_node *cgn = cgraph_node::get (fndecl);
921 /* If the language requires deep unsharing, we need a pointer set to make
922 sure we don't repeatedly unshare subtrees of unshareable nodes. */
923 hash_set<tree> *visited
924 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
926 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
927 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
928 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
930 delete visited;
932 if (cgn)
933 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
934 unshare_body (cgn->decl);
937 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
938 Subtrees are walked until the first unvisited node is encountered. */
940 static tree
941 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
943 tree t = *tp;
945 /* If this node has been visited, unmark it and keep looking. */
946 if (TREE_VISITED (t))
947 TREE_VISITED (t) = 0;
949 /* Otherwise, don't look any deeper. */
950 else
951 *walk_subtrees = 0;
953 return NULL_TREE;
956 /* Unmark the visited trees rooted at *TP. */
958 static inline void
959 unmark_visited (tree *tp)
961 walk_tree (tp, unmark_visited_r, NULL, NULL);
964 /* Likewise, but mark all trees as not visited. */
966 static void
967 unvisit_body (tree fndecl)
969 struct cgraph_node *cgn = cgraph_node::get (fndecl);
971 unmark_visited (&DECL_SAVED_TREE (fndecl));
972 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
973 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
975 if (cgn)
976 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
977 unvisit_body (cgn->decl);
980 /* Unconditionally make an unshared copy of EXPR. This is used when using
981 stored expressions which span multiple functions, such as BINFO_VTABLE,
982 as the normal unsharing process can't tell that they're shared. */
984 tree
985 unshare_expr (tree expr)
987 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
988 return expr;
991 /* Worker for unshare_expr_without_location. */
993 static tree
994 prune_expr_location (tree *tp, int *walk_subtrees, void *)
996 if (EXPR_P (*tp))
997 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
998 else
999 *walk_subtrees = 0;
1000 return NULL_TREE;
1003 /* Similar to unshare_expr but also prune all expression locations
1004 from EXPR. */
1006 tree
1007 unshare_expr_without_location (tree expr)
1009 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1010 if (EXPR_P (expr))
1011 walk_tree (&expr, prune_expr_location, NULL, NULL);
1012 return expr;
1015 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1016 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1017 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1018 EXPR is the location of the EXPR. */
1020 static location_t
1021 rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION)
1023 if (!expr)
1024 return or_else;
1026 if (EXPR_HAS_LOCATION (expr))
1027 return EXPR_LOCATION (expr);
1029 if (TREE_CODE (expr) != STATEMENT_LIST)
1030 return or_else;
1032 tree_stmt_iterator i = tsi_start (expr);
1034 bool found = false;
1035 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
1037 found = true;
1038 tsi_next (&i);
1041 if (!found || !tsi_one_before_end_p (i))
1042 return or_else;
1044 return rexpr_location (tsi_stmt (i), or_else);
1047 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1048 rexpr_location for the potential recursion. */
1050 static inline bool
1051 rexpr_has_location (tree expr)
1053 return rexpr_location (expr) != UNKNOWN_LOCATION;
1057 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1058 contain statements and have a value. Assign its value to a temporary
1059 and give it void_type_node. Return the temporary, or NULL_TREE if
1060 WRAPPER was already void. */
1062 tree
1063 voidify_wrapper_expr (tree wrapper, tree temp)
1065 tree type = TREE_TYPE (wrapper);
1066 if (type && !VOID_TYPE_P (type))
1068 tree *p;
1070 /* Set p to point to the body of the wrapper. Loop until we find
1071 something that isn't a wrapper. */
1072 for (p = &wrapper; p && *p; )
1074 switch (TREE_CODE (*p))
1076 case BIND_EXPR:
1077 TREE_SIDE_EFFECTS (*p) = 1;
1078 TREE_TYPE (*p) = void_type_node;
1079 /* For a BIND_EXPR, the body is operand 1. */
1080 p = &BIND_EXPR_BODY (*p);
1081 break;
1083 case CLEANUP_POINT_EXPR:
1084 case TRY_FINALLY_EXPR:
1085 case TRY_CATCH_EXPR:
1086 TREE_SIDE_EFFECTS (*p) = 1;
1087 TREE_TYPE (*p) = void_type_node;
1088 p = &TREE_OPERAND (*p, 0);
1089 break;
1091 case STATEMENT_LIST:
1093 tree_stmt_iterator i = tsi_last (*p);
1094 TREE_SIDE_EFFECTS (*p) = 1;
1095 TREE_TYPE (*p) = void_type_node;
1096 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1098 break;
1100 case COMPOUND_EXPR:
1101 /* Advance to the last statement. Set all container types to
1102 void. */
1103 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1105 TREE_SIDE_EFFECTS (*p) = 1;
1106 TREE_TYPE (*p) = void_type_node;
1108 break;
1110 case TRANSACTION_EXPR:
1111 TREE_SIDE_EFFECTS (*p) = 1;
1112 TREE_TYPE (*p) = void_type_node;
1113 p = &TRANSACTION_EXPR_BODY (*p);
1114 break;
1116 default:
1117 /* Assume that any tree upon which voidify_wrapper_expr is
1118 directly called is a wrapper, and that its body is op0. */
1119 if (p == &wrapper)
1121 TREE_SIDE_EFFECTS (*p) = 1;
1122 TREE_TYPE (*p) = void_type_node;
1123 p = &TREE_OPERAND (*p, 0);
1124 break;
1126 goto out;
1130 out:
1131 if (p == NULL || IS_EMPTY_STMT (*p))
1132 temp = NULL_TREE;
1133 else if (temp)
1135 /* The wrapper is on the RHS of an assignment that we're pushing
1136 down. */
1137 gcc_assert (TREE_CODE (temp) == INIT_EXPR
1138 || TREE_CODE (temp) == MODIFY_EXPR);
1139 TREE_OPERAND (temp, 1) = *p;
1140 *p = temp;
1142 else
1144 temp = create_tmp_var (type, "retval");
1145 *p = build2 (INIT_EXPR, type, temp, *p);
1148 return temp;
1151 return NULL_TREE;
1154 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1155 a temporary through which they communicate. */
1157 static void
1158 build_stack_save_restore (gcall **save, gcall **restore)
1160 tree tmp_var;
1162 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1163 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1164 gimple_call_set_lhs (*save, tmp_var);
1166 *restore
1167 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1168 1, tmp_var);
1171 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1173 static tree
1174 build_asan_poison_call_expr (tree decl)
1176 /* Do not poison variables that have size equal to zero. */
1177 tree unit_size = DECL_SIZE_UNIT (decl);
1178 if (zerop (unit_size))
1179 return NULL_TREE;
1181 tree base = build_fold_addr_expr (decl);
1183 return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
1184 void_type_node, 3,
1185 build_int_cst (integer_type_node,
1186 ASAN_MARK_POISON),
1187 base, unit_size);
1190 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1191 on POISON flag, shadow memory of a DECL variable. The call will be
1192 put on location identified by IT iterator, where BEFORE flag drives
1193 position where the stmt will be put. */
1195 static void
1196 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
1197 bool before)
1199 tree unit_size = DECL_SIZE_UNIT (decl);
1200 tree base = build_fold_addr_expr (decl);
1202 /* Do not poison variables that have size equal to zero. */
1203 if (zerop (unit_size))
1204 return;
1206 /* It's necessary to have all stack variables aligned to ASAN granularity
1207 bytes. */
1208 if (DECL_ALIGN_UNIT (decl) <= ASAN_SHADOW_GRANULARITY)
1209 SET_DECL_ALIGN (decl, BITS_PER_UNIT * ASAN_SHADOW_GRANULARITY);
1211 HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
1213 gimple *g
1214 = gimple_build_call_internal (IFN_ASAN_MARK, 3,
1215 build_int_cst (integer_type_node, flags),
1216 base, unit_size);
1218 if (before)
1219 gsi_insert_before (it, g, GSI_NEW_STMT);
1220 else
1221 gsi_insert_after (it, g, GSI_NEW_STMT);
1224 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1225 either poisons or unpoisons a DECL. Created statement is appended
1226 to SEQ_P gimple sequence. */
1228 static void
1229 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
1231 gimple_stmt_iterator it = gsi_last (*seq_p);
1232 bool before = false;
1234 if (gsi_end_p (it))
1235 before = true;
1237 asan_poison_variable (decl, poison, &it, before);
1240 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1242 static int
1243 sort_by_decl_uid (const void *a, const void *b)
1245 const tree *t1 = (const tree *)a;
1246 const tree *t2 = (const tree *)b;
1248 int uid1 = DECL_UID (*t1);
1249 int uid2 = DECL_UID (*t2);
1251 if (uid1 < uid2)
1252 return -1;
1253 else if (uid1 > uid2)
1254 return 1;
1255 else
1256 return 0;
1259 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1260 depending on POISON flag. Created statement is appended
1261 to SEQ_P gimple sequence. */
1263 static void
1264 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
1266 unsigned c = variables->elements ();
1267 if (c == 0)
1268 return;
1270 auto_vec<tree> sorted_variables (c);
1272 for (hash_set<tree>::iterator it = variables->begin ();
1273 it != variables->end (); ++it)
1274 sorted_variables.safe_push (*it);
1276 sorted_variables.qsort (sort_by_decl_uid);
1278 unsigned i;
1279 tree var;
1280 FOR_EACH_VEC_ELT (sorted_variables, i, var)
1282 asan_poison_variable (var, poison, seq_p);
1284 /* Add use_after_scope_memory attribute for the variable in order
1285 to prevent re-written into SSA. */
1286 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
1287 DECL_ATTRIBUTES (var)))
1288 DECL_ATTRIBUTES (var)
1289 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
1290 integer_one_node,
1291 DECL_ATTRIBUTES (var));
1295 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1297 static enum gimplify_status
1298 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1300 tree bind_expr = *expr_p;
1301 bool old_keep_stack = gimplify_ctxp->keep_stack;
1302 bool old_save_stack = gimplify_ctxp->save_stack;
1303 tree t;
1304 gbind *bind_stmt;
1305 gimple_seq body, cleanup;
1306 gcall *stack_save;
1307 location_t start_locus = 0, end_locus = 0;
1308 tree ret_clauses = NULL;
1310 tree temp = voidify_wrapper_expr (bind_expr, NULL);
1312 /* Mark variables seen in this bind expr. */
1313 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1315 if (VAR_P (t))
1317 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1319 /* Mark variable as local. */
1320 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t)
1321 && (! DECL_SEEN_IN_BIND_EXPR_P (t)
1322 || splay_tree_lookup (ctx->variables,
1323 (splay_tree_key) t) == NULL))
1325 if (ctx->region_type == ORT_SIMD
1326 && TREE_ADDRESSABLE (t)
1327 && !TREE_STATIC (t))
1328 omp_add_variable (ctx, t, GOVD_PRIVATE | GOVD_SEEN);
1329 else
1330 omp_add_variable (ctx, t, GOVD_LOCAL | GOVD_SEEN);
1333 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1335 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1336 cfun->has_local_explicit_reg_vars = true;
1339 /* Preliminarily mark non-addressed complex variables as eligible
1340 for promotion to gimple registers. We'll transform their uses
1341 as we find them. */
1342 if ((TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
1343 || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
1344 && !TREE_THIS_VOLATILE (t)
1345 && (VAR_P (t) && !DECL_HARD_REGISTER (t))
1346 && !needs_to_live_in_memory (t))
1347 DECL_GIMPLE_REG_P (t) = 1;
1350 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1351 BIND_EXPR_BLOCK (bind_expr));
1352 gimple_push_bind_expr (bind_stmt);
1354 gimplify_ctxp->keep_stack = false;
1355 gimplify_ctxp->save_stack = false;
1357 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1358 body = NULL;
1359 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1360 gimple_bind_set_body (bind_stmt, body);
1362 /* Source location wise, the cleanup code (stack_restore and clobbers)
1363 belongs to the end of the block, so propagate what we have. The
1364 stack_save operation belongs to the beginning of block, which we can
1365 infer from the bind_expr directly if the block has no explicit
1366 assignment. */
1367 if (BIND_EXPR_BLOCK (bind_expr))
1369 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1370 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1372 if (start_locus == 0)
1373 start_locus = EXPR_LOCATION (bind_expr);
1375 cleanup = NULL;
1376 stack_save = NULL;
1378 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1379 the stack space allocated to the VLAs. */
1380 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1382 gcall *stack_restore;
1384 /* Save stack on entry and restore it on exit. Add a try_finally
1385 block to achieve this. */
1386 build_stack_save_restore (&stack_save, &stack_restore);
1388 gimple_set_location (stack_save, start_locus);
1389 gimple_set_location (stack_restore, end_locus);
1391 gimplify_seq_add_stmt (&cleanup, stack_restore);
1394 /* Add clobbers for all variables that go out of scope. */
1395 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1397 if (VAR_P (t)
1398 && !is_global_var (t)
1399 && DECL_CONTEXT (t) == current_function_decl)
1401 if (!DECL_HARD_REGISTER (t)
1402 && !TREE_THIS_VOLATILE (t)
1403 && !DECL_HAS_VALUE_EXPR_P (t)
1404 /* Only care for variables that have to be in memory. Others
1405 will be rewritten into SSA names, hence moved to the
1406 top-level. */
1407 && !is_gimple_reg (t)
1408 && flag_stack_reuse != SR_NONE)
1410 tree clobber = build_clobber (TREE_TYPE (t));
1411 gimple *clobber_stmt;
1412 clobber_stmt = gimple_build_assign (t, clobber);
1413 gimple_set_location (clobber_stmt, end_locus);
1414 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1417 if (flag_openacc && oacc_declare_returns != NULL)
1419 tree *c = oacc_declare_returns->get (t);
1420 if (c != NULL)
1422 if (ret_clauses)
1423 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1425 ret_clauses = *c;
1427 oacc_declare_returns->remove (t);
1429 if (oacc_declare_returns->is_empty ())
1431 delete oacc_declare_returns;
1432 oacc_declare_returns = NULL;
1438 if (asan_poisoned_variables != NULL
1439 && asan_poisoned_variables->contains (t))
1441 asan_poisoned_variables->remove (t);
1442 asan_poison_variable (t, true, &cleanup);
1445 if (gimplify_ctxp->live_switch_vars != NULL
1446 && gimplify_ctxp->live_switch_vars->contains (t))
1447 gimplify_ctxp->live_switch_vars->remove (t);
1450 if (ret_clauses)
1452 gomp_target *stmt;
1453 gimple_stmt_iterator si = gsi_start (cleanup);
1455 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1456 ret_clauses);
1457 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1460 if (cleanup)
1462 gtry *gs;
1463 gimple_seq new_body;
1465 new_body = NULL;
1466 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1467 GIMPLE_TRY_FINALLY);
1469 if (stack_save)
1470 gimplify_seq_add_stmt (&new_body, stack_save);
1471 gimplify_seq_add_stmt (&new_body, gs);
1472 gimple_bind_set_body (bind_stmt, new_body);
1475 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1476 if (!gimplify_ctxp->keep_stack)
1477 gimplify_ctxp->keep_stack = old_keep_stack;
1478 gimplify_ctxp->save_stack = old_save_stack;
1480 gimple_pop_bind_expr ();
1482 gimplify_seq_add_stmt (pre_p, bind_stmt);
1484 if (temp)
1486 *expr_p = temp;
1487 return GS_OK;
1490 *expr_p = NULL_TREE;
1491 return GS_ALL_DONE;
1494 /* Maybe add early return predict statement to PRE_P sequence. */
1496 static void
1497 maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
1499 /* If we are not in a conditional context, add PREDICT statement. */
1500 if (gimple_conditional_context ())
1502 gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
1503 NOT_TAKEN);
1504 gimplify_seq_add_stmt (pre_p, predict);
1508 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1509 GIMPLE value, it is assigned to a new temporary and the statement is
1510 re-written to return the temporary.
1512 PRE_P points to the sequence where side effects that must happen before
1513 STMT should be stored. */
1515 static enum gimplify_status
1516 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1518 greturn *ret;
1519 tree ret_expr = TREE_OPERAND (stmt, 0);
1520 tree result_decl, result;
1522 if (ret_expr == error_mark_node)
1523 return GS_ERROR;
1525 if (!ret_expr
1526 || TREE_CODE (ret_expr) == RESULT_DECL)
1528 maybe_add_early_return_predict_stmt (pre_p);
1529 greturn *ret = gimple_build_return (ret_expr);
1530 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1531 gimplify_seq_add_stmt (pre_p, ret);
1532 return GS_ALL_DONE;
1535 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1536 result_decl = NULL_TREE;
1537 else
1539 result_decl = TREE_OPERAND (ret_expr, 0);
1541 /* See through a return by reference. */
1542 if (TREE_CODE (result_decl) == INDIRECT_REF)
1543 result_decl = TREE_OPERAND (result_decl, 0);
1545 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1546 || TREE_CODE (ret_expr) == INIT_EXPR)
1547 && TREE_CODE (result_decl) == RESULT_DECL);
1550 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1551 Recall that aggregate_value_p is FALSE for any aggregate type that is
1552 returned in registers. If we're returning values in registers, then
1553 we don't want to extend the lifetime of the RESULT_DECL, particularly
1554 across another call. In addition, for those aggregates for which
1555 hard_function_value generates a PARALLEL, we'll die during normal
1556 expansion of structure assignments; there's special code in expand_return
1557 to handle this case that does not exist in expand_expr. */
1558 if (!result_decl)
1559 result = NULL_TREE;
1560 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1562 if (TREE_CODE (DECL_SIZE (result_decl)) != INTEGER_CST)
1564 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1565 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1566 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1567 should be effectively allocated by the caller, i.e. all calls to
1568 this function must be subject to the Return Slot Optimization. */
1569 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1570 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1572 result = result_decl;
1574 else if (gimplify_ctxp->return_temp)
1575 result = gimplify_ctxp->return_temp;
1576 else
1578 result = create_tmp_reg (TREE_TYPE (result_decl));
1580 /* ??? With complex control flow (usually involving abnormal edges),
1581 we can wind up warning about an uninitialized value for this. Due
1582 to how this variable is constructed and initialized, this is never
1583 true. Give up and never warn. */
1584 TREE_NO_WARNING (result) = 1;
1586 gimplify_ctxp->return_temp = result;
1589 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1590 Then gimplify the whole thing. */
1591 if (result != result_decl)
1592 TREE_OPERAND (ret_expr, 0) = result;
1594 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1596 maybe_add_early_return_predict_stmt (pre_p);
1597 ret = gimple_build_return (result);
1598 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1599 gimplify_seq_add_stmt (pre_p, ret);
1601 return GS_ALL_DONE;
1604 /* Gimplify a variable-length array DECL. */
1606 static void
1607 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1609 /* This is a variable-sized decl. Simplify its size and mark it
1610 for deferred expansion. */
1611 tree t, addr, ptr_type;
1613 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1614 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1616 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1617 if (DECL_HAS_VALUE_EXPR_P (decl))
1618 return;
1620 /* All occurrences of this decl in final gimplified code will be
1621 replaced by indirection. Setting DECL_VALUE_EXPR does two
1622 things: First, it lets the rest of the gimplifier know what
1623 replacement to use. Second, it lets the debug info know
1624 where to find the value. */
1625 ptr_type = build_pointer_type (TREE_TYPE (decl));
1626 addr = create_tmp_var (ptr_type, get_name (decl));
1627 DECL_IGNORED_P (addr) = 0;
1628 t = build_fold_indirect_ref (addr);
1629 TREE_THIS_NOTRAP (t) = 1;
1630 SET_DECL_VALUE_EXPR (decl, t);
1631 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1633 t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
1634 max_int_size_in_bytes (TREE_TYPE (decl)));
1635 /* The call has been built for a variable-sized object. */
1636 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1637 t = fold_convert (ptr_type, t);
1638 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1640 gimplify_and_add (t, seq_p);
1643 /* A helper function to be called via walk_tree. Mark all labels under *TP
1644 as being forced. To be called for DECL_INITIAL of static variables. */
1646 static tree
1647 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1649 if (TYPE_P (*tp))
1650 *walk_subtrees = 0;
1651 if (TREE_CODE (*tp) == LABEL_DECL)
1653 FORCED_LABEL (*tp) = 1;
1654 cfun->has_forced_label_in_static = 1;
1657 return NULL_TREE;
1660 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1661 and initialization explicit. */
1663 static enum gimplify_status
1664 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1666 tree stmt = *stmt_p;
1667 tree decl = DECL_EXPR_DECL (stmt);
1669 *stmt_p = NULL_TREE;
1671 if (TREE_TYPE (decl) == error_mark_node)
1672 return GS_ERROR;
1674 if ((TREE_CODE (decl) == TYPE_DECL
1675 || VAR_P (decl))
1676 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1678 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1679 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1680 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1683 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1684 in case its size expressions contain problematic nodes like CALL_EXPR. */
1685 if (TREE_CODE (decl) == TYPE_DECL
1686 && DECL_ORIGINAL_TYPE (decl)
1687 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1689 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1690 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1691 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1694 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1696 tree init = DECL_INITIAL (decl);
1697 bool is_vla = false;
1699 if (TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST
1700 || (!TREE_STATIC (decl)
1701 && flag_stack_check == GENERIC_STACK_CHECK
1702 && compare_tree_int (DECL_SIZE_UNIT (decl),
1703 STACK_CHECK_MAX_VAR_SIZE) > 0))
1705 gimplify_vla_decl (decl, seq_p);
1706 is_vla = true;
1709 if (asan_poisoned_variables
1710 && !is_vla
1711 && TREE_ADDRESSABLE (decl)
1712 && !TREE_STATIC (decl)
1713 && !DECL_HAS_VALUE_EXPR_P (decl)
1714 && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
1715 && dbg_cnt (asan_use_after_scope)
1716 && !gimplify_omp_ctxp)
1718 asan_poisoned_variables->add (decl);
1719 asan_poison_variable (decl, false, seq_p);
1720 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
1721 gimplify_ctxp->live_switch_vars->add (decl);
1724 /* Some front ends do not explicitly declare all anonymous
1725 artificial variables. We compensate here by declaring the
1726 variables, though it would be better if the front ends would
1727 explicitly declare them. */
1728 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1729 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1730 gimple_add_tmp_var (decl);
1732 if (init && init != error_mark_node)
1734 if (!TREE_STATIC (decl))
1736 DECL_INITIAL (decl) = NULL_TREE;
1737 init = build2 (INIT_EXPR, void_type_node, decl, init);
1738 gimplify_and_add (init, seq_p);
1739 ggc_free (init);
1741 else
1742 /* We must still examine initializers for static variables
1743 as they may contain a label address. */
1744 walk_tree (&init, force_labels_r, NULL, NULL);
1748 return GS_ALL_DONE;
1751 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1752 and replacing the LOOP_EXPR with goto, but if the loop contains an
1753 EXIT_EXPR, we need to append a label for it to jump to. */
1755 static enum gimplify_status
1756 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1758 tree saved_label = gimplify_ctxp->exit_label;
1759 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1761 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1763 gimplify_ctxp->exit_label = NULL_TREE;
1765 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1767 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
1769 if (gimplify_ctxp->exit_label)
1770 gimplify_seq_add_stmt (pre_p,
1771 gimple_build_label (gimplify_ctxp->exit_label));
1773 gimplify_ctxp->exit_label = saved_label;
1775 *expr_p = NULL;
1776 return GS_ALL_DONE;
1779 /* Gimplify a statement list onto a sequence. These may be created either
1780 by an enlightened front-end, or by shortcut_cond_expr. */
1782 static enum gimplify_status
1783 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
1785 tree temp = voidify_wrapper_expr (*expr_p, NULL);
1787 tree_stmt_iterator i = tsi_start (*expr_p);
1789 while (!tsi_end_p (i))
1791 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
1792 tsi_delink (&i);
1795 if (temp)
1797 *expr_p = temp;
1798 return GS_OK;
1801 return GS_ALL_DONE;
1804 /* Callback for walk_gimple_seq. */
1806 static tree
1807 warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
1808 struct walk_stmt_info *wi)
1810 gimple *stmt = gsi_stmt (*gsi_p);
1812 *handled_ops_p = true;
1813 switch (gimple_code (stmt))
1815 case GIMPLE_TRY:
1816 /* A compiler-generated cleanup or a user-written try block.
1817 If it's empty, don't dive into it--that would result in
1818 worse location info. */
1819 if (gimple_try_eval (stmt) == NULL)
1821 wi->info = stmt;
1822 return integer_zero_node;
1824 /* Fall through. */
1825 case GIMPLE_BIND:
1826 case GIMPLE_CATCH:
1827 case GIMPLE_EH_FILTER:
1828 case GIMPLE_TRANSACTION:
1829 /* Walk the sub-statements. */
1830 *handled_ops_p = false;
1831 break;
1833 case GIMPLE_DEBUG:
1834 /* Ignore these. We may generate them before declarations that
1835 are never executed. If there's something to warn about,
1836 there will be non-debug stmts too, and we'll catch those. */
1837 break;
1839 case GIMPLE_CALL:
1840 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
1842 *handled_ops_p = false;
1843 break;
1845 /* Fall through. */
1846 default:
1847 /* Save the first "real" statement (not a decl/lexical scope/...). */
1848 wi->info = stmt;
1849 return integer_zero_node;
1851 return NULL_TREE;
1854 /* Possibly warn about unreachable statements between switch's controlling
1855 expression and the first case. SEQ is the body of a switch expression. */
1857 static void
1858 maybe_warn_switch_unreachable (gimple_seq seq)
1860 if (!warn_switch_unreachable
1861 /* This warning doesn't play well with Fortran when optimizations
1862 are on. */
1863 || lang_GNU_Fortran ()
1864 || seq == NULL)
1865 return;
1867 struct walk_stmt_info wi;
1868 memset (&wi, 0, sizeof (wi));
1869 walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi);
1870 gimple *stmt = (gimple *) wi.info;
1872 if (stmt && gimple_code (stmt) != GIMPLE_LABEL)
1874 if (gimple_code (stmt) == GIMPLE_GOTO
1875 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
1876 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
1877 /* Don't warn for compiler-generated gotos. These occur
1878 in Duff's devices, for example. */;
1879 else
1880 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
1881 "statement will never be executed");
1886 /* A label entry that pairs label and a location. */
1887 struct label_entry
1889 tree label;
1890 location_t loc;
1893 /* Find LABEL in vector of label entries VEC. */
1895 static struct label_entry *
1896 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
1898 unsigned int i;
1899 struct label_entry *l;
1901 FOR_EACH_VEC_ELT (*vec, i, l)
1902 if (l->label == label)
1903 return l;
1904 return NULL;
1907 /* Return true if LABEL, a LABEL_DECL, represents a case label
1908 in a vector of labels CASES. */
1910 static bool
1911 case_label_p (const vec<tree> *cases, tree label)
1913 unsigned int i;
1914 tree l;
1916 FOR_EACH_VEC_ELT (*cases, i, l)
1917 if (CASE_LABEL (l) == label)
1918 return true;
1919 return false;
1922 /* Find the last nondebug statement in a scope STMT. */
1924 static gimple *
1925 last_stmt_in_scope (gimple *stmt)
1927 if (!stmt)
1928 return NULL;
1930 switch (gimple_code (stmt))
1932 case GIMPLE_BIND:
1934 gbind *bind = as_a <gbind *> (stmt);
1935 stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
1936 return last_stmt_in_scope (stmt);
1939 case GIMPLE_TRY:
1941 gtry *try_stmt = as_a <gtry *> (stmt);
1942 stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
1943 gimple *last_eval = last_stmt_in_scope (stmt);
1944 if (gimple_stmt_may_fallthru (last_eval)
1945 && (last_eval == NULL
1946 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
1947 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
1949 stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
1950 return last_stmt_in_scope (stmt);
1952 else
1953 return last_eval;
1956 case GIMPLE_DEBUG:
1957 gcc_unreachable ();
1959 default:
1960 return stmt;
1964 /* Collect interesting labels in LABELS and return the statement preceding
1965 another case label, or a user-defined label. Store a location useful
1966 to give warnings at *PREVLOC (usually the location of the returned
1967 statement or of its surrounding scope). */
1969 static gimple *
1970 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
1971 auto_vec <struct label_entry> *labels,
1972 location_t *prevloc)
1974 gimple *prev = NULL;
1976 *prevloc = UNKNOWN_LOCATION;
1979 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
1981 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
1982 which starts on a GIMPLE_SWITCH and ends with a break label.
1983 Handle that as a single statement that can fall through. */
1984 gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
1985 gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
1986 gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
1987 if (last
1988 && gimple_code (first) == GIMPLE_SWITCH
1989 && gimple_code (last) == GIMPLE_LABEL)
1991 tree label = gimple_label_label (as_a <glabel *> (last));
1992 if (SWITCH_BREAK_LABEL_P (label))
1994 prev = bind;
1995 gsi_next (gsi_p);
1996 continue;
2000 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
2001 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
2003 /* Nested scope. Only look at the last statement of
2004 the innermost scope. */
2005 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
2006 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
2007 if (last)
2009 prev = last;
2010 /* It might be a label without a location. Use the
2011 location of the scope then. */
2012 if (!gimple_has_location (prev))
2013 *prevloc = bind_loc;
2015 gsi_next (gsi_p);
2016 continue;
2019 /* Ifs are tricky. */
2020 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
2022 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
2023 tree false_lab = gimple_cond_false_label (cond_stmt);
2024 location_t if_loc = gimple_location (cond_stmt);
2026 /* If we have e.g.
2027 if (i > 1) goto <D.2259>; else goto D;
2028 we can't do much with the else-branch. */
2029 if (!DECL_ARTIFICIAL (false_lab))
2030 break;
2032 /* Go on until the false label, then one step back. */
2033 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
2035 gimple *stmt = gsi_stmt (*gsi_p);
2036 if (gimple_code (stmt) == GIMPLE_LABEL
2037 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
2038 break;
2041 /* Not found? Oops. */
2042 if (gsi_end_p (*gsi_p))
2043 break;
2045 struct label_entry l = { false_lab, if_loc };
2046 labels->safe_push (l);
2048 /* Go to the last statement of the then branch. */
2049 gsi_prev (gsi_p);
2051 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2052 <D.1759>:
2053 <stmt>;
2054 goto <D.1761>;
2055 <D.1760>:
2057 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2058 && !gimple_has_location (gsi_stmt (*gsi_p)))
2060 /* Look at the statement before, it might be
2061 attribute fallthrough, in which case don't warn. */
2062 gsi_prev (gsi_p);
2063 bool fallthru_before_dest
2064 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2065 gsi_next (gsi_p);
2066 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2067 if (!fallthru_before_dest)
2069 struct label_entry l = { goto_dest, if_loc };
2070 labels->safe_push (l);
2073 /* And move back. */
2074 gsi_next (gsi_p);
2077 /* Remember the last statement. Skip labels that are of no interest
2078 to us. */
2079 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2081 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2082 if (find_label_entry (labels, label))
2083 prev = gsi_stmt (*gsi_p);
2085 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2087 else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2088 prev = gsi_stmt (*gsi_p);
2089 gsi_next (gsi_p);
2091 while (!gsi_end_p (*gsi_p)
2092 /* Stop if we find a case or a user-defined label. */
2093 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2094 || !gimple_has_location (gsi_stmt (*gsi_p))));
2096 if (prev && gimple_has_location (prev))
2097 *prevloc = gimple_location (prev);
2098 return prev;
2101 /* Return true if the switch fallthough warning should occur. LABEL is
2102 the label statement that we're falling through to. */
2104 static bool
2105 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2107 gimple_stmt_iterator gsi = *gsi_p;
2109 /* Don't warn if the label is marked with a "falls through" comment. */
2110 if (FALLTHROUGH_LABEL_P (label))
2111 return false;
2113 /* Don't warn for non-case labels followed by a statement:
2114 case 0:
2115 foo ();
2116 label:
2117 bar ();
2118 as these are likely intentional. */
2119 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2121 tree l;
2122 while (!gsi_end_p (gsi)
2123 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2124 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2125 && !case_label_p (&gimplify_ctxp->case_labels, l))
2126 gsi_next_nondebug (&gsi);
2127 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2128 return false;
2131 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2132 immediately breaks. */
2133 gsi = *gsi_p;
2135 /* Skip all immediately following labels. */
2136 while (!gsi_end_p (gsi)
2137 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2138 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2139 gsi_next_nondebug (&gsi);
2141 /* { ... something; default:; } */
2142 if (gsi_end_p (gsi)
2143 /* { ... something; default: break; } or
2144 { ... something; default: goto L; } */
2145 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2146 /* { ... something; default: return; } */
2147 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2148 return false;
2150 return true;
2153 /* Callback for walk_gimple_seq. */
2155 static tree
2156 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2157 struct walk_stmt_info *)
2159 gimple *stmt = gsi_stmt (*gsi_p);
2161 *handled_ops_p = true;
2162 switch (gimple_code (stmt))
2164 case GIMPLE_TRY:
2165 case GIMPLE_BIND:
2166 case GIMPLE_CATCH:
2167 case GIMPLE_EH_FILTER:
2168 case GIMPLE_TRANSACTION:
2169 /* Walk the sub-statements. */
2170 *handled_ops_p = false;
2171 break;
2173 /* Find a sequence of form:
2175 GIMPLE_LABEL
2176 [...]
2177 <may fallthru stmt>
2178 GIMPLE_LABEL
2180 and possibly warn. */
2181 case GIMPLE_LABEL:
2183 /* Found a label. Skip all immediately following labels. */
2184 while (!gsi_end_p (*gsi_p)
2185 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2186 gsi_next_nondebug (gsi_p);
2188 /* There might be no more statements. */
2189 if (gsi_end_p (*gsi_p))
2190 return integer_zero_node;
2192 /* Vector of labels that fall through. */
2193 auto_vec <struct label_entry> labels;
2194 location_t prevloc;
2195 gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
2197 /* There might be no more statements. */
2198 if (gsi_end_p (*gsi_p))
2199 return integer_zero_node;
2201 gimple *next = gsi_stmt (*gsi_p);
2202 tree label;
2203 /* If what follows is a label, then we may have a fallthrough. */
2204 if (gimple_code (next) == GIMPLE_LABEL
2205 && gimple_has_location (next)
2206 && (label = gimple_label_label (as_a <glabel *> (next)))
2207 && prev != NULL)
2209 struct label_entry *l;
2210 bool warned_p = false;
2211 auto_diagnostic_group d;
2212 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2213 /* Quiet. */;
2214 else if (gimple_code (prev) == GIMPLE_LABEL
2215 && (label = gimple_label_label (as_a <glabel *> (prev)))
2216 && (l = find_label_entry (&labels, label)))
2217 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2218 "this statement may fall through");
2219 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2220 /* Try to be clever and don't warn when the statement
2221 can't actually fall through. */
2222 && gimple_stmt_may_fallthru (prev)
2223 && prevloc != UNKNOWN_LOCATION)
2224 warned_p = warning_at (prevloc,
2225 OPT_Wimplicit_fallthrough_,
2226 "this statement may fall through");
2227 if (warned_p)
2228 inform (gimple_location (next), "here");
2230 /* Mark this label as processed so as to prevent multiple
2231 warnings in nested switches. */
2232 FALLTHROUGH_LABEL_P (label) = true;
2234 /* So that next warn_implicit_fallthrough_r will start looking for
2235 a new sequence starting with this label. */
2236 gsi_prev (gsi_p);
2239 break;
2240 default:
2241 break;
2243 return NULL_TREE;
2246 /* Warn when a switch case falls through. */
2248 static void
2249 maybe_warn_implicit_fallthrough (gimple_seq seq)
2251 if (!warn_implicit_fallthrough)
2252 return;
2254 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2255 if (!(lang_GNU_C ()
2256 || lang_GNU_CXX ()
2257 || lang_GNU_OBJC ()))
2258 return;
2260 struct walk_stmt_info wi;
2261 memset (&wi, 0, sizeof (wi));
2262 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2265 /* Callback for walk_gimple_seq. */
2267 static tree
2268 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2269 struct walk_stmt_info *wi)
2271 gimple *stmt = gsi_stmt (*gsi_p);
2273 *handled_ops_p = true;
2274 switch (gimple_code (stmt))
2276 case GIMPLE_TRY:
2277 case GIMPLE_BIND:
2278 case GIMPLE_CATCH:
2279 case GIMPLE_EH_FILTER:
2280 case GIMPLE_TRANSACTION:
2281 /* Walk the sub-statements. */
2282 *handled_ops_p = false;
2283 break;
2284 case GIMPLE_CALL:
2285 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2287 gsi_remove (gsi_p, true);
2288 if (gsi_end_p (*gsi_p))
2290 *static_cast<location_t *>(wi->info) = gimple_location (stmt);
2291 return integer_zero_node;
2294 bool found = false;
2295 location_t loc = gimple_location (stmt);
2297 gimple_stmt_iterator gsi2 = *gsi_p;
2298 stmt = gsi_stmt (gsi2);
2299 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2301 /* Go on until the artificial label. */
2302 tree goto_dest = gimple_goto_dest (stmt);
2303 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2305 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2306 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2307 == goto_dest)
2308 break;
2311 /* Not found? Stop. */
2312 if (gsi_end_p (gsi2))
2313 break;
2315 /* Look one past it. */
2316 gsi_next (&gsi2);
2319 /* We're looking for a case label or default label here. */
2320 while (!gsi_end_p (gsi2))
2322 stmt = gsi_stmt (gsi2);
2323 if (gimple_code (stmt) == GIMPLE_LABEL)
2325 tree label = gimple_label_label (as_a <glabel *> (stmt));
2326 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2328 found = true;
2329 break;
2332 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2334 else if (!is_gimple_debug (stmt))
2335 /* Anything else is not expected. */
2336 break;
2337 gsi_next (&gsi2);
2339 if (!found)
2340 warning_at (loc, 0, "attribute %<fallthrough%> not preceding "
2341 "a case label or default label");
2343 break;
2344 default:
2345 break;
2347 return NULL_TREE;
2350 /* Expand all FALLTHROUGH () calls in SEQ. */
2352 static void
2353 expand_FALLTHROUGH (gimple_seq *seq_p)
2355 struct walk_stmt_info wi;
2356 location_t loc;
2357 memset (&wi, 0, sizeof (wi));
2358 wi.info = (void *) &loc;
2359 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2360 if (wi.callback_result == integer_zero_node)
2361 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2362 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2363 warning_at (loc, 0, "attribute %<fallthrough%> not preceding "
2364 "a case label or default label");
2368 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2369 branch to. */
2371 static enum gimplify_status
2372 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2374 tree switch_expr = *expr_p;
2375 gimple_seq switch_body_seq = NULL;
2376 enum gimplify_status ret;
2377 tree index_type = TREE_TYPE (switch_expr);
2378 if (index_type == NULL_TREE)
2379 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2381 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2382 fb_rvalue);
2383 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2384 return ret;
2386 if (SWITCH_BODY (switch_expr))
2388 vec<tree> labels;
2389 vec<tree> saved_labels;
2390 hash_set<tree> *saved_live_switch_vars = NULL;
2391 tree default_case = NULL_TREE;
2392 gswitch *switch_stmt;
2394 /* Save old labels, get new ones from body, then restore the old
2395 labels. Save all the things from the switch body to append after. */
2396 saved_labels = gimplify_ctxp->case_labels;
2397 gimplify_ctxp->case_labels.create (8);
2399 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2400 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2401 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2402 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2403 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2404 else
2405 gimplify_ctxp->live_switch_vars = NULL;
2407 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2408 gimplify_ctxp->in_switch_expr = true;
2410 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2412 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2413 maybe_warn_switch_unreachable (switch_body_seq);
2414 maybe_warn_implicit_fallthrough (switch_body_seq);
2415 /* Only do this for the outermost GIMPLE_SWITCH. */
2416 if (!gimplify_ctxp->in_switch_expr)
2417 expand_FALLTHROUGH (&switch_body_seq);
2419 labels = gimplify_ctxp->case_labels;
2420 gimplify_ctxp->case_labels = saved_labels;
2422 if (gimplify_ctxp->live_switch_vars)
2424 gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
2425 delete gimplify_ctxp->live_switch_vars;
2427 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2429 preprocess_case_label_vec_for_gimple (labels, index_type,
2430 &default_case);
2432 bool add_bind = false;
2433 if (!default_case)
2435 glabel *new_default;
2437 default_case
2438 = build_case_label (NULL_TREE, NULL_TREE,
2439 create_artificial_label (UNKNOWN_LOCATION));
2440 if (old_in_switch_expr)
2442 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2443 add_bind = true;
2445 new_default = gimple_build_label (CASE_LABEL (default_case));
2446 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2448 else if (old_in_switch_expr)
2450 gimple *last = gimple_seq_last_stmt (switch_body_seq);
2451 if (last && gimple_code (last) == GIMPLE_LABEL)
2453 tree label = gimple_label_label (as_a <glabel *> (last));
2454 if (SWITCH_BREAK_LABEL_P (label))
2455 add_bind = true;
2459 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2460 default_case, labels);
2461 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2462 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2463 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2464 so that we can easily find the start and end of the switch
2465 statement. */
2466 if (add_bind)
2468 gimple_seq bind_body = NULL;
2469 gimplify_seq_add_stmt (&bind_body, switch_stmt);
2470 gimple_seq_add_seq (&bind_body, switch_body_seq);
2471 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
2472 gimple_set_location (bind, EXPR_LOCATION (switch_expr));
2473 gimplify_seq_add_stmt (pre_p, bind);
2475 else
2477 gimplify_seq_add_stmt (pre_p, switch_stmt);
2478 gimplify_seq_add_seq (pre_p, switch_body_seq);
2480 labels.release ();
2482 else
2483 gcc_unreachable ();
2485 return GS_ALL_DONE;
2488 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2490 static enum gimplify_status
2491 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2493 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2494 == current_function_decl);
2496 tree label = LABEL_EXPR_LABEL (*expr_p);
2497 glabel *label_stmt = gimple_build_label (label);
2498 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2499 gimplify_seq_add_stmt (pre_p, label_stmt);
2501 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2502 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2503 NOT_TAKEN));
2504 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2505 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2506 TAKEN));
2508 return GS_ALL_DONE;
2511 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2513 static enum gimplify_status
2514 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2516 struct gimplify_ctx *ctxp;
2517 glabel *label_stmt;
2519 /* Invalid programs can play Duff's Device type games with, for example,
2520 #pragma omp parallel. At least in the C front end, we don't
2521 detect such invalid branches until after gimplification, in the
2522 diagnose_omp_blocks pass. */
2523 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2524 if (ctxp->case_labels.exists ())
2525 break;
2527 tree label = CASE_LABEL (*expr_p);
2528 label_stmt = gimple_build_label (label);
2529 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2530 ctxp->case_labels.safe_push (*expr_p);
2531 gimplify_seq_add_stmt (pre_p, label_stmt);
2533 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2534 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2535 NOT_TAKEN));
2536 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2537 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2538 TAKEN));
2540 return GS_ALL_DONE;
2543 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2544 if necessary. */
2546 tree
2547 build_and_jump (tree *label_p)
2549 if (label_p == NULL)
2550 /* If there's nowhere to jump, just fall through. */
2551 return NULL_TREE;
2553 if (*label_p == NULL_TREE)
2555 tree label = create_artificial_label (UNKNOWN_LOCATION);
2556 *label_p = label;
2559 return build1 (GOTO_EXPR, void_type_node, *label_p);
2562 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2563 This also involves building a label to jump to and communicating it to
2564 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2566 static enum gimplify_status
2567 gimplify_exit_expr (tree *expr_p)
2569 tree cond = TREE_OPERAND (*expr_p, 0);
2570 tree expr;
2572 expr = build_and_jump (&gimplify_ctxp->exit_label);
2573 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2574 *expr_p = expr;
2576 return GS_OK;
2579 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2580 different from its canonical type, wrap the whole thing inside a
2581 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2582 type.
2584 The canonical type of a COMPONENT_REF is the type of the field being
2585 referenced--unless the field is a bit-field which can be read directly
2586 in a smaller mode, in which case the canonical type is the
2587 sign-appropriate type corresponding to that mode. */
2589 static void
2590 canonicalize_component_ref (tree *expr_p)
2592 tree expr = *expr_p;
2593 tree type;
2595 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2597 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2598 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2599 else
2600 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2602 /* One could argue that all the stuff below is not necessary for
2603 the non-bitfield case and declare it a FE error if type
2604 adjustment would be needed. */
2605 if (TREE_TYPE (expr) != type)
2607 #ifdef ENABLE_TYPES_CHECKING
2608 tree old_type = TREE_TYPE (expr);
2609 #endif
2610 int type_quals;
2612 /* We need to preserve qualifiers and propagate them from
2613 operand 0. */
2614 type_quals = TYPE_QUALS (type)
2615 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2616 if (TYPE_QUALS (type) != type_quals)
2617 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2619 /* Set the type of the COMPONENT_REF to the underlying type. */
2620 TREE_TYPE (expr) = type;
2622 #ifdef ENABLE_TYPES_CHECKING
2623 /* It is now a FE error, if the conversion from the canonical
2624 type to the original expression type is not useless. */
2625 gcc_assert (useless_type_conversion_p (old_type, type));
2626 #endif
2630 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2631 to foo, embed that change in the ADDR_EXPR by converting
2632 T array[U];
2633 (T *)&array
2635 &array[L]
2636 where L is the lower bound. For simplicity, only do this for constant
2637 lower bound.
2638 The constraint is that the type of &array[L] is trivially convertible
2639 to T *. */
2641 static void
2642 canonicalize_addr_expr (tree *expr_p)
2644 tree expr = *expr_p;
2645 tree addr_expr = TREE_OPERAND (expr, 0);
2646 tree datype, ddatype, pddatype;
2648 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2649 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2650 || TREE_CODE (addr_expr) != ADDR_EXPR)
2651 return;
2653 /* The addr_expr type should be a pointer to an array. */
2654 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2655 if (TREE_CODE (datype) != ARRAY_TYPE)
2656 return;
2658 /* The pointer to element type shall be trivially convertible to
2659 the expression pointer type. */
2660 ddatype = TREE_TYPE (datype);
2661 pddatype = build_pointer_type (ddatype);
2662 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2663 pddatype))
2664 return;
2666 /* The lower bound and element sizes must be constant. */
2667 if (!TYPE_SIZE_UNIT (ddatype)
2668 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2669 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2670 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2671 return;
2673 /* All checks succeeded. Build a new node to merge the cast. */
2674 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2675 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2676 NULL_TREE, NULL_TREE);
2677 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2679 /* We can have stripped a required restrict qualifier above. */
2680 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2681 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2684 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2685 underneath as appropriate. */
2687 static enum gimplify_status
2688 gimplify_conversion (tree *expr_p)
2690 location_t loc = EXPR_LOCATION (*expr_p);
2691 gcc_assert (CONVERT_EXPR_P (*expr_p));
2693 /* Then strip away all but the outermost conversion. */
2694 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
2696 /* And remove the outermost conversion if it's useless. */
2697 if (tree_ssa_useless_type_conversion (*expr_p))
2698 *expr_p = TREE_OPERAND (*expr_p, 0);
2700 /* If we still have a conversion at the toplevel,
2701 then canonicalize some constructs. */
2702 if (CONVERT_EXPR_P (*expr_p))
2704 tree sub = TREE_OPERAND (*expr_p, 0);
2706 /* If a NOP conversion is changing the type of a COMPONENT_REF
2707 expression, then canonicalize its type now in order to expose more
2708 redundant conversions. */
2709 if (TREE_CODE (sub) == COMPONENT_REF)
2710 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
2712 /* If a NOP conversion is changing a pointer to array of foo
2713 to a pointer to foo, embed that change in the ADDR_EXPR. */
2714 else if (TREE_CODE (sub) == ADDR_EXPR)
2715 canonicalize_addr_expr (expr_p);
2718 /* If we have a conversion to a non-register type force the
2719 use of a VIEW_CONVERT_EXPR instead. */
2720 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
2721 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
2722 TREE_OPERAND (*expr_p, 0));
2724 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2725 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
2726 TREE_SET_CODE (*expr_p, NOP_EXPR);
2728 return GS_OK;
2731 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2732 DECL_VALUE_EXPR, and it's worth re-examining things. */
2734 static enum gimplify_status
2735 gimplify_var_or_parm_decl (tree *expr_p)
2737 tree decl = *expr_p;
2739 /* ??? If this is a local variable, and it has not been seen in any
2740 outer BIND_EXPR, then it's probably the result of a duplicate
2741 declaration, for which we've already issued an error. It would
2742 be really nice if the front end wouldn't leak these at all.
2743 Currently the only known culprit is C++ destructors, as seen
2744 in g++.old-deja/g++.jason/binding.C. */
2745 if (VAR_P (decl)
2746 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
2747 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
2748 && decl_function_context (decl) == current_function_decl)
2750 gcc_assert (seen_error ());
2751 return GS_ERROR;
2754 /* When within an OMP context, notice uses of variables. */
2755 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
2756 return GS_ALL_DONE;
2758 /* If the decl is an alias for another expression, substitute it now. */
2759 if (DECL_HAS_VALUE_EXPR_P (decl))
2761 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
2762 return GS_OK;
2765 return GS_ALL_DONE;
2768 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2770 static void
2771 recalculate_side_effects (tree t)
2773 enum tree_code code = TREE_CODE (t);
2774 int len = TREE_OPERAND_LENGTH (t);
2775 int i;
2777 switch (TREE_CODE_CLASS (code))
2779 case tcc_expression:
2780 switch (code)
2782 case INIT_EXPR:
2783 case MODIFY_EXPR:
2784 case VA_ARG_EXPR:
2785 case PREDECREMENT_EXPR:
2786 case PREINCREMENT_EXPR:
2787 case POSTDECREMENT_EXPR:
2788 case POSTINCREMENT_EXPR:
2789 /* All of these have side-effects, no matter what their
2790 operands are. */
2791 return;
2793 default:
2794 break;
2796 /* Fall through. */
2798 case tcc_comparison: /* a comparison expression */
2799 case tcc_unary: /* a unary arithmetic expression */
2800 case tcc_binary: /* a binary arithmetic expression */
2801 case tcc_reference: /* a reference */
2802 case tcc_vl_exp: /* a function call */
2803 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
2804 for (i = 0; i < len; ++i)
2806 tree op = TREE_OPERAND (t, i);
2807 if (op && TREE_SIDE_EFFECTS (op))
2808 TREE_SIDE_EFFECTS (t) = 1;
2810 break;
2812 case tcc_constant:
2813 /* No side-effects. */
2814 return;
2816 default:
2817 gcc_unreachable ();
2821 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
2822 node *EXPR_P.
2824 compound_lval
2825 : min_lval '[' val ']'
2826 | min_lval '.' ID
2827 | compound_lval '[' val ']'
2828 | compound_lval '.' ID
2830 This is not part of the original SIMPLE definition, which separates
2831 array and member references, but it seems reasonable to handle them
2832 together. Also, this way we don't run into problems with union
2833 aliasing; gcc requires that for accesses through a union to alias, the
2834 union reference must be explicit, which was not always the case when we
2835 were splitting up array and member refs.
2837 PRE_P points to the sequence where side effects that must happen before
2838 *EXPR_P should be stored.
2840 POST_P points to the sequence where side effects that must happen after
2841 *EXPR_P should be stored. */
2843 static enum gimplify_status
2844 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2845 fallback_t fallback)
2847 tree *p;
2848 enum gimplify_status ret = GS_ALL_DONE, tret;
2849 int i;
2850 location_t loc = EXPR_LOCATION (*expr_p);
2851 tree expr = *expr_p;
2853 /* Create a stack of the subexpressions so later we can walk them in
2854 order from inner to outer. */
2855 auto_vec<tree, 10> expr_stack;
2857 /* We can handle anything that get_inner_reference can deal with. */
2858 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
2860 restart:
2861 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
2862 if (TREE_CODE (*p) == INDIRECT_REF)
2863 *p = fold_indirect_ref_loc (loc, *p);
2865 if (handled_component_p (*p))
2867 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
2868 additional COMPONENT_REFs. */
2869 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
2870 && gimplify_var_or_parm_decl (p) == GS_OK)
2871 goto restart;
2872 else
2873 break;
2875 expr_stack.safe_push (*p);
2878 gcc_assert (expr_stack.length ());
2880 /* Now EXPR_STACK is a stack of pointers to all the refs we've
2881 walked through and P points to the innermost expression.
2883 Java requires that we elaborated nodes in source order. That
2884 means we must gimplify the inner expression followed by each of
2885 the indices, in order. But we can't gimplify the inner
2886 expression until we deal with any variable bounds, sizes, or
2887 positions in order to deal with PLACEHOLDER_EXPRs.
2889 So we do this in three steps. First we deal with the annotations
2890 for any variables in the components, then we gimplify the base,
2891 then we gimplify any indices, from left to right. */
2892 for (i = expr_stack.length () - 1; i >= 0; i--)
2894 tree t = expr_stack[i];
2896 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2898 /* Gimplify the low bound and element type size and put them into
2899 the ARRAY_REF. If these values are set, they have already been
2900 gimplified. */
2901 if (TREE_OPERAND (t, 2) == NULL_TREE)
2903 tree low = unshare_expr (array_ref_low_bound (t));
2904 if (!is_gimple_min_invariant (low))
2906 TREE_OPERAND (t, 2) = low;
2907 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2908 post_p, is_gimple_reg,
2909 fb_rvalue);
2910 ret = MIN (ret, tret);
2913 else
2915 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2916 is_gimple_reg, fb_rvalue);
2917 ret = MIN (ret, tret);
2920 if (TREE_OPERAND (t, 3) == NULL_TREE)
2922 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
2923 tree elmt_size = unshare_expr (array_ref_element_size (t));
2924 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
2926 /* Divide the element size by the alignment of the element
2927 type (above). */
2928 elmt_size
2929 = size_binop_loc (loc, EXACT_DIV_EXPR, elmt_size, factor);
2931 if (!is_gimple_min_invariant (elmt_size))
2933 TREE_OPERAND (t, 3) = elmt_size;
2934 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
2935 post_p, is_gimple_reg,
2936 fb_rvalue);
2937 ret = MIN (ret, tret);
2940 else
2942 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
2943 is_gimple_reg, fb_rvalue);
2944 ret = MIN (ret, tret);
2947 else if (TREE_CODE (t) == COMPONENT_REF)
2949 /* Set the field offset into T and gimplify it. */
2950 if (TREE_OPERAND (t, 2) == NULL_TREE)
2952 tree offset = unshare_expr (component_ref_field_offset (t));
2953 tree field = TREE_OPERAND (t, 1);
2954 tree factor
2955 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
2957 /* Divide the offset by its alignment. */
2958 offset = size_binop_loc (loc, EXACT_DIV_EXPR, offset, factor);
2960 if (!is_gimple_min_invariant (offset))
2962 TREE_OPERAND (t, 2) = offset;
2963 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2964 post_p, is_gimple_reg,
2965 fb_rvalue);
2966 ret = MIN (ret, tret);
2969 else
2971 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2972 is_gimple_reg, fb_rvalue);
2973 ret = MIN (ret, tret);
2978 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
2979 so as to match the min_lval predicate. Failure to do so may result
2980 in the creation of large aggregate temporaries. */
2981 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
2982 fallback | fb_lvalue);
2983 ret = MIN (ret, tret);
2985 /* And finally, the indices and operands of ARRAY_REF. During this
2986 loop we also remove any useless conversions. */
2987 for (; expr_stack.length () > 0; )
2989 tree t = expr_stack.pop ();
2991 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2993 /* Gimplify the dimension. */
2994 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
2996 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
2997 is_gimple_val, fb_rvalue);
2998 ret = MIN (ret, tret);
3002 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
3004 /* The innermost expression P may have originally had
3005 TREE_SIDE_EFFECTS set which would have caused all the outer
3006 expressions in *EXPR_P leading to P to also have had
3007 TREE_SIDE_EFFECTS set. */
3008 recalculate_side_effects (t);
3011 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3012 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
3014 canonicalize_component_ref (expr_p);
3017 expr_stack.release ();
3019 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
3021 return ret;
3024 /* Gimplify the self modifying expression pointed to by EXPR_P
3025 (++, --, +=, -=).
3027 PRE_P points to the list where side effects that must happen before
3028 *EXPR_P should be stored.
3030 POST_P points to the list where side effects that must happen after
3031 *EXPR_P should be stored.
3033 WANT_VALUE is nonzero iff we want to use the value of this expression
3034 in another expression.
3036 ARITH_TYPE is the type the computation should be performed in. */
3038 enum gimplify_status
3039 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3040 bool want_value, tree arith_type)
3042 enum tree_code code;
3043 tree lhs, lvalue, rhs, t1;
3044 gimple_seq post = NULL, *orig_post_p = post_p;
3045 bool postfix;
3046 enum tree_code arith_code;
3047 enum gimplify_status ret;
3048 location_t loc = EXPR_LOCATION (*expr_p);
3050 code = TREE_CODE (*expr_p);
3052 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3053 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3055 /* Prefix or postfix? */
3056 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3057 /* Faster to treat as prefix if result is not used. */
3058 postfix = want_value;
3059 else
3060 postfix = false;
3062 /* For postfix, make sure the inner expression's post side effects
3063 are executed after side effects from this expression. */
3064 if (postfix)
3065 post_p = &post;
3067 /* Add or subtract? */
3068 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3069 arith_code = PLUS_EXPR;
3070 else
3071 arith_code = MINUS_EXPR;
3073 /* Gimplify the LHS into a GIMPLE lvalue. */
3074 lvalue = TREE_OPERAND (*expr_p, 0);
3075 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3076 if (ret == GS_ERROR)
3077 return ret;
3079 /* Extract the operands to the arithmetic operation. */
3080 lhs = lvalue;
3081 rhs = TREE_OPERAND (*expr_p, 1);
3083 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3084 that as the result value and in the postqueue operation. */
3085 if (postfix)
3087 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3088 if (ret == GS_ERROR)
3089 return ret;
3091 lhs = get_initialized_tmp_var (lhs, pre_p, NULL);
3094 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3095 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3097 rhs = convert_to_ptrofftype_loc (loc, rhs);
3098 if (arith_code == MINUS_EXPR)
3099 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3100 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3102 else
3103 t1 = fold_convert (TREE_TYPE (*expr_p),
3104 fold_build2 (arith_code, arith_type,
3105 fold_convert (arith_type, lhs),
3106 fold_convert (arith_type, rhs)));
3108 if (postfix)
3110 gimplify_assign (lvalue, t1, pre_p);
3111 gimplify_seq_add_seq (orig_post_p, post);
3112 *expr_p = lhs;
3113 return GS_ALL_DONE;
3115 else
3117 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3118 return GS_OK;
3122 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3124 static void
3125 maybe_with_size_expr (tree *expr_p)
3127 tree expr = *expr_p;
3128 tree type = TREE_TYPE (expr);
3129 tree size;
3131 /* If we've already wrapped this or the type is error_mark_node, we can't do
3132 anything. */
3133 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3134 || type == error_mark_node)
3135 return;
3137 /* If the size isn't known or is a constant, we have nothing to do. */
3138 size = TYPE_SIZE_UNIT (type);
3139 if (!size || poly_int_tree_p (size))
3140 return;
3142 /* Otherwise, make a WITH_SIZE_EXPR. */
3143 size = unshare_expr (size);
3144 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3145 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3148 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3149 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3150 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3151 gimplified to an SSA name. */
3153 enum gimplify_status
3154 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3155 bool allow_ssa)
3157 bool (*test) (tree);
3158 fallback_t fb;
3160 /* In general, we allow lvalues for function arguments to avoid
3161 extra overhead of copying large aggregates out of even larger
3162 aggregates into temporaries only to copy the temporaries to
3163 the argument list. Make optimizers happy by pulling out to
3164 temporaries those types that fit in registers. */
3165 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3166 test = is_gimple_val, fb = fb_rvalue;
3167 else
3169 test = is_gimple_lvalue, fb = fb_either;
3170 /* Also strip a TARGET_EXPR that would force an extra copy. */
3171 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3173 tree init = TARGET_EXPR_INITIAL (*arg_p);
3174 if (init
3175 && !VOID_TYPE_P (TREE_TYPE (init)))
3176 *arg_p = init;
3180 /* If this is a variable sized type, we must remember the size. */
3181 maybe_with_size_expr (arg_p);
3183 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3184 /* Make sure arguments have the same location as the function call
3185 itself. */
3186 protected_set_expr_location (*arg_p, call_location);
3188 /* There is a sequence point before a function call. Side effects in
3189 the argument list must occur before the actual call. So, when
3190 gimplifying arguments, force gimplify_expr to use an internal
3191 post queue which is then appended to the end of PRE_P. */
3192 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3195 /* Don't fold inside offloading or taskreg regions: it can break code by
3196 adding decl references that weren't in the source. We'll do it during
3197 omplower pass instead. */
3199 static bool
3200 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3202 struct gimplify_omp_ctx *ctx;
3203 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3204 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3205 return false;
3206 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3207 return false;
3208 /* Delay folding of builtins until the IL is in consistent state
3209 so the diagnostic machinery can do a better job. */
3210 if (gimple_call_builtin_p (gsi_stmt (*gsi)))
3211 return false;
3212 return fold_stmt (gsi);
3215 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3216 WANT_VALUE is true if the result of the call is desired. */
3218 static enum gimplify_status
3219 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3221 tree fndecl, parms, p, fnptrtype;
3222 enum gimplify_status ret;
3223 int i, nargs;
3224 gcall *call;
3225 bool builtin_va_start_p = false;
3226 location_t loc = EXPR_LOCATION (*expr_p);
3228 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3230 /* For reliable diagnostics during inlining, it is necessary that
3231 every call_expr be annotated with file and line. */
3232 if (! EXPR_HAS_LOCATION (*expr_p))
3233 SET_EXPR_LOCATION (*expr_p, input_location);
3235 /* Gimplify internal functions created in the FEs. */
3236 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3238 if (want_value)
3239 return GS_ALL_DONE;
3241 nargs = call_expr_nargs (*expr_p);
3242 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3243 auto_vec<tree> vargs (nargs);
3245 for (i = 0; i < nargs; i++)
3247 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3248 EXPR_LOCATION (*expr_p));
3249 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3252 gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3253 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3254 gimplify_seq_add_stmt (pre_p, call);
3255 return GS_ALL_DONE;
3258 /* This may be a call to a builtin function.
3260 Builtin function calls may be transformed into different
3261 (and more efficient) builtin function calls under certain
3262 circumstances. Unfortunately, gimplification can muck things
3263 up enough that the builtin expanders are not aware that certain
3264 transformations are still valid.
3266 So we attempt transformation/gimplification of the call before
3267 we gimplify the CALL_EXPR. At this time we do not manage to
3268 transform all calls in the same manner as the expanders do, but
3269 we do transform most of them. */
3270 fndecl = get_callee_fndecl (*expr_p);
3271 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3272 switch (DECL_FUNCTION_CODE (fndecl))
3274 CASE_BUILT_IN_ALLOCA:
3275 /* If the call has been built for a variable-sized object, then we
3276 want to restore the stack level when the enclosing BIND_EXPR is
3277 exited to reclaim the allocated space; otherwise, we precisely
3278 need to do the opposite and preserve the latest stack level. */
3279 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3280 gimplify_ctxp->save_stack = true;
3281 else
3282 gimplify_ctxp->keep_stack = true;
3283 break;
3285 case BUILT_IN_VA_START:
3287 builtin_va_start_p = TRUE;
3288 if (call_expr_nargs (*expr_p) < 2)
3290 error ("too few arguments to function %<va_start%>");
3291 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3292 return GS_OK;
3295 if (fold_builtin_next_arg (*expr_p, true))
3297 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3298 return GS_OK;
3300 break;
3303 case BUILT_IN_EH_RETURN:
3304 cfun->calls_eh_return = true;
3305 break;
3307 default:
3310 if (fndecl && fndecl_built_in_p (fndecl))
3312 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3313 if (new_tree && new_tree != *expr_p)
3315 /* There was a transformation of this call which computes the
3316 same value, but in a more efficient way. Return and try
3317 again. */
3318 *expr_p = new_tree;
3319 return GS_OK;
3323 /* Remember the original function pointer type. */
3324 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3326 /* There is a sequence point before the call, so any side effects in
3327 the calling expression must occur before the actual call. Force
3328 gimplify_expr to use an internal post queue. */
3329 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3330 is_gimple_call_addr, fb_rvalue);
3332 nargs = call_expr_nargs (*expr_p);
3334 /* Get argument types for verification. */
3335 fndecl = get_callee_fndecl (*expr_p);
3336 parms = NULL_TREE;
3337 if (fndecl)
3338 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3339 else
3340 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3342 if (fndecl && DECL_ARGUMENTS (fndecl))
3343 p = DECL_ARGUMENTS (fndecl);
3344 else if (parms)
3345 p = parms;
3346 else
3347 p = NULL_TREE;
3348 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3351 /* If the last argument is __builtin_va_arg_pack () and it is not
3352 passed as a named argument, decrease the number of CALL_EXPR
3353 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3354 if (!p
3355 && i < nargs
3356 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3358 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3359 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3361 if (last_arg_fndecl
3362 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3364 tree call = *expr_p;
3366 --nargs;
3367 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3368 CALL_EXPR_FN (call),
3369 nargs, CALL_EXPR_ARGP (call));
3371 /* Copy all CALL_EXPR flags, location and block, except
3372 CALL_EXPR_VA_ARG_PACK flag. */
3373 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3374 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3375 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3376 = CALL_EXPR_RETURN_SLOT_OPT (call);
3377 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3378 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3380 /* Set CALL_EXPR_VA_ARG_PACK. */
3381 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3385 /* If the call returns twice then after building the CFG the call
3386 argument computations will no longer dominate the call because
3387 we add an abnormal incoming edge to the call. So do not use SSA
3388 vars there. */
3389 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3391 /* Gimplify the function arguments. */
3392 if (nargs > 0)
3394 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3395 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3396 PUSH_ARGS_REVERSED ? i-- : i++)
3398 enum gimplify_status t;
3400 /* Avoid gimplifying the second argument to va_start, which needs to
3401 be the plain PARM_DECL. */
3402 if ((i != 1) || !builtin_va_start_p)
3404 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3405 EXPR_LOCATION (*expr_p), ! returns_twice);
3407 if (t == GS_ERROR)
3408 ret = GS_ERROR;
3413 /* Gimplify the static chain. */
3414 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3416 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3417 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3418 else
3420 enum gimplify_status t;
3421 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3422 EXPR_LOCATION (*expr_p), ! returns_twice);
3423 if (t == GS_ERROR)
3424 ret = GS_ERROR;
3428 /* Verify the function result. */
3429 if (want_value && fndecl
3430 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3432 error_at (loc, "using result of function returning %<void%>");
3433 ret = GS_ERROR;
3436 /* Try this again in case gimplification exposed something. */
3437 if (ret != GS_ERROR)
3439 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3441 if (new_tree && new_tree != *expr_p)
3443 /* There was a transformation of this call which computes the
3444 same value, but in a more efficient way. Return and try
3445 again. */
3446 *expr_p = new_tree;
3447 return GS_OK;
3450 else
3452 *expr_p = error_mark_node;
3453 return GS_ERROR;
3456 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3457 decl. This allows us to eliminate redundant or useless
3458 calls to "const" functions. */
3459 if (TREE_CODE (*expr_p) == CALL_EXPR)
3461 int flags = call_expr_flags (*expr_p);
3462 if (flags & (ECF_CONST | ECF_PURE)
3463 /* An infinite loop is considered a side effect. */
3464 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3465 TREE_SIDE_EFFECTS (*expr_p) = 0;
3468 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3469 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3470 form and delegate the creation of a GIMPLE_CALL to
3471 gimplify_modify_expr. This is always possible because when
3472 WANT_VALUE is true, the caller wants the result of this call into
3473 a temporary, which means that we will emit an INIT_EXPR in
3474 internal_get_tmp_var which will then be handled by
3475 gimplify_modify_expr. */
3476 if (!want_value)
3478 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3479 have to do is replicate it as a GIMPLE_CALL tuple. */
3480 gimple_stmt_iterator gsi;
3481 call = gimple_build_call_from_tree (*expr_p, fnptrtype);
3482 notice_special_calls (call);
3483 gimplify_seq_add_stmt (pre_p, call);
3484 gsi = gsi_last (*pre_p);
3485 maybe_fold_stmt (&gsi);
3486 *expr_p = NULL_TREE;
3488 else
3489 /* Remember the original function type. */
3490 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3491 CALL_EXPR_FN (*expr_p));
3493 return ret;
3496 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3497 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3499 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3500 condition is true or false, respectively. If null, we should generate
3501 our own to skip over the evaluation of this specific expression.
3503 LOCUS is the source location of the COND_EXPR.
3505 This function is the tree equivalent of do_jump.
3507 shortcut_cond_r should only be called by shortcut_cond_expr. */
3509 static tree
3510 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3511 location_t locus)
3513 tree local_label = NULL_TREE;
3514 tree t, expr = NULL;
3516 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3517 retain the shortcut semantics. Just insert the gotos here;
3518 shortcut_cond_expr will append the real blocks later. */
3519 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3521 location_t new_locus;
3523 /* Turn if (a && b) into
3525 if (a); else goto no;
3526 if (b) goto yes; else goto no;
3527 (no:) */
3529 if (false_label_p == NULL)
3530 false_label_p = &local_label;
3532 /* Keep the original source location on the first 'if'. */
3533 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3534 append_to_statement_list (t, &expr);
3536 /* Set the source location of the && on the second 'if'. */
3537 new_locus = rexpr_location (pred, locus);
3538 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3539 new_locus);
3540 append_to_statement_list (t, &expr);
3542 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3544 location_t new_locus;
3546 /* Turn if (a || b) into
3548 if (a) goto yes;
3549 if (b) goto yes; else goto no;
3550 (yes:) */
3552 if (true_label_p == NULL)
3553 true_label_p = &local_label;
3555 /* Keep the original source location on the first 'if'. */
3556 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3557 append_to_statement_list (t, &expr);
3559 /* Set the source location of the || on the second 'if'. */
3560 new_locus = rexpr_location (pred, locus);
3561 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3562 new_locus);
3563 append_to_statement_list (t, &expr);
3565 else if (TREE_CODE (pred) == COND_EXPR
3566 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3567 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3569 location_t new_locus;
3571 /* As long as we're messing with gotos, turn if (a ? b : c) into
3572 if (a)
3573 if (b) goto yes; else goto no;
3574 else
3575 if (c) goto yes; else goto no;
3577 Don't do this if one of the arms has void type, which can happen
3578 in C++ when the arm is throw. */
3580 /* Keep the original source location on the first 'if'. Set the source
3581 location of the ? on the second 'if'. */
3582 new_locus = rexpr_location (pred, locus);
3583 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3584 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3585 false_label_p, locus),
3586 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3587 false_label_p, new_locus));
3589 else
3591 expr = build3 (COND_EXPR, void_type_node, pred,
3592 build_and_jump (true_label_p),
3593 build_and_jump (false_label_p));
3594 SET_EXPR_LOCATION (expr, locus);
3597 if (local_label)
3599 t = build1 (LABEL_EXPR, void_type_node, local_label);
3600 append_to_statement_list (t, &expr);
3603 return expr;
3606 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3607 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3608 statement, if it is the last one. Otherwise, return NULL. */
3610 static tree
3611 find_goto (tree expr)
3613 if (!expr)
3614 return NULL_TREE;
3616 if (TREE_CODE (expr) == GOTO_EXPR)
3617 return expr;
3619 if (TREE_CODE (expr) != STATEMENT_LIST)
3620 return NULL_TREE;
3622 tree_stmt_iterator i = tsi_start (expr);
3624 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
3625 tsi_next (&i);
3627 if (!tsi_one_before_end_p (i))
3628 return NULL_TREE;
3630 return find_goto (tsi_stmt (i));
3633 /* Same as find_goto, except that it returns NULL if the destination
3634 is not a LABEL_DECL. */
3636 static inline tree
3637 find_goto_label (tree expr)
3639 tree dest = find_goto (expr);
3640 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
3641 return dest;
3642 return NULL_TREE;
3645 /* Given a conditional expression EXPR with short-circuit boolean
3646 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3647 predicate apart into the equivalent sequence of conditionals. */
3649 static tree
3650 shortcut_cond_expr (tree expr)
3652 tree pred = TREE_OPERAND (expr, 0);
3653 tree then_ = TREE_OPERAND (expr, 1);
3654 tree else_ = TREE_OPERAND (expr, 2);
3655 tree true_label, false_label, end_label, t;
3656 tree *true_label_p;
3657 tree *false_label_p;
3658 bool emit_end, emit_false, jump_over_else;
3659 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3660 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3662 /* First do simple transformations. */
3663 if (!else_se)
3665 /* If there is no 'else', turn
3666 if (a && b) then c
3667 into
3668 if (a) if (b) then c. */
3669 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3671 /* Keep the original source location on the first 'if'. */
3672 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3673 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3674 /* Set the source location of the && on the second 'if'. */
3675 if (rexpr_has_location (pred))
3676 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3677 then_ = shortcut_cond_expr (expr);
3678 then_se = then_ && TREE_SIDE_EFFECTS (then_);
3679 pred = TREE_OPERAND (pred, 0);
3680 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
3681 SET_EXPR_LOCATION (expr, locus);
3685 if (!then_se)
3687 /* If there is no 'then', turn
3688 if (a || b); else d
3689 into
3690 if (a); else if (b); else d. */
3691 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3693 /* Keep the original source location on the first 'if'. */
3694 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3695 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3696 /* Set the source location of the || on the second 'if'. */
3697 if (rexpr_has_location (pred))
3698 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3699 else_ = shortcut_cond_expr (expr);
3700 else_se = else_ && TREE_SIDE_EFFECTS (else_);
3701 pred = TREE_OPERAND (pred, 0);
3702 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
3703 SET_EXPR_LOCATION (expr, locus);
3707 /* If we're done, great. */
3708 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
3709 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
3710 return expr;
3712 /* Otherwise we need to mess with gotos. Change
3713 if (a) c; else d;
3715 if (a); else goto no;
3716 c; goto end;
3717 no: d; end:
3718 and recursively gimplify the condition. */
3720 true_label = false_label = end_label = NULL_TREE;
3722 /* If our arms just jump somewhere, hijack those labels so we don't
3723 generate jumps to jumps. */
3725 if (tree then_goto = find_goto_label (then_))
3727 true_label = GOTO_DESTINATION (then_goto);
3728 then_ = NULL;
3729 then_se = false;
3732 if (tree else_goto = find_goto_label (else_))
3734 false_label = GOTO_DESTINATION (else_goto);
3735 else_ = NULL;
3736 else_se = false;
3739 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3740 if (true_label)
3741 true_label_p = &true_label;
3742 else
3743 true_label_p = NULL;
3745 /* The 'else' branch also needs a label if it contains interesting code. */
3746 if (false_label || else_se)
3747 false_label_p = &false_label;
3748 else
3749 false_label_p = NULL;
3751 /* If there was nothing else in our arms, just forward the label(s). */
3752 if (!then_se && !else_se)
3753 return shortcut_cond_r (pred, true_label_p, false_label_p,
3754 EXPR_LOC_OR_LOC (expr, input_location));
3756 /* If our last subexpression already has a terminal label, reuse it. */
3757 if (else_se)
3758 t = expr_last (else_);
3759 else if (then_se)
3760 t = expr_last (then_);
3761 else
3762 t = NULL;
3763 if (t && TREE_CODE (t) == LABEL_EXPR)
3764 end_label = LABEL_EXPR_LABEL (t);
3766 /* If we don't care about jumping to the 'else' branch, jump to the end
3767 if the condition is false. */
3768 if (!false_label_p)
3769 false_label_p = &end_label;
3771 /* We only want to emit these labels if we aren't hijacking them. */
3772 emit_end = (end_label == NULL_TREE);
3773 emit_false = (false_label == NULL_TREE);
3775 /* We only emit the jump over the else clause if we have to--if the
3776 then clause may fall through. Otherwise we can wind up with a
3777 useless jump and a useless label at the end of gimplified code,
3778 which will cause us to think that this conditional as a whole
3779 falls through even if it doesn't. If we then inline a function
3780 which ends with such a condition, that can cause us to issue an
3781 inappropriate warning about control reaching the end of a
3782 non-void function. */
3783 jump_over_else = block_may_fallthru (then_);
3785 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
3786 EXPR_LOC_OR_LOC (expr, input_location));
3788 expr = NULL;
3789 append_to_statement_list (pred, &expr);
3791 append_to_statement_list (then_, &expr);
3792 if (else_se)
3794 if (jump_over_else)
3796 tree last = expr_last (expr);
3797 t = build_and_jump (&end_label);
3798 if (rexpr_has_location (last))
3799 SET_EXPR_LOCATION (t, rexpr_location (last));
3800 append_to_statement_list (t, &expr);
3802 if (emit_false)
3804 t = build1 (LABEL_EXPR, void_type_node, false_label);
3805 append_to_statement_list (t, &expr);
3807 append_to_statement_list (else_, &expr);
3809 if (emit_end && end_label)
3811 t = build1 (LABEL_EXPR, void_type_node, end_label);
3812 append_to_statement_list (t, &expr);
3815 return expr;
3818 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
3820 tree
3821 gimple_boolify (tree expr)
3823 tree type = TREE_TYPE (expr);
3824 location_t loc = EXPR_LOCATION (expr);
3826 if (TREE_CODE (expr) == NE_EXPR
3827 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
3828 && integer_zerop (TREE_OPERAND (expr, 1)))
3830 tree call = TREE_OPERAND (expr, 0);
3831 tree fn = get_callee_fndecl (call);
3833 /* For __builtin_expect ((long) (x), y) recurse into x as well
3834 if x is truth_value_p. */
3835 if (fn
3836 && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
3837 && call_expr_nargs (call) == 2)
3839 tree arg = CALL_EXPR_ARG (call, 0);
3840 if (arg)
3842 if (TREE_CODE (arg) == NOP_EXPR
3843 && TREE_TYPE (arg) == TREE_TYPE (call))
3844 arg = TREE_OPERAND (arg, 0);
3845 if (truth_value_p (TREE_CODE (arg)))
3847 arg = gimple_boolify (arg);
3848 CALL_EXPR_ARG (call, 0)
3849 = fold_convert_loc (loc, TREE_TYPE (call), arg);
3855 switch (TREE_CODE (expr))
3857 case TRUTH_AND_EXPR:
3858 case TRUTH_OR_EXPR:
3859 case TRUTH_XOR_EXPR:
3860 case TRUTH_ANDIF_EXPR:
3861 case TRUTH_ORIF_EXPR:
3862 /* Also boolify the arguments of truth exprs. */
3863 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
3864 /* FALLTHRU */
3866 case TRUTH_NOT_EXPR:
3867 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3869 /* These expressions always produce boolean results. */
3870 if (TREE_CODE (type) != BOOLEAN_TYPE)
3871 TREE_TYPE (expr) = boolean_type_node;
3872 return expr;
3874 case ANNOTATE_EXPR:
3875 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
3877 case annot_expr_ivdep_kind:
3878 case annot_expr_unroll_kind:
3879 case annot_expr_no_vector_kind:
3880 case annot_expr_vector_kind:
3881 case annot_expr_parallel_kind:
3882 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3883 if (TREE_CODE (type) != BOOLEAN_TYPE)
3884 TREE_TYPE (expr) = boolean_type_node;
3885 return expr;
3886 default:
3887 gcc_unreachable ();
3890 default:
3891 if (COMPARISON_CLASS_P (expr))
3893 /* There expressions always prduce boolean results. */
3894 if (TREE_CODE (type) != BOOLEAN_TYPE)
3895 TREE_TYPE (expr) = boolean_type_node;
3896 return expr;
3898 /* Other expressions that get here must have boolean values, but
3899 might need to be converted to the appropriate mode. */
3900 if (TREE_CODE (type) == BOOLEAN_TYPE)
3901 return expr;
3902 return fold_convert_loc (loc, boolean_type_node, expr);
3906 /* Given a conditional expression *EXPR_P without side effects, gimplify
3907 its operands. New statements are inserted to PRE_P. */
3909 static enum gimplify_status
3910 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
3912 tree expr = *expr_p, cond;
3913 enum gimplify_status ret, tret;
3914 enum tree_code code;
3916 cond = gimple_boolify (COND_EXPR_COND (expr));
3918 /* We need to handle && and || specially, as their gimplification
3919 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
3920 code = TREE_CODE (cond);
3921 if (code == TRUTH_ANDIF_EXPR)
3922 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
3923 else if (code == TRUTH_ORIF_EXPR)
3924 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
3925 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
3926 COND_EXPR_COND (*expr_p) = cond;
3928 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
3929 is_gimple_val, fb_rvalue);
3930 ret = MIN (ret, tret);
3931 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
3932 is_gimple_val, fb_rvalue);
3934 return MIN (ret, tret);
3937 /* Return true if evaluating EXPR could trap.
3938 EXPR is GENERIC, while tree_could_trap_p can be called
3939 only on GIMPLE. */
3941 bool
3942 generic_expr_could_trap_p (tree expr)
3944 unsigned i, n;
3946 if (!expr || is_gimple_val (expr))
3947 return false;
3949 if (!EXPR_P (expr) || tree_could_trap_p (expr))
3950 return true;
3952 n = TREE_OPERAND_LENGTH (expr);
3953 for (i = 0; i < n; i++)
3954 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
3955 return true;
3957 return false;
3960 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
3961 into
3963 if (p) if (p)
3964 t1 = a; a;
3965 else or else
3966 t1 = b; b;
3969 The second form is used when *EXPR_P is of type void.
3971 PRE_P points to the list where side effects that must happen before
3972 *EXPR_P should be stored. */
3974 static enum gimplify_status
3975 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
3977 tree expr = *expr_p;
3978 tree type = TREE_TYPE (expr);
3979 location_t loc = EXPR_LOCATION (expr);
3980 tree tmp, arm1, arm2;
3981 enum gimplify_status ret;
3982 tree label_true, label_false, label_cont;
3983 bool have_then_clause_p, have_else_clause_p;
3984 gcond *cond_stmt;
3985 enum tree_code pred_code;
3986 gimple_seq seq = NULL;
3988 /* If this COND_EXPR has a value, copy the values into a temporary within
3989 the arms. */
3990 if (!VOID_TYPE_P (type))
3992 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
3993 tree result;
3995 /* If either an rvalue is ok or we do not require an lvalue, create the
3996 temporary. But we cannot do that if the type is addressable. */
3997 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
3998 && !TREE_ADDRESSABLE (type))
4000 if (gimplify_ctxp->allow_rhs_cond_expr
4001 /* If either branch has side effects or could trap, it can't be
4002 evaluated unconditionally. */
4003 && !TREE_SIDE_EFFECTS (then_)
4004 && !generic_expr_could_trap_p (then_)
4005 && !TREE_SIDE_EFFECTS (else_)
4006 && !generic_expr_could_trap_p (else_))
4007 return gimplify_pure_cond_expr (expr_p, pre_p);
4009 tmp = create_tmp_var (type, "iftmp");
4010 result = tmp;
4013 /* Otherwise, only create and copy references to the values. */
4014 else
4016 type = build_pointer_type (type);
4018 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4019 then_ = build_fold_addr_expr_loc (loc, then_);
4021 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4022 else_ = build_fold_addr_expr_loc (loc, else_);
4024 expr
4025 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
4027 tmp = create_tmp_var (type, "iftmp");
4028 result = build_simple_mem_ref_loc (loc, tmp);
4031 /* Build the new then clause, `tmp = then_;'. But don't build the
4032 assignment if the value is void; in C++ it can be if it's a throw. */
4033 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4034 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
4036 /* Similarly, build the new else clause, `tmp = else_;'. */
4037 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4038 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
4040 TREE_TYPE (expr) = void_type_node;
4041 recalculate_side_effects (expr);
4043 /* Move the COND_EXPR to the prequeue. */
4044 gimplify_stmt (&expr, pre_p);
4046 *expr_p = result;
4047 return GS_ALL_DONE;
4050 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4051 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4052 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4053 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4055 /* Make sure the condition has BOOLEAN_TYPE. */
4056 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4058 /* Break apart && and || conditions. */
4059 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4060 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4062 expr = shortcut_cond_expr (expr);
4064 if (expr != *expr_p)
4066 *expr_p = expr;
4068 /* We can't rely on gimplify_expr to re-gimplify the expanded
4069 form properly, as cleanups might cause the target labels to be
4070 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4071 set up a conditional context. */
4072 gimple_push_condition ();
4073 gimplify_stmt (expr_p, &seq);
4074 gimple_pop_condition (pre_p);
4075 gimple_seq_add_seq (pre_p, seq);
4077 return GS_ALL_DONE;
4081 /* Now do the normal gimplification. */
4083 /* Gimplify condition. */
4084 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, is_gimple_condexpr,
4085 fb_rvalue);
4086 if (ret == GS_ERROR)
4087 return GS_ERROR;
4088 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4090 gimple_push_condition ();
4092 have_then_clause_p = have_else_clause_p = false;
4093 label_true = find_goto_label (TREE_OPERAND (expr, 1));
4094 if (label_true
4095 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4096 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4097 have different locations, otherwise we end up with incorrect
4098 location information on the branches. */
4099 && (optimize
4100 || !EXPR_HAS_LOCATION (expr)
4101 || !rexpr_has_location (label_true)
4102 || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4104 have_then_clause_p = true;
4105 label_true = GOTO_DESTINATION (label_true);
4107 else
4108 label_true = create_artificial_label (UNKNOWN_LOCATION);
4109 label_false = find_goto_label (TREE_OPERAND (expr, 2));
4110 if (label_false
4111 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4112 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4113 have different locations, otherwise we end up with incorrect
4114 location information on the branches. */
4115 && (optimize
4116 || !EXPR_HAS_LOCATION (expr)
4117 || !rexpr_has_location (label_false)
4118 || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4120 have_else_clause_p = true;
4121 label_false = GOTO_DESTINATION (label_false);
4123 else
4124 label_false = create_artificial_label (UNKNOWN_LOCATION);
4126 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4127 &arm2);
4128 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4129 label_false);
4130 gimple_set_no_warning (cond_stmt, TREE_NO_WARNING (COND_EXPR_COND (expr)));
4131 gimplify_seq_add_stmt (&seq, cond_stmt);
4132 gimple_stmt_iterator gsi = gsi_last (seq);
4133 maybe_fold_stmt (&gsi);
4135 label_cont = NULL_TREE;
4136 if (!have_then_clause_p)
4138 /* For if (...) {} else { code; } put label_true after
4139 the else block. */
4140 if (TREE_OPERAND (expr, 1) == NULL_TREE
4141 && !have_else_clause_p
4142 && TREE_OPERAND (expr, 2) != NULL_TREE)
4143 label_cont = label_true;
4144 else
4146 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4147 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4148 /* For if (...) { code; } else {} or
4149 if (...) { code; } else goto label; or
4150 if (...) { code; return; } else { ... }
4151 label_cont isn't needed. */
4152 if (!have_else_clause_p
4153 && TREE_OPERAND (expr, 2) != NULL_TREE
4154 && gimple_seq_may_fallthru (seq))
4156 gimple *g;
4157 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4159 g = gimple_build_goto (label_cont);
4161 /* GIMPLE_COND's are very low level; they have embedded
4162 gotos. This particular embedded goto should not be marked
4163 with the location of the original COND_EXPR, as it would
4164 correspond to the COND_EXPR's condition, not the ELSE or the
4165 THEN arms. To avoid marking it with the wrong location, flag
4166 it as "no location". */
4167 gimple_set_do_not_emit_location (g);
4169 gimplify_seq_add_stmt (&seq, g);
4173 if (!have_else_clause_p)
4175 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4176 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4178 if (label_cont)
4179 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4181 gimple_pop_condition (pre_p);
4182 gimple_seq_add_seq (pre_p, seq);
4184 if (ret == GS_ERROR)
4185 ; /* Do nothing. */
4186 else if (have_then_clause_p || have_else_clause_p)
4187 ret = GS_ALL_DONE;
4188 else
4190 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4191 expr = TREE_OPERAND (expr, 0);
4192 gimplify_stmt (&expr, pre_p);
4195 *expr_p = NULL;
4196 return ret;
4199 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4200 to be marked addressable.
4202 We cannot rely on such an expression being directly markable if a temporary
4203 has been created by the gimplification. In this case, we create another
4204 temporary and initialize it with a copy, which will become a store after we
4205 mark it addressable. This can happen if the front-end passed us something
4206 that it could not mark addressable yet, like a Fortran pass-by-reference
4207 parameter (int) floatvar. */
4209 static void
4210 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4212 while (handled_component_p (*expr_p))
4213 expr_p = &TREE_OPERAND (*expr_p, 0);
4214 if (is_gimple_reg (*expr_p))
4216 /* Do not allow an SSA name as the temporary. */
4217 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
4218 DECL_GIMPLE_REG_P (var) = 0;
4219 *expr_p = var;
4223 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4224 a call to __builtin_memcpy. */
4226 static enum gimplify_status
4227 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4228 gimple_seq *seq_p)
4230 tree t, to, to_ptr, from, from_ptr;
4231 gcall *gs;
4232 location_t loc = EXPR_LOCATION (*expr_p);
4234 to = TREE_OPERAND (*expr_p, 0);
4235 from = TREE_OPERAND (*expr_p, 1);
4237 /* Mark the RHS addressable. Beware that it may not be possible to do so
4238 directly if a temporary has been created by the gimplification. */
4239 prepare_gimple_addressable (&from, seq_p);
4241 mark_addressable (from);
4242 from_ptr = build_fold_addr_expr_loc (loc, from);
4243 gimplify_arg (&from_ptr, seq_p, loc);
4245 mark_addressable (to);
4246 to_ptr = build_fold_addr_expr_loc (loc, to);
4247 gimplify_arg (&to_ptr, seq_p, loc);
4249 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4251 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4253 if (want_value)
4255 /* tmp = memcpy() */
4256 t = create_tmp_var (TREE_TYPE (to_ptr));
4257 gimple_call_set_lhs (gs, t);
4258 gimplify_seq_add_stmt (seq_p, gs);
4260 *expr_p = build_simple_mem_ref (t);
4261 return GS_ALL_DONE;
4264 gimplify_seq_add_stmt (seq_p, gs);
4265 *expr_p = NULL;
4266 return GS_ALL_DONE;
4269 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4270 a call to __builtin_memset. In this case we know that the RHS is
4271 a CONSTRUCTOR with an empty element list. */
4273 static enum gimplify_status
4274 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4275 gimple_seq *seq_p)
4277 tree t, from, to, to_ptr;
4278 gcall *gs;
4279 location_t loc = EXPR_LOCATION (*expr_p);
4281 /* Assert our assumptions, to abort instead of producing wrong code
4282 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4283 not be immediately exposed. */
4284 from = TREE_OPERAND (*expr_p, 1);
4285 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4286 from = TREE_OPERAND (from, 0);
4288 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4289 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4291 /* Now proceed. */
4292 to = TREE_OPERAND (*expr_p, 0);
4294 to_ptr = build_fold_addr_expr_loc (loc, to);
4295 gimplify_arg (&to_ptr, seq_p, loc);
4296 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4298 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4300 if (want_value)
4302 /* tmp = memset() */
4303 t = create_tmp_var (TREE_TYPE (to_ptr));
4304 gimple_call_set_lhs (gs, t);
4305 gimplify_seq_add_stmt (seq_p, gs);
4307 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4308 return GS_ALL_DONE;
4311 gimplify_seq_add_stmt (seq_p, gs);
4312 *expr_p = NULL;
4313 return GS_ALL_DONE;
4316 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4317 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4318 assignment. Return non-null if we detect a potential overlap. */
4320 struct gimplify_init_ctor_preeval_data
4322 /* The base decl of the lhs object. May be NULL, in which case we
4323 have to assume the lhs is indirect. */
4324 tree lhs_base_decl;
4326 /* The alias set of the lhs object. */
4327 alias_set_type lhs_alias_set;
4330 static tree
4331 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4333 struct gimplify_init_ctor_preeval_data *data
4334 = (struct gimplify_init_ctor_preeval_data *) xdata;
4335 tree t = *tp;
4337 /* If we find the base object, obviously we have overlap. */
4338 if (data->lhs_base_decl == t)
4339 return t;
4341 /* If the constructor component is indirect, determine if we have a
4342 potential overlap with the lhs. The only bits of information we
4343 have to go on at this point are addressability and alias sets. */
4344 if ((INDIRECT_REF_P (t)
4345 || TREE_CODE (t) == MEM_REF)
4346 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4347 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4348 return t;
4350 /* If the constructor component is a call, determine if it can hide a
4351 potential overlap with the lhs through an INDIRECT_REF like above.
4352 ??? Ugh - this is completely broken. In fact this whole analysis
4353 doesn't look conservative. */
4354 if (TREE_CODE (t) == CALL_EXPR)
4356 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4358 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4359 if (POINTER_TYPE_P (TREE_VALUE (type))
4360 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4361 && alias_sets_conflict_p (data->lhs_alias_set,
4362 get_alias_set
4363 (TREE_TYPE (TREE_VALUE (type)))))
4364 return t;
4367 if (IS_TYPE_OR_DECL_P (t))
4368 *walk_subtrees = 0;
4369 return NULL;
4372 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4373 force values that overlap with the lhs (as described by *DATA)
4374 into temporaries. */
4376 static void
4377 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4378 struct gimplify_init_ctor_preeval_data *data)
4380 enum gimplify_status one;
4382 /* If the value is constant, then there's nothing to pre-evaluate. */
4383 if (TREE_CONSTANT (*expr_p))
4385 /* Ensure it does not have side effects, it might contain a reference to
4386 the object we're initializing. */
4387 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4388 return;
4391 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4392 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4393 return;
4395 /* Recurse for nested constructors. */
4396 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4398 unsigned HOST_WIDE_INT ix;
4399 constructor_elt *ce;
4400 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4402 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4403 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4405 return;
4408 /* If this is a variable sized type, we must remember the size. */
4409 maybe_with_size_expr (expr_p);
4411 /* Gimplify the constructor element to something appropriate for the rhs
4412 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4413 the gimplifier will consider this a store to memory. Doing this
4414 gimplification now means that we won't have to deal with complicated
4415 language-specific trees, nor trees like SAVE_EXPR that can induce
4416 exponential search behavior. */
4417 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4418 if (one == GS_ERROR)
4420 *expr_p = NULL;
4421 return;
4424 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4425 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4426 always be true for all scalars, since is_gimple_mem_rhs insists on a
4427 temporary variable for them. */
4428 if (DECL_P (*expr_p))
4429 return;
4431 /* If this is of variable size, we have no choice but to assume it doesn't
4432 overlap since we can't make a temporary for it. */
4433 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4434 return;
4436 /* Otherwise, we must search for overlap ... */
4437 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4438 return;
4440 /* ... and if found, force the value into a temporary. */
4441 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4444 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4445 a RANGE_EXPR in a CONSTRUCTOR for an array.
4447 var = lower;
4448 loop_entry:
4449 object[var] = value;
4450 if (var == upper)
4451 goto loop_exit;
4452 var = var + 1;
4453 goto loop_entry;
4454 loop_exit:
4456 We increment var _after_ the loop exit check because we might otherwise
4457 fail if upper == TYPE_MAX_VALUE (type for upper).
4459 Note that we never have to deal with SAVE_EXPRs here, because this has
4460 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4462 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4463 gimple_seq *, bool);
4465 static void
4466 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4467 tree value, tree array_elt_type,
4468 gimple_seq *pre_p, bool cleared)
4470 tree loop_entry_label, loop_exit_label, fall_thru_label;
4471 tree var, var_type, cref, tmp;
4473 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4474 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4475 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4477 /* Create and initialize the index variable. */
4478 var_type = TREE_TYPE (upper);
4479 var = create_tmp_var (var_type);
4480 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4482 /* Add the loop entry label. */
4483 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4485 /* Build the reference. */
4486 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4487 var, NULL_TREE, NULL_TREE);
4489 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4490 the store. Otherwise just assign value to the reference. */
4492 if (TREE_CODE (value) == CONSTRUCTOR)
4493 /* NB we might have to call ourself recursively through
4494 gimplify_init_ctor_eval if the value is a constructor. */
4495 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4496 pre_p, cleared);
4497 else
4498 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4500 /* We exit the loop when the index var is equal to the upper bound. */
4501 gimplify_seq_add_stmt (pre_p,
4502 gimple_build_cond (EQ_EXPR, var, upper,
4503 loop_exit_label, fall_thru_label));
4505 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4507 /* Otherwise, increment the index var... */
4508 tmp = build2 (PLUS_EXPR, var_type, var,
4509 fold_convert (var_type, integer_one_node));
4510 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4512 /* ...and jump back to the loop entry. */
4513 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4515 /* Add the loop exit label. */
4516 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4519 /* Return true if FDECL is accessing a field that is zero sized. */
4521 static bool
4522 zero_sized_field_decl (const_tree fdecl)
4524 if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl)
4525 && integer_zerop (DECL_SIZE (fdecl)))
4526 return true;
4527 return false;
4530 /* Return true if TYPE is zero sized. */
4532 static bool
4533 zero_sized_type (const_tree type)
4535 if (AGGREGATE_TYPE_P (type) && TYPE_SIZE (type)
4536 && integer_zerop (TYPE_SIZE (type)))
4537 return true;
4538 return false;
4541 /* A subroutine of gimplify_init_constructor. Generate individual
4542 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4543 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4544 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4545 zeroed first. */
4547 static void
4548 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4549 gimple_seq *pre_p, bool cleared)
4551 tree array_elt_type = NULL;
4552 unsigned HOST_WIDE_INT ix;
4553 tree purpose, value;
4555 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4556 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4558 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4560 tree cref;
4562 /* NULL values are created above for gimplification errors. */
4563 if (value == NULL)
4564 continue;
4566 if (cleared && initializer_zerop (value))
4567 continue;
4569 /* ??? Here's to hoping the front end fills in all of the indices,
4570 so we don't have to figure out what's missing ourselves. */
4571 gcc_assert (purpose);
4573 /* Skip zero-sized fields, unless value has side-effects. This can
4574 happen with calls to functions returning a zero-sized type, which
4575 we shouldn't discard. As a number of downstream passes don't
4576 expect sets of zero-sized fields, we rely on the gimplification of
4577 the MODIFY_EXPR we make below to drop the assignment statement. */
4578 if (! TREE_SIDE_EFFECTS (value) && zero_sized_field_decl (purpose))
4579 continue;
4581 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4582 whole range. */
4583 if (TREE_CODE (purpose) == RANGE_EXPR)
4585 tree lower = TREE_OPERAND (purpose, 0);
4586 tree upper = TREE_OPERAND (purpose, 1);
4588 /* If the lower bound is equal to upper, just treat it as if
4589 upper was the index. */
4590 if (simple_cst_equal (lower, upper))
4591 purpose = upper;
4592 else
4594 gimplify_init_ctor_eval_range (object, lower, upper, value,
4595 array_elt_type, pre_p, cleared);
4596 continue;
4600 if (array_elt_type)
4602 /* Do not use bitsizetype for ARRAY_REF indices. */
4603 if (TYPE_DOMAIN (TREE_TYPE (object)))
4604 purpose
4605 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4606 purpose);
4607 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4608 purpose, NULL_TREE, NULL_TREE);
4610 else
4612 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4613 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4614 unshare_expr (object), purpose, NULL_TREE);
4617 if (TREE_CODE (value) == CONSTRUCTOR
4618 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4619 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4620 pre_p, cleared);
4621 else
4623 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4624 gimplify_and_add (init, pre_p);
4625 ggc_free (init);
4630 /* Return the appropriate RHS predicate for this LHS. */
4632 gimple_predicate
4633 rhs_predicate_for (tree lhs)
4635 if (is_gimple_reg (lhs))
4636 return is_gimple_reg_rhs_or_call;
4637 else
4638 return is_gimple_mem_rhs_or_call;
4641 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4642 before the LHS has been gimplified. */
4644 static gimple_predicate
4645 initial_rhs_predicate_for (tree lhs)
4647 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4648 return is_gimple_reg_rhs_or_call;
4649 else
4650 return is_gimple_mem_rhs_or_call;
4653 /* Gimplify a C99 compound literal expression. This just means adding
4654 the DECL_EXPR before the current statement and using its anonymous
4655 decl instead. */
4657 static enum gimplify_status
4658 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
4659 bool (*gimple_test_f) (tree),
4660 fallback_t fallback)
4662 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
4663 tree decl = DECL_EXPR_DECL (decl_s);
4664 tree init = DECL_INITIAL (decl);
4665 /* Mark the decl as addressable if the compound literal
4666 expression is addressable now, otherwise it is marked too late
4667 after we gimplify the initialization expression. */
4668 if (TREE_ADDRESSABLE (*expr_p))
4669 TREE_ADDRESSABLE (decl) = 1;
4670 /* Otherwise, if we don't need an lvalue and have a literal directly
4671 substitute it. Check if it matches the gimple predicate, as
4672 otherwise we'd generate a new temporary, and we can as well just
4673 use the decl we already have. */
4674 else if (!TREE_ADDRESSABLE (decl)
4675 && !TREE_THIS_VOLATILE (decl)
4676 && init
4677 && (fallback & fb_lvalue) == 0
4678 && gimple_test_f (init))
4680 *expr_p = init;
4681 return GS_OK;
4684 /* Preliminarily mark non-addressed complex variables as eligible
4685 for promotion to gimple registers. We'll transform their uses
4686 as we find them. */
4687 if ((TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE
4688 || TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE)
4689 && !TREE_THIS_VOLATILE (decl)
4690 && !needs_to_live_in_memory (decl))
4691 DECL_GIMPLE_REG_P (decl) = 1;
4693 /* If the decl is not addressable, then it is being used in some
4694 expression or on the right hand side of a statement, and it can
4695 be put into a readonly data section. */
4696 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
4697 TREE_READONLY (decl) = 1;
4699 /* This decl isn't mentioned in the enclosing block, so add it to the
4700 list of temps. FIXME it seems a bit of a kludge to say that
4701 anonymous artificial vars aren't pushed, but everything else is. */
4702 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
4703 gimple_add_tmp_var (decl);
4705 gimplify_and_add (decl_s, pre_p);
4706 *expr_p = decl;
4707 return GS_OK;
4710 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4711 return a new CONSTRUCTOR if something changed. */
4713 static tree
4714 optimize_compound_literals_in_ctor (tree orig_ctor)
4716 tree ctor = orig_ctor;
4717 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
4718 unsigned int idx, num = vec_safe_length (elts);
4720 for (idx = 0; idx < num; idx++)
4722 tree value = (*elts)[idx].value;
4723 tree newval = value;
4724 if (TREE_CODE (value) == CONSTRUCTOR)
4725 newval = optimize_compound_literals_in_ctor (value);
4726 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
4728 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
4729 tree decl = DECL_EXPR_DECL (decl_s);
4730 tree init = DECL_INITIAL (decl);
4732 if (!TREE_ADDRESSABLE (value)
4733 && !TREE_ADDRESSABLE (decl)
4734 && init
4735 && TREE_CODE (init) == CONSTRUCTOR)
4736 newval = optimize_compound_literals_in_ctor (init);
4738 if (newval == value)
4739 continue;
4741 if (ctor == orig_ctor)
4743 ctor = copy_node (orig_ctor);
4744 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
4745 elts = CONSTRUCTOR_ELTS (ctor);
4747 (*elts)[idx].value = newval;
4749 return ctor;
4752 /* A subroutine of gimplify_modify_expr. Break out elements of a
4753 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4755 Note that we still need to clear any elements that don't have explicit
4756 initializers, so if not all elements are initialized we keep the
4757 original MODIFY_EXPR, we just remove all of the constructor elements.
4759 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4760 GS_ERROR if we would have to create a temporary when gimplifying
4761 this constructor. Otherwise, return GS_OK.
4763 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4765 static enum gimplify_status
4766 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4767 bool want_value, bool notify_temp_creation)
4769 tree object, ctor, type;
4770 enum gimplify_status ret;
4771 vec<constructor_elt, va_gc> *elts;
4773 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
4775 if (!notify_temp_creation)
4777 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
4778 is_gimple_lvalue, fb_lvalue);
4779 if (ret == GS_ERROR)
4780 return ret;
4783 object = TREE_OPERAND (*expr_p, 0);
4784 ctor = TREE_OPERAND (*expr_p, 1)
4785 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
4786 type = TREE_TYPE (ctor);
4787 elts = CONSTRUCTOR_ELTS (ctor);
4788 ret = GS_ALL_DONE;
4790 switch (TREE_CODE (type))
4792 case RECORD_TYPE:
4793 case UNION_TYPE:
4794 case QUAL_UNION_TYPE:
4795 case ARRAY_TYPE:
4797 struct gimplify_init_ctor_preeval_data preeval_data;
4798 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
4799 HOST_WIDE_INT num_unique_nonzero_elements;
4800 bool cleared, complete_p, valid_const_initializer;
4801 /* Use readonly data for initializers of this or smaller size
4802 regardless of the num_nonzero_elements / num_unique_nonzero_elements
4803 ratio. */
4804 const HOST_WIDE_INT min_unique_size = 64;
4805 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
4806 is smaller than this, use readonly data. */
4807 const int unique_nonzero_ratio = 8;
4809 /* Aggregate types must lower constructors to initialization of
4810 individual elements. The exception is that a CONSTRUCTOR node
4811 with no elements indicates zero-initialization of the whole. */
4812 if (vec_safe_is_empty (elts))
4814 if (notify_temp_creation)
4815 return GS_OK;
4816 break;
4819 /* Fetch information about the constructor to direct later processing.
4820 We might want to make static versions of it in various cases, and
4821 can only do so if it known to be a valid constant initializer. */
4822 valid_const_initializer
4823 = categorize_ctor_elements (ctor, &num_nonzero_elements,
4824 &num_unique_nonzero_elements,
4825 &num_ctor_elements, &complete_p);
4827 /* If a const aggregate variable is being initialized, then it
4828 should never be a lose to promote the variable to be static. */
4829 if (valid_const_initializer
4830 && num_nonzero_elements > 1
4831 && TREE_READONLY (object)
4832 && VAR_P (object)
4833 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))
4834 /* For ctors that have many repeated nonzero elements
4835 represented through RANGE_EXPRs, prefer initializing
4836 those through runtime loops over copies of large amounts
4837 of data from readonly data section. */
4838 && (num_unique_nonzero_elements
4839 > num_nonzero_elements / unique_nonzero_ratio
4840 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
4841 <= (unsigned HOST_WIDE_INT) min_unique_size)))
4843 if (notify_temp_creation)
4844 return GS_ERROR;
4845 DECL_INITIAL (object) = ctor;
4846 TREE_STATIC (object) = 1;
4847 if (!DECL_NAME (object))
4848 DECL_NAME (object) = create_tmp_var_name ("C");
4849 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
4851 /* ??? C++ doesn't automatically append a .<number> to the
4852 assembler name, and even when it does, it looks at FE private
4853 data structures to figure out what that number should be,
4854 which are not set for this variable. I suppose this is
4855 important for local statics for inline functions, which aren't
4856 "local" in the object file sense. So in order to get a unique
4857 TU-local symbol, we must invoke the lhd version now. */
4858 lhd_set_decl_assembler_name (object);
4860 *expr_p = NULL_TREE;
4861 break;
4864 /* If there are "lots" of initialized elements, even discounting
4865 those that are not address constants (and thus *must* be
4866 computed at runtime), then partition the constructor into
4867 constant and non-constant parts. Block copy the constant
4868 parts in, then generate code for the non-constant parts. */
4869 /* TODO. There's code in cp/typeck.c to do this. */
4871 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
4872 /* store_constructor will ignore the clearing of variable-sized
4873 objects. Initializers for such objects must explicitly set
4874 every field that needs to be set. */
4875 cleared = false;
4876 else if (!complete_p)
4877 /* If the constructor isn't complete, clear the whole object
4878 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
4880 ??? This ought not to be needed. For any element not present
4881 in the initializer, we should simply set them to zero. Except
4882 we'd need to *find* the elements that are not present, and that
4883 requires trickery to avoid quadratic compile-time behavior in
4884 large cases or excessive memory use in small cases. */
4885 cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
4886 else if (num_ctor_elements - num_nonzero_elements
4887 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
4888 && num_nonzero_elements < num_ctor_elements / 4)
4889 /* If there are "lots" of zeros, it's more efficient to clear
4890 the memory and then set the nonzero elements. */
4891 cleared = true;
4892 else
4893 cleared = false;
4895 /* If there are "lots" of initialized elements, and all of them
4896 are valid address constants, then the entire initializer can
4897 be dropped to memory, and then memcpy'd out. Don't do this
4898 for sparse arrays, though, as it's more efficient to follow
4899 the standard CONSTRUCTOR behavior of memset followed by
4900 individual element initialization. Also don't do this for small
4901 all-zero initializers (which aren't big enough to merit
4902 clearing), and don't try to make bitwise copies of
4903 TREE_ADDRESSABLE types. */
4905 if (valid_const_initializer
4906 && !(cleared || num_nonzero_elements == 0)
4907 && !TREE_ADDRESSABLE (type))
4909 HOST_WIDE_INT size = int_size_in_bytes (type);
4910 unsigned int align;
4912 /* ??? We can still get unbounded array types, at least
4913 from the C++ front end. This seems wrong, but attempt
4914 to work around it for now. */
4915 if (size < 0)
4917 size = int_size_in_bytes (TREE_TYPE (object));
4918 if (size >= 0)
4919 TREE_TYPE (ctor) = type = TREE_TYPE (object);
4922 /* Find the maximum alignment we can assume for the object. */
4923 /* ??? Make use of DECL_OFFSET_ALIGN. */
4924 if (DECL_P (object))
4925 align = DECL_ALIGN (object);
4926 else
4927 align = TYPE_ALIGN (type);
4929 /* Do a block move either if the size is so small as to make
4930 each individual move a sub-unit move on average, or if it
4931 is so large as to make individual moves inefficient. */
4932 if (size > 0
4933 && num_nonzero_elements > 1
4934 /* For ctors that have many repeated nonzero elements
4935 represented through RANGE_EXPRs, prefer initializing
4936 those through runtime loops over copies of large amounts
4937 of data from readonly data section. */
4938 && (num_unique_nonzero_elements
4939 > num_nonzero_elements / unique_nonzero_ratio
4940 || size <= min_unique_size)
4941 && (size < num_nonzero_elements
4942 || !can_move_by_pieces (size, align)))
4944 if (notify_temp_creation)
4945 return GS_ERROR;
4947 walk_tree (&ctor, force_labels_r, NULL, NULL);
4948 ctor = tree_output_constant_def (ctor);
4949 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
4950 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
4951 TREE_OPERAND (*expr_p, 1) = ctor;
4953 /* This is no longer an assignment of a CONSTRUCTOR, but
4954 we still may have processing to do on the LHS. So
4955 pretend we didn't do anything here to let that happen. */
4956 return GS_UNHANDLED;
4960 /* If the target is volatile, we have non-zero elements and more than
4961 one field to assign, initialize the target from a temporary. */
4962 if (TREE_THIS_VOLATILE (object)
4963 && !TREE_ADDRESSABLE (type)
4964 && num_nonzero_elements > 0
4965 && vec_safe_length (elts) > 1)
4967 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
4968 TREE_OPERAND (*expr_p, 0) = temp;
4969 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
4970 *expr_p,
4971 build2 (MODIFY_EXPR, void_type_node,
4972 object, temp));
4973 return GS_OK;
4976 if (notify_temp_creation)
4977 return GS_OK;
4979 /* If there are nonzero elements and if needed, pre-evaluate to capture
4980 elements overlapping with the lhs into temporaries. We must do this
4981 before clearing to fetch the values before they are zeroed-out. */
4982 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
4984 preeval_data.lhs_base_decl = get_base_address (object);
4985 if (!DECL_P (preeval_data.lhs_base_decl))
4986 preeval_data.lhs_base_decl = NULL;
4987 preeval_data.lhs_alias_set = get_alias_set (object);
4989 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
4990 pre_p, post_p, &preeval_data);
4993 bool ctor_has_side_effects_p
4994 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
4996 if (cleared)
4998 /* Zap the CONSTRUCTOR element list, which simplifies this case.
4999 Note that we still have to gimplify, in order to handle the
5000 case of variable sized types. Avoid shared tree structures. */
5001 CONSTRUCTOR_ELTS (ctor) = NULL;
5002 TREE_SIDE_EFFECTS (ctor) = 0;
5003 object = unshare_expr (object);
5004 gimplify_stmt (expr_p, pre_p);
5007 /* If we have not block cleared the object, or if there are nonzero
5008 elements in the constructor, or if the constructor has side effects,
5009 add assignments to the individual scalar fields of the object. */
5010 if (!cleared
5011 || num_nonzero_elements > 0
5012 || ctor_has_side_effects_p)
5013 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
5015 *expr_p = NULL_TREE;
5017 break;
5019 case COMPLEX_TYPE:
5021 tree r, i;
5023 if (notify_temp_creation)
5024 return GS_OK;
5026 /* Extract the real and imaginary parts out of the ctor. */
5027 gcc_assert (elts->length () == 2);
5028 r = (*elts)[0].value;
5029 i = (*elts)[1].value;
5030 if (r == NULL || i == NULL)
5032 tree zero = build_zero_cst (TREE_TYPE (type));
5033 if (r == NULL)
5034 r = zero;
5035 if (i == NULL)
5036 i = zero;
5039 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5040 represent creation of a complex value. */
5041 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
5043 ctor = build_complex (type, r, i);
5044 TREE_OPERAND (*expr_p, 1) = ctor;
5046 else
5048 ctor = build2 (COMPLEX_EXPR, type, r, i);
5049 TREE_OPERAND (*expr_p, 1) = ctor;
5050 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
5051 pre_p,
5052 post_p,
5053 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
5054 fb_rvalue);
5057 break;
5059 case VECTOR_TYPE:
5061 unsigned HOST_WIDE_INT ix;
5062 constructor_elt *ce;
5064 if (notify_temp_creation)
5065 return GS_OK;
5067 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5068 if (TREE_CONSTANT (ctor))
5070 bool constant_p = true;
5071 tree value;
5073 /* Even when ctor is constant, it might contain non-*_CST
5074 elements, such as addresses or trapping values like
5075 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5076 in VECTOR_CST nodes. */
5077 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5078 if (!CONSTANT_CLASS_P (value))
5080 constant_p = false;
5081 break;
5084 if (constant_p)
5086 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5087 break;
5090 TREE_CONSTANT (ctor) = 0;
5093 /* Vector types use CONSTRUCTOR all the way through gimple
5094 compilation as a general initializer. */
5095 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5097 enum gimplify_status tret;
5098 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5099 fb_rvalue);
5100 if (tret == GS_ERROR)
5101 ret = GS_ERROR;
5102 else if (TREE_STATIC (ctor)
5103 && !initializer_constant_valid_p (ce->value,
5104 TREE_TYPE (ce->value)))
5105 TREE_STATIC (ctor) = 0;
5107 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5108 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5110 break;
5112 default:
5113 /* So how did we get a CONSTRUCTOR for a scalar type? */
5114 gcc_unreachable ();
5117 if (ret == GS_ERROR)
5118 return GS_ERROR;
5119 /* If we have gimplified both sides of the initializer but have
5120 not emitted an assignment, do so now. */
5121 if (*expr_p)
5123 tree lhs = TREE_OPERAND (*expr_p, 0);
5124 tree rhs = TREE_OPERAND (*expr_p, 1);
5125 if (want_value && object == lhs)
5126 lhs = unshare_expr (lhs);
5127 gassign *init = gimple_build_assign (lhs, rhs);
5128 gimplify_seq_add_stmt (pre_p, init);
5130 if (want_value)
5132 *expr_p = object;
5133 return GS_OK;
5135 else
5137 *expr_p = NULL;
5138 return GS_ALL_DONE;
5142 /* Given a pointer value OP0, return a simplified version of an
5143 indirection through OP0, or NULL_TREE if no simplification is
5144 possible. This may only be applied to a rhs of an expression.
5145 Note that the resulting type may be different from the type pointed
5146 to in the sense that it is still compatible from the langhooks
5147 point of view. */
5149 static tree
5150 gimple_fold_indirect_ref_rhs (tree t)
5152 return gimple_fold_indirect_ref (t);
5155 /* Subroutine of gimplify_modify_expr to do simplifications of
5156 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5157 something changes. */
5159 static enum gimplify_status
5160 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5161 gimple_seq *pre_p, gimple_seq *post_p,
5162 bool want_value)
5164 enum gimplify_status ret = GS_UNHANDLED;
5165 bool changed;
5169 changed = false;
5170 switch (TREE_CODE (*from_p))
5172 case VAR_DECL:
5173 /* If we're assigning from a read-only variable initialized with
5174 a constructor, do the direct assignment from the constructor,
5175 but only if neither source nor target are volatile since this
5176 latter assignment might end up being done on a per-field basis. */
5177 if (DECL_INITIAL (*from_p)
5178 && TREE_READONLY (*from_p)
5179 && !TREE_THIS_VOLATILE (*from_p)
5180 && !TREE_THIS_VOLATILE (*to_p)
5181 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR)
5183 tree old_from = *from_p;
5184 enum gimplify_status subret;
5186 /* Move the constructor into the RHS. */
5187 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5189 /* Let's see if gimplify_init_constructor will need to put
5190 it in memory. */
5191 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5192 false, true);
5193 if (subret == GS_ERROR)
5195 /* If so, revert the change. */
5196 *from_p = old_from;
5198 else
5200 ret = GS_OK;
5201 changed = true;
5204 break;
5205 case INDIRECT_REF:
5207 /* If we have code like
5209 *(const A*)(A*)&x
5211 where the type of "x" is a (possibly cv-qualified variant
5212 of "A"), treat the entire expression as identical to "x".
5213 This kind of code arises in C++ when an object is bound
5214 to a const reference, and if "x" is a TARGET_EXPR we want
5215 to take advantage of the optimization below. */
5216 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5217 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5218 if (t)
5220 if (TREE_THIS_VOLATILE (t) != volatile_p)
5222 if (DECL_P (t))
5223 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5224 build_fold_addr_expr (t));
5225 if (REFERENCE_CLASS_P (t))
5226 TREE_THIS_VOLATILE (t) = volatile_p;
5228 *from_p = t;
5229 ret = GS_OK;
5230 changed = true;
5232 break;
5235 case TARGET_EXPR:
5237 /* If we are initializing something from a TARGET_EXPR, strip the
5238 TARGET_EXPR and initialize it directly, if possible. This can't
5239 be done if the initializer is void, since that implies that the
5240 temporary is set in some non-trivial way.
5242 ??? What about code that pulls out the temp and uses it
5243 elsewhere? I think that such code never uses the TARGET_EXPR as
5244 an initializer. If I'm wrong, we'll die because the temp won't
5245 have any RTL. In that case, I guess we'll need to replace
5246 references somehow. */
5247 tree init = TARGET_EXPR_INITIAL (*from_p);
5249 if (init
5250 && (TREE_CODE (*expr_p) != MODIFY_EXPR
5251 || !TARGET_EXPR_NO_ELIDE (*from_p))
5252 && !VOID_TYPE_P (TREE_TYPE (init)))
5254 *from_p = init;
5255 ret = GS_OK;
5256 changed = true;
5259 break;
5261 case COMPOUND_EXPR:
5262 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5263 caught. */
5264 gimplify_compound_expr (from_p, pre_p, true);
5265 ret = GS_OK;
5266 changed = true;
5267 break;
5269 case CONSTRUCTOR:
5270 /* If we already made some changes, let the front end have a
5271 crack at this before we break it down. */
5272 if (ret != GS_UNHANDLED)
5273 break;
5274 /* If we're initializing from a CONSTRUCTOR, break this into
5275 individual MODIFY_EXPRs. */
5276 return gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5277 false);
5279 case COND_EXPR:
5280 /* If we're assigning to a non-register type, push the assignment
5281 down into the branches. This is mandatory for ADDRESSABLE types,
5282 since we cannot generate temporaries for such, but it saves a
5283 copy in other cases as well. */
5284 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5286 /* This code should mirror the code in gimplify_cond_expr. */
5287 enum tree_code code = TREE_CODE (*expr_p);
5288 tree cond = *from_p;
5289 tree result = *to_p;
5291 ret = gimplify_expr (&result, pre_p, post_p,
5292 is_gimple_lvalue, fb_lvalue);
5293 if (ret != GS_ERROR)
5294 ret = GS_OK;
5296 /* If we are going to write RESULT more than once, clear
5297 TREE_READONLY flag, otherwise we might incorrectly promote
5298 the variable to static const and initialize it at compile
5299 time in one of the branches. */
5300 if (VAR_P (result)
5301 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5302 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5303 TREE_READONLY (result) = 0;
5304 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5305 TREE_OPERAND (cond, 1)
5306 = build2 (code, void_type_node, result,
5307 TREE_OPERAND (cond, 1));
5308 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5309 TREE_OPERAND (cond, 2)
5310 = build2 (code, void_type_node, unshare_expr (result),
5311 TREE_OPERAND (cond, 2));
5313 TREE_TYPE (cond) = void_type_node;
5314 recalculate_side_effects (cond);
5316 if (want_value)
5318 gimplify_and_add (cond, pre_p);
5319 *expr_p = unshare_expr (result);
5321 else
5322 *expr_p = cond;
5323 return ret;
5325 break;
5327 case CALL_EXPR:
5328 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5329 return slot so that we don't generate a temporary. */
5330 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5331 && aggregate_value_p (*from_p, *from_p))
5333 bool use_target;
5335 if (!(rhs_predicate_for (*to_p))(*from_p))
5336 /* If we need a temporary, *to_p isn't accurate. */
5337 use_target = false;
5338 /* It's OK to use the return slot directly unless it's an NRV. */
5339 else if (TREE_CODE (*to_p) == RESULT_DECL
5340 && DECL_NAME (*to_p) == NULL_TREE
5341 && needs_to_live_in_memory (*to_p))
5342 use_target = true;
5343 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5344 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5345 /* Don't force regs into memory. */
5346 use_target = false;
5347 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5348 /* It's OK to use the target directly if it's being
5349 initialized. */
5350 use_target = true;
5351 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5352 != INTEGER_CST)
5353 /* Always use the target and thus RSO for variable-sized types.
5354 GIMPLE cannot deal with a variable-sized assignment
5355 embedded in a call statement. */
5356 use_target = true;
5357 else if (TREE_CODE (*to_p) != SSA_NAME
5358 && (!is_gimple_variable (*to_p)
5359 || needs_to_live_in_memory (*to_p)))
5360 /* Don't use the original target if it's already addressable;
5361 if its address escapes, and the called function uses the
5362 NRV optimization, a conforming program could see *to_p
5363 change before the called function returns; see c++/19317.
5364 When optimizing, the return_slot pass marks more functions
5365 as safe after we have escape info. */
5366 use_target = false;
5367 else
5368 use_target = true;
5370 if (use_target)
5372 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5373 mark_addressable (*to_p);
5376 break;
5378 case WITH_SIZE_EXPR:
5379 /* Likewise for calls that return an aggregate of non-constant size,
5380 since we would not be able to generate a temporary at all. */
5381 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5383 *from_p = TREE_OPERAND (*from_p, 0);
5384 /* We don't change ret in this case because the
5385 WITH_SIZE_EXPR might have been added in
5386 gimplify_modify_expr, so returning GS_OK would lead to an
5387 infinite loop. */
5388 changed = true;
5390 break;
5392 /* If we're initializing from a container, push the initialization
5393 inside it. */
5394 case CLEANUP_POINT_EXPR:
5395 case BIND_EXPR:
5396 case STATEMENT_LIST:
5398 tree wrap = *from_p;
5399 tree t;
5401 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5402 fb_lvalue);
5403 if (ret != GS_ERROR)
5404 ret = GS_OK;
5406 t = voidify_wrapper_expr (wrap, *expr_p);
5407 gcc_assert (t == *expr_p);
5409 if (want_value)
5411 gimplify_and_add (wrap, pre_p);
5412 *expr_p = unshare_expr (*to_p);
5414 else
5415 *expr_p = wrap;
5416 return GS_OK;
5419 case COMPOUND_LITERAL_EXPR:
5421 tree complit = TREE_OPERAND (*expr_p, 1);
5422 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5423 tree decl = DECL_EXPR_DECL (decl_s);
5424 tree init = DECL_INITIAL (decl);
5426 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5427 into struct T x = { 0, 1, 2 } if the address of the
5428 compound literal has never been taken. */
5429 if (!TREE_ADDRESSABLE (complit)
5430 && !TREE_ADDRESSABLE (decl)
5431 && init)
5433 *expr_p = copy_node (*expr_p);
5434 TREE_OPERAND (*expr_p, 1) = init;
5435 return GS_OK;
5439 default:
5440 break;
5443 while (changed);
5445 return ret;
5449 /* Return true if T looks like a valid GIMPLE statement. */
5451 static bool
5452 is_gimple_stmt (tree t)
5454 const enum tree_code code = TREE_CODE (t);
5456 switch (code)
5458 case NOP_EXPR:
5459 /* The only valid NOP_EXPR is the empty statement. */
5460 return IS_EMPTY_STMT (t);
5462 case BIND_EXPR:
5463 case COND_EXPR:
5464 /* These are only valid if they're void. */
5465 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5467 case SWITCH_EXPR:
5468 case GOTO_EXPR:
5469 case RETURN_EXPR:
5470 case LABEL_EXPR:
5471 case CASE_LABEL_EXPR:
5472 case TRY_CATCH_EXPR:
5473 case TRY_FINALLY_EXPR:
5474 case EH_FILTER_EXPR:
5475 case CATCH_EXPR:
5476 case ASM_EXPR:
5477 case STATEMENT_LIST:
5478 case OACC_PARALLEL:
5479 case OACC_KERNELS:
5480 case OACC_DATA:
5481 case OACC_HOST_DATA:
5482 case OACC_DECLARE:
5483 case OACC_UPDATE:
5484 case OACC_ENTER_DATA:
5485 case OACC_EXIT_DATA:
5486 case OACC_CACHE:
5487 case OMP_PARALLEL:
5488 case OMP_FOR:
5489 case OMP_SIMD:
5490 case OMP_DISTRIBUTE:
5491 case OACC_LOOP:
5492 case OMP_SECTIONS:
5493 case OMP_SECTION:
5494 case OMP_SINGLE:
5495 case OMP_MASTER:
5496 case OMP_TASKGROUP:
5497 case OMP_ORDERED:
5498 case OMP_CRITICAL:
5499 case OMP_TASK:
5500 case OMP_TARGET:
5501 case OMP_TARGET_DATA:
5502 case OMP_TARGET_UPDATE:
5503 case OMP_TARGET_ENTER_DATA:
5504 case OMP_TARGET_EXIT_DATA:
5505 case OMP_TASKLOOP:
5506 case OMP_TEAMS:
5507 /* These are always void. */
5508 return true;
5510 case CALL_EXPR:
5511 case MODIFY_EXPR:
5512 case PREDICT_EXPR:
5513 /* These are valid regardless of their type. */
5514 return true;
5516 default:
5517 return false;
5522 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5523 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with
5524 DECL_GIMPLE_REG_P set.
5526 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5527 other, unmodified part of the complex object just before the total store.
5528 As a consequence, if the object is still uninitialized, an undefined value
5529 will be loaded into a register, which may result in a spurious exception
5530 if the register is floating-point and the value happens to be a signaling
5531 NaN for example. Then the fully-fledged complex operations lowering pass
5532 followed by a DCE pass are necessary in order to fix things up. */
5534 static enum gimplify_status
5535 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5536 bool want_value)
5538 enum tree_code code, ocode;
5539 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5541 lhs = TREE_OPERAND (*expr_p, 0);
5542 rhs = TREE_OPERAND (*expr_p, 1);
5543 code = TREE_CODE (lhs);
5544 lhs = TREE_OPERAND (lhs, 0);
5546 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5547 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5548 TREE_NO_WARNING (other) = 1;
5549 other = get_formal_tmp_var (other, pre_p);
5551 realpart = code == REALPART_EXPR ? rhs : other;
5552 imagpart = code == REALPART_EXPR ? other : rhs;
5554 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5555 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5556 else
5557 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5559 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5560 *expr_p = (want_value) ? rhs : NULL_TREE;
5562 return GS_ALL_DONE;
5565 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5567 modify_expr
5568 : varname '=' rhs
5569 | '*' ID '=' rhs
5571 PRE_P points to the list where side effects that must happen before
5572 *EXPR_P should be stored.
5574 POST_P points to the list where side effects that must happen after
5575 *EXPR_P should be stored.
5577 WANT_VALUE is nonzero iff we want to use the value of this expression
5578 in another expression. */
5580 static enum gimplify_status
5581 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5582 bool want_value)
5584 tree *from_p = &TREE_OPERAND (*expr_p, 1);
5585 tree *to_p = &TREE_OPERAND (*expr_p, 0);
5586 enum gimplify_status ret = GS_UNHANDLED;
5587 gimple *assign;
5588 location_t loc = EXPR_LOCATION (*expr_p);
5589 gimple_stmt_iterator gsi;
5591 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
5592 || TREE_CODE (*expr_p) == INIT_EXPR);
5594 /* Trying to simplify a clobber using normal logic doesn't work,
5595 so handle it here. */
5596 if (TREE_CLOBBER_P (*from_p))
5598 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5599 if (ret == GS_ERROR)
5600 return ret;
5601 gcc_assert (!want_value);
5602 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
5604 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
5605 pre_p, post_p);
5606 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
5608 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
5609 *expr_p = NULL;
5610 return GS_ALL_DONE;
5613 /* Insert pointer conversions required by the middle-end that are not
5614 required by the frontend. This fixes middle-end type checking for
5615 for example gcc.dg/redecl-6.c. */
5616 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
5618 STRIP_USELESS_TYPE_CONVERSION (*from_p);
5619 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
5620 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
5623 /* See if any simplifications can be done based on what the RHS is. */
5624 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5625 want_value);
5626 if (ret != GS_UNHANDLED)
5627 return ret;
5629 /* For zero sized types only gimplify the left hand side and right hand
5630 side as statements and throw away the assignment. Do this after
5631 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5632 types properly. */
5633 if (zero_sized_type (TREE_TYPE (*from_p))
5634 && !want_value
5635 /* Don't do this for calls that return addressable types, expand_call
5636 relies on those having a lhs. */
5637 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
5638 && TREE_CODE (*from_p) == CALL_EXPR))
5640 gimplify_stmt (from_p, pre_p);
5641 gimplify_stmt (to_p, pre_p);
5642 *expr_p = NULL_TREE;
5643 return GS_ALL_DONE;
5646 /* If the value being copied is of variable width, compute the length
5647 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5648 before gimplifying any of the operands so that we can resolve any
5649 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5650 the size of the expression to be copied, not of the destination, so
5651 that is what we must do here. */
5652 maybe_with_size_expr (from_p);
5654 /* As a special case, we have to temporarily allow for assignments
5655 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5656 a toplevel statement, when gimplifying the GENERIC expression
5657 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5658 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5660 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5661 prevent gimplify_expr from trying to create a new temporary for
5662 foo's LHS, we tell it that it should only gimplify until it
5663 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5664 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5665 and all we need to do here is set 'a' to be its LHS. */
5667 /* Gimplify the RHS first for C++17 and bug 71104. */
5668 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
5669 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
5670 if (ret == GS_ERROR)
5671 return ret;
5673 /* Then gimplify the LHS. */
5674 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5675 twice we have to make sure to gimplify into non-SSA as otherwise
5676 the abnormal edge added later will make those defs not dominate
5677 their uses.
5678 ??? Technically this applies only to the registers used in the
5679 resulting non-register *TO_P. */
5680 bool saved_into_ssa = gimplify_ctxp->into_ssa;
5681 if (saved_into_ssa
5682 && TREE_CODE (*from_p) == CALL_EXPR
5683 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
5684 gimplify_ctxp->into_ssa = false;
5685 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5686 gimplify_ctxp->into_ssa = saved_into_ssa;
5687 if (ret == GS_ERROR)
5688 return ret;
5690 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5691 guess for the predicate was wrong. */
5692 gimple_predicate final_pred = rhs_predicate_for (*to_p);
5693 if (final_pred != initial_pred)
5695 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
5696 if (ret == GS_ERROR)
5697 return ret;
5700 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5701 size as argument to the call. */
5702 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5704 tree call = TREE_OPERAND (*from_p, 0);
5705 tree vlasize = TREE_OPERAND (*from_p, 1);
5707 if (TREE_CODE (call) == CALL_EXPR
5708 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
5710 int nargs = call_expr_nargs (call);
5711 tree type = TREE_TYPE (call);
5712 tree ap = CALL_EXPR_ARG (call, 0);
5713 tree tag = CALL_EXPR_ARG (call, 1);
5714 tree aptag = CALL_EXPR_ARG (call, 2);
5715 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
5716 IFN_VA_ARG, type,
5717 nargs + 1, ap, tag,
5718 aptag, vlasize);
5719 TREE_OPERAND (*from_p, 0) = newcall;
5723 /* Now see if the above changed *from_p to something we handle specially. */
5724 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5725 want_value);
5726 if (ret != GS_UNHANDLED)
5727 return ret;
5729 /* If we've got a variable sized assignment between two lvalues (i.e. does
5730 not involve a call), then we can make things a bit more straightforward
5731 by converting the assignment to memcpy or memset. */
5732 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5734 tree from = TREE_OPERAND (*from_p, 0);
5735 tree size = TREE_OPERAND (*from_p, 1);
5737 if (TREE_CODE (from) == CONSTRUCTOR)
5738 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
5740 if (is_gimple_addressable (from))
5742 *from_p = from;
5743 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
5744 pre_p);
5748 /* Transform partial stores to non-addressable complex variables into
5749 total stores. This allows us to use real instead of virtual operands
5750 for these variables, which improves optimization. */
5751 if ((TREE_CODE (*to_p) == REALPART_EXPR
5752 || TREE_CODE (*to_p) == IMAGPART_EXPR)
5753 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
5754 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
5756 /* Try to alleviate the effects of the gimplification creating artificial
5757 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
5758 make sure not to create DECL_DEBUG_EXPR links across functions. */
5759 if (!gimplify_ctxp->into_ssa
5760 && VAR_P (*from_p)
5761 && DECL_IGNORED_P (*from_p)
5762 && DECL_P (*to_p)
5763 && !DECL_IGNORED_P (*to_p)
5764 && decl_function_context (*to_p) == current_function_decl
5765 && decl_function_context (*from_p) == current_function_decl)
5767 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
5768 DECL_NAME (*from_p)
5769 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
5770 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
5771 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
5774 if (want_value && TREE_THIS_VOLATILE (*to_p))
5775 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
5777 if (TREE_CODE (*from_p) == CALL_EXPR)
5779 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
5780 instead of a GIMPLE_ASSIGN. */
5781 gcall *call_stmt;
5782 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
5784 /* Gimplify internal functions created in the FEs. */
5785 int nargs = call_expr_nargs (*from_p), i;
5786 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
5787 auto_vec<tree> vargs (nargs);
5789 for (i = 0; i < nargs; i++)
5791 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
5792 EXPR_LOCATION (*from_p));
5793 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
5795 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
5796 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
5797 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
5799 else
5801 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
5802 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
5803 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
5804 tree fndecl = get_callee_fndecl (*from_p);
5805 if (fndecl
5806 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
5807 && call_expr_nargs (*from_p) == 3)
5808 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
5809 CALL_EXPR_ARG (*from_p, 0),
5810 CALL_EXPR_ARG (*from_p, 1),
5811 CALL_EXPR_ARG (*from_p, 2));
5812 else
5814 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
5817 notice_special_calls (call_stmt);
5818 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
5819 gimple_call_set_lhs (call_stmt, *to_p);
5820 else if (TREE_CODE (*to_p) == SSA_NAME)
5821 /* The above is somewhat premature, avoid ICEing later for a
5822 SSA name w/o a definition. We may have uses in the GIMPLE IL.
5823 ??? This doesn't make it a default-def. */
5824 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
5826 assign = call_stmt;
5828 else
5830 assign = gimple_build_assign (*to_p, *from_p);
5831 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
5832 if (COMPARISON_CLASS_P (*from_p))
5833 gimple_set_no_warning (assign, TREE_NO_WARNING (*from_p));
5836 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
5838 /* We should have got an SSA name from the start. */
5839 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
5840 || ! gimple_in_ssa_p (cfun));
5843 gimplify_seq_add_stmt (pre_p, assign);
5844 gsi = gsi_last (*pre_p);
5845 maybe_fold_stmt (&gsi);
5847 if (want_value)
5849 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
5850 return GS_OK;
5852 else
5853 *expr_p = NULL;
5855 return GS_ALL_DONE;
5858 /* Gimplify a comparison between two variable-sized objects. Do this
5859 with a call to BUILT_IN_MEMCMP. */
5861 static enum gimplify_status
5862 gimplify_variable_sized_compare (tree *expr_p)
5864 location_t loc = EXPR_LOCATION (*expr_p);
5865 tree op0 = TREE_OPERAND (*expr_p, 0);
5866 tree op1 = TREE_OPERAND (*expr_p, 1);
5867 tree t, arg, dest, src, expr;
5869 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
5870 arg = unshare_expr (arg);
5871 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
5872 src = build_fold_addr_expr_loc (loc, op1);
5873 dest = build_fold_addr_expr_loc (loc, op0);
5874 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
5875 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
5877 expr
5878 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
5879 SET_EXPR_LOCATION (expr, loc);
5880 *expr_p = expr;
5882 return GS_OK;
5885 /* Gimplify a comparison between two aggregate objects of integral scalar
5886 mode as a comparison between the bitwise equivalent scalar values. */
5888 static enum gimplify_status
5889 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
5891 location_t loc = EXPR_LOCATION (*expr_p);
5892 tree op0 = TREE_OPERAND (*expr_p, 0);
5893 tree op1 = TREE_OPERAND (*expr_p, 1);
5895 tree type = TREE_TYPE (op0);
5896 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
5898 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
5899 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
5901 *expr_p
5902 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
5904 return GS_OK;
5907 /* Gimplify an expression sequence. This function gimplifies each
5908 expression and rewrites the original expression with the last
5909 expression of the sequence in GIMPLE form.
5911 PRE_P points to the list where the side effects for all the
5912 expressions in the sequence will be emitted.
5914 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
5916 static enum gimplify_status
5917 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
5919 tree t = *expr_p;
5923 tree *sub_p = &TREE_OPERAND (t, 0);
5925 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
5926 gimplify_compound_expr (sub_p, pre_p, false);
5927 else
5928 gimplify_stmt (sub_p, pre_p);
5930 t = TREE_OPERAND (t, 1);
5932 while (TREE_CODE (t) == COMPOUND_EXPR);
5934 *expr_p = t;
5935 if (want_value)
5936 return GS_OK;
5937 else
5939 gimplify_stmt (expr_p, pre_p);
5940 return GS_ALL_DONE;
5944 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
5945 gimplify. After gimplification, EXPR_P will point to a new temporary
5946 that holds the original value of the SAVE_EXPR node.
5948 PRE_P points to the list where side effects that must happen before
5949 *EXPR_P should be stored. */
5951 static enum gimplify_status
5952 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
5954 enum gimplify_status ret = GS_ALL_DONE;
5955 tree val;
5957 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
5958 val = TREE_OPERAND (*expr_p, 0);
5960 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
5961 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
5963 /* The operand may be a void-valued expression. It is
5964 being executed only for its side-effects. */
5965 if (TREE_TYPE (val) == void_type_node)
5967 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5968 is_gimple_stmt, fb_none);
5969 val = NULL;
5971 else
5972 /* The temporary may not be an SSA name as later abnormal and EH
5973 control flow may invalidate use/def domination. When in SSA
5974 form then assume there are no such issues and SAVE_EXPRs only
5975 appear via GENERIC foldings. */
5976 val = get_initialized_tmp_var (val, pre_p, post_p,
5977 gimple_in_ssa_p (cfun));
5979 TREE_OPERAND (*expr_p, 0) = val;
5980 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
5983 *expr_p = val;
5985 return ret;
5988 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
5990 unary_expr
5991 : ...
5992 | '&' varname
5995 PRE_P points to the list where side effects that must happen before
5996 *EXPR_P should be stored.
5998 POST_P points to the list where side effects that must happen after
5999 *EXPR_P should be stored. */
6001 static enum gimplify_status
6002 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6004 tree expr = *expr_p;
6005 tree op0 = TREE_OPERAND (expr, 0);
6006 enum gimplify_status ret;
6007 location_t loc = EXPR_LOCATION (*expr_p);
6009 switch (TREE_CODE (op0))
6011 case INDIRECT_REF:
6012 do_indirect_ref:
6013 /* Check if we are dealing with an expression of the form '&*ptr'.
6014 While the front end folds away '&*ptr' into 'ptr', these
6015 expressions may be generated internally by the compiler (e.g.,
6016 builtins like __builtin_va_end). */
6017 /* Caution: the silent array decomposition semantics we allow for
6018 ADDR_EXPR means we can't always discard the pair. */
6019 /* Gimplification of the ADDR_EXPR operand may drop
6020 cv-qualification conversions, so make sure we add them if
6021 needed. */
6023 tree op00 = TREE_OPERAND (op0, 0);
6024 tree t_expr = TREE_TYPE (expr);
6025 tree t_op00 = TREE_TYPE (op00);
6027 if (!useless_type_conversion_p (t_expr, t_op00))
6028 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
6029 *expr_p = op00;
6030 ret = GS_OK;
6032 break;
6034 case VIEW_CONVERT_EXPR:
6035 /* Take the address of our operand and then convert it to the type of
6036 this ADDR_EXPR.
6038 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6039 all clear. The impact of this transformation is even less clear. */
6041 /* If the operand is a useless conversion, look through it. Doing so
6042 guarantees that the ADDR_EXPR and its operand will remain of the
6043 same type. */
6044 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
6045 op0 = TREE_OPERAND (op0, 0);
6047 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
6048 build_fold_addr_expr_loc (loc,
6049 TREE_OPERAND (op0, 0)));
6050 ret = GS_OK;
6051 break;
6053 case MEM_REF:
6054 if (integer_zerop (TREE_OPERAND (op0, 1)))
6055 goto do_indirect_ref;
6057 /* fall through */
6059 default:
6060 /* If we see a call to a declared builtin or see its address
6061 being taken (we can unify those cases here) then we can mark
6062 the builtin for implicit generation by GCC. */
6063 if (TREE_CODE (op0) == FUNCTION_DECL
6064 && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6065 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6066 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6068 /* We use fb_either here because the C frontend sometimes takes
6069 the address of a call that returns a struct; see
6070 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6071 the implied temporary explicit. */
6073 /* Make the operand addressable. */
6074 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6075 is_gimple_addressable, fb_either);
6076 if (ret == GS_ERROR)
6077 break;
6079 /* Then mark it. Beware that it may not be possible to do so directly
6080 if a temporary has been created by the gimplification. */
6081 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6083 op0 = TREE_OPERAND (expr, 0);
6085 /* For various reasons, the gimplification of the expression
6086 may have made a new INDIRECT_REF. */
6087 if (TREE_CODE (op0) == INDIRECT_REF)
6088 goto do_indirect_ref;
6090 mark_addressable (TREE_OPERAND (expr, 0));
6092 /* The FEs may end up building ADDR_EXPRs early on a decl with
6093 an incomplete type. Re-build ADDR_EXPRs in canonical form
6094 here. */
6095 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6096 *expr_p = build_fold_addr_expr (op0);
6098 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6099 recompute_tree_invariant_for_addr_expr (*expr_p);
6101 /* If we re-built the ADDR_EXPR add a conversion to the original type
6102 if required. */
6103 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6104 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6106 break;
6109 return ret;
6112 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6113 value; output operands should be a gimple lvalue. */
6115 static enum gimplify_status
6116 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6118 tree expr;
6119 int noutputs;
6120 const char **oconstraints;
6121 int i;
6122 tree link;
6123 const char *constraint;
6124 bool allows_mem, allows_reg, is_inout;
6125 enum gimplify_status ret, tret;
6126 gasm *stmt;
6127 vec<tree, va_gc> *inputs;
6128 vec<tree, va_gc> *outputs;
6129 vec<tree, va_gc> *clobbers;
6130 vec<tree, va_gc> *labels;
6131 tree link_next;
6133 expr = *expr_p;
6134 noutputs = list_length (ASM_OUTPUTS (expr));
6135 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6137 inputs = NULL;
6138 outputs = NULL;
6139 clobbers = NULL;
6140 labels = NULL;
6142 ret = GS_ALL_DONE;
6143 link_next = NULL_TREE;
6144 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6146 bool ok;
6147 size_t constraint_len;
6149 link_next = TREE_CHAIN (link);
6151 oconstraints[i]
6152 = constraint
6153 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6154 constraint_len = strlen (constraint);
6155 if (constraint_len == 0)
6156 continue;
6158 ok = parse_output_constraint (&constraint, i, 0, 0,
6159 &allows_mem, &allows_reg, &is_inout);
6160 if (!ok)
6162 ret = GS_ERROR;
6163 is_inout = false;
6166 /* If we can't make copies, we can only accept memory. */
6167 if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link))))
6169 if (allows_mem)
6170 allows_reg = 0;
6171 else
6173 error ("impossible constraint in %<asm%>");
6174 error ("non-memory output %d must stay in memory", i);
6175 return GS_ERROR;
6179 if (!allows_reg && allows_mem)
6180 mark_addressable (TREE_VALUE (link));
6182 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6183 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6184 fb_lvalue | fb_mayfail);
6185 if (tret == GS_ERROR)
6187 error ("invalid lvalue in %<asm%> output %d", i);
6188 ret = tret;
6191 /* If the constraint does not allow memory make sure we gimplify
6192 it to a register if it is not already but its base is. This
6193 happens for complex and vector components. */
6194 if (!allows_mem)
6196 tree op = TREE_VALUE (link);
6197 if (! is_gimple_val (op)
6198 && is_gimple_reg_type (TREE_TYPE (op))
6199 && is_gimple_reg (get_base_address (op)))
6201 tree tem = create_tmp_reg (TREE_TYPE (op));
6202 tree ass;
6203 if (is_inout)
6205 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6206 tem, unshare_expr (op));
6207 gimplify_and_add (ass, pre_p);
6209 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6210 gimplify_and_add (ass, post_p);
6212 TREE_VALUE (link) = tem;
6213 tret = GS_OK;
6217 vec_safe_push (outputs, link);
6218 TREE_CHAIN (link) = NULL_TREE;
6220 if (is_inout)
6222 /* An input/output operand. To give the optimizers more
6223 flexibility, split it into separate input and output
6224 operands. */
6225 tree input;
6226 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6227 char buf[11];
6229 /* Turn the in/out constraint into an output constraint. */
6230 char *p = xstrdup (constraint);
6231 p[0] = '=';
6232 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6234 /* And add a matching input constraint. */
6235 if (allows_reg)
6237 sprintf (buf, "%u", i);
6239 /* If there are multiple alternatives in the constraint,
6240 handle each of them individually. Those that allow register
6241 will be replaced with operand number, the others will stay
6242 unchanged. */
6243 if (strchr (p, ',') != NULL)
6245 size_t len = 0, buflen = strlen (buf);
6246 char *beg, *end, *str, *dst;
6248 for (beg = p + 1;;)
6250 end = strchr (beg, ',');
6251 if (end == NULL)
6252 end = strchr (beg, '\0');
6253 if ((size_t) (end - beg) < buflen)
6254 len += buflen + 1;
6255 else
6256 len += end - beg + 1;
6257 if (*end)
6258 beg = end + 1;
6259 else
6260 break;
6263 str = (char *) alloca (len);
6264 for (beg = p + 1, dst = str;;)
6266 const char *tem;
6267 bool mem_p, reg_p, inout_p;
6269 end = strchr (beg, ',');
6270 if (end)
6271 *end = '\0';
6272 beg[-1] = '=';
6273 tem = beg - 1;
6274 parse_output_constraint (&tem, i, 0, 0,
6275 &mem_p, &reg_p, &inout_p);
6276 if (dst != str)
6277 *dst++ = ',';
6278 if (reg_p)
6280 memcpy (dst, buf, buflen);
6281 dst += buflen;
6283 else
6285 if (end)
6286 len = end - beg;
6287 else
6288 len = strlen (beg);
6289 memcpy (dst, beg, len);
6290 dst += len;
6292 if (end)
6293 beg = end + 1;
6294 else
6295 break;
6297 *dst = '\0';
6298 input = build_string (dst - str, str);
6300 else
6301 input = build_string (strlen (buf), buf);
6303 else
6304 input = build_string (constraint_len - 1, constraint + 1);
6306 free (p);
6308 input = build_tree_list (build_tree_list (NULL_TREE, input),
6309 unshare_expr (TREE_VALUE (link)));
6310 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6314 link_next = NULL_TREE;
6315 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6317 link_next = TREE_CHAIN (link);
6318 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6319 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6320 oconstraints, &allows_mem, &allows_reg);
6322 /* If we can't make copies, we can only accept memory. */
6323 if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link))))
6325 if (allows_mem)
6326 allows_reg = 0;
6327 else
6329 error ("impossible constraint in %<asm%>");
6330 error ("non-memory input %d must stay in memory", i);
6331 return GS_ERROR;
6335 /* If the operand is a memory input, it should be an lvalue. */
6336 if (!allows_reg && allows_mem)
6338 tree inputv = TREE_VALUE (link);
6339 STRIP_NOPS (inputv);
6340 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6341 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6342 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6343 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6344 || TREE_CODE (inputv) == MODIFY_EXPR)
6345 TREE_VALUE (link) = error_mark_node;
6346 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6347 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6348 if (tret != GS_ERROR)
6350 /* Unlike output operands, memory inputs are not guaranteed
6351 to be lvalues by the FE, and while the expressions are
6352 marked addressable there, if it is e.g. a statement
6353 expression, temporaries in it might not end up being
6354 addressable. They might be already used in the IL and thus
6355 it is too late to make them addressable now though. */
6356 tree x = TREE_VALUE (link);
6357 while (handled_component_p (x))
6358 x = TREE_OPERAND (x, 0);
6359 if (TREE_CODE (x) == MEM_REF
6360 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6361 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6362 if ((VAR_P (x)
6363 || TREE_CODE (x) == PARM_DECL
6364 || TREE_CODE (x) == RESULT_DECL)
6365 && !TREE_ADDRESSABLE (x)
6366 && is_gimple_reg (x))
6368 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6369 input_location), 0,
6370 "memory input %d is not directly addressable",
6372 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6375 mark_addressable (TREE_VALUE (link));
6376 if (tret == GS_ERROR)
6378 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6379 "memory input %d is not directly addressable", i);
6380 ret = tret;
6383 else
6385 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6386 is_gimple_asm_val, fb_rvalue);
6387 if (tret == GS_ERROR)
6388 ret = tret;
6391 TREE_CHAIN (link) = NULL_TREE;
6392 vec_safe_push (inputs, link);
6395 link_next = NULL_TREE;
6396 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6398 link_next = TREE_CHAIN (link);
6399 TREE_CHAIN (link) = NULL_TREE;
6400 vec_safe_push (clobbers, link);
6403 link_next = NULL_TREE;
6404 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6406 link_next = TREE_CHAIN (link);
6407 TREE_CHAIN (link) = NULL_TREE;
6408 vec_safe_push (labels, link);
6411 /* Do not add ASMs with errors to the gimple IL stream. */
6412 if (ret != GS_ERROR)
6414 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6415 inputs, outputs, clobbers, labels);
6417 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
6418 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6419 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
6421 gimplify_seq_add_stmt (pre_p, stmt);
6424 return ret;
6427 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6428 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6429 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6430 return to this function.
6432 FIXME should we complexify the prequeue handling instead? Or use flags
6433 for all the cleanups and let the optimizer tighten them up? The current
6434 code seems pretty fragile; it will break on a cleanup within any
6435 non-conditional nesting. But any such nesting would be broken, anyway;
6436 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6437 and continues out of it. We can do that at the RTL level, though, so
6438 having an optimizer to tighten up try/finally regions would be a Good
6439 Thing. */
6441 static enum gimplify_status
6442 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6444 gimple_stmt_iterator iter;
6445 gimple_seq body_sequence = NULL;
6447 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6449 /* We only care about the number of conditions between the innermost
6450 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6451 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6452 int old_conds = gimplify_ctxp->conditions;
6453 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6454 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6455 gimplify_ctxp->conditions = 0;
6456 gimplify_ctxp->conditional_cleanups = NULL;
6457 gimplify_ctxp->in_cleanup_point_expr = true;
6459 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6461 gimplify_ctxp->conditions = old_conds;
6462 gimplify_ctxp->conditional_cleanups = old_cleanups;
6463 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6465 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6467 gimple *wce = gsi_stmt (iter);
6469 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6471 if (gsi_one_before_end_p (iter))
6473 /* Note that gsi_insert_seq_before and gsi_remove do not
6474 scan operands, unlike some other sequence mutators. */
6475 if (!gimple_wce_cleanup_eh_only (wce))
6476 gsi_insert_seq_before_without_update (&iter,
6477 gimple_wce_cleanup (wce),
6478 GSI_SAME_STMT);
6479 gsi_remove (&iter, true);
6480 break;
6482 else
6484 gtry *gtry;
6485 gimple_seq seq;
6486 enum gimple_try_flags kind;
6488 if (gimple_wce_cleanup_eh_only (wce))
6489 kind = GIMPLE_TRY_CATCH;
6490 else
6491 kind = GIMPLE_TRY_FINALLY;
6492 seq = gsi_split_seq_after (iter);
6494 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6495 /* Do not use gsi_replace here, as it may scan operands.
6496 We want to do a simple structural modification only. */
6497 gsi_set_stmt (&iter, gtry);
6498 iter = gsi_start (gtry->eval);
6501 else
6502 gsi_next (&iter);
6505 gimplify_seq_add_seq (pre_p, body_sequence);
6506 if (temp)
6508 *expr_p = temp;
6509 return GS_OK;
6511 else
6513 *expr_p = NULL;
6514 return GS_ALL_DONE;
6518 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6519 is the cleanup action required. EH_ONLY is true if the cleanup should
6520 only be executed if an exception is thrown, not on normal exit.
6521 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6522 only valid for clobbers. */
6524 static void
6525 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6526 bool force_uncond = false)
6528 gimple *wce;
6529 gimple_seq cleanup_stmts = NULL;
6531 /* Errors can result in improperly nested cleanups. Which results in
6532 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6533 if (seen_error ())
6534 return;
6536 if (gimple_conditional_context ())
6538 /* If we're in a conditional context, this is more complex. We only
6539 want to run the cleanup if we actually ran the initialization that
6540 necessitates it, but we want to run it after the end of the
6541 conditional context. So we wrap the try/finally around the
6542 condition and use a flag to determine whether or not to actually
6543 run the destructor. Thus
6545 test ? f(A()) : 0
6547 becomes (approximately)
6549 flag = 0;
6550 try {
6551 if (test) { A::A(temp); flag = 1; val = f(temp); }
6552 else { val = 0; }
6553 } finally {
6554 if (flag) A::~A(temp);
6558 if (force_uncond)
6560 gimplify_stmt (&cleanup, &cleanup_stmts);
6561 wce = gimple_build_wce (cleanup_stmts);
6562 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6564 else
6566 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6567 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
6568 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
6570 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
6571 gimplify_stmt (&cleanup, &cleanup_stmts);
6572 wce = gimple_build_wce (cleanup_stmts);
6574 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
6575 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6576 gimplify_seq_add_stmt (pre_p, ftrue);
6578 /* Because of this manipulation, and the EH edges that jump
6579 threading cannot redirect, the temporary (VAR) will appear
6580 to be used uninitialized. Don't warn. */
6581 TREE_NO_WARNING (var) = 1;
6584 else
6586 gimplify_stmt (&cleanup, &cleanup_stmts);
6587 wce = gimple_build_wce (cleanup_stmts);
6588 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6589 gimplify_seq_add_stmt (pre_p, wce);
6593 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6595 static enum gimplify_status
6596 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6598 tree targ = *expr_p;
6599 tree temp = TARGET_EXPR_SLOT (targ);
6600 tree init = TARGET_EXPR_INITIAL (targ);
6601 enum gimplify_status ret;
6603 bool unpoison_empty_seq = false;
6604 gimple_stmt_iterator unpoison_it;
6606 if (init)
6608 tree cleanup = NULL_TREE;
6610 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6611 to the temps list. Handle also variable length TARGET_EXPRs. */
6612 if (TREE_CODE (DECL_SIZE (temp)) != INTEGER_CST)
6614 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
6615 gimplify_type_sizes (TREE_TYPE (temp), pre_p);
6616 gimplify_vla_decl (temp, pre_p);
6618 else
6620 /* Save location where we need to place unpoisoning. It's possible
6621 that a variable will be converted to needs_to_live_in_memory. */
6622 unpoison_it = gsi_last (*pre_p);
6623 unpoison_empty_seq = gsi_end_p (unpoison_it);
6625 gimple_add_tmp_var (temp);
6628 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6629 expression is supposed to initialize the slot. */
6630 if (VOID_TYPE_P (TREE_TYPE (init)))
6631 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6632 else
6634 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
6635 init = init_expr;
6636 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6637 init = NULL;
6638 ggc_free (init_expr);
6640 if (ret == GS_ERROR)
6642 /* PR c++/28266 Make sure this is expanded only once. */
6643 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6644 return GS_ERROR;
6646 if (init)
6647 gimplify_and_add (init, pre_p);
6649 /* If needed, push the cleanup for the temp. */
6650 if (TARGET_EXPR_CLEANUP (targ))
6652 if (CLEANUP_EH_ONLY (targ))
6653 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
6654 CLEANUP_EH_ONLY (targ), pre_p);
6655 else
6656 cleanup = TARGET_EXPR_CLEANUP (targ);
6659 /* Add a clobber for the temporary going out of scope, like
6660 gimplify_bind_expr. */
6661 if (gimplify_ctxp->in_cleanup_point_expr
6662 && needs_to_live_in_memory (temp))
6664 if (flag_stack_reuse == SR_ALL)
6666 tree clobber = build_clobber (TREE_TYPE (temp));
6667 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
6668 gimple_push_cleanup (temp, clobber, false, pre_p, true);
6670 if (asan_poisoned_variables
6671 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
6672 && !TREE_STATIC (temp)
6673 && dbg_cnt (asan_use_after_scope)
6674 && !gimplify_omp_ctxp)
6676 tree asan_cleanup = build_asan_poison_call_expr (temp);
6677 if (asan_cleanup)
6679 if (unpoison_empty_seq)
6680 unpoison_it = gsi_start (*pre_p);
6682 asan_poison_variable (temp, false, &unpoison_it,
6683 unpoison_empty_seq);
6684 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
6688 if (cleanup)
6689 gimple_push_cleanup (temp, cleanup, false, pre_p);
6691 /* Only expand this once. */
6692 TREE_OPERAND (targ, 3) = init;
6693 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6695 else
6696 /* We should have expanded this before. */
6697 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
6699 *expr_p = temp;
6700 return GS_OK;
6703 /* Gimplification of expression trees. */
6705 /* Gimplify an expression which appears at statement context. The
6706 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
6707 NULL, a new sequence is allocated.
6709 Return true if we actually added a statement to the queue. */
6711 bool
6712 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
6714 gimple_seq_node last;
6716 last = gimple_seq_last (*seq_p);
6717 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
6718 return last != gimple_seq_last (*seq_p);
6721 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
6722 to CTX. If entries already exist, force them to be some flavor of private.
6723 If there is no enclosing parallel, do nothing. */
6725 void
6726 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
6728 splay_tree_node n;
6730 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
6731 return;
6735 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6736 if (n != NULL)
6738 if (n->value & GOVD_SHARED)
6739 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
6740 else if (n->value & GOVD_MAP)
6741 n->value |= GOVD_MAP_TO_ONLY;
6742 else
6743 return;
6745 else if ((ctx->region_type & ORT_TARGET) != 0)
6747 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
6748 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6749 else
6750 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
6752 else if (ctx->region_type != ORT_WORKSHARE
6753 && ctx->region_type != ORT_TASKGROUP
6754 && ctx->region_type != ORT_SIMD
6755 && ctx->region_type != ORT_ACC
6756 && !(ctx->region_type & ORT_TARGET_DATA))
6757 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6759 ctx = ctx->outer_context;
6761 while (ctx);
6764 /* Similarly for each of the type sizes of TYPE. */
6766 static void
6767 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
6769 if (type == NULL || type == error_mark_node)
6770 return;
6771 type = TYPE_MAIN_VARIANT (type);
6773 if (ctx->privatized_types->add (type))
6774 return;
6776 switch (TREE_CODE (type))
6778 case INTEGER_TYPE:
6779 case ENUMERAL_TYPE:
6780 case BOOLEAN_TYPE:
6781 case REAL_TYPE:
6782 case FIXED_POINT_TYPE:
6783 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
6784 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
6785 break;
6787 case ARRAY_TYPE:
6788 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6789 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
6790 break;
6792 case RECORD_TYPE:
6793 case UNION_TYPE:
6794 case QUAL_UNION_TYPE:
6796 tree field;
6797 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
6798 if (TREE_CODE (field) == FIELD_DECL)
6800 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
6801 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
6804 break;
6806 case POINTER_TYPE:
6807 case REFERENCE_TYPE:
6808 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6809 break;
6811 default:
6812 break;
6815 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
6816 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
6817 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
6820 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
6822 static void
6823 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
6825 splay_tree_node n;
6826 unsigned int nflags;
6827 tree t;
6829 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
6830 return;
6832 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
6833 there are constructors involved somewhere. Exception is a shared clause,
6834 there is nothing privatized in that case. */
6835 if ((flags & GOVD_SHARED) == 0
6836 && (TREE_ADDRESSABLE (TREE_TYPE (decl))
6837 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
6838 flags |= GOVD_SEEN;
6840 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6841 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
6843 /* We shouldn't be re-adding the decl with the same data
6844 sharing class. */
6845 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
6846 nflags = n->value | flags;
6847 /* The only combination of data sharing classes we should see is
6848 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
6849 reduction variables to be used in data sharing clauses. */
6850 gcc_assert ((ctx->region_type & ORT_ACC) != 0
6851 || ((nflags & GOVD_DATA_SHARE_CLASS)
6852 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
6853 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
6854 n->value = nflags;
6855 return;
6858 /* When adding a variable-sized variable, we have to handle all sorts
6859 of additional bits of data: the pointer replacement variable, and
6860 the parameters of the type. */
6861 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
6863 /* Add the pointer replacement variable as PRIVATE if the variable
6864 replacement is private, else FIRSTPRIVATE since we'll need the
6865 address of the original variable either for SHARED, or for the
6866 copy into or out of the context. */
6867 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
6869 if (flags & GOVD_MAP)
6870 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
6871 else if (flags & GOVD_PRIVATE)
6872 nflags = GOVD_PRIVATE;
6873 else if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
6874 && (flags & GOVD_FIRSTPRIVATE))
6875 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
6876 else
6877 nflags = GOVD_FIRSTPRIVATE;
6878 nflags |= flags & GOVD_SEEN;
6879 t = DECL_VALUE_EXPR (decl);
6880 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
6881 t = TREE_OPERAND (t, 0);
6882 gcc_assert (DECL_P (t));
6883 omp_add_variable (ctx, t, nflags);
6886 /* Add all of the variable and type parameters (which should have
6887 been gimplified to a formal temporary) as FIRSTPRIVATE. */
6888 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
6889 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
6890 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
6892 /* The variable-sized variable itself is never SHARED, only some form
6893 of PRIVATE. The sharing would take place via the pointer variable
6894 which we remapped above. */
6895 if (flags & GOVD_SHARED)
6896 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
6897 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
6899 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
6900 alloca statement we generate for the variable, so make sure it
6901 is available. This isn't automatically needed for the SHARED
6902 case, since we won't be allocating local storage then.
6903 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
6904 in this case omp_notice_variable will be called later
6905 on when it is gimplified. */
6906 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
6907 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
6908 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
6910 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
6911 && lang_hooks.decls.omp_privatize_by_reference (decl))
6913 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
6915 /* Similar to the direct variable sized case above, we'll need the
6916 size of references being privatized. */
6917 if ((flags & GOVD_SHARED) == 0)
6919 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
6920 if (DECL_P (t))
6921 omp_notice_variable (ctx, t, true);
6925 if (n != NULL)
6926 n->value |= flags;
6927 else
6928 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
6930 /* For reductions clauses in OpenACC loop directives, by default create a
6931 copy clause on the enclosing parallel construct for carrying back the
6932 results. */
6933 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
6935 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
6936 while (outer_ctx)
6938 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
6939 if (n != NULL)
6941 /* Ignore local variables and explicitly declared clauses. */
6942 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
6943 break;
6944 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
6946 /* According to the OpenACC spec, such a reduction variable
6947 should already have a copy map on a kernels construct,
6948 verify that here. */
6949 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
6950 && (n->value & GOVD_MAP));
6952 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
6954 /* Remove firstprivate and make it a copy map. */
6955 n->value &= ~GOVD_FIRSTPRIVATE;
6956 n->value |= GOVD_MAP;
6959 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
6961 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
6962 GOVD_MAP | GOVD_SEEN);
6963 break;
6965 outer_ctx = outer_ctx->outer_context;
6970 /* Notice a threadprivate variable DECL used in OMP context CTX.
6971 This just prints out diagnostics about threadprivate variable uses
6972 in untied tasks. If DECL2 is non-NULL, prevent this warning
6973 on that variable. */
6975 static bool
6976 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
6977 tree decl2)
6979 splay_tree_node n;
6980 struct gimplify_omp_ctx *octx;
6982 for (octx = ctx; octx; octx = octx->outer_context)
6983 if ((octx->region_type & ORT_TARGET) != 0)
6985 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
6986 if (n == NULL)
6988 error ("threadprivate variable %qE used in target region",
6989 DECL_NAME (decl));
6990 error_at (octx->location, "enclosing target region");
6991 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
6993 if (decl2)
6994 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
6997 if (ctx->region_type != ORT_UNTIED_TASK)
6998 return false;
6999 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7000 if (n == NULL)
7002 error ("threadprivate variable %qE used in untied task",
7003 DECL_NAME (decl));
7004 error_at (ctx->location, "enclosing task");
7005 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
7007 if (decl2)
7008 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
7009 return false;
7012 /* Return true if global var DECL is device resident. */
7014 static bool
7015 device_resident_p (tree decl)
7017 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
7019 if (!attr)
7020 return false;
7022 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
7024 tree c = TREE_VALUE (t);
7025 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
7026 return true;
7029 return false;
7032 /* Return true if DECL has an ACC DECLARE attribute. */
7034 static bool
7035 is_oacc_declared (tree decl)
7037 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
7038 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
7039 return declared != NULL_TREE;
7042 /* Determine outer default flags for DECL mentioned in an OMP region
7043 but not declared in an enclosing clause.
7045 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7046 remapped firstprivate instead of shared. To some extent this is
7047 addressed in omp_firstprivatize_type_sizes, but not
7048 effectively. */
7050 static unsigned
7051 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
7052 bool in_code, unsigned flags)
7054 enum omp_clause_default_kind default_kind = ctx->default_kind;
7055 enum omp_clause_default_kind kind;
7057 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
7058 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7059 default_kind = kind;
7061 switch (default_kind)
7063 case OMP_CLAUSE_DEFAULT_NONE:
7065 const char *rtype;
7067 if (ctx->region_type & ORT_PARALLEL)
7068 rtype = "parallel";
7069 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
7070 rtype = "taskloop";
7071 else if (ctx->region_type & ORT_TASK)
7072 rtype = "task";
7073 else if (ctx->region_type & ORT_TEAMS)
7074 rtype = "teams";
7075 else
7076 gcc_unreachable ();
7078 error ("%qE not specified in enclosing %qs",
7079 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7080 error_at (ctx->location, "enclosing %qs", rtype);
7082 /* FALLTHRU */
7083 case OMP_CLAUSE_DEFAULT_SHARED:
7084 flags |= GOVD_SHARED;
7085 break;
7086 case OMP_CLAUSE_DEFAULT_PRIVATE:
7087 flags |= GOVD_PRIVATE;
7088 break;
7089 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7090 flags |= GOVD_FIRSTPRIVATE;
7091 break;
7092 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7093 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7094 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7095 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7097 omp_notice_variable (octx, decl, in_code);
7098 for (; octx; octx = octx->outer_context)
7100 splay_tree_node n2;
7102 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7103 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7104 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7105 continue;
7106 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7108 flags |= GOVD_FIRSTPRIVATE;
7109 goto found_outer;
7111 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7113 flags |= GOVD_SHARED;
7114 goto found_outer;
7119 if (TREE_CODE (decl) == PARM_DECL
7120 || (!is_global_var (decl)
7121 && DECL_CONTEXT (decl) == current_function_decl))
7122 flags |= GOVD_FIRSTPRIVATE;
7123 else
7124 flags |= GOVD_SHARED;
7125 found_outer:
7126 break;
7128 default:
7129 gcc_unreachable ();
7132 return flags;
7136 /* Determine outer default flags for DECL mentioned in an OACC region
7137 but not declared in an enclosing clause. */
7139 static unsigned
7140 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7142 const char *rkind;
7143 bool on_device = false;
7144 bool declared = is_oacc_declared (decl);
7145 tree type = TREE_TYPE (decl);
7147 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7148 type = TREE_TYPE (type);
7150 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7151 && is_global_var (decl)
7152 && device_resident_p (decl))
7154 on_device = true;
7155 flags |= GOVD_MAP_TO_ONLY;
7158 switch (ctx->region_type)
7160 case ORT_ACC_KERNELS:
7161 rkind = "kernels";
7163 if (AGGREGATE_TYPE_P (type))
7165 /* Aggregates default to 'present_or_copy', or 'present'. */
7166 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7167 flags |= GOVD_MAP;
7168 else
7169 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7171 else
7172 /* Scalars default to 'copy'. */
7173 flags |= GOVD_MAP | GOVD_MAP_FORCE;
7175 break;
7177 case ORT_ACC_PARALLEL:
7178 rkind = "parallel";
7180 if (on_device || declared)
7181 flags |= GOVD_MAP;
7182 else if (AGGREGATE_TYPE_P (type))
7184 /* Aggregates default to 'present_or_copy', or 'present'. */
7185 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7186 flags |= GOVD_MAP;
7187 else
7188 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7190 else
7191 /* Scalars default to 'firstprivate'. */
7192 flags |= GOVD_FIRSTPRIVATE;
7194 break;
7196 default:
7197 gcc_unreachable ();
7200 if (DECL_ARTIFICIAL (decl))
7201 ; /* We can get compiler-generated decls, and should not complain
7202 about them. */
7203 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7205 error ("%qE not specified in enclosing OpenACC %qs construct",
7206 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
7207 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
7209 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7210 ; /* Handled above. */
7211 else
7212 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7214 return flags;
7217 /* Record the fact that DECL was used within the OMP context CTX.
7218 IN_CODE is true when real code uses DECL, and false when we should
7219 merely emit default(none) errors. Return true if DECL is going to
7220 be remapped and thus DECL shouldn't be gimplified into its
7221 DECL_VALUE_EXPR (if any). */
7223 static bool
7224 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7226 splay_tree_node n;
7227 unsigned flags = in_code ? GOVD_SEEN : 0;
7228 bool ret = false, shared;
7230 if (error_operand_p (decl))
7231 return false;
7233 if (ctx->region_type == ORT_NONE)
7234 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7236 if (is_global_var (decl))
7238 /* Threadprivate variables are predetermined. */
7239 if (DECL_THREAD_LOCAL_P (decl))
7240 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7242 if (DECL_HAS_VALUE_EXPR_P (decl))
7244 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7246 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7247 return omp_notice_threadprivate_variable (ctx, decl, value);
7250 if (gimplify_omp_ctxp->outer_context == NULL
7251 && VAR_P (decl)
7252 && oacc_get_fn_attrib (current_function_decl))
7254 location_t loc = DECL_SOURCE_LOCATION (decl);
7256 if (lookup_attribute ("omp declare target link",
7257 DECL_ATTRIBUTES (decl)))
7259 error_at (loc,
7260 "%qE with %<link%> clause used in %<routine%> function",
7261 DECL_NAME (decl));
7262 return false;
7264 else if (!lookup_attribute ("omp declare target",
7265 DECL_ATTRIBUTES (decl)))
7267 error_at (loc,
7268 "%qE requires a %<declare%> directive for use "
7269 "in a %<routine%> function", DECL_NAME (decl));
7270 return false;
7275 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7276 if ((ctx->region_type & ORT_TARGET) != 0)
7278 ret = lang_hooks.decls.omp_disregard_value_expr (decl, true);
7279 if (n == NULL)
7281 unsigned nflags = flags;
7282 if ((ctx->region_type & ORT_ACC) == 0)
7284 bool is_declare_target = false;
7285 if (is_global_var (decl)
7286 && varpool_node::get_create (decl)->offloadable)
7288 struct gimplify_omp_ctx *octx;
7289 for (octx = ctx->outer_context;
7290 octx; octx = octx->outer_context)
7292 n = splay_tree_lookup (octx->variables,
7293 (splay_tree_key)decl);
7294 if (n
7295 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7296 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7297 break;
7299 is_declare_target = octx == NULL;
7301 if (!is_declare_target)
7303 int gdmk;
7304 if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7305 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7306 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7307 == POINTER_TYPE)))
7308 gdmk = GDMK_POINTER;
7309 else if (lang_hooks.decls.omp_scalar_p (decl))
7310 gdmk = GDMK_SCALAR;
7311 else
7312 gdmk = GDMK_AGGREGATE;
7313 if (ctx->defaultmap[gdmk] == 0)
7315 tree d = lang_hooks.decls.omp_report_decl (decl);
7316 error ("%qE not specified in enclosing %<target%>",
7317 DECL_NAME (d));
7318 error_at (ctx->location, "enclosing %<target%>");
7320 else if (ctx->defaultmap[gdmk]
7321 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
7322 nflags |= ctx->defaultmap[gdmk];
7323 else
7325 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
7326 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
7331 struct gimplify_omp_ctx *octx = ctx->outer_context;
7332 if ((ctx->region_type & ORT_ACC) && octx)
7334 /* Look in outer OpenACC contexts, to see if there's a
7335 data attribute for this variable. */
7336 omp_notice_variable (octx, decl, in_code);
7338 for (; octx; octx = octx->outer_context)
7340 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7341 break;
7342 splay_tree_node n2
7343 = splay_tree_lookup (octx->variables,
7344 (splay_tree_key) decl);
7345 if (n2)
7347 if (octx->region_type == ORT_ACC_HOST_DATA)
7348 error ("variable %qE declared in enclosing "
7349 "%<host_data%> region", DECL_NAME (decl));
7350 nflags |= GOVD_MAP;
7351 if (octx->region_type == ORT_ACC_DATA
7352 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7353 nflags |= GOVD_MAP_0LEN_ARRAY;
7354 goto found_outer;
7359 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
7360 | GOVD_MAP_ALLOC_ONLY)) == flags)
7362 tree type = TREE_TYPE (decl);
7364 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
7365 && lang_hooks.decls.omp_privatize_by_reference (decl))
7366 type = TREE_TYPE (type);
7367 if (!lang_hooks.types.omp_mappable_type (type))
7369 error ("%qD referenced in target region does not have "
7370 "a mappable type", decl);
7371 nflags |= GOVD_MAP | GOVD_EXPLICIT;
7373 else
7375 if ((ctx->region_type & ORT_ACC) != 0)
7376 nflags = oacc_default_clause (ctx, decl, flags);
7377 else
7378 nflags |= GOVD_MAP;
7381 found_outer:
7382 omp_add_variable (ctx, decl, nflags);
7384 else
7386 /* If nothing changed, there's nothing left to do. */
7387 if ((n->value & flags) == flags)
7388 return ret;
7389 flags |= n->value;
7390 n->value = flags;
7392 goto do_outer;
7395 if (n == NULL)
7397 if (ctx->region_type == ORT_WORKSHARE
7398 || ctx->region_type == ORT_TASKGROUP
7399 || ctx->region_type == ORT_SIMD
7400 || ctx->region_type == ORT_ACC
7401 || (ctx->region_type & ORT_TARGET_DATA) != 0)
7402 goto do_outer;
7404 flags = omp_default_clause (ctx, decl, in_code, flags);
7406 if ((flags & GOVD_PRIVATE)
7407 && lang_hooks.decls.omp_private_outer_ref (decl))
7408 flags |= GOVD_PRIVATE_OUTER_REF;
7410 omp_add_variable (ctx, decl, flags);
7412 shared = (flags & GOVD_SHARED) != 0;
7413 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7414 goto do_outer;
7417 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7418 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7419 && DECL_SIZE (decl))
7421 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7423 splay_tree_node n2;
7424 tree t = DECL_VALUE_EXPR (decl);
7425 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7426 t = TREE_OPERAND (t, 0);
7427 gcc_assert (DECL_P (t));
7428 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7429 n2->value |= GOVD_SEEN;
7431 else if (lang_hooks.decls.omp_privatize_by_reference (decl)
7432 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7433 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7434 != INTEGER_CST))
7436 splay_tree_node n2;
7437 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7438 gcc_assert (DECL_P (t));
7439 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7440 if (n2)
7441 omp_notice_variable (ctx, t, true);
7445 shared = ((flags | n->value) & GOVD_SHARED) != 0;
7446 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7448 /* If nothing changed, there's nothing left to do. */
7449 if ((n->value & flags) == flags)
7450 return ret;
7451 flags |= n->value;
7452 n->value = flags;
7454 do_outer:
7455 /* If the variable is private in the current context, then we don't
7456 need to propagate anything to an outer context. */
7457 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7458 return ret;
7459 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7460 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7461 return ret;
7462 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7463 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7464 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7465 return ret;
7466 if (ctx->outer_context
7467 && omp_notice_variable (ctx->outer_context, decl, in_code))
7468 return true;
7469 return ret;
7472 /* Verify that DECL is private within CTX. If there's specific information
7473 to the contrary in the innermost scope, generate an error. */
7475 static bool
7476 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
7478 splay_tree_node n;
7480 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7481 if (n != NULL)
7483 if (n->value & GOVD_SHARED)
7485 if (ctx == gimplify_omp_ctxp)
7487 if (simd)
7488 error ("iteration variable %qE is predetermined linear",
7489 DECL_NAME (decl));
7490 else
7491 error ("iteration variable %qE should be private",
7492 DECL_NAME (decl));
7493 n->value = GOVD_PRIVATE;
7494 return true;
7496 else
7497 return false;
7499 else if ((n->value & GOVD_EXPLICIT) != 0
7500 && (ctx == gimplify_omp_ctxp
7501 || (ctx->region_type == ORT_COMBINED_PARALLEL
7502 && gimplify_omp_ctxp->outer_context == ctx)))
7504 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
7505 error ("iteration variable %qE should not be firstprivate",
7506 DECL_NAME (decl));
7507 else if ((n->value & GOVD_REDUCTION) != 0)
7508 error ("iteration variable %qE should not be reduction",
7509 DECL_NAME (decl));
7510 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
7511 error ("iteration variable %qE should not be linear",
7512 DECL_NAME (decl));
7514 return (ctx == gimplify_omp_ctxp
7515 || (ctx->region_type == ORT_COMBINED_PARALLEL
7516 && gimplify_omp_ctxp->outer_context == ctx));
7519 if (ctx->region_type != ORT_WORKSHARE
7520 && ctx->region_type != ORT_TASKGROUP
7521 && ctx->region_type != ORT_SIMD
7522 && ctx->region_type != ORT_ACC)
7523 return false;
7524 else if (ctx->outer_context)
7525 return omp_is_private (ctx->outer_context, decl, simd);
7526 return false;
7529 /* Return true if DECL is private within a parallel region
7530 that binds to the current construct's context or in parallel
7531 region's REDUCTION clause. */
7533 static bool
7534 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
7536 splay_tree_node n;
7540 ctx = ctx->outer_context;
7541 if (ctx == NULL)
7543 if (is_global_var (decl))
7544 return false;
7546 /* References might be private, but might be shared too,
7547 when checking for copyprivate, assume they might be
7548 private, otherwise assume they might be shared. */
7549 if (copyprivate)
7550 return true;
7552 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7553 return false;
7555 /* Treat C++ privatized non-static data members outside
7556 of the privatization the same. */
7557 if (omp_member_access_dummy_var (decl))
7558 return false;
7560 return true;
7563 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
7565 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7566 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
7567 continue;
7569 if (n != NULL)
7571 if ((n->value & GOVD_LOCAL) != 0
7572 && omp_member_access_dummy_var (decl))
7573 return false;
7574 return (n->value & GOVD_SHARED) == 0;
7577 while (ctx->region_type == ORT_WORKSHARE
7578 || ctx->region_type == ORT_TASKGROUP
7579 || ctx->region_type == ORT_SIMD
7580 || ctx->region_type == ORT_ACC);
7581 return false;
7584 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7586 static tree
7587 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
7589 tree t = *tp;
7591 /* If this node has been visited, unmark it and keep looking. */
7592 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
7593 return t;
7595 if (IS_TYPE_OR_DECL_P (t))
7596 *walk_subtrees = 0;
7597 return NULL_TREE;
7600 /* If *LIST_P contains any OpenMP depend clauses with iterators,
7601 lower all the depend clauses by populating corresponding depend
7602 array. Returns 0 if there are no such depend clauses, or
7603 2 if all depend clauses should be removed, 1 otherwise. */
7605 static int
7606 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
7608 tree c;
7609 gimple *g;
7610 size_t n[4] = { 0, 0, 0, 0 };
7611 bool unused[4];
7612 tree counts[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
7613 tree last_iter = NULL_TREE, last_count = NULL_TREE;
7614 size_t i, j;
7615 location_t first_loc = UNKNOWN_LOCATION;
7617 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
7618 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
7620 switch (OMP_CLAUSE_DEPEND_KIND (c))
7622 case OMP_CLAUSE_DEPEND_IN:
7623 i = 2;
7624 break;
7625 case OMP_CLAUSE_DEPEND_OUT:
7626 case OMP_CLAUSE_DEPEND_INOUT:
7627 i = 0;
7628 break;
7629 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
7630 i = 1;
7631 break;
7632 case OMP_CLAUSE_DEPEND_DEPOBJ:
7633 i = 3;
7634 break;
7635 case OMP_CLAUSE_DEPEND_SOURCE:
7636 case OMP_CLAUSE_DEPEND_SINK:
7637 continue;
7638 default:
7639 gcc_unreachable ();
7641 tree t = OMP_CLAUSE_DECL (c);
7642 if (first_loc == UNKNOWN_LOCATION)
7643 first_loc = OMP_CLAUSE_LOCATION (c);
7644 if (TREE_CODE (t) == TREE_LIST
7645 && TREE_PURPOSE (t)
7646 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
7648 if (TREE_PURPOSE (t) != last_iter)
7650 tree tcnt = size_one_node;
7651 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
7653 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
7654 is_gimple_val, fb_rvalue) == GS_ERROR
7655 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
7656 is_gimple_val, fb_rvalue) == GS_ERROR
7657 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
7658 is_gimple_val, fb_rvalue) == GS_ERROR
7659 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
7660 is_gimple_val, fb_rvalue)
7661 == GS_ERROR))
7662 return 2;
7663 tree var = TREE_VEC_ELT (it, 0);
7664 tree begin = TREE_VEC_ELT (it, 1);
7665 tree end = TREE_VEC_ELT (it, 2);
7666 tree step = TREE_VEC_ELT (it, 3);
7667 tree orig_step = TREE_VEC_ELT (it, 4);
7668 tree type = TREE_TYPE (var);
7669 tree stype = TREE_TYPE (step);
7670 location_t loc = DECL_SOURCE_LOCATION (var);
7671 tree endmbegin;
7672 /* Compute count for this iterator as
7673 orig_step > 0
7674 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
7675 : (begin > end ? (end - begin + (step + 1)) / step : 0)
7676 and compute product of those for the entire depend
7677 clause. */
7678 if (POINTER_TYPE_P (type))
7679 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
7680 stype, end, begin);
7681 else
7682 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
7683 end, begin);
7684 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
7685 step,
7686 build_int_cst (stype, 1));
7687 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
7688 build_int_cst (stype, 1));
7689 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
7690 unshare_expr (endmbegin),
7691 stepm1);
7692 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
7693 pos, step);
7694 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
7695 endmbegin, stepp1);
7696 if (TYPE_UNSIGNED (stype))
7698 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
7699 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
7701 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
7702 neg, step);
7703 step = NULL_TREE;
7704 tree cond = fold_build2_loc (loc, LT_EXPR,
7705 boolean_type_node,
7706 begin, end);
7707 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
7708 build_int_cst (stype, 0));
7709 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
7710 end, begin);
7711 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
7712 build_int_cst (stype, 0));
7713 tree osteptype = TREE_TYPE (orig_step);
7714 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
7715 orig_step,
7716 build_int_cst (osteptype, 0));
7717 tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
7718 cond, pos, neg);
7719 cnt = fold_convert_loc (loc, sizetype, cnt);
7720 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
7721 fb_rvalue) == GS_ERROR)
7722 return 2;
7723 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
7725 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
7726 fb_rvalue) == GS_ERROR)
7727 return 2;
7728 last_iter = TREE_PURPOSE (t);
7729 last_count = tcnt;
7731 if (counts[i] == NULL_TREE)
7732 counts[i] = last_count;
7733 else
7734 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
7735 PLUS_EXPR, counts[i], last_count);
7737 else
7738 n[i]++;
7740 for (i = 0; i < 4; i++)
7741 if (counts[i])
7742 break;
7743 if (i == 4)
7744 return 0;
7746 tree total = size_zero_node;
7747 for (i = 0; i < 4; i++)
7749 unused[i] = counts[i] == NULL_TREE && n[i] == 0;
7750 if (counts[i] == NULL_TREE)
7751 counts[i] = size_zero_node;
7752 if (n[i])
7753 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
7754 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
7755 fb_rvalue) == GS_ERROR)
7756 return 2;
7757 total = size_binop (PLUS_EXPR, total, counts[i]);
7760 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
7761 == GS_ERROR)
7762 return 2;
7763 bool is_old = unused[1] && unused[3];
7764 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
7765 size_int (is_old ? 1 : 4));
7766 tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
7767 tree array = create_tmp_var_raw (type);
7768 TREE_ADDRESSABLE (array) = 1;
7769 if (TREE_CODE (totalpx) != INTEGER_CST)
7771 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
7772 gimplify_type_sizes (TREE_TYPE (array), pre_p);
7773 if (gimplify_omp_ctxp)
7775 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
7776 while (ctx
7777 && (ctx->region_type == ORT_WORKSHARE
7778 || ctx->region_type == ORT_TASKGROUP
7779 || ctx->region_type == ORT_SIMD
7780 || ctx->region_type == ORT_ACC))
7781 ctx = ctx->outer_context;
7782 if (ctx)
7783 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
7785 gimplify_vla_decl (array, pre_p);
7787 else
7788 gimple_add_tmp_var (array);
7789 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
7790 NULL_TREE);
7791 tree tem;
7792 if (!is_old)
7794 tem = build2 (MODIFY_EXPR, void_type_node, r,
7795 build_int_cst (ptr_type_node, 0));
7796 gimplify_and_add (tem, pre_p);
7797 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
7798 NULL_TREE);
7800 tem = build2 (MODIFY_EXPR, void_type_node, r,
7801 fold_convert (ptr_type_node, total));
7802 gimplify_and_add (tem, pre_p);
7803 for (i = 1; i < (is_old ? 2 : 4); i++)
7805 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
7806 NULL_TREE, NULL_TREE);
7807 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
7808 gimplify_and_add (tem, pre_p);
7811 tree cnts[4];
7812 for (j = 4; j; j--)
7813 if (!unused[j - 1])
7814 break;
7815 for (i = 0; i < 4; i++)
7817 if (i && (i >= j || unused[i - 1]))
7819 cnts[i] = cnts[i - 1];
7820 continue;
7822 cnts[i] = create_tmp_var (sizetype);
7823 if (i == 0)
7824 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
7825 else
7827 tree t;
7828 if (is_old)
7829 t = size_binop (PLUS_EXPR, counts[0], size_int (2));
7830 else
7831 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
7832 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
7833 == GS_ERROR)
7834 return 2;
7835 g = gimple_build_assign (cnts[i], t);
7837 gimple_seq_add_stmt (pre_p, g);
7840 last_iter = NULL_TREE;
7841 tree last_bind = NULL_TREE;
7842 tree *last_body = NULL;
7843 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
7844 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
7846 switch (OMP_CLAUSE_DEPEND_KIND (c))
7848 case OMP_CLAUSE_DEPEND_IN:
7849 i = 2;
7850 break;
7851 case OMP_CLAUSE_DEPEND_OUT:
7852 case OMP_CLAUSE_DEPEND_INOUT:
7853 i = 0;
7854 break;
7855 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
7856 i = 1;
7857 break;
7858 case OMP_CLAUSE_DEPEND_DEPOBJ:
7859 i = 3;
7860 break;
7861 case OMP_CLAUSE_DEPEND_SOURCE:
7862 case OMP_CLAUSE_DEPEND_SINK:
7863 continue;
7864 default:
7865 gcc_unreachable ();
7867 tree t = OMP_CLAUSE_DECL (c);
7868 if (TREE_CODE (t) == TREE_LIST
7869 && TREE_PURPOSE (t)
7870 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
7872 if (TREE_PURPOSE (t) != last_iter)
7874 if (last_bind)
7875 gimplify_and_add (last_bind, pre_p);
7876 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
7877 last_bind = build3 (BIND_EXPR, void_type_node,
7878 BLOCK_VARS (block), NULL, block);
7879 TREE_SIDE_EFFECTS (last_bind) = 1;
7880 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
7881 tree *p = &BIND_EXPR_BODY (last_bind);
7882 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
7884 tree var = TREE_VEC_ELT (it, 0);
7885 tree begin = TREE_VEC_ELT (it, 1);
7886 tree end = TREE_VEC_ELT (it, 2);
7887 tree step = TREE_VEC_ELT (it, 3);
7888 tree orig_step = TREE_VEC_ELT (it, 4);
7889 tree type = TREE_TYPE (var);
7890 location_t loc = DECL_SOURCE_LOCATION (var);
7891 /* Emit:
7892 var = begin;
7893 goto cond_label;
7894 beg_label:
7896 var = var + step;
7897 cond_label:
7898 if (orig_step > 0) {
7899 if (var < end) goto beg_label;
7900 } else {
7901 if (var > end) goto beg_label;
7903 for each iterator, with inner iterators added to
7904 the ... above. */
7905 tree beg_label = create_artificial_label (loc);
7906 tree cond_label = NULL_TREE;
7907 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
7908 var, begin);
7909 append_to_statement_list_force (tem, p);
7910 tem = build_and_jump (&cond_label);
7911 append_to_statement_list_force (tem, p);
7912 tem = build1 (LABEL_EXPR, void_type_node, beg_label);
7913 append_to_statement_list (tem, p);
7914 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
7915 NULL_TREE, NULL_TREE);
7916 TREE_SIDE_EFFECTS (bind) = 1;
7917 SET_EXPR_LOCATION (bind, loc);
7918 append_to_statement_list_force (bind, p);
7919 if (POINTER_TYPE_P (type))
7920 tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
7921 var, fold_convert_loc (loc, sizetype,
7922 step));
7923 else
7924 tem = build2_loc (loc, PLUS_EXPR, type, var, step);
7925 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
7926 var, tem);
7927 append_to_statement_list_force (tem, p);
7928 tem = build1 (LABEL_EXPR, void_type_node, cond_label);
7929 append_to_statement_list (tem, p);
7930 tree cond = fold_build2_loc (loc, LT_EXPR,
7931 boolean_type_node,
7932 var, end);
7933 tree pos
7934 = fold_build3_loc (loc, COND_EXPR, void_type_node,
7935 cond, build_and_jump (&beg_label),
7936 void_node);
7937 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
7938 var, end);
7939 tree neg
7940 = fold_build3_loc (loc, COND_EXPR, void_type_node,
7941 cond, build_and_jump (&beg_label),
7942 void_node);
7943 tree osteptype = TREE_TYPE (orig_step);
7944 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
7945 orig_step,
7946 build_int_cst (osteptype, 0));
7947 tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
7948 cond, pos, neg);
7949 append_to_statement_list_force (tem, p);
7950 p = &BIND_EXPR_BODY (bind);
7952 last_body = p;
7954 last_iter = TREE_PURPOSE (t);
7955 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
7957 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
7958 0), last_body);
7959 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
7961 if (error_operand_p (TREE_VALUE (t)))
7962 return 2;
7963 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
7964 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
7965 NULL_TREE, NULL_TREE);
7966 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
7967 void_type_node, r, TREE_VALUE (t));
7968 append_to_statement_list_force (tem, last_body);
7969 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
7970 void_type_node, cnts[i],
7971 size_binop (PLUS_EXPR, cnts[i], size_int (1)));
7972 append_to_statement_list_force (tem, last_body);
7973 TREE_VALUE (t) = null_pointer_node;
7975 else
7977 if (last_bind)
7979 gimplify_and_add (last_bind, pre_p);
7980 last_bind = NULL_TREE;
7982 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
7984 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
7985 NULL, is_gimple_val, fb_rvalue);
7986 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
7988 if (error_operand_p (OMP_CLAUSE_DECL (c)))
7989 return 2;
7990 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
7991 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
7992 is_gimple_val, fb_rvalue) == GS_ERROR)
7993 return 2;
7994 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
7995 NULL_TREE, NULL_TREE);
7996 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
7997 gimplify_and_add (tem, pre_p);
7998 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, cnts[i],
7999 size_int (1)));
8000 gimple_seq_add_stmt (pre_p, g);
8003 if (last_bind)
8004 gimplify_and_add (last_bind, pre_p);
8005 tree cond = boolean_false_node;
8006 if (is_old)
8008 if (!unused[0])
8009 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
8010 size_binop_loc (first_loc, PLUS_EXPR, counts[0],
8011 size_int (2)));
8012 if (!unused[2])
8013 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8014 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8015 cnts[2],
8016 size_binop_loc (first_loc, PLUS_EXPR,
8017 totalpx,
8018 size_int (1))));
8020 else
8022 tree prev = size_int (5);
8023 for (i = 0; i < 4; i++)
8025 if (unused[i])
8026 continue;
8027 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
8028 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8029 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8030 cnts[i], unshare_expr (prev)));
8033 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
8034 build_call_expr_loc (first_loc,
8035 builtin_decl_explicit (BUILT_IN_TRAP),
8036 0), void_node);
8037 gimplify_and_add (tem, pre_p);
8038 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
8039 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
8040 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
8041 OMP_CLAUSE_CHAIN (c) = *list_p;
8042 *list_p = c;
8043 return 1;
8046 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
8047 and previous omp contexts. */
8049 static void
8050 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
8051 enum omp_region_type region_type,
8052 enum tree_code code)
8054 struct gimplify_omp_ctx *ctx, *outer_ctx;
8055 tree c;
8056 hash_map<tree, tree> *struct_map_to_clause = NULL;
8057 tree *prev_list_p = NULL;
8058 int handled_depend_iterators = -1;
8059 int nowait = -1;
8061 ctx = new_omp_context (region_type);
8062 outer_ctx = ctx->outer_context;
8063 if (code == OMP_TARGET)
8065 if (!lang_GNU_Fortran ())
8066 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
8067 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
8069 if (!lang_GNU_Fortran ())
8070 switch (code)
8072 case OMP_TARGET:
8073 case OMP_TARGET_DATA:
8074 case OMP_TARGET_ENTER_DATA:
8075 case OMP_TARGET_EXIT_DATA:
8076 case OACC_DECLARE:
8077 case OACC_HOST_DATA:
8078 case OACC_PARALLEL:
8079 case OACC_KERNELS:
8080 ctx->target_firstprivatize_array_bases = true;
8081 default:
8082 break;
8085 while ((c = *list_p) != NULL)
8087 bool remove = false;
8088 bool notice_outer = true;
8089 const char *check_non_private = NULL;
8090 unsigned int flags;
8091 tree decl;
8093 switch (OMP_CLAUSE_CODE (c))
8095 case OMP_CLAUSE_PRIVATE:
8096 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
8097 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
8099 flags |= GOVD_PRIVATE_OUTER_REF;
8100 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
8102 else
8103 notice_outer = false;
8104 goto do_add;
8105 case OMP_CLAUSE_SHARED:
8106 flags = GOVD_SHARED | GOVD_EXPLICIT;
8107 goto do_add;
8108 case OMP_CLAUSE_FIRSTPRIVATE:
8109 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8110 check_non_private = "firstprivate";
8111 goto do_add;
8112 case OMP_CLAUSE_LASTPRIVATE:
8113 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
8114 switch (code)
8116 case OMP_DISTRIBUTE:
8117 error_at (OMP_CLAUSE_LOCATION (c),
8118 "conditional %<lastprivate%> clause on "
8119 "%<distribute%> construct");
8120 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8121 break;
8122 case OMP_TASKLOOP:
8123 error_at (OMP_CLAUSE_LOCATION (c),
8124 "conditional %<lastprivate%> clause on "
8125 "%<taskloop%> construct");
8126 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8127 break;
8128 default:
8129 break;
8131 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
8132 check_non_private = "lastprivate";
8133 decl = OMP_CLAUSE_DECL (c);
8134 if (error_operand_p (decl))
8135 goto do_add;
8136 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
8137 && !lang_hooks.decls.omp_scalar_p (decl))
8139 error_at (OMP_CLAUSE_LOCATION (c),
8140 "non-scalar variable %qD in conditional "
8141 "%<lastprivate%> clause", decl);
8142 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8144 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
8146 if (code == OMP_FOR || code == OMP_SECTIONS)
8147 flags |= GOVD_LASTPRIVATE_CONDITIONAL;
8148 else
8150 sorry_at (OMP_CLAUSE_LOCATION (c),
8151 "%<conditional%> modifier on %<lastprivate%> "
8152 "clause not supported yet");
8153 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8156 if (outer_ctx
8157 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
8158 || ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
8159 == ORT_COMBINED_TEAMS))
8160 && splay_tree_lookup (outer_ctx->variables,
8161 (splay_tree_key) decl) == NULL)
8163 omp_add_variable (outer_ctx, decl, GOVD_SHARED | GOVD_SEEN);
8164 if (outer_ctx->outer_context)
8165 omp_notice_variable (outer_ctx->outer_context, decl, true);
8167 else if (outer_ctx
8168 && (outer_ctx->region_type & ORT_TASK) != 0
8169 && outer_ctx->combined_loop
8170 && splay_tree_lookup (outer_ctx->variables,
8171 (splay_tree_key) decl) == NULL)
8173 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8174 if (outer_ctx->outer_context)
8175 omp_notice_variable (outer_ctx->outer_context, decl, true);
8177 else if (outer_ctx
8178 && (outer_ctx->region_type == ORT_WORKSHARE
8179 || outer_ctx->region_type == ORT_ACC)
8180 && outer_ctx->combined_loop
8181 && splay_tree_lookup (outer_ctx->variables,
8182 (splay_tree_key) decl) == NULL
8183 && !omp_check_private (outer_ctx, decl, false))
8185 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8186 if (outer_ctx->outer_context
8187 && (outer_ctx->outer_context->region_type
8188 == ORT_COMBINED_PARALLEL)
8189 && splay_tree_lookup (outer_ctx->outer_context->variables,
8190 (splay_tree_key) decl) == NULL)
8192 struct gimplify_omp_ctx *octx = outer_ctx->outer_context;
8193 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
8194 if (octx->outer_context)
8196 octx = octx->outer_context;
8197 if (octx->region_type == ORT_WORKSHARE
8198 && octx->combined_loop
8199 && splay_tree_lookup (octx->variables,
8200 (splay_tree_key) decl) == NULL
8201 && !omp_check_private (octx, decl, false))
8203 omp_add_variable (octx, decl,
8204 GOVD_LASTPRIVATE | GOVD_SEEN);
8205 octx = octx->outer_context;
8206 if (octx
8207 && ((octx->region_type & ORT_COMBINED_TEAMS)
8208 == ORT_COMBINED_TEAMS)
8209 && (splay_tree_lookup (octx->variables,
8210 (splay_tree_key) decl)
8211 == NULL))
8213 omp_add_variable (octx, decl,
8214 GOVD_SHARED | GOVD_SEEN);
8215 octx = octx->outer_context;
8218 if (octx)
8219 omp_notice_variable (octx, decl, true);
8222 else if (outer_ctx->outer_context)
8223 omp_notice_variable (outer_ctx->outer_context, decl, true);
8225 goto do_add;
8226 case OMP_CLAUSE_REDUCTION:
8227 if (OMP_CLAUSE_REDUCTION_TASK (c))
8229 if (region_type == ORT_WORKSHARE)
8231 if (nowait == -1)
8232 nowait = omp_find_clause (*list_p,
8233 OMP_CLAUSE_NOWAIT) != NULL_TREE;
8234 if (nowait
8235 && (outer_ctx == NULL
8236 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
8238 error_at (OMP_CLAUSE_LOCATION (c),
8239 "%<task%> reduction modifier on a construct "
8240 "with a %<nowait%> clause");
8241 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
8244 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
8246 error_at (OMP_CLAUSE_LOCATION (c),
8247 "invalid %<task%> reduction modifier on construct "
8248 "other than %<parallel%>, %<for%> or %<sections%>");
8249 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
8252 /* FALLTHRU */
8253 case OMP_CLAUSE_IN_REDUCTION:
8254 case OMP_CLAUSE_TASK_REDUCTION:
8255 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
8256 /* OpenACC permits reductions on private variables. */
8257 if (!(region_type & ORT_ACC)
8258 /* taskgroup is actually not a worksharing region. */
8259 && code != OMP_TASKGROUP)
8260 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
8261 decl = OMP_CLAUSE_DECL (c);
8262 if (TREE_CODE (decl) == MEM_REF)
8264 tree type = TREE_TYPE (decl);
8265 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
8266 NULL, is_gimple_val, fb_rvalue, false)
8267 == GS_ERROR)
8269 remove = true;
8270 break;
8272 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
8273 if (DECL_P (v))
8275 omp_firstprivatize_variable (ctx, v);
8276 omp_notice_variable (ctx, v, true);
8278 decl = TREE_OPERAND (decl, 0);
8279 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
8281 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
8282 NULL, is_gimple_val, fb_rvalue, false)
8283 == GS_ERROR)
8285 remove = true;
8286 break;
8288 v = TREE_OPERAND (decl, 1);
8289 if (DECL_P (v))
8291 omp_firstprivatize_variable (ctx, v);
8292 omp_notice_variable (ctx, v, true);
8294 decl = TREE_OPERAND (decl, 0);
8296 if (TREE_CODE (decl) == ADDR_EXPR
8297 || TREE_CODE (decl) == INDIRECT_REF)
8298 decl = TREE_OPERAND (decl, 0);
8300 goto do_add_decl;
8301 case OMP_CLAUSE_LINEAR:
8302 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
8303 is_gimple_val, fb_rvalue) == GS_ERROR)
8305 remove = true;
8306 break;
8308 else
8310 if (code == OMP_SIMD
8311 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
8313 struct gimplify_omp_ctx *octx = outer_ctx;
8314 if (octx
8315 && octx->region_type == ORT_WORKSHARE
8316 && octx->combined_loop
8317 && !octx->distribute)
8319 if (octx->outer_context
8320 && (octx->outer_context->region_type
8321 == ORT_COMBINED_PARALLEL))
8322 octx = octx->outer_context->outer_context;
8323 else
8324 octx = octx->outer_context;
8326 if (octx
8327 && octx->region_type == ORT_WORKSHARE
8328 && octx->combined_loop
8329 && octx->distribute)
8331 error_at (OMP_CLAUSE_LOCATION (c),
8332 "%<linear%> clause for variable other than "
8333 "loop iterator specified on construct "
8334 "combined with %<distribute%>");
8335 remove = true;
8336 break;
8339 /* For combined #pragma omp parallel for simd, need to put
8340 lastprivate and perhaps firstprivate too on the
8341 parallel. Similarly for #pragma omp for simd. */
8342 struct gimplify_omp_ctx *octx = outer_ctx;
8343 decl = NULL_TREE;
8346 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8347 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8348 break;
8349 decl = OMP_CLAUSE_DECL (c);
8350 if (error_operand_p (decl))
8352 decl = NULL_TREE;
8353 break;
8355 flags = GOVD_SEEN;
8356 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
8357 flags |= GOVD_FIRSTPRIVATE;
8358 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8359 flags |= GOVD_LASTPRIVATE;
8360 if (octx
8361 && octx->region_type == ORT_WORKSHARE
8362 && octx->combined_loop)
8364 if (octx->outer_context
8365 && (octx->outer_context->region_type
8366 == ORT_COMBINED_PARALLEL))
8367 octx = octx->outer_context;
8368 else if (omp_check_private (octx, decl, false))
8369 break;
8371 else if (octx
8372 && (octx->region_type & ORT_TASK) != 0
8373 && octx->combined_loop)
8375 else if (octx
8376 && octx->region_type == ORT_COMBINED_PARALLEL
8377 && ctx->region_type == ORT_WORKSHARE
8378 && octx == outer_ctx)
8379 flags = GOVD_SEEN | GOVD_SHARED;
8380 else if (octx
8381 && ((octx->region_type & ORT_COMBINED_TEAMS)
8382 == ORT_COMBINED_TEAMS))
8383 flags = GOVD_SEEN | GOVD_SHARED;
8384 else if (octx
8385 && octx->region_type == ORT_COMBINED_TARGET)
8387 flags &= ~GOVD_LASTPRIVATE;
8388 if (flags == GOVD_SEEN)
8389 break;
8391 else
8392 break;
8393 splay_tree_node on
8394 = splay_tree_lookup (octx->variables,
8395 (splay_tree_key) decl);
8396 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
8398 octx = NULL;
8399 break;
8401 omp_add_variable (octx, decl, flags);
8402 if (octx->outer_context == NULL)
8403 break;
8404 octx = octx->outer_context;
8406 while (1);
8407 if (octx
8408 && decl
8409 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8410 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
8411 omp_notice_variable (octx, decl, true);
8413 flags = GOVD_LINEAR | GOVD_EXPLICIT;
8414 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8415 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8417 notice_outer = false;
8418 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
8420 goto do_add;
8422 case OMP_CLAUSE_MAP:
8423 decl = OMP_CLAUSE_DECL (c);
8424 if (error_operand_p (decl))
8425 remove = true;
8426 switch (code)
8428 case OMP_TARGET:
8429 break;
8430 case OACC_DATA:
8431 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
8432 break;
8433 /* FALLTHRU */
8434 case OMP_TARGET_DATA:
8435 case OMP_TARGET_ENTER_DATA:
8436 case OMP_TARGET_EXIT_DATA:
8437 case OACC_ENTER_DATA:
8438 case OACC_EXIT_DATA:
8439 case OACC_HOST_DATA:
8440 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
8441 || (OMP_CLAUSE_MAP_KIND (c)
8442 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8443 /* For target {,enter ,exit }data only the array slice is
8444 mapped, but not the pointer to it. */
8445 remove = true;
8446 break;
8447 default:
8448 break;
8450 if (remove)
8451 break;
8452 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
8454 struct gimplify_omp_ctx *octx;
8455 for (octx = outer_ctx; octx; octx = octx->outer_context)
8457 if (octx->region_type != ORT_ACC_HOST_DATA)
8458 break;
8459 splay_tree_node n2
8460 = splay_tree_lookup (octx->variables,
8461 (splay_tree_key) decl);
8462 if (n2)
8463 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
8464 "declared in enclosing %<host_data%> region",
8465 DECL_NAME (decl));
8468 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
8469 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
8470 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
8471 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
8472 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
8474 remove = true;
8475 break;
8477 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
8478 || (OMP_CLAUSE_MAP_KIND (c)
8479 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8480 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
8482 OMP_CLAUSE_SIZE (c)
8483 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
8484 false);
8485 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
8486 GOVD_FIRSTPRIVATE | GOVD_SEEN);
8488 if (!DECL_P (decl))
8490 tree d = decl, *pd;
8491 if (TREE_CODE (d) == ARRAY_REF)
8493 while (TREE_CODE (d) == ARRAY_REF)
8494 d = TREE_OPERAND (d, 0);
8495 if (TREE_CODE (d) == COMPONENT_REF
8496 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
8497 decl = d;
8499 pd = &OMP_CLAUSE_DECL (c);
8500 if (d == decl
8501 && TREE_CODE (decl) == INDIRECT_REF
8502 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
8503 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8504 == REFERENCE_TYPE))
8506 pd = &TREE_OPERAND (decl, 0);
8507 decl = TREE_OPERAND (decl, 0);
8509 if (TREE_CODE (decl) == COMPONENT_REF)
8511 while (TREE_CODE (decl) == COMPONENT_REF)
8512 decl = TREE_OPERAND (decl, 0);
8513 if (TREE_CODE (decl) == INDIRECT_REF
8514 && DECL_P (TREE_OPERAND (decl, 0))
8515 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8516 == REFERENCE_TYPE))
8517 decl = TREE_OPERAND (decl, 0);
8519 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, fb_lvalue)
8520 == GS_ERROR)
8522 remove = true;
8523 break;
8525 if (DECL_P (decl))
8527 if (error_operand_p (decl))
8529 remove = true;
8530 break;
8533 tree stype = TREE_TYPE (decl);
8534 if (TREE_CODE (stype) == REFERENCE_TYPE)
8535 stype = TREE_TYPE (stype);
8536 if (TYPE_SIZE_UNIT (stype) == NULL
8537 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
8539 error_at (OMP_CLAUSE_LOCATION (c),
8540 "mapping field %qE of variable length "
8541 "structure", OMP_CLAUSE_DECL (c));
8542 remove = true;
8543 break;
8546 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
8548 /* Error recovery. */
8549 if (prev_list_p == NULL)
8551 remove = true;
8552 break;
8554 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
8556 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
8557 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
8559 remove = true;
8560 break;
8565 tree offset;
8566 poly_int64 bitsize, bitpos;
8567 machine_mode mode;
8568 int unsignedp, reversep, volatilep = 0;
8569 tree base = OMP_CLAUSE_DECL (c);
8570 while (TREE_CODE (base) == ARRAY_REF)
8571 base = TREE_OPERAND (base, 0);
8572 if (TREE_CODE (base) == INDIRECT_REF)
8573 base = TREE_OPERAND (base, 0);
8574 base = get_inner_reference (base, &bitsize, &bitpos, &offset,
8575 &mode, &unsignedp, &reversep,
8576 &volatilep);
8577 tree orig_base = base;
8578 if ((TREE_CODE (base) == INDIRECT_REF
8579 || (TREE_CODE (base) == MEM_REF
8580 && integer_zerop (TREE_OPERAND (base, 1))))
8581 && DECL_P (TREE_OPERAND (base, 0))
8582 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
8583 == REFERENCE_TYPE))
8584 base = TREE_OPERAND (base, 0);
8585 gcc_assert (base == decl
8586 && (offset == NULL_TREE
8587 || poly_int_tree_p (offset)));
8589 splay_tree_node n
8590 = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
8591 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
8592 == GOMP_MAP_ALWAYS_POINTER);
8593 if (n == NULL || (n->value & GOVD_MAP) == 0)
8595 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8596 OMP_CLAUSE_MAP);
8597 OMP_CLAUSE_SET_MAP_KIND (l, GOMP_MAP_STRUCT);
8598 if (orig_base != base)
8599 OMP_CLAUSE_DECL (l) = unshare_expr (orig_base);
8600 else
8601 OMP_CLAUSE_DECL (l) = decl;
8602 OMP_CLAUSE_SIZE (l) = size_int (1);
8603 if (struct_map_to_clause == NULL)
8604 struct_map_to_clause = new hash_map<tree, tree>;
8605 struct_map_to_clause->put (decl, l);
8606 if (ptr)
8608 enum gomp_map_kind mkind
8609 = code == OMP_TARGET_EXIT_DATA
8610 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8611 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8612 OMP_CLAUSE_MAP);
8613 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8614 OMP_CLAUSE_DECL (c2)
8615 = unshare_expr (OMP_CLAUSE_DECL (c));
8616 OMP_CLAUSE_CHAIN (c2) = *prev_list_p;
8617 OMP_CLAUSE_SIZE (c2)
8618 = TYPE_SIZE_UNIT (ptr_type_node);
8619 OMP_CLAUSE_CHAIN (l) = c2;
8620 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
8622 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
8623 tree c3
8624 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8625 OMP_CLAUSE_MAP);
8626 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8627 OMP_CLAUSE_DECL (c3)
8628 = unshare_expr (OMP_CLAUSE_DECL (c4));
8629 OMP_CLAUSE_SIZE (c3)
8630 = TYPE_SIZE_UNIT (ptr_type_node);
8631 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
8632 OMP_CLAUSE_CHAIN (c2) = c3;
8634 *prev_list_p = l;
8635 prev_list_p = NULL;
8637 else
8639 OMP_CLAUSE_CHAIN (l) = c;
8640 *list_p = l;
8641 list_p = &OMP_CLAUSE_CHAIN (l);
8643 if (orig_base != base && code == OMP_TARGET)
8645 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8646 OMP_CLAUSE_MAP);
8647 enum gomp_map_kind mkind
8648 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
8649 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8650 OMP_CLAUSE_DECL (c2) = decl;
8651 OMP_CLAUSE_SIZE (c2) = size_zero_node;
8652 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
8653 OMP_CLAUSE_CHAIN (l) = c2;
8655 flags = GOVD_MAP | GOVD_EXPLICIT;
8656 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
8657 flags |= GOVD_SEEN;
8658 goto do_add_decl;
8660 else
8662 tree *osc = struct_map_to_clause->get (decl);
8663 tree *sc = NULL, *scp = NULL;
8664 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
8665 n->value |= GOVD_SEEN;
8666 poly_offset_int o1, o2;
8667 if (offset)
8668 o1 = wi::to_poly_offset (offset);
8669 else
8670 o1 = 0;
8671 if (maybe_ne (bitpos, 0))
8672 o1 += bits_to_bytes_round_down (bitpos);
8673 sc = &OMP_CLAUSE_CHAIN (*osc);
8674 if (*sc != c
8675 && (OMP_CLAUSE_MAP_KIND (*sc)
8676 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8677 sc = &OMP_CLAUSE_CHAIN (*sc);
8678 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
8679 if (ptr && sc == prev_list_p)
8680 break;
8681 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
8682 != COMPONENT_REF
8683 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
8684 != INDIRECT_REF)
8685 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
8686 != ARRAY_REF))
8687 break;
8688 else
8690 tree offset2;
8691 poly_int64 bitsize2, bitpos2;
8692 base = OMP_CLAUSE_DECL (*sc);
8693 if (TREE_CODE (base) == ARRAY_REF)
8695 while (TREE_CODE (base) == ARRAY_REF)
8696 base = TREE_OPERAND (base, 0);
8697 if (TREE_CODE (base) != COMPONENT_REF
8698 || (TREE_CODE (TREE_TYPE (base))
8699 != ARRAY_TYPE))
8700 break;
8702 else if (TREE_CODE (base) == INDIRECT_REF
8703 && (TREE_CODE (TREE_OPERAND (base, 0))
8704 == COMPONENT_REF)
8705 && (TREE_CODE (TREE_TYPE
8706 (TREE_OPERAND (base, 0)))
8707 == REFERENCE_TYPE))
8708 base = TREE_OPERAND (base, 0);
8709 base = get_inner_reference (base, &bitsize2,
8710 &bitpos2, &offset2,
8711 &mode, &unsignedp,
8712 &reversep, &volatilep);
8713 if ((TREE_CODE (base) == INDIRECT_REF
8714 || (TREE_CODE (base) == MEM_REF
8715 && integer_zerop (TREE_OPERAND (base,
8716 1))))
8717 && DECL_P (TREE_OPERAND (base, 0))
8718 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base,
8719 0)))
8720 == REFERENCE_TYPE))
8721 base = TREE_OPERAND (base, 0);
8722 if (base != decl)
8723 break;
8724 if (scp)
8725 continue;
8726 gcc_assert (offset == NULL_TREE
8727 || poly_int_tree_p (offset));
8728 tree d1 = OMP_CLAUSE_DECL (*sc);
8729 tree d2 = OMP_CLAUSE_DECL (c);
8730 while (TREE_CODE (d1) == ARRAY_REF)
8731 d1 = TREE_OPERAND (d1, 0);
8732 while (TREE_CODE (d2) == ARRAY_REF)
8733 d2 = TREE_OPERAND (d2, 0);
8734 if (TREE_CODE (d1) == INDIRECT_REF)
8735 d1 = TREE_OPERAND (d1, 0);
8736 if (TREE_CODE (d2) == INDIRECT_REF)
8737 d2 = TREE_OPERAND (d2, 0);
8738 while (TREE_CODE (d1) == COMPONENT_REF)
8739 if (TREE_CODE (d2) == COMPONENT_REF
8740 && TREE_OPERAND (d1, 1)
8741 == TREE_OPERAND (d2, 1))
8743 d1 = TREE_OPERAND (d1, 0);
8744 d2 = TREE_OPERAND (d2, 0);
8746 else
8747 break;
8748 if (d1 == d2)
8750 error_at (OMP_CLAUSE_LOCATION (c),
8751 "%qE appears more than once in map "
8752 "clauses", OMP_CLAUSE_DECL (c));
8753 remove = true;
8754 break;
8756 if (offset2)
8757 o2 = wi::to_poly_offset (offset2);
8758 else
8759 o2 = 0;
8760 o2 += bits_to_bytes_round_down (bitpos2);
8761 if (maybe_lt (o1, o2)
8762 || (known_eq (o1, o2)
8763 && maybe_lt (bitpos, bitpos2)))
8765 if (ptr)
8766 scp = sc;
8767 else
8768 break;
8771 if (remove)
8772 break;
8773 OMP_CLAUSE_SIZE (*osc)
8774 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
8775 size_one_node);
8776 if (ptr)
8778 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8779 OMP_CLAUSE_MAP);
8780 tree cl = NULL_TREE;
8781 enum gomp_map_kind mkind
8782 = code == OMP_TARGET_EXIT_DATA
8783 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8784 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8785 OMP_CLAUSE_DECL (c2)
8786 = unshare_expr (OMP_CLAUSE_DECL (c));
8787 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : *prev_list_p;
8788 OMP_CLAUSE_SIZE (c2)
8789 = TYPE_SIZE_UNIT (ptr_type_node);
8790 cl = scp ? *prev_list_p : c2;
8791 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
8793 tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
8794 tree c3
8795 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8796 OMP_CLAUSE_MAP);
8797 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8798 OMP_CLAUSE_DECL (c3)
8799 = unshare_expr (OMP_CLAUSE_DECL (c4));
8800 OMP_CLAUSE_SIZE (c3)
8801 = TYPE_SIZE_UNIT (ptr_type_node);
8802 OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
8803 if (!scp)
8804 OMP_CLAUSE_CHAIN (c2) = c3;
8805 else
8806 cl = c3;
8808 if (scp)
8809 *scp = c2;
8810 if (sc == prev_list_p)
8812 *sc = cl;
8813 prev_list_p = NULL;
8815 else
8817 *prev_list_p = OMP_CLAUSE_CHAIN (c);
8818 list_p = prev_list_p;
8819 prev_list_p = NULL;
8820 OMP_CLAUSE_CHAIN (c) = *sc;
8821 *sc = cl;
8822 continue;
8825 else if (*sc != c)
8827 *list_p = OMP_CLAUSE_CHAIN (c);
8828 OMP_CLAUSE_CHAIN (c) = *sc;
8829 *sc = c;
8830 continue;
8834 if (!remove
8835 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
8836 && OMP_CLAUSE_CHAIN (c)
8837 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
8838 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
8839 == GOMP_MAP_ALWAYS_POINTER))
8840 prev_list_p = list_p;
8841 break;
8843 flags = GOVD_MAP | GOVD_EXPLICIT;
8844 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
8845 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
8846 flags |= GOVD_MAP_ALWAYS_TO;
8847 goto do_add;
8849 case OMP_CLAUSE_DEPEND:
8850 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
8852 tree deps = OMP_CLAUSE_DECL (c);
8853 while (deps && TREE_CODE (deps) == TREE_LIST)
8855 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
8856 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
8857 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
8858 pre_p, NULL, is_gimple_val, fb_rvalue);
8859 deps = TREE_CHAIN (deps);
8861 break;
8863 else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
8864 break;
8865 if (handled_depend_iterators == -1)
8866 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
8867 if (handled_depend_iterators)
8869 if (handled_depend_iterators == 2)
8870 remove = true;
8871 break;
8873 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8875 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8876 NULL, is_gimple_val, fb_rvalue);
8877 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8879 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8881 remove = true;
8882 break;
8884 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8885 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8886 is_gimple_val, fb_rvalue) == GS_ERROR)
8888 remove = true;
8889 break;
8891 break;
8893 case OMP_CLAUSE_TO:
8894 case OMP_CLAUSE_FROM:
8895 case OMP_CLAUSE__CACHE_:
8896 decl = OMP_CLAUSE_DECL (c);
8897 if (error_operand_p (decl))
8899 remove = true;
8900 break;
8902 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
8903 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
8904 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
8905 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
8906 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
8908 remove = true;
8909 break;
8911 if (!DECL_P (decl))
8913 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
8914 NULL, is_gimple_lvalue, fb_lvalue)
8915 == GS_ERROR)
8917 remove = true;
8918 break;
8920 break;
8922 goto do_notice;
8924 case OMP_CLAUSE_USE_DEVICE_PTR:
8925 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8926 goto do_add;
8927 case OMP_CLAUSE_IS_DEVICE_PTR:
8928 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8929 goto do_add;
8931 do_add:
8932 decl = OMP_CLAUSE_DECL (c);
8933 do_add_decl:
8934 if (error_operand_p (decl))
8936 remove = true;
8937 break;
8939 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
8941 tree t = omp_member_access_dummy_var (decl);
8942 if (t)
8944 tree v = DECL_VALUE_EXPR (decl);
8945 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
8946 if (outer_ctx)
8947 omp_notice_variable (outer_ctx, t, true);
8950 if (code == OACC_DATA
8951 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
8952 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
8953 flags |= GOVD_MAP_0LEN_ARRAY;
8954 omp_add_variable (ctx, decl, flags);
8955 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
8956 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
8957 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
8958 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
8960 omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
8961 GOVD_LOCAL | GOVD_SEEN);
8962 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
8963 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
8964 find_decl_expr,
8965 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
8966 NULL) == NULL_TREE)
8967 omp_add_variable (ctx,
8968 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
8969 GOVD_LOCAL | GOVD_SEEN);
8970 gimplify_omp_ctxp = ctx;
8971 push_gimplify_context ();
8973 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
8974 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
8976 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
8977 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
8978 pop_gimplify_context
8979 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
8980 push_gimplify_context ();
8981 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
8982 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
8983 pop_gimplify_context
8984 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
8985 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
8986 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
8988 gimplify_omp_ctxp = outer_ctx;
8990 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
8991 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
8993 gimplify_omp_ctxp = ctx;
8994 push_gimplify_context ();
8995 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
8997 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
8998 NULL, NULL);
8999 TREE_SIDE_EFFECTS (bind) = 1;
9000 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
9001 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
9003 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
9004 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
9005 pop_gimplify_context
9006 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
9007 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
9009 gimplify_omp_ctxp = outer_ctx;
9011 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9012 && OMP_CLAUSE_LINEAR_STMT (c))
9014 gimplify_omp_ctxp = ctx;
9015 push_gimplify_context ();
9016 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
9018 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
9019 NULL, NULL);
9020 TREE_SIDE_EFFECTS (bind) = 1;
9021 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
9022 OMP_CLAUSE_LINEAR_STMT (c) = bind;
9024 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
9025 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
9026 pop_gimplify_context
9027 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
9028 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
9030 gimplify_omp_ctxp = outer_ctx;
9032 if (notice_outer)
9033 goto do_notice;
9034 break;
9036 case OMP_CLAUSE_COPYIN:
9037 case OMP_CLAUSE_COPYPRIVATE:
9038 decl = OMP_CLAUSE_DECL (c);
9039 if (error_operand_p (decl))
9041 remove = true;
9042 break;
9044 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
9045 && !remove
9046 && !omp_check_private (ctx, decl, true))
9048 remove = true;
9049 if (is_global_var (decl))
9051 if (DECL_THREAD_LOCAL_P (decl))
9052 remove = false;
9053 else if (DECL_HAS_VALUE_EXPR_P (decl))
9055 tree value = get_base_address (DECL_VALUE_EXPR (decl));
9057 if (value
9058 && DECL_P (value)
9059 && DECL_THREAD_LOCAL_P (value))
9060 remove = false;
9063 if (remove)
9064 error_at (OMP_CLAUSE_LOCATION (c),
9065 "copyprivate variable %qE is not threadprivate"
9066 " or private in outer context", DECL_NAME (decl));
9068 do_notice:
9069 if ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
9070 && outer_ctx
9071 && outer_ctx->region_type == ORT_COMBINED_PARALLEL
9072 && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9073 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
9074 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE))
9076 splay_tree_node on
9077 = splay_tree_lookup (outer_ctx->variables,
9078 (splay_tree_key)decl);
9079 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
9081 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9082 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
9083 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
9084 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
9085 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
9086 == POINTER_TYPE))))
9087 omp_firstprivatize_variable (outer_ctx, decl);
9088 else
9089 omp_add_variable (outer_ctx, decl,
9090 GOVD_SEEN | GOVD_SHARED);
9091 omp_notice_variable (outer_ctx, decl, true);
9094 if (outer_ctx)
9095 omp_notice_variable (outer_ctx, decl, true);
9096 if (check_non_private
9097 && region_type == ORT_WORKSHARE
9098 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
9099 || decl == OMP_CLAUSE_DECL (c)
9100 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
9101 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
9102 == ADDR_EXPR
9103 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
9104 == POINTER_PLUS_EXPR
9105 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
9106 (OMP_CLAUSE_DECL (c), 0), 0))
9107 == ADDR_EXPR)))))
9108 && omp_check_private (ctx, decl, false))
9110 error ("%s variable %qE is private in outer context",
9111 check_non_private, DECL_NAME (decl));
9112 remove = true;
9114 break;
9116 case OMP_CLAUSE_IF:
9117 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
9118 && OMP_CLAUSE_IF_MODIFIER (c) != code)
9120 const char *p[2];
9121 for (int i = 0; i < 2; i++)
9122 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
9124 case VOID_CST: p[i] = "cancel"; break;
9125 case OMP_PARALLEL: p[i] = "parallel"; break;
9126 case OMP_SIMD: p[i] = "simd"; break;
9127 case OMP_TASK: p[i] = "task"; break;
9128 case OMP_TASKLOOP: p[i] = "taskloop"; break;
9129 case OMP_TARGET_DATA: p[i] = "target data"; break;
9130 case OMP_TARGET: p[i] = "target"; break;
9131 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
9132 case OMP_TARGET_ENTER_DATA:
9133 p[i] = "target enter data"; break;
9134 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
9135 default: gcc_unreachable ();
9137 error_at (OMP_CLAUSE_LOCATION (c),
9138 "expected %qs %<if%> clause modifier rather than %qs",
9139 p[0], p[1]);
9140 remove = true;
9142 /* Fall through. */
9144 case OMP_CLAUSE_FINAL:
9145 OMP_CLAUSE_OPERAND (c, 0)
9146 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
9147 /* Fall through. */
9149 case OMP_CLAUSE_SCHEDULE:
9150 case OMP_CLAUSE_NUM_THREADS:
9151 case OMP_CLAUSE_NUM_TEAMS:
9152 case OMP_CLAUSE_THREAD_LIMIT:
9153 case OMP_CLAUSE_DIST_SCHEDULE:
9154 case OMP_CLAUSE_DEVICE:
9155 case OMP_CLAUSE_PRIORITY:
9156 case OMP_CLAUSE_GRAINSIZE:
9157 case OMP_CLAUSE_NUM_TASKS:
9158 case OMP_CLAUSE_HINT:
9159 case OMP_CLAUSE_ASYNC:
9160 case OMP_CLAUSE_WAIT:
9161 case OMP_CLAUSE_NUM_GANGS:
9162 case OMP_CLAUSE_NUM_WORKERS:
9163 case OMP_CLAUSE_VECTOR_LENGTH:
9164 case OMP_CLAUSE_WORKER:
9165 case OMP_CLAUSE_VECTOR:
9166 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
9167 is_gimple_val, fb_rvalue) == GS_ERROR)
9168 remove = true;
9169 break;
9171 case OMP_CLAUSE_GANG:
9172 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
9173 is_gimple_val, fb_rvalue) == GS_ERROR)
9174 remove = true;
9175 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
9176 is_gimple_val, fb_rvalue) == GS_ERROR)
9177 remove = true;
9178 break;
9180 case OMP_CLAUSE_NOWAIT:
9181 nowait = 1;
9182 break;
9184 case OMP_CLAUSE_ORDERED:
9185 case OMP_CLAUSE_UNTIED:
9186 case OMP_CLAUSE_COLLAPSE:
9187 case OMP_CLAUSE_TILE:
9188 case OMP_CLAUSE_AUTO:
9189 case OMP_CLAUSE_SEQ:
9190 case OMP_CLAUSE_INDEPENDENT:
9191 case OMP_CLAUSE_MERGEABLE:
9192 case OMP_CLAUSE_PROC_BIND:
9193 case OMP_CLAUSE_SAFELEN:
9194 case OMP_CLAUSE_SIMDLEN:
9195 case OMP_CLAUSE_NOGROUP:
9196 case OMP_CLAUSE_THREADS:
9197 case OMP_CLAUSE_SIMD:
9198 case OMP_CLAUSE_IF_PRESENT:
9199 case OMP_CLAUSE_FINALIZE:
9200 break;
9202 case OMP_CLAUSE_DEFAULTMAP:
9203 enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
9204 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
9206 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
9207 gdmkmin = GDMK_SCALAR;
9208 gdmkmax = GDMK_POINTER;
9209 break;
9210 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
9211 gdmkmin = gdmkmax = GDMK_SCALAR;
9212 break;
9213 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
9214 gdmkmin = gdmkmax = GDMK_AGGREGATE;
9215 break;
9216 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
9217 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
9218 break;
9219 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
9220 gdmkmin = gdmkmax = GDMK_POINTER;
9221 break;
9222 default:
9223 gcc_unreachable ();
9225 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
9226 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
9228 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
9229 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
9230 break;
9231 case OMP_CLAUSE_DEFAULTMAP_TO:
9232 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
9233 break;
9234 case OMP_CLAUSE_DEFAULTMAP_FROM:
9235 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
9236 break;
9237 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
9238 ctx->defaultmap[gdmk] = GOVD_MAP;
9239 break;
9240 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
9241 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
9242 break;
9243 case OMP_CLAUSE_DEFAULTMAP_NONE:
9244 ctx->defaultmap[gdmk] = 0;
9245 break;
9246 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
9247 switch (gdmk)
9249 case GDMK_SCALAR:
9250 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
9251 break;
9252 case GDMK_AGGREGATE:
9253 case GDMK_ALLOCATABLE:
9254 ctx->defaultmap[gdmk] = GOVD_MAP;
9255 break;
9256 case GDMK_POINTER:
9257 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
9258 break;
9259 default:
9260 gcc_unreachable ();
9262 break;
9263 default:
9264 gcc_unreachable ();
9266 break;
9268 case OMP_CLAUSE_ALIGNED:
9269 decl = OMP_CLAUSE_DECL (c);
9270 if (error_operand_p (decl))
9272 remove = true;
9273 break;
9275 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
9276 is_gimple_val, fb_rvalue) == GS_ERROR)
9278 remove = true;
9279 break;
9281 if (!is_global_var (decl)
9282 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
9283 omp_add_variable (ctx, decl, GOVD_ALIGNED);
9284 break;
9286 case OMP_CLAUSE_NONTEMPORAL:
9287 decl = OMP_CLAUSE_DECL (c);
9288 if (error_operand_p (decl))
9290 remove = true;
9291 break;
9293 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
9294 break;
9296 case OMP_CLAUSE_DEFAULT:
9297 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
9298 break;
9300 default:
9301 gcc_unreachable ();
9304 if (code == OACC_DATA
9305 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9306 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9307 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9308 remove = true;
9309 if (remove)
9310 *list_p = OMP_CLAUSE_CHAIN (c);
9311 else
9312 list_p = &OMP_CLAUSE_CHAIN (c);
9315 gimplify_omp_ctxp = ctx;
9316 if (struct_map_to_clause)
9317 delete struct_map_to_clause;
9320 /* Return true if DECL is a candidate for shared to firstprivate
9321 optimization. We only consider non-addressable scalars, not
9322 too big, and not references. */
9324 static bool
9325 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
9327 if (TREE_ADDRESSABLE (decl))
9328 return false;
9329 tree type = TREE_TYPE (decl);
9330 if (!is_gimple_reg_type (type)
9331 || TREE_CODE (type) == REFERENCE_TYPE
9332 || TREE_ADDRESSABLE (type))
9333 return false;
9334 /* Don't optimize too large decls, as each thread/task will have
9335 its own. */
9336 HOST_WIDE_INT len = int_size_in_bytes (type);
9337 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
9338 return false;
9339 if (lang_hooks.decls.omp_privatize_by_reference (decl))
9340 return false;
9341 return true;
9344 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
9345 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
9346 GOVD_WRITTEN in outer contexts. */
9348 static void
9349 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
9351 for (; ctx; ctx = ctx->outer_context)
9353 splay_tree_node n = splay_tree_lookup (ctx->variables,
9354 (splay_tree_key) decl);
9355 if (n == NULL)
9356 continue;
9357 else if (n->value & GOVD_SHARED)
9359 n->value |= GOVD_WRITTEN;
9360 return;
9362 else if (n->value & GOVD_DATA_SHARE_CLASS)
9363 return;
9367 /* Helper callback for walk_gimple_seq to discover possible stores
9368 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
9369 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
9370 for those. */
9372 static tree
9373 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
9375 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
9377 *walk_subtrees = 0;
9378 if (!wi->is_lhs)
9379 return NULL_TREE;
9381 tree op = *tp;
9384 if (handled_component_p (op))
9385 op = TREE_OPERAND (op, 0);
9386 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
9387 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
9388 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
9389 else
9390 break;
9392 while (1);
9393 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
9394 return NULL_TREE;
9396 omp_mark_stores (gimplify_omp_ctxp, op);
9397 return NULL_TREE;
9400 /* Helper callback for walk_gimple_seq to discover possible stores
9401 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
9402 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
9403 for those. */
9405 static tree
9406 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
9407 bool *handled_ops_p,
9408 struct walk_stmt_info *wi)
9410 gimple *stmt = gsi_stmt (*gsi_p);
9411 switch (gimple_code (stmt))
9413 /* Don't recurse on OpenMP constructs for which
9414 gimplify_adjust_omp_clauses already handled the bodies,
9415 except handle gimple_omp_for_pre_body. */
9416 case GIMPLE_OMP_FOR:
9417 *handled_ops_p = true;
9418 if (gimple_omp_for_pre_body (stmt))
9419 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
9420 omp_find_stores_stmt, omp_find_stores_op, wi);
9421 break;
9422 case GIMPLE_OMP_PARALLEL:
9423 case GIMPLE_OMP_TASK:
9424 case GIMPLE_OMP_SECTIONS:
9425 case GIMPLE_OMP_SINGLE:
9426 case GIMPLE_OMP_TARGET:
9427 case GIMPLE_OMP_TEAMS:
9428 case GIMPLE_OMP_CRITICAL:
9429 *handled_ops_p = true;
9430 break;
9431 default:
9432 break;
9434 return NULL_TREE;
9437 struct gimplify_adjust_omp_clauses_data
9439 tree *list_p;
9440 gimple_seq *pre_p;
9443 /* For all variables that were not actually used within the context,
9444 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
9446 static int
9447 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
9449 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
9450 gimple_seq *pre_p
9451 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
9452 tree decl = (tree) n->key;
9453 unsigned flags = n->value;
9454 enum omp_clause_code code;
9455 tree clause;
9456 bool private_debug;
9458 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
9459 return 0;
9460 if ((flags & GOVD_SEEN) == 0)
9461 return 0;
9462 if (flags & GOVD_DEBUG_PRIVATE)
9464 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
9465 private_debug = true;
9467 else if (flags & GOVD_MAP)
9468 private_debug = false;
9469 else
9470 private_debug
9471 = lang_hooks.decls.omp_private_debug_clause (decl,
9472 !!(flags & GOVD_SHARED));
9473 if (private_debug)
9474 code = OMP_CLAUSE_PRIVATE;
9475 else if (flags & GOVD_MAP)
9477 code = OMP_CLAUSE_MAP;
9478 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
9479 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
9481 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
9482 return 0;
9485 else if (flags & GOVD_SHARED)
9487 if (is_global_var (decl))
9489 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
9490 while (ctx != NULL)
9492 splay_tree_node on
9493 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9494 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
9495 | GOVD_PRIVATE | GOVD_REDUCTION
9496 | GOVD_LINEAR | GOVD_MAP)) != 0)
9497 break;
9498 ctx = ctx->outer_context;
9500 if (ctx == NULL)
9501 return 0;
9503 code = OMP_CLAUSE_SHARED;
9505 else if (flags & GOVD_PRIVATE)
9506 code = OMP_CLAUSE_PRIVATE;
9507 else if (flags & GOVD_FIRSTPRIVATE)
9509 code = OMP_CLAUSE_FIRSTPRIVATE;
9510 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
9511 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
9512 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
9514 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
9515 "%<target%> construct", decl);
9516 return 0;
9519 else if (flags & GOVD_LASTPRIVATE)
9520 code = OMP_CLAUSE_LASTPRIVATE;
9521 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
9522 return 0;
9523 else
9524 gcc_unreachable ();
9526 if (((flags & GOVD_LASTPRIVATE)
9527 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
9528 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9529 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
9531 tree chain = *list_p;
9532 clause = build_omp_clause (input_location, code);
9533 OMP_CLAUSE_DECL (clause) = decl;
9534 OMP_CLAUSE_CHAIN (clause) = chain;
9535 if (private_debug)
9536 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
9537 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
9538 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
9539 else if (code == OMP_CLAUSE_SHARED
9540 && (flags & GOVD_WRITTEN) == 0
9541 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9542 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
9543 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
9544 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
9545 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
9547 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
9548 OMP_CLAUSE_DECL (nc) = decl;
9549 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
9550 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
9551 OMP_CLAUSE_DECL (clause)
9552 = build_simple_mem_ref_loc (input_location, decl);
9553 OMP_CLAUSE_DECL (clause)
9554 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
9555 build_int_cst (build_pointer_type (char_type_node), 0));
9556 OMP_CLAUSE_SIZE (clause) = size_zero_node;
9557 OMP_CLAUSE_SIZE (nc) = size_zero_node;
9558 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
9559 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
9560 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
9561 OMP_CLAUSE_CHAIN (nc) = chain;
9562 OMP_CLAUSE_CHAIN (clause) = nc;
9563 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9564 gimplify_omp_ctxp = ctx->outer_context;
9565 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
9566 pre_p, NULL, is_gimple_val, fb_rvalue);
9567 gimplify_omp_ctxp = ctx;
9569 else if (code == OMP_CLAUSE_MAP)
9571 int kind;
9572 /* Not all combinations of these GOVD_MAP flags are actually valid. */
9573 switch (flags & (GOVD_MAP_TO_ONLY
9574 | GOVD_MAP_FORCE
9575 | GOVD_MAP_FORCE_PRESENT
9576 | GOVD_MAP_ALLOC_ONLY
9577 | GOVD_MAP_FROM_ONLY))
9579 case 0:
9580 kind = GOMP_MAP_TOFROM;
9581 break;
9582 case GOVD_MAP_FORCE:
9583 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
9584 break;
9585 case GOVD_MAP_TO_ONLY:
9586 kind = GOMP_MAP_TO;
9587 break;
9588 case GOVD_MAP_FROM_ONLY:
9589 kind = GOMP_MAP_FROM;
9590 break;
9591 case GOVD_MAP_ALLOC_ONLY:
9592 kind = GOMP_MAP_ALLOC;
9593 break;
9594 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
9595 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
9596 break;
9597 case GOVD_MAP_FORCE_PRESENT:
9598 kind = GOMP_MAP_FORCE_PRESENT;
9599 break;
9600 default:
9601 gcc_unreachable ();
9603 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
9604 if (DECL_SIZE (decl)
9605 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
9607 tree decl2 = DECL_VALUE_EXPR (decl);
9608 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
9609 decl2 = TREE_OPERAND (decl2, 0);
9610 gcc_assert (DECL_P (decl2));
9611 tree mem = build_simple_mem_ref (decl2);
9612 OMP_CLAUSE_DECL (clause) = mem;
9613 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
9614 if (gimplify_omp_ctxp->outer_context)
9616 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
9617 omp_notice_variable (ctx, decl2, true);
9618 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
9620 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
9621 OMP_CLAUSE_MAP);
9622 OMP_CLAUSE_DECL (nc) = decl;
9623 OMP_CLAUSE_SIZE (nc) = size_zero_node;
9624 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
9625 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
9626 else
9627 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
9628 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
9629 OMP_CLAUSE_CHAIN (clause) = nc;
9631 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
9632 && lang_hooks.decls.omp_privatize_by_reference (decl))
9634 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
9635 OMP_CLAUSE_SIZE (clause)
9636 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
9637 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9638 gimplify_omp_ctxp = ctx->outer_context;
9639 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
9640 pre_p, NULL, is_gimple_val, fb_rvalue);
9641 gimplify_omp_ctxp = ctx;
9642 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
9643 OMP_CLAUSE_MAP);
9644 OMP_CLAUSE_DECL (nc) = decl;
9645 OMP_CLAUSE_SIZE (nc) = size_zero_node;
9646 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
9647 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
9648 OMP_CLAUSE_CHAIN (clause) = nc;
9650 else
9651 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
9653 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
9655 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
9656 OMP_CLAUSE_DECL (nc) = decl;
9657 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
9658 OMP_CLAUSE_CHAIN (nc) = chain;
9659 OMP_CLAUSE_CHAIN (clause) = nc;
9660 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9661 gimplify_omp_ctxp = ctx->outer_context;
9662 lang_hooks.decls.omp_finish_clause (nc, pre_p);
9663 gimplify_omp_ctxp = ctx;
9665 *list_p = clause;
9666 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9667 gimplify_omp_ctxp = ctx->outer_context;
9668 lang_hooks.decls.omp_finish_clause (clause, pre_p);
9669 if (gimplify_omp_ctxp)
9670 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
9671 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
9672 && DECL_P (OMP_CLAUSE_SIZE (clause)))
9673 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
9674 true);
9675 gimplify_omp_ctxp = ctx;
9676 return 0;
9679 static void
9680 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
9681 enum tree_code code)
9683 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
9684 tree c, decl;
9686 if (body)
9688 struct gimplify_omp_ctx *octx;
9689 for (octx = ctx; octx; octx = octx->outer_context)
9690 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
9691 break;
9692 if (octx)
9694 struct walk_stmt_info wi;
9695 memset (&wi, 0, sizeof (wi));
9696 walk_gimple_seq (body, omp_find_stores_stmt,
9697 omp_find_stores_op, &wi);
9700 while ((c = *list_p) != NULL)
9702 splay_tree_node n;
9703 bool remove = false;
9705 switch (OMP_CLAUSE_CODE (c))
9707 case OMP_CLAUSE_FIRSTPRIVATE:
9708 if ((ctx->region_type & ORT_TARGET)
9709 && (ctx->region_type & ORT_ACC) == 0
9710 && TYPE_ATOMIC (strip_array_types
9711 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
9713 error_at (OMP_CLAUSE_LOCATION (c),
9714 "%<_Atomic%> %qD in %<firstprivate%> clause on "
9715 "%<target%> construct", OMP_CLAUSE_DECL (c));
9716 remove = true;
9717 break;
9719 /* FALLTHRU */
9720 case OMP_CLAUSE_PRIVATE:
9721 case OMP_CLAUSE_SHARED:
9722 case OMP_CLAUSE_LINEAR:
9723 decl = OMP_CLAUSE_DECL (c);
9724 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9725 remove = !(n->value & GOVD_SEEN);
9726 if (! remove)
9728 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
9729 if ((n->value & GOVD_DEBUG_PRIVATE)
9730 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
9732 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
9733 || ((n->value & GOVD_DATA_SHARE_CLASS)
9734 == GOVD_SHARED));
9735 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
9736 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
9738 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
9739 && (n->value & GOVD_WRITTEN) == 0
9740 && DECL_P (decl)
9741 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9742 OMP_CLAUSE_SHARED_READONLY (c) = 1;
9743 else if (DECL_P (decl)
9744 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
9745 && (n->value & GOVD_WRITTEN) != 0)
9746 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9747 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
9748 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9749 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
9751 break;
9753 case OMP_CLAUSE_LASTPRIVATE:
9754 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
9755 accurately reflect the presence of a FIRSTPRIVATE clause. */
9756 decl = OMP_CLAUSE_DECL (c);
9757 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9758 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
9759 = (n->value & GOVD_FIRSTPRIVATE) != 0;
9760 if (code == OMP_DISTRIBUTE
9761 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
9763 remove = true;
9764 error_at (OMP_CLAUSE_LOCATION (c),
9765 "same variable used in %<firstprivate%> and "
9766 "%<lastprivate%> clauses on %<distribute%> "
9767 "construct");
9769 if (!remove
9770 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
9771 && DECL_P (decl)
9772 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
9773 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
9774 break;
9776 case OMP_CLAUSE_ALIGNED:
9777 decl = OMP_CLAUSE_DECL (c);
9778 if (!is_global_var (decl))
9780 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9781 remove = n == NULL || !(n->value & GOVD_SEEN);
9782 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
9784 struct gimplify_omp_ctx *octx;
9785 if (n != NULL
9786 && (n->value & (GOVD_DATA_SHARE_CLASS
9787 & ~GOVD_FIRSTPRIVATE)))
9788 remove = true;
9789 else
9790 for (octx = ctx->outer_context; octx;
9791 octx = octx->outer_context)
9793 n = splay_tree_lookup (octx->variables,
9794 (splay_tree_key) decl);
9795 if (n == NULL)
9796 continue;
9797 if (n->value & GOVD_LOCAL)
9798 break;
9799 /* We have to avoid assigning a shared variable
9800 to itself when trying to add
9801 __builtin_assume_aligned. */
9802 if (n->value & GOVD_SHARED)
9804 remove = true;
9805 break;
9810 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
9812 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9813 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
9814 remove = true;
9816 break;
9818 case OMP_CLAUSE_NONTEMPORAL:
9819 decl = OMP_CLAUSE_DECL (c);
9820 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9821 remove = n == NULL || !(n->value & GOVD_SEEN);
9822 break;
9824 case OMP_CLAUSE_MAP:
9825 if (code == OMP_TARGET_EXIT_DATA
9826 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
9828 remove = true;
9829 break;
9831 decl = OMP_CLAUSE_DECL (c);
9832 /* Data clauses associated with acc parallel reductions must be
9833 compatible with present_or_copy. Warn and adjust the clause
9834 if that is not the case. */
9835 if (ctx->region_type == ORT_ACC_PARALLEL)
9837 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
9838 n = NULL;
9840 if (DECL_P (t))
9841 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
9843 if (n && (n->value & GOVD_REDUCTION))
9845 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
9847 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
9848 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
9849 && kind != GOMP_MAP_FORCE_PRESENT
9850 && kind != GOMP_MAP_POINTER)
9852 warning_at (OMP_CLAUSE_LOCATION (c), 0,
9853 "incompatible data clause with reduction "
9854 "on %qE; promoting to %<present_or_copy%>",
9855 DECL_NAME (t));
9856 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
9860 if (!DECL_P (decl))
9862 if ((ctx->region_type & ORT_TARGET) != 0
9863 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
9865 if (TREE_CODE (decl) == INDIRECT_REF
9866 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
9867 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9868 == REFERENCE_TYPE))
9869 decl = TREE_OPERAND (decl, 0);
9870 if (TREE_CODE (decl) == COMPONENT_REF)
9872 while (TREE_CODE (decl) == COMPONENT_REF)
9873 decl = TREE_OPERAND (decl, 0);
9874 if (DECL_P (decl))
9876 n = splay_tree_lookup (ctx->variables,
9877 (splay_tree_key) decl);
9878 if (!(n->value & GOVD_SEEN))
9879 remove = true;
9883 break;
9885 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9886 if ((ctx->region_type & ORT_TARGET) != 0
9887 && !(n->value & GOVD_SEEN)
9888 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
9889 && (!is_global_var (decl)
9890 || !lookup_attribute ("omp declare target link",
9891 DECL_ATTRIBUTES (decl))))
9893 remove = true;
9894 /* For struct element mapping, if struct is never referenced
9895 in target block and none of the mapping has always modifier,
9896 remove all the struct element mappings, which immediately
9897 follow the GOMP_MAP_STRUCT map clause. */
9898 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
9900 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
9901 while (cnt--)
9902 OMP_CLAUSE_CHAIN (c)
9903 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
9906 else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
9907 && code == OMP_TARGET_EXIT_DATA)
9908 remove = true;
9909 else if (DECL_SIZE (decl)
9910 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
9911 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
9912 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
9913 && (OMP_CLAUSE_MAP_KIND (c)
9914 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9916 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
9917 for these, TREE_CODE (DECL_SIZE (decl)) will always be
9918 INTEGER_CST. */
9919 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
9921 tree decl2 = DECL_VALUE_EXPR (decl);
9922 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
9923 decl2 = TREE_OPERAND (decl2, 0);
9924 gcc_assert (DECL_P (decl2));
9925 tree mem = build_simple_mem_ref (decl2);
9926 OMP_CLAUSE_DECL (c) = mem;
9927 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
9928 if (ctx->outer_context)
9930 omp_notice_variable (ctx->outer_context, decl2, true);
9931 omp_notice_variable (ctx->outer_context,
9932 OMP_CLAUSE_SIZE (c), true);
9934 if (((ctx->region_type & ORT_TARGET) != 0
9935 || !ctx->target_firstprivatize_array_bases)
9936 && ((n->value & GOVD_SEEN) == 0
9937 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
9939 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9940 OMP_CLAUSE_MAP);
9941 OMP_CLAUSE_DECL (nc) = decl;
9942 OMP_CLAUSE_SIZE (nc) = size_zero_node;
9943 if (ctx->target_firstprivatize_array_bases)
9944 OMP_CLAUSE_SET_MAP_KIND (nc,
9945 GOMP_MAP_FIRSTPRIVATE_POINTER);
9946 else
9947 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
9948 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
9949 OMP_CLAUSE_CHAIN (c) = nc;
9950 c = nc;
9953 else
9955 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9956 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
9957 gcc_assert ((n->value & GOVD_SEEN) == 0
9958 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
9959 == 0));
9961 break;
9963 case OMP_CLAUSE_TO:
9964 case OMP_CLAUSE_FROM:
9965 case OMP_CLAUSE__CACHE_:
9966 decl = OMP_CLAUSE_DECL (c);
9967 if (!DECL_P (decl))
9968 break;
9969 if (DECL_SIZE (decl)
9970 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
9972 tree decl2 = DECL_VALUE_EXPR (decl);
9973 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
9974 decl2 = TREE_OPERAND (decl2, 0);
9975 gcc_assert (DECL_P (decl2));
9976 tree mem = build_simple_mem_ref (decl2);
9977 OMP_CLAUSE_DECL (c) = mem;
9978 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
9979 if (ctx->outer_context)
9981 omp_notice_variable (ctx->outer_context, decl2, true);
9982 omp_notice_variable (ctx->outer_context,
9983 OMP_CLAUSE_SIZE (c), true);
9986 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9987 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
9988 break;
9990 case OMP_CLAUSE_REDUCTION:
9991 case OMP_CLAUSE_IN_REDUCTION:
9992 case OMP_CLAUSE_TASK_REDUCTION:
9993 decl = OMP_CLAUSE_DECL (c);
9994 /* OpenACC reductions need a present_or_copy data clause.
9995 Add one if necessary. Emit error when the reduction is private. */
9996 if (ctx->region_type == ORT_ACC_PARALLEL)
9998 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9999 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
10001 remove = true;
10002 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
10003 "reduction on %qE", DECL_NAME (decl));
10005 else if ((n->value & GOVD_MAP) == 0)
10007 tree next = OMP_CLAUSE_CHAIN (c);
10008 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
10009 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
10010 OMP_CLAUSE_DECL (nc) = decl;
10011 OMP_CLAUSE_CHAIN (c) = nc;
10012 lang_hooks.decls.omp_finish_clause (nc, pre_p);
10013 while (1)
10015 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
10016 if (OMP_CLAUSE_CHAIN (nc) == NULL)
10017 break;
10018 nc = OMP_CLAUSE_CHAIN (nc);
10020 OMP_CLAUSE_CHAIN (nc) = next;
10021 n->value |= GOVD_MAP;
10024 if (DECL_P (decl)
10025 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10026 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10027 break;
10028 case OMP_CLAUSE_COPYIN:
10029 case OMP_CLAUSE_COPYPRIVATE:
10030 case OMP_CLAUSE_IF:
10031 case OMP_CLAUSE_NUM_THREADS:
10032 case OMP_CLAUSE_NUM_TEAMS:
10033 case OMP_CLAUSE_THREAD_LIMIT:
10034 case OMP_CLAUSE_DIST_SCHEDULE:
10035 case OMP_CLAUSE_DEVICE:
10036 case OMP_CLAUSE_SCHEDULE:
10037 case OMP_CLAUSE_NOWAIT:
10038 case OMP_CLAUSE_ORDERED:
10039 case OMP_CLAUSE_DEFAULT:
10040 case OMP_CLAUSE_UNTIED:
10041 case OMP_CLAUSE_COLLAPSE:
10042 case OMP_CLAUSE_FINAL:
10043 case OMP_CLAUSE_MERGEABLE:
10044 case OMP_CLAUSE_PROC_BIND:
10045 case OMP_CLAUSE_SAFELEN:
10046 case OMP_CLAUSE_SIMDLEN:
10047 case OMP_CLAUSE_DEPEND:
10048 case OMP_CLAUSE_PRIORITY:
10049 case OMP_CLAUSE_GRAINSIZE:
10050 case OMP_CLAUSE_NUM_TASKS:
10051 case OMP_CLAUSE_NOGROUP:
10052 case OMP_CLAUSE_THREADS:
10053 case OMP_CLAUSE_SIMD:
10054 case OMP_CLAUSE_HINT:
10055 case OMP_CLAUSE_DEFAULTMAP:
10056 case OMP_CLAUSE_USE_DEVICE_PTR:
10057 case OMP_CLAUSE_IS_DEVICE_PTR:
10058 case OMP_CLAUSE_ASYNC:
10059 case OMP_CLAUSE_WAIT:
10060 case OMP_CLAUSE_INDEPENDENT:
10061 case OMP_CLAUSE_NUM_GANGS:
10062 case OMP_CLAUSE_NUM_WORKERS:
10063 case OMP_CLAUSE_VECTOR_LENGTH:
10064 case OMP_CLAUSE_GANG:
10065 case OMP_CLAUSE_WORKER:
10066 case OMP_CLAUSE_VECTOR:
10067 case OMP_CLAUSE_AUTO:
10068 case OMP_CLAUSE_SEQ:
10069 case OMP_CLAUSE_TILE:
10070 case OMP_CLAUSE_IF_PRESENT:
10071 case OMP_CLAUSE_FINALIZE:
10072 break;
10074 default:
10075 gcc_unreachable ();
10078 if (remove)
10079 *list_p = OMP_CLAUSE_CHAIN (c);
10080 else
10081 list_p = &OMP_CLAUSE_CHAIN (c);
10084 /* Add in any implicit data sharing. */
10085 struct gimplify_adjust_omp_clauses_data data;
10086 data.list_p = list_p;
10087 data.pre_p = pre_p;
10088 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
10090 gimplify_omp_ctxp = ctx->outer_context;
10091 delete_omp_context (ctx);
10094 /* Gimplify OACC_CACHE. */
10096 static void
10097 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
10099 tree expr = *expr_p;
10101 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
10102 OACC_CACHE);
10103 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
10104 OACC_CACHE);
10106 /* TODO: Do something sensible with this information. */
10108 *expr_p = NULL_TREE;
10111 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
10112 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
10113 kind. The entry kind will replace the one in CLAUSE, while the exit
10114 kind will be used in a new omp_clause and returned to the caller. */
10116 static tree
10117 gimplify_oacc_declare_1 (tree clause)
10119 HOST_WIDE_INT kind, new_op;
10120 bool ret = false;
10121 tree c = NULL;
10123 kind = OMP_CLAUSE_MAP_KIND (clause);
10125 switch (kind)
10127 case GOMP_MAP_ALLOC:
10128 new_op = GOMP_MAP_RELEASE;
10129 ret = true;
10130 break;
10132 case GOMP_MAP_FROM:
10133 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
10134 new_op = GOMP_MAP_FROM;
10135 ret = true;
10136 break;
10138 case GOMP_MAP_TOFROM:
10139 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
10140 new_op = GOMP_MAP_FROM;
10141 ret = true;
10142 break;
10144 case GOMP_MAP_DEVICE_RESIDENT:
10145 case GOMP_MAP_FORCE_DEVICEPTR:
10146 case GOMP_MAP_FORCE_PRESENT:
10147 case GOMP_MAP_LINK:
10148 case GOMP_MAP_POINTER:
10149 case GOMP_MAP_TO:
10150 break;
10152 default:
10153 gcc_unreachable ();
10154 break;
10157 if (ret)
10159 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
10160 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
10161 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
10164 return c;
10167 /* Gimplify OACC_DECLARE. */
10169 static void
10170 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
10172 tree expr = *expr_p;
10173 gomp_target *stmt;
10174 tree clauses, t, decl;
10176 clauses = OACC_DECLARE_CLAUSES (expr);
10178 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
10179 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
10181 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
10183 decl = OMP_CLAUSE_DECL (t);
10185 if (TREE_CODE (decl) == MEM_REF)
10186 decl = TREE_OPERAND (decl, 0);
10188 if (VAR_P (decl) && !is_oacc_declared (decl))
10190 tree attr = get_identifier ("oacc declare target");
10191 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
10192 DECL_ATTRIBUTES (decl));
10195 if (VAR_P (decl)
10196 && !is_global_var (decl)
10197 && DECL_CONTEXT (decl) == current_function_decl)
10199 tree c = gimplify_oacc_declare_1 (t);
10200 if (c)
10202 if (oacc_declare_returns == NULL)
10203 oacc_declare_returns = new hash_map<tree, tree>;
10205 oacc_declare_returns->put (decl, c);
10209 if (gimplify_omp_ctxp)
10210 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
10213 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
10214 clauses);
10216 gimplify_seq_add_stmt (pre_p, stmt);
10218 *expr_p = NULL_TREE;
10221 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
10222 gimplification of the body, as well as scanning the body for used
10223 variables. We need to do this scan now, because variable-sized
10224 decls will be decomposed during gimplification. */
10226 static void
10227 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
10229 tree expr = *expr_p;
10230 gimple *g;
10231 gimple_seq body = NULL;
10233 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
10234 OMP_PARALLEL_COMBINED (expr)
10235 ? ORT_COMBINED_PARALLEL
10236 : ORT_PARALLEL, OMP_PARALLEL);
10238 push_gimplify_context ();
10240 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
10241 if (gimple_code (g) == GIMPLE_BIND)
10242 pop_gimplify_context (g);
10243 else
10244 pop_gimplify_context (NULL);
10246 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
10247 OMP_PARALLEL);
10249 g = gimple_build_omp_parallel (body,
10250 OMP_PARALLEL_CLAUSES (expr),
10251 NULL_TREE, NULL_TREE);
10252 if (OMP_PARALLEL_COMBINED (expr))
10253 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
10254 gimplify_seq_add_stmt (pre_p, g);
10255 *expr_p = NULL_TREE;
10258 /* Gimplify the contents of an OMP_TASK statement. This involves
10259 gimplification of the body, as well as scanning the body for used
10260 variables. We need to do this scan now, because variable-sized
10261 decls will be decomposed during gimplification. */
10263 static void
10264 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
10266 tree expr = *expr_p;
10267 gimple *g;
10268 gimple_seq body = NULL;
10270 if (OMP_TASK_BODY (expr) == NULL_TREE)
10271 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
10272 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10273 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
10275 error_at (OMP_CLAUSE_LOCATION (c),
10276 "%<mutexinoutset%> kind in %<depend%> clause on a "
10277 "%<taskwait%> construct");
10278 break;
10281 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
10282 omp_find_clause (OMP_TASK_CLAUSES (expr),
10283 OMP_CLAUSE_UNTIED)
10284 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
10286 if (OMP_TASK_BODY (expr))
10288 push_gimplify_context ();
10290 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
10291 if (gimple_code (g) == GIMPLE_BIND)
10292 pop_gimplify_context (g);
10293 else
10294 pop_gimplify_context (NULL);
10297 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
10298 OMP_TASK);
10300 g = gimple_build_omp_task (body,
10301 OMP_TASK_CLAUSES (expr),
10302 NULL_TREE, NULL_TREE,
10303 NULL_TREE, NULL_TREE, NULL_TREE);
10304 if (OMP_TASK_BODY (expr) == NULL_TREE)
10305 gimple_omp_task_set_taskwait_p (g, true);
10306 gimplify_seq_add_stmt (pre_p, g);
10307 *expr_p = NULL_TREE;
10310 /* Helper function of gimplify_omp_for, find OMP_FOR resp. OMP_SIMD
10311 with non-NULL OMP_FOR_INIT. Also, fill in pdata array,
10312 pdata[0] non-NULL if there is anything non-trivial in between, pdata[1]
10313 is address of OMP_PARALLEL in between if any, pdata[2] is address of
10314 OMP_FOR in between if any and pdata[3] is address of the inner
10315 OMP_FOR/OMP_SIMD. */
10317 static tree
10318 find_combined_omp_for (tree *tp, int *walk_subtrees, void *data)
10320 tree **pdata = (tree **) data;
10321 *walk_subtrees = 0;
10322 switch (TREE_CODE (*tp))
10324 case OMP_FOR:
10325 if (OMP_FOR_INIT (*tp) != NULL_TREE)
10327 pdata[3] = tp;
10328 return *tp;
10330 pdata[2] = tp;
10331 *walk_subtrees = 1;
10332 break;
10333 case OMP_SIMD:
10334 if (OMP_FOR_INIT (*tp) != NULL_TREE)
10336 pdata[3] = tp;
10337 return *tp;
10339 break;
10340 case BIND_EXPR:
10341 if (BIND_EXPR_VARS (*tp)
10342 || (BIND_EXPR_BLOCK (*tp)
10343 && BLOCK_VARS (BIND_EXPR_BLOCK (*tp))))
10344 pdata[0] = tp;
10345 *walk_subtrees = 1;
10346 break;
10347 case STATEMENT_LIST:
10348 if (!tsi_one_before_end_p (tsi_start (*tp)))
10349 pdata[0] = tp;
10350 *walk_subtrees = 1;
10351 break;
10352 case TRY_FINALLY_EXPR:
10353 pdata[0] = tp;
10354 *walk_subtrees = 1;
10355 break;
10356 case OMP_PARALLEL:
10357 pdata[1] = tp;
10358 *walk_subtrees = 1;
10359 break;
10360 default:
10361 break;
10363 return NULL_TREE;
10366 /* Gimplify the gross structure of an OMP_FOR statement. */
10368 static enum gimplify_status
10369 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
10371 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
10372 enum gimplify_status ret = GS_ALL_DONE;
10373 enum gimplify_status tret;
10374 gomp_for *gfor;
10375 gimple_seq for_body, for_pre_body;
10376 int i;
10377 bitmap has_decl_expr = NULL;
10378 enum omp_region_type ort = ORT_WORKSHARE;
10380 orig_for_stmt = for_stmt = *expr_p;
10382 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
10384 tree *data[4] = { NULL, NULL, NULL, NULL };
10385 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
10386 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
10387 find_combined_omp_for, data, NULL);
10388 if (inner_for_stmt == NULL_TREE)
10390 gcc_assert (seen_error ());
10391 *expr_p = NULL_TREE;
10392 return GS_ERROR;
10394 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
10396 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
10397 &OMP_FOR_PRE_BODY (for_stmt));
10398 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
10400 if (OMP_FOR_PRE_BODY (inner_for_stmt))
10402 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
10403 &OMP_FOR_PRE_BODY (for_stmt));
10404 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
10407 if (data[0])
10409 /* We have some statements or variable declarations in between
10410 the composite construct directives. Move them around the
10411 inner_for_stmt. */
10412 data[0] = expr_p;
10413 for (i = 0; i < 3; i++)
10414 if (data[i])
10416 tree t = *data[i];
10417 if (i < 2 && data[i + 1] == &OMP_BODY (t))
10418 data[i + 1] = data[i];
10419 *data[i] = OMP_BODY (t);
10420 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
10421 NULL_TREE, make_node (BLOCK));
10422 OMP_BODY (t) = body;
10423 append_to_statement_list_force (inner_for_stmt,
10424 &BIND_EXPR_BODY (body));
10425 *data[3] = t;
10426 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
10427 gcc_assert (*data[3] == inner_for_stmt);
10429 return GS_OK;
10432 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
10433 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
10434 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
10435 i)) == TREE_LIST
10436 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
10437 i)))
10439 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
10440 /* Class iterators aren't allowed on OMP_SIMD, so the only
10441 case we need to solve is distribute parallel for. */
10442 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
10443 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
10444 && data[1]);
10445 tree orig_decl = TREE_PURPOSE (orig);
10446 tree last = TREE_VALUE (orig);
10447 tree *pc;
10448 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
10449 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
10450 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
10451 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
10452 && OMP_CLAUSE_DECL (*pc) == orig_decl)
10453 break;
10454 if (*pc == NULL_TREE)
10456 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
10458 /* private clause will appear only on inner_for_stmt.
10459 Change it into firstprivate, and add private clause
10460 on for_stmt. */
10461 tree c = copy_node (*pc);
10462 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
10463 OMP_FOR_CLAUSES (for_stmt) = c;
10464 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
10465 lang_hooks.decls.omp_finish_clause (*pc, pre_p);
10467 else
10469 /* lastprivate clause will appear on both inner_for_stmt
10470 and for_stmt. Add firstprivate clause to
10471 inner_for_stmt. */
10472 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
10473 OMP_CLAUSE_FIRSTPRIVATE);
10474 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
10475 OMP_CLAUSE_CHAIN (c) = *pc;
10476 *pc = c;
10477 lang_hooks.decls.omp_finish_clause (*pc, pre_p);
10479 tree c = build_omp_clause (UNKNOWN_LOCATION,
10480 OMP_CLAUSE_FIRSTPRIVATE);
10481 OMP_CLAUSE_DECL (c) = last;
10482 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
10483 OMP_PARALLEL_CLAUSES (*data[1]) = c;
10484 c = build_omp_clause (UNKNOWN_LOCATION,
10485 *pc ? OMP_CLAUSE_SHARED
10486 : OMP_CLAUSE_FIRSTPRIVATE);
10487 OMP_CLAUSE_DECL (c) = orig_decl;
10488 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
10489 OMP_PARALLEL_CLAUSES (*data[1]) = c;
10491 /* Similarly, take care of C++ range for temporaries, those should
10492 be firstprivate on OMP_PARALLEL if any. */
10493 if (data[1])
10494 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
10495 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
10496 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
10497 i)) == TREE_LIST
10498 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
10499 i)))
10501 tree orig
10502 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
10503 tree v = TREE_CHAIN (orig);
10504 tree c = build_omp_clause (UNKNOWN_LOCATION,
10505 OMP_CLAUSE_FIRSTPRIVATE);
10506 /* First add firstprivate clause for the __for_end artificial
10507 decl. */
10508 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
10509 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
10510 == REFERENCE_TYPE)
10511 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
10512 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
10513 OMP_PARALLEL_CLAUSES (*data[1]) = c;
10514 if (TREE_VEC_ELT (v, 0))
10516 /* And now the same for __for_range artificial decl if it
10517 exists. */
10518 c = build_omp_clause (UNKNOWN_LOCATION,
10519 OMP_CLAUSE_FIRSTPRIVATE);
10520 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
10521 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
10522 == REFERENCE_TYPE)
10523 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
10524 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
10525 OMP_PARALLEL_CLAUSES (*data[1]) = c;
10530 switch (TREE_CODE (for_stmt))
10532 case OMP_FOR:
10533 case OMP_DISTRIBUTE:
10534 break;
10535 case OACC_LOOP:
10536 ort = ORT_ACC;
10537 break;
10538 case OMP_TASKLOOP:
10539 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
10540 ort = ORT_UNTIED_TASKLOOP;
10541 else
10542 ort = ORT_TASKLOOP;
10543 break;
10544 case OMP_SIMD:
10545 ort = ORT_SIMD;
10546 break;
10547 default:
10548 gcc_unreachable ();
10551 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
10552 clause for the IV. */
10553 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
10555 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
10556 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
10557 decl = TREE_OPERAND (t, 0);
10558 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
10559 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10560 && OMP_CLAUSE_DECL (c) == decl)
10562 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
10563 break;
10567 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
10568 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
10569 TREE_CODE (for_stmt));
10571 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
10572 gimplify_omp_ctxp->distribute = true;
10574 /* Handle OMP_FOR_INIT. */
10575 for_pre_body = NULL;
10576 if ((ort == ORT_SIMD
10577 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
10578 && OMP_FOR_PRE_BODY (for_stmt))
10580 has_decl_expr = BITMAP_ALLOC (NULL);
10581 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
10582 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
10583 == VAR_DECL)
10585 t = OMP_FOR_PRE_BODY (for_stmt);
10586 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
10588 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
10590 tree_stmt_iterator si;
10591 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
10592 tsi_next (&si))
10594 t = tsi_stmt (si);
10595 if (TREE_CODE (t) == DECL_EXPR
10596 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
10597 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
10601 if (OMP_FOR_PRE_BODY (for_stmt))
10603 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
10604 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
10605 else
10607 struct gimplify_omp_ctx ctx;
10608 memset (&ctx, 0, sizeof (ctx));
10609 ctx.region_type = ORT_NONE;
10610 gimplify_omp_ctxp = &ctx;
10611 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
10612 gimplify_omp_ctxp = NULL;
10615 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
10617 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
10618 for_stmt = inner_for_stmt;
10620 /* For taskloop, need to gimplify the start, end and step before the
10621 taskloop, outside of the taskloop omp context. */
10622 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
10624 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
10626 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
10627 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
10629 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
10630 TREE_OPERAND (t, 1)
10631 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
10632 gimple_seq_empty_p (for_pre_body)
10633 ? pre_p : &for_pre_body, NULL,
10634 false);
10635 /* Reference to pointer conversion is considered useless,
10636 but is significant for firstprivate clause. Force it
10637 here. */
10638 if (TREE_CODE (type) == POINTER_TYPE
10639 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1)))
10640 == REFERENCE_TYPE))
10642 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
10643 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v,
10644 TREE_OPERAND (t, 1));
10645 gimplify_and_add (m, gimple_seq_empty_p (for_pre_body)
10646 ? pre_p : &for_pre_body);
10647 TREE_OPERAND (t, 1) = v;
10649 tree c = build_omp_clause (input_location,
10650 OMP_CLAUSE_FIRSTPRIVATE);
10651 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
10652 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
10653 OMP_FOR_CLAUSES (orig_for_stmt) = c;
10656 /* Handle OMP_FOR_COND. */
10657 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
10658 if (!is_gimple_constant (TREE_OPERAND (t, 1)))
10660 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
10661 TREE_OPERAND (t, 1)
10662 = get_initialized_tmp_var (TREE_OPERAND (t, 1),
10663 gimple_seq_empty_p (for_pre_body)
10664 ? pre_p : &for_pre_body, NULL,
10665 false);
10666 /* Reference to pointer conversion is considered useless,
10667 but is significant for firstprivate clause. Force it
10668 here. */
10669 if (TREE_CODE (type) == POINTER_TYPE
10670 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1)))
10671 == REFERENCE_TYPE))
10673 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
10674 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v,
10675 TREE_OPERAND (t, 1));
10676 gimplify_and_add (m, gimple_seq_empty_p (for_pre_body)
10677 ? pre_p : &for_pre_body);
10678 TREE_OPERAND (t, 1) = v;
10680 tree c = build_omp_clause (input_location,
10681 OMP_CLAUSE_FIRSTPRIVATE);
10682 OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
10683 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
10684 OMP_FOR_CLAUSES (orig_for_stmt) = c;
10687 /* Handle OMP_FOR_INCR. */
10688 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
10689 if (TREE_CODE (t) == MODIFY_EXPR)
10691 decl = TREE_OPERAND (t, 0);
10692 t = TREE_OPERAND (t, 1);
10693 tree *tp = &TREE_OPERAND (t, 1);
10694 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
10695 tp = &TREE_OPERAND (t, 0);
10697 if (!is_gimple_constant (*tp))
10699 gimple_seq *seq = gimple_seq_empty_p (for_pre_body)
10700 ? pre_p : &for_pre_body;
10701 *tp = get_initialized_tmp_var (*tp, seq, NULL, false);
10702 tree c = build_omp_clause (input_location,
10703 OMP_CLAUSE_FIRSTPRIVATE);
10704 OMP_CLAUSE_DECL (c) = *tp;
10705 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
10706 OMP_FOR_CLAUSES (orig_for_stmt) = c;
10711 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
10712 OMP_TASKLOOP);
10715 if (orig_for_stmt != for_stmt)
10716 gimplify_omp_ctxp->combined_loop = true;
10718 for_body = NULL;
10719 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
10720 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
10721 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
10722 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
10724 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
10725 bool is_doacross = false;
10726 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
10728 is_doacross = true;
10729 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
10730 (OMP_FOR_INIT (for_stmt))
10731 * 2);
10733 int collapse = 1, tile = 0;
10734 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
10735 if (c)
10736 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
10737 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
10738 if (c)
10739 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
10740 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
10742 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
10743 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
10744 decl = TREE_OPERAND (t, 0);
10745 gcc_assert (DECL_P (decl));
10746 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
10747 || POINTER_TYPE_P (TREE_TYPE (decl)));
10748 if (is_doacross)
10750 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
10752 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
10753 if (TREE_CODE (orig_decl) == TREE_LIST)
10755 orig_decl = TREE_PURPOSE (orig_decl);
10756 if (!orig_decl)
10757 orig_decl = decl;
10759 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
10761 else
10762 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
10763 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
10766 /* Make sure the iteration variable is private. */
10767 tree c = NULL_TREE;
10768 tree c2 = NULL_TREE;
10769 if (orig_for_stmt != for_stmt)
10771 /* Preserve this information until we gimplify the inner simd. */
10772 if (has_decl_expr
10773 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
10774 TREE_PRIVATE (t) = 1;
10776 else if (ort == ORT_SIMD)
10778 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
10779 (splay_tree_key) decl);
10780 omp_is_private (gimplify_omp_ctxp, decl,
10781 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
10782 != 1));
10783 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
10785 omp_notice_variable (gimplify_omp_ctxp, decl, true);
10786 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
10787 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
10788 OMP_CLAUSE_LASTPRIVATE);
10789 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
10790 OMP_CLAUSE_LASTPRIVATE))
10791 if (OMP_CLAUSE_DECL (c3) == decl)
10793 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
10794 "conditional %<lastprivate%> on loop "
10795 "iterator %qD ignored", decl);
10796 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
10797 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
10800 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
10802 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
10803 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
10804 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
10805 if ((has_decl_expr
10806 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
10807 || TREE_PRIVATE (t))
10809 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
10810 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
10812 struct gimplify_omp_ctx *outer
10813 = gimplify_omp_ctxp->outer_context;
10814 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
10816 if (outer->region_type == ORT_WORKSHARE
10817 && outer->combined_loop)
10819 n = splay_tree_lookup (outer->variables,
10820 (splay_tree_key)decl);
10821 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
10823 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
10824 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
10826 else
10828 struct gimplify_omp_ctx *octx = outer->outer_context;
10829 if (octx
10830 && octx->region_type == ORT_COMBINED_PARALLEL
10831 && octx->outer_context
10832 && (octx->outer_context->region_type
10833 == ORT_WORKSHARE)
10834 && octx->outer_context->combined_loop)
10836 octx = octx->outer_context;
10837 n = splay_tree_lookup (octx->variables,
10838 (splay_tree_key)decl);
10839 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
10841 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
10842 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
10849 OMP_CLAUSE_DECL (c) = decl;
10850 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
10851 OMP_FOR_CLAUSES (for_stmt) = c;
10852 omp_add_variable (gimplify_omp_ctxp, decl, flags);
10853 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
10855 if (outer->region_type == ORT_WORKSHARE
10856 && outer->combined_loop)
10858 if (outer->outer_context
10859 && (outer->outer_context->region_type
10860 == ORT_COMBINED_PARALLEL))
10861 outer = outer->outer_context;
10862 else if (omp_check_private (outer, decl, false))
10863 outer = NULL;
10865 else if (((outer->region_type & ORT_TASKLOOP)
10866 == ORT_TASKLOOP)
10867 && outer->combined_loop
10868 && !omp_check_private (gimplify_omp_ctxp,
10869 decl, false))
10871 else if (outer->region_type != ORT_COMBINED_PARALLEL)
10873 omp_notice_variable (outer, decl, true);
10874 outer = NULL;
10876 if (outer)
10878 n = splay_tree_lookup (outer->variables,
10879 (splay_tree_key)decl);
10880 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
10882 omp_add_variable (outer, decl,
10883 GOVD_LASTPRIVATE | GOVD_SEEN);
10884 if (outer->region_type == ORT_COMBINED_PARALLEL
10885 && outer->outer_context
10886 && (outer->outer_context->region_type
10887 == ORT_WORKSHARE)
10888 && outer->outer_context->combined_loop)
10890 outer = outer->outer_context;
10891 n = splay_tree_lookup (outer->variables,
10892 (splay_tree_key)decl);
10893 if (omp_check_private (outer, decl, false))
10894 outer = NULL;
10895 else if (n == NULL
10896 || ((n->value & GOVD_DATA_SHARE_CLASS)
10897 == 0))
10898 omp_add_variable (outer, decl,
10899 GOVD_LASTPRIVATE
10900 | GOVD_SEEN);
10901 else
10902 outer = NULL;
10904 if (outer && outer->outer_context
10905 && ((outer->outer_context->region_type
10906 & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS
10907 || (((outer->region_type & ORT_TASKLOOP)
10908 == ORT_TASKLOOP)
10909 && (outer->outer_context->region_type
10910 == ORT_COMBINED_PARALLEL))))
10912 outer = outer->outer_context;
10913 n = splay_tree_lookup (outer->variables,
10914 (splay_tree_key)decl);
10915 if (n == NULL
10916 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
10917 omp_add_variable (outer, decl,
10918 GOVD_SHARED | GOVD_SEEN);
10919 else
10920 outer = NULL;
10922 if (outer && outer->outer_context)
10923 omp_notice_variable (outer->outer_context, decl,
10924 true);
10929 else
10931 bool lastprivate
10932 = (!has_decl_expr
10933 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
10934 if (TREE_PRIVATE (t))
10935 lastprivate = false;
10936 struct gimplify_omp_ctx *outer
10937 = gimplify_omp_ctxp->outer_context;
10938 if (outer && lastprivate)
10940 if (outer->region_type == ORT_WORKSHARE
10941 && outer->combined_loop)
10943 n = splay_tree_lookup (outer->variables,
10944 (splay_tree_key)decl);
10945 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
10947 lastprivate = false;
10948 outer = NULL;
10950 else if (outer->outer_context
10951 && (outer->outer_context->region_type
10952 == ORT_COMBINED_PARALLEL))
10953 outer = outer->outer_context;
10954 else if (omp_check_private (outer, decl, false))
10955 outer = NULL;
10957 else if (((outer->region_type & ORT_TASKLOOP)
10958 == ORT_TASKLOOP)
10959 && outer->combined_loop
10960 && !omp_check_private (gimplify_omp_ctxp,
10961 decl, false))
10963 else if (outer->region_type != ORT_COMBINED_PARALLEL)
10965 omp_notice_variable (outer, decl, true);
10966 outer = NULL;
10968 if (outer)
10970 n = splay_tree_lookup (outer->variables,
10971 (splay_tree_key)decl);
10972 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
10974 omp_add_variable (outer, decl,
10975 GOVD_LASTPRIVATE | GOVD_SEEN);
10976 if (outer->region_type == ORT_COMBINED_PARALLEL
10977 && outer->outer_context
10978 && (outer->outer_context->region_type
10979 == ORT_WORKSHARE)
10980 && outer->outer_context->combined_loop)
10982 outer = outer->outer_context;
10983 n = splay_tree_lookup (outer->variables,
10984 (splay_tree_key)decl);
10985 if (omp_check_private (outer, decl, false))
10986 outer = NULL;
10987 else if (n == NULL
10988 || ((n->value & GOVD_DATA_SHARE_CLASS)
10989 == 0))
10990 omp_add_variable (outer, decl,
10991 GOVD_LASTPRIVATE
10992 | GOVD_SEEN);
10993 else
10994 outer = NULL;
10996 if (outer && outer->outer_context
10997 && ((outer->outer_context->region_type
10998 & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS
10999 || (((outer->region_type & ORT_TASKLOOP)
11000 == ORT_TASKLOOP)
11001 && (outer->outer_context->region_type
11002 == ORT_COMBINED_PARALLEL))))
11004 outer = outer->outer_context;
11005 n = splay_tree_lookup (outer->variables,
11006 (splay_tree_key)decl);
11007 if (n == NULL
11008 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11009 omp_add_variable (outer, decl,
11010 GOVD_SHARED | GOVD_SEEN);
11011 else
11012 outer = NULL;
11014 if (outer && outer->outer_context)
11015 omp_notice_variable (outer->outer_context, decl,
11016 true);
11021 c = build_omp_clause (input_location,
11022 lastprivate ? OMP_CLAUSE_LASTPRIVATE
11023 : OMP_CLAUSE_PRIVATE);
11024 OMP_CLAUSE_DECL (c) = decl;
11025 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
11026 OMP_FOR_CLAUSES (for_stmt) = c;
11027 omp_add_variable (gimplify_omp_ctxp, decl,
11028 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
11029 | GOVD_EXPLICIT | GOVD_SEEN);
11030 c = NULL_TREE;
11033 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
11035 omp_notice_variable (gimplify_omp_ctxp, decl, true);
11036 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
11037 (splay_tree_key) decl);
11038 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
11039 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
11040 OMP_CLAUSE_LASTPRIVATE);
11041 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
11042 OMP_CLAUSE_LASTPRIVATE))
11043 if (OMP_CLAUSE_DECL (c3) == decl)
11045 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
11046 "conditional %<lastprivate%> on loop "
11047 "iterator %qD ignored", decl);
11048 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
11049 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
11052 else
11053 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
11055 /* If DECL is not a gimple register, create a temporary variable to act
11056 as an iteration counter. This is valid, since DECL cannot be
11057 modified in the body of the loop. Similarly for any iteration vars
11058 in simd with collapse > 1 where the iterator vars must be
11059 lastprivate. */
11060 if (orig_for_stmt != for_stmt)
11061 var = decl;
11062 else if (!is_gimple_reg (decl)
11063 || (ort == ORT_SIMD
11064 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1))
11066 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11067 /* Make sure omp_add_variable is not called on it prematurely.
11068 We call it ourselves a few lines later. */
11069 gimplify_omp_ctxp = NULL;
11070 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
11071 gimplify_omp_ctxp = ctx;
11072 TREE_OPERAND (t, 0) = var;
11074 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
11076 if (ort == ORT_SIMD
11077 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
11079 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
11080 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
11081 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
11082 OMP_CLAUSE_DECL (c2) = var;
11083 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
11084 OMP_FOR_CLAUSES (for_stmt) = c2;
11085 omp_add_variable (gimplify_omp_ctxp, var,
11086 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
11087 if (c == NULL_TREE)
11089 c = c2;
11090 c2 = NULL_TREE;
11093 else
11094 omp_add_variable (gimplify_omp_ctxp, var,
11095 GOVD_PRIVATE | GOVD_SEEN);
11097 else
11098 var = decl;
11100 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
11101 is_gimple_val, fb_rvalue, false);
11102 ret = MIN (ret, tret);
11103 if (ret == GS_ERROR)
11104 return ret;
11106 /* Handle OMP_FOR_COND. */
11107 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
11108 gcc_assert (COMPARISON_CLASS_P (t));
11109 gcc_assert (TREE_OPERAND (t, 0) == decl);
11111 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
11112 is_gimple_val, fb_rvalue, false);
11113 ret = MIN (ret, tret);
11115 /* Handle OMP_FOR_INCR. */
11116 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11117 switch (TREE_CODE (t))
11119 case PREINCREMENT_EXPR:
11120 case POSTINCREMENT_EXPR:
11122 tree decl = TREE_OPERAND (t, 0);
11123 /* c_omp_for_incr_canonicalize_ptr() should have been
11124 called to massage things appropriately. */
11125 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
11127 if (orig_for_stmt != for_stmt)
11128 break;
11129 t = build_int_cst (TREE_TYPE (decl), 1);
11130 if (c)
11131 OMP_CLAUSE_LINEAR_STEP (c) = t;
11132 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
11133 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
11134 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
11135 break;
11138 case PREDECREMENT_EXPR:
11139 case POSTDECREMENT_EXPR:
11140 /* c_omp_for_incr_canonicalize_ptr() should have been
11141 called to massage things appropriately. */
11142 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
11143 if (orig_for_stmt != for_stmt)
11144 break;
11145 t = build_int_cst (TREE_TYPE (decl), -1);
11146 if (c)
11147 OMP_CLAUSE_LINEAR_STEP (c) = t;
11148 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
11149 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
11150 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
11151 break;
11153 case MODIFY_EXPR:
11154 gcc_assert (TREE_OPERAND (t, 0) == decl);
11155 TREE_OPERAND (t, 0) = var;
11157 t = TREE_OPERAND (t, 1);
11158 switch (TREE_CODE (t))
11160 case PLUS_EXPR:
11161 if (TREE_OPERAND (t, 1) == decl)
11163 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
11164 TREE_OPERAND (t, 0) = var;
11165 break;
11168 /* Fallthru. */
11169 case MINUS_EXPR:
11170 case POINTER_PLUS_EXPR:
11171 gcc_assert (TREE_OPERAND (t, 0) == decl);
11172 TREE_OPERAND (t, 0) = var;
11173 break;
11174 default:
11175 gcc_unreachable ();
11178 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
11179 is_gimple_val, fb_rvalue, false);
11180 ret = MIN (ret, tret);
11181 if (c)
11183 tree step = TREE_OPERAND (t, 1);
11184 tree stept = TREE_TYPE (decl);
11185 if (POINTER_TYPE_P (stept))
11186 stept = sizetype;
11187 step = fold_convert (stept, step);
11188 if (TREE_CODE (t) == MINUS_EXPR)
11189 step = fold_build1 (NEGATE_EXPR, stept, step);
11190 OMP_CLAUSE_LINEAR_STEP (c) = step;
11191 if (step != TREE_OPERAND (t, 1))
11193 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
11194 &for_pre_body, NULL,
11195 is_gimple_val, fb_rvalue, false);
11196 ret = MIN (ret, tret);
11199 break;
11201 default:
11202 gcc_unreachable ();
11205 if (c2)
11207 gcc_assert (c);
11208 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
11211 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
11213 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
11214 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11215 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
11216 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11217 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
11218 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
11219 && OMP_CLAUSE_DECL (c) == decl)
11221 if (is_doacross && (collapse == 1 || i >= collapse))
11222 t = var;
11223 else
11225 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11226 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
11227 gcc_assert (TREE_OPERAND (t, 0) == var);
11228 t = TREE_OPERAND (t, 1);
11229 gcc_assert (TREE_CODE (t) == PLUS_EXPR
11230 || TREE_CODE (t) == MINUS_EXPR
11231 || TREE_CODE (t) == POINTER_PLUS_EXPR);
11232 gcc_assert (TREE_OPERAND (t, 0) == var);
11233 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
11234 is_doacross ? var : decl,
11235 TREE_OPERAND (t, 1));
11237 gimple_seq *seq;
11238 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
11239 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
11240 else
11241 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
11242 push_gimplify_context ();
11243 gimplify_assign (decl, t, seq);
11244 gimple *bind = NULL;
11245 if (gimplify_ctxp->temps)
11247 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
11248 *seq = NULL;
11249 gimplify_seq_add_stmt (seq, bind);
11251 pop_gimplify_context (bind);
11256 BITMAP_FREE (has_decl_expr);
11258 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11260 push_gimplify_context ();
11261 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
11263 OMP_FOR_BODY (orig_for_stmt)
11264 = build3 (BIND_EXPR, void_type_node, NULL,
11265 OMP_FOR_BODY (orig_for_stmt), NULL);
11266 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
11270 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
11271 &for_body);
11273 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11275 if (gimple_code (g) == GIMPLE_BIND)
11276 pop_gimplify_context (g);
11277 else
11278 pop_gimplify_context (NULL);
11281 if (orig_for_stmt != for_stmt)
11282 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11284 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11285 decl = TREE_OPERAND (t, 0);
11286 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11287 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11288 gimplify_omp_ctxp = ctx->outer_context;
11289 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
11290 gimplify_omp_ctxp = ctx;
11291 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
11292 TREE_OPERAND (t, 0) = var;
11293 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11294 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
11295 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
11298 gimplify_adjust_omp_clauses (pre_p, for_body,
11299 &OMP_FOR_CLAUSES (orig_for_stmt),
11300 TREE_CODE (orig_for_stmt));
11302 int kind;
11303 switch (TREE_CODE (orig_for_stmt))
11305 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
11306 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
11307 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
11308 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
11309 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
11310 default:
11311 gcc_unreachable ();
11313 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
11314 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
11315 for_pre_body);
11316 if (orig_for_stmt != for_stmt)
11317 gimple_omp_for_set_combined_p (gfor, true);
11318 if (gimplify_omp_ctxp
11319 && (gimplify_omp_ctxp->combined_loop
11320 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
11321 && gimplify_omp_ctxp->outer_context
11322 && gimplify_omp_ctxp->outer_context->combined_loop)))
11324 gimple_omp_for_set_combined_into_p (gfor, true);
11325 if (gimplify_omp_ctxp->combined_loop)
11326 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
11327 else
11328 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
11331 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11333 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11334 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
11335 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
11336 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
11337 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
11338 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
11339 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11340 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
11343 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
11344 constructs with GIMPLE_OMP_TASK sandwiched in between them.
11345 The outer taskloop stands for computing the number of iterations,
11346 counts for collapsed loops and holding taskloop specific clauses.
11347 The task construct stands for the effect of data sharing on the
11348 explicit task it creates and the inner taskloop stands for expansion
11349 of the static loop inside of the explicit task construct. */
11350 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11352 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
11353 tree task_clauses = NULL_TREE;
11354 tree c = *gfor_clauses_ptr;
11355 tree *gtask_clauses_ptr = &task_clauses;
11356 tree outer_for_clauses = NULL_TREE;
11357 tree *gforo_clauses_ptr = &outer_for_clauses;
11358 for (; c; c = OMP_CLAUSE_CHAIN (c))
11359 switch (OMP_CLAUSE_CODE (c))
11361 /* These clauses are allowed on task, move them there. */
11362 case OMP_CLAUSE_SHARED:
11363 case OMP_CLAUSE_FIRSTPRIVATE:
11364 case OMP_CLAUSE_DEFAULT:
11365 case OMP_CLAUSE_IF:
11366 case OMP_CLAUSE_UNTIED:
11367 case OMP_CLAUSE_FINAL:
11368 case OMP_CLAUSE_MERGEABLE:
11369 case OMP_CLAUSE_PRIORITY:
11370 case OMP_CLAUSE_REDUCTION:
11371 case OMP_CLAUSE_IN_REDUCTION:
11372 *gtask_clauses_ptr = c;
11373 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11374 break;
11375 case OMP_CLAUSE_PRIVATE:
11376 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
11378 /* We want private on outer for and firstprivate
11379 on task. */
11380 *gtask_clauses_ptr
11381 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11382 OMP_CLAUSE_FIRSTPRIVATE);
11383 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
11384 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
11385 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
11386 *gforo_clauses_ptr = c;
11387 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11389 else
11391 *gtask_clauses_ptr = c;
11392 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11394 break;
11395 /* These clauses go into outer taskloop clauses. */
11396 case OMP_CLAUSE_GRAINSIZE:
11397 case OMP_CLAUSE_NUM_TASKS:
11398 case OMP_CLAUSE_NOGROUP:
11399 *gforo_clauses_ptr = c;
11400 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11401 break;
11402 /* Taskloop clause we duplicate on both taskloops. */
11403 case OMP_CLAUSE_COLLAPSE:
11404 *gfor_clauses_ptr = c;
11405 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11406 *gforo_clauses_ptr = copy_node (c);
11407 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
11408 break;
11409 /* For lastprivate, keep the clause on inner taskloop, and add
11410 a shared clause on task. If the same decl is also firstprivate,
11411 add also firstprivate clause on the inner taskloop. */
11412 case OMP_CLAUSE_LASTPRIVATE:
11413 if (OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c))
11415 /* For taskloop C++ lastprivate IVs, we want:
11416 1) private on outer taskloop
11417 2) firstprivate and shared on task
11418 3) lastprivate on inner taskloop */
11419 *gtask_clauses_ptr
11420 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11421 OMP_CLAUSE_FIRSTPRIVATE);
11422 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
11423 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL);
11424 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
11425 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
11426 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11427 OMP_CLAUSE_PRIVATE);
11428 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
11429 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
11430 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
11431 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
11433 *gfor_clauses_ptr = c;
11434 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
11435 *gtask_clauses_ptr
11436 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
11437 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
11438 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
11439 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
11440 gtask_clauses_ptr
11441 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
11442 break;
11443 default:
11444 gcc_unreachable ();
11446 *gfor_clauses_ptr = NULL_TREE;
11447 *gtask_clauses_ptr = NULL_TREE;
11448 *gforo_clauses_ptr = NULL_TREE;
11449 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
11450 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
11451 NULL_TREE, NULL_TREE, NULL_TREE);
11452 gimple_omp_task_set_taskloop_p (g, true);
11453 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
11454 gomp_for *gforo
11455 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
11456 gimple_omp_for_collapse (gfor),
11457 gimple_omp_for_pre_body (gfor));
11458 gimple_omp_for_set_pre_body (gfor, NULL);
11459 gimple_omp_for_set_combined_p (gforo, true);
11460 gimple_omp_for_set_combined_into_p (gfor, true);
11461 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
11463 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
11464 tree v = create_tmp_var (type);
11465 gimple_omp_for_set_index (gforo, i, v);
11466 t = unshare_expr (gimple_omp_for_initial (gfor, i));
11467 gimple_omp_for_set_initial (gforo, i, t);
11468 gimple_omp_for_set_cond (gforo, i,
11469 gimple_omp_for_cond (gfor, i));
11470 t = unshare_expr (gimple_omp_for_final (gfor, i));
11471 gimple_omp_for_set_final (gforo, i, t);
11472 t = unshare_expr (gimple_omp_for_incr (gfor, i));
11473 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
11474 TREE_OPERAND (t, 0) = v;
11475 gimple_omp_for_set_incr (gforo, i, t);
11476 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
11477 OMP_CLAUSE_DECL (t) = v;
11478 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
11479 gimple_omp_for_set_clauses (gforo, t);
11481 gimplify_seq_add_stmt (pre_p, gforo);
11483 else
11484 gimplify_seq_add_stmt (pre_p, gfor);
11485 if (ret != GS_ALL_DONE)
11486 return GS_ERROR;
11487 *expr_p = NULL_TREE;
11488 return GS_ALL_DONE;
11491 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
11492 of OMP_TARGET's body. */
11494 static tree
11495 find_omp_teams (tree *tp, int *walk_subtrees, void *)
11497 *walk_subtrees = 0;
11498 switch (TREE_CODE (*tp))
11500 case OMP_TEAMS:
11501 return *tp;
11502 case BIND_EXPR:
11503 case STATEMENT_LIST:
11504 *walk_subtrees = 1;
11505 break;
11506 default:
11507 break;
11509 return NULL_TREE;
11512 /* Helper function of optimize_target_teams, determine if the expression
11513 can be computed safely before the target construct on the host. */
11515 static tree
11516 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
11518 splay_tree_node n;
11520 if (TYPE_P (*tp))
11522 *walk_subtrees = 0;
11523 return NULL_TREE;
11525 switch (TREE_CODE (*tp))
11527 case VAR_DECL:
11528 case PARM_DECL:
11529 case RESULT_DECL:
11530 *walk_subtrees = 0;
11531 if (error_operand_p (*tp)
11532 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
11533 || DECL_HAS_VALUE_EXPR_P (*tp)
11534 || DECL_THREAD_LOCAL_P (*tp)
11535 || TREE_SIDE_EFFECTS (*tp)
11536 || TREE_THIS_VOLATILE (*tp))
11537 return *tp;
11538 if (is_global_var (*tp)
11539 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
11540 || lookup_attribute ("omp declare target link",
11541 DECL_ATTRIBUTES (*tp))))
11542 return *tp;
11543 if (VAR_P (*tp)
11544 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
11545 && !is_global_var (*tp)
11546 && decl_function_context (*tp) == current_function_decl)
11547 return *tp;
11548 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
11549 (splay_tree_key) *tp);
11550 if (n == NULL)
11552 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
11553 return NULL_TREE;
11554 return *tp;
11556 else if (n->value & GOVD_LOCAL)
11557 return *tp;
11558 else if (n->value & GOVD_FIRSTPRIVATE)
11559 return NULL_TREE;
11560 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
11561 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
11562 return NULL_TREE;
11563 return *tp;
11564 case INTEGER_CST:
11565 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
11566 return *tp;
11567 return NULL_TREE;
11568 case TARGET_EXPR:
11569 if (TARGET_EXPR_INITIAL (*tp)
11570 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
11571 return *tp;
11572 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
11573 walk_subtrees, NULL);
11574 /* Allow some reasonable subset of integral arithmetics. */
11575 case PLUS_EXPR:
11576 case MINUS_EXPR:
11577 case MULT_EXPR:
11578 case TRUNC_DIV_EXPR:
11579 case CEIL_DIV_EXPR:
11580 case FLOOR_DIV_EXPR:
11581 case ROUND_DIV_EXPR:
11582 case TRUNC_MOD_EXPR:
11583 case CEIL_MOD_EXPR:
11584 case FLOOR_MOD_EXPR:
11585 case ROUND_MOD_EXPR:
11586 case RDIV_EXPR:
11587 case EXACT_DIV_EXPR:
11588 case MIN_EXPR:
11589 case MAX_EXPR:
11590 case LSHIFT_EXPR:
11591 case RSHIFT_EXPR:
11592 case BIT_IOR_EXPR:
11593 case BIT_XOR_EXPR:
11594 case BIT_AND_EXPR:
11595 case NEGATE_EXPR:
11596 case ABS_EXPR:
11597 case BIT_NOT_EXPR:
11598 case NON_LVALUE_EXPR:
11599 CASE_CONVERT:
11600 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
11601 return *tp;
11602 return NULL_TREE;
11603 /* And disallow anything else, except for comparisons. */
11604 default:
11605 if (COMPARISON_CLASS_P (*tp))
11606 return NULL_TREE;
11607 return *tp;
11611 /* Try to determine if the num_teams and/or thread_limit expressions
11612 can have their values determined already before entering the
11613 target construct.
11614 INTEGER_CSTs trivially are,
11615 integral decls that are firstprivate (explicitly or implicitly)
11616 or explicitly map(always, to:) or map(always, tofrom:) on the target
11617 region too, and expressions involving simple arithmetics on those
11618 too, function calls are not ok, dereferencing something neither etc.
11619 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
11620 EXPR based on what we find:
11621 0 stands for clause not specified at all, use implementation default
11622 -1 stands for value that can't be determined easily before entering
11623 the target construct.
11624 If teams construct is not present at all, use 1 for num_teams
11625 and 0 for thread_limit (only one team is involved, and the thread
11626 limit is implementation defined. */
11628 static void
11629 optimize_target_teams (tree target, gimple_seq *pre_p)
11631 tree body = OMP_BODY (target);
11632 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
11633 tree num_teams = integer_zero_node;
11634 tree thread_limit = integer_zero_node;
11635 location_t num_teams_loc = EXPR_LOCATION (target);
11636 location_t thread_limit_loc = EXPR_LOCATION (target);
11637 tree c, *p, expr;
11638 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
11640 if (teams == NULL_TREE)
11641 num_teams = integer_one_node;
11642 else
11643 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
11645 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
11647 p = &num_teams;
11648 num_teams_loc = OMP_CLAUSE_LOCATION (c);
11650 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
11652 p = &thread_limit;
11653 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
11655 else
11656 continue;
11657 expr = OMP_CLAUSE_OPERAND (c, 0);
11658 if (TREE_CODE (expr) == INTEGER_CST)
11660 *p = expr;
11661 continue;
11663 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
11665 *p = integer_minus_one_node;
11666 continue;
11668 *p = expr;
11669 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
11670 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
11671 == GS_ERROR)
11673 gimplify_omp_ctxp = target_ctx;
11674 *p = integer_minus_one_node;
11675 continue;
11677 gimplify_omp_ctxp = target_ctx;
11678 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
11679 OMP_CLAUSE_OPERAND (c, 0) = *p;
11681 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
11682 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
11683 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
11684 OMP_TARGET_CLAUSES (target) = c;
11685 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
11686 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
11687 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
11688 OMP_TARGET_CLAUSES (target) = c;
11691 /* Gimplify the gross structure of several OMP constructs. */
11693 static void
11694 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
11696 tree expr = *expr_p;
11697 gimple *stmt;
11698 gimple_seq body = NULL;
11699 enum omp_region_type ort;
11701 switch (TREE_CODE (expr))
11703 case OMP_SECTIONS:
11704 case OMP_SINGLE:
11705 ort = ORT_WORKSHARE;
11706 break;
11707 case OMP_TARGET:
11708 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
11709 break;
11710 case OACC_KERNELS:
11711 ort = ORT_ACC_KERNELS;
11712 break;
11713 case OACC_PARALLEL:
11714 ort = ORT_ACC_PARALLEL;
11715 break;
11716 case OACC_DATA:
11717 ort = ORT_ACC_DATA;
11718 break;
11719 case OMP_TARGET_DATA:
11720 ort = ORT_TARGET_DATA;
11721 break;
11722 case OMP_TEAMS:
11723 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
11724 if (gimplify_omp_ctxp == NULL
11725 || (gimplify_omp_ctxp->region_type == ORT_TARGET
11726 && gimplify_omp_ctxp->outer_context == NULL
11727 && lookup_attribute ("omp declare target",
11728 DECL_ATTRIBUTES (current_function_decl))))
11729 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
11730 break;
11731 case OACC_HOST_DATA:
11732 ort = ORT_ACC_HOST_DATA;
11733 break;
11734 default:
11735 gcc_unreachable ();
11737 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
11738 TREE_CODE (expr));
11739 if (TREE_CODE (expr) == OMP_TARGET)
11740 optimize_target_teams (expr, pre_p);
11741 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
11742 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
11744 push_gimplify_context ();
11745 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
11746 if (gimple_code (g) == GIMPLE_BIND)
11747 pop_gimplify_context (g);
11748 else
11749 pop_gimplify_context (NULL);
11750 if ((ort & ORT_TARGET_DATA) != 0)
11752 enum built_in_function end_ix;
11753 switch (TREE_CODE (expr))
11755 case OACC_DATA:
11756 case OACC_HOST_DATA:
11757 end_ix = BUILT_IN_GOACC_DATA_END;
11758 break;
11759 case OMP_TARGET_DATA:
11760 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
11761 break;
11762 default:
11763 gcc_unreachable ();
11765 tree fn = builtin_decl_explicit (end_ix);
11766 g = gimple_build_call (fn, 0);
11767 gimple_seq cleanup = NULL;
11768 gimple_seq_add_stmt (&cleanup, g);
11769 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
11770 body = NULL;
11771 gimple_seq_add_stmt (&body, g);
11774 else
11775 gimplify_and_add (OMP_BODY (expr), &body);
11776 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
11777 TREE_CODE (expr));
11779 switch (TREE_CODE (expr))
11781 case OACC_DATA:
11782 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
11783 OMP_CLAUSES (expr));
11784 break;
11785 case OACC_KERNELS:
11786 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
11787 OMP_CLAUSES (expr));
11788 break;
11789 case OACC_HOST_DATA:
11790 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
11791 OMP_CLAUSES (expr));
11792 break;
11793 case OACC_PARALLEL:
11794 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
11795 OMP_CLAUSES (expr));
11796 break;
11797 case OMP_SECTIONS:
11798 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
11799 break;
11800 case OMP_SINGLE:
11801 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
11802 break;
11803 case OMP_TARGET:
11804 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
11805 OMP_CLAUSES (expr));
11806 break;
11807 case OMP_TARGET_DATA:
11808 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
11809 OMP_CLAUSES (expr));
11810 break;
11811 case OMP_TEAMS:
11812 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
11813 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
11814 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
11815 break;
11816 default:
11817 gcc_unreachable ();
11820 gimplify_seq_add_stmt (pre_p, stmt);
11821 *expr_p = NULL_TREE;
11824 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
11825 target update constructs. */
11827 static void
11828 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
11830 tree expr = *expr_p;
11831 int kind;
11832 gomp_target *stmt;
11833 enum omp_region_type ort = ORT_WORKSHARE;
11835 switch (TREE_CODE (expr))
11837 case OACC_ENTER_DATA:
11838 case OACC_EXIT_DATA:
11839 kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
11840 ort = ORT_ACC;
11841 break;
11842 case OACC_UPDATE:
11843 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
11844 ort = ORT_ACC;
11845 break;
11846 case OMP_TARGET_UPDATE:
11847 kind = GF_OMP_TARGET_KIND_UPDATE;
11848 break;
11849 case OMP_TARGET_ENTER_DATA:
11850 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
11851 break;
11852 case OMP_TARGET_EXIT_DATA:
11853 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
11854 break;
11855 default:
11856 gcc_unreachable ();
11858 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
11859 ort, TREE_CODE (expr));
11860 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
11861 TREE_CODE (expr));
11862 if (TREE_CODE (expr) == OACC_UPDATE
11863 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
11864 OMP_CLAUSE_IF_PRESENT))
11866 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
11867 clause. */
11868 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
11869 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
11870 switch (OMP_CLAUSE_MAP_KIND (c))
11872 case GOMP_MAP_FORCE_TO:
11873 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
11874 break;
11875 case GOMP_MAP_FORCE_FROM:
11876 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
11877 break;
11878 default:
11879 break;
11882 else if (TREE_CODE (expr) == OACC_EXIT_DATA
11883 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
11884 OMP_CLAUSE_FINALIZE))
11886 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote that "finalize"
11887 semantics apply to all mappings of this OpenACC directive. */
11888 bool finalize_marked = false;
11889 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
11890 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
11891 switch (OMP_CLAUSE_MAP_KIND (c))
11893 case GOMP_MAP_FROM:
11894 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
11895 finalize_marked = true;
11896 break;
11897 case GOMP_MAP_RELEASE:
11898 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
11899 finalize_marked = true;
11900 break;
11901 default:
11902 /* Check consistency: libgomp relies on the very first data
11903 mapping clause being marked, so make sure we did that before
11904 any other mapping clauses. */
11905 gcc_assert (finalize_marked);
11906 break;
11909 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
11911 gimplify_seq_add_stmt (pre_p, stmt);
11912 *expr_p = NULL_TREE;
11915 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
11916 stabilized the lhs of the atomic operation as *ADDR. Return true if
11917 EXPR is this stabilized form. */
11919 static bool
11920 goa_lhs_expr_p (tree expr, tree addr)
11922 /* Also include casts to other type variants. The C front end is fond
11923 of adding these for e.g. volatile variables. This is like
11924 STRIP_TYPE_NOPS but includes the main variant lookup. */
11925 STRIP_USELESS_TYPE_CONVERSION (expr);
11927 if (TREE_CODE (expr) == INDIRECT_REF)
11929 expr = TREE_OPERAND (expr, 0);
11930 while (expr != addr
11931 && (CONVERT_EXPR_P (expr)
11932 || TREE_CODE (expr) == NON_LVALUE_EXPR)
11933 && TREE_CODE (expr) == TREE_CODE (addr)
11934 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
11936 expr = TREE_OPERAND (expr, 0);
11937 addr = TREE_OPERAND (addr, 0);
11939 if (expr == addr)
11940 return true;
11941 return (TREE_CODE (addr) == ADDR_EXPR
11942 && TREE_CODE (expr) == ADDR_EXPR
11943 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
11945 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
11946 return true;
11947 return false;
11950 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
11951 expression does not involve the lhs, evaluate it into a temporary.
11952 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
11953 or -1 if an error was encountered. */
11955 static int
11956 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
11957 tree lhs_var)
11959 tree expr = *expr_p;
11960 int saw_lhs;
11962 if (goa_lhs_expr_p (expr, lhs_addr))
11964 *expr_p = lhs_var;
11965 return 1;
11967 if (is_gimple_val (expr))
11968 return 0;
11970 saw_lhs = 0;
11971 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
11973 case tcc_binary:
11974 case tcc_comparison:
11975 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
11976 lhs_var);
11977 /* FALLTHRU */
11978 case tcc_unary:
11979 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
11980 lhs_var);
11981 break;
11982 case tcc_expression:
11983 switch (TREE_CODE (expr))
11985 case TRUTH_ANDIF_EXPR:
11986 case TRUTH_ORIF_EXPR:
11987 case TRUTH_AND_EXPR:
11988 case TRUTH_OR_EXPR:
11989 case TRUTH_XOR_EXPR:
11990 case BIT_INSERT_EXPR:
11991 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
11992 lhs_addr, lhs_var);
11993 /* FALLTHRU */
11994 case TRUTH_NOT_EXPR:
11995 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
11996 lhs_addr, lhs_var);
11997 break;
11998 case COMPOUND_EXPR:
11999 /* Break out any preevaluations from cp_build_modify_expr. */
12000 for (; TREE_CODE (expr) == COMPOUND_EXPR;
12001 expr = TREE_OPERAND (expr, 1))
12002 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
12003 *expr_p = expr;
12004 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var);
12005 default:
12006 break;
12008 break;
12009 case tcc_reference:
12010 if (TREE_CODE (expr) == BIT_FIELD_REF)
12011 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
12012 lhs_addr, lhs_var);
12013 break;
12014 default:
12015 break;
12018 if (saw_lhs == 0)
12020 enum gimplify_status gs;
12021 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
12022 if (gs != GS_ALL_DONE)
12023 saw_lhs = -1;
12026 return saw_lhs;
12029 /* Gimplify an OMP_ATOMIC statement. */
12031 static enum gimplify_status
12032 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
12034 tree addr = TREE_OPERAND (*expr_p, 0);
12035 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
12036 ? NULL : TREE_OPERAND (*expr_p, 1);
12037 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
12038 tree tmp_load;
12039 gomp_atomic_load *loadstmt;
12040 gomp_atomic_store *storestmt;
12042 tmp_load = create_tmp_reg (type);
12043 if (rhs && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load) < 0)
12044 return GS_ERROR;
12046 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
12047 != GS_ALL_DONE)
12048 return GS_ERROR;
12050 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
12051 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
12052 gimplify_seq_add_stmt (pre_p, loadstmt);
12053 if (rhs)
12055 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
12056 representatives. Use BIT_FIELD_REF on the lhs instead. */
12057 if (TREE_CODE (rhs) == BIT_INSERT_EXPR
12058 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
12060 tree bitpos = TREE_OPERAND (rhs, 2);
12061 tree op1 = TREE_OPERAND (rhs, 1);
12062 tree bitsize;
12063 tree tmp_store = tmp_load;
12064 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
12065 tmp_store = get_initialized_tmp_var (tmp_load, pre_p, NULL);
12066 if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
12067 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
12068 else
12069 bitsize = TYPE_SIZE (TREE_TYPE (op1));
12070 gcc_assert (TREE_OPERAND (rhs, 0) == tmp_load);
12071 tree t = build2_loc (EXPR_LOCATION (rhs),
12072 MODIFY_EXPR, void_type_node,
12073 build3_loc (EXPR_LOCATION (rhs), BIT_FIELD_REF,
12074 TREE_TYPE (op1), tmp_store, bitsize,
12075 bitpos), op1);
12076 gimplify_and_add (t, pre_p);
12077 rhs = tmp_store;
12079 if (gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
12080 != GS_ALL_DONE)
12081 return GS_ERROR;
12084 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
12085 rhs = tmp_load;
12086 storestmt
12087 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
12088 gimplify_seq_add_stmt (pre_p, storestmt);
12089 switch (TREE_CODE (*expr_p))
12091 case OMP_ATOMIC_READ:
12092 case OMP_ATOMIC_CAPTURE_OLD:
12093 *expr_p = tmp_load;
12094 gimple_omp_atomic_set_need_value (loadstmt);
12095 break;
12096 case OMP_ATOMIC_CAPTURE_NEW:
12097 *expr_p = rhs;
12098 gimple_omp_atomic_set_need_value (storestmt);
12099 break;
12100 default:
12101 *expr_p = NULL;
12102 break;
12105 return GS_ALL_DONE;
12108 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
12109 body, and adding some EH bits. */
12111 static enum gimplify_status
12112 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
12114 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
12115 gimple *body_stmt;
12116 gtransaction *trans_stmt;
12117 gimple_seq body = NULL;
12118 int subcode = 0;
12120 /* Wrap the transaction body in a BIND_EXPR so we have a context
12121 where to put decls for OMP. */
12122 if (TREE_CODE (tbody) != BIND_EXPR)
12124 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
12125 TREE_SIDE_EFFECTS (bind) = 1;
12126 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
12127 TRANSACTION_EXPR_BODY (expr) = bind;
12130 push_gimplify_context ();
12131 temp = voidify_wrapper_expr (*expr_p, NULL);
12133 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
12134 pop_gimplify_context (body_stmt);
12136 trans_stmt = gimple_build_transaction (body);
12137 if (TRANSACTION_EXPR_OUTER (expr))
12138 subcode = GTMA_IS_OUTER;
12139 else if (TRANSACTION_EXPR_RELAXED (expr))
12140 subcode = GTMA_IS_RELAXED;
12141 gimple_transaction_set_subcode (trans_stmt, subcode);
12143 gimplify_seq_add_stmt (pre_p, trans_stmt);
12145 if (temp)
12147 *expr_p = temp;
12148 return GS_OK;
12151 *expr_p = NULL_TREE;
12152 return GS_ALL_DONE;
12155 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
12156 is the OMP_BODY of the original EXPR (which has already been
12157 gimplified so it's not present in the EXPR).
12159 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
12161 static gimple *
12162 gimplify_omp_ordered (tree expr, gimple_seq body)
12164 tree c, decls;
12165 int failures = 0;
12166 unsigned int i;
12167 tree source_c = NULL_TREE;
12168 tree sink_c = NULL_TREE;
12170 if (gimplify_omp_ctxp)
12172 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
12173 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
12174 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
12175 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
12176 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
12178 error_at (OMP_CLAUSE_LOCATION (c),
12179 "%<ordered%> construct with %<depend%> clause must be "
12180 "closely nested inside a loop with %<ordered%> clause "
12181 "with a parameter");
12182 failures++;
12184 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
12185 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
12187 bool fail = false;
12188 for (decls = OMP_CLAUSE_DECL (c), i = 0;
12189 decls && TREE_CODE (decls) == TREE_LIST;
12190 decls = TREE_CHAIN (decls), ++i)
12191 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
12192 continue;
12193 else if (TREE_VALUE (decls)
12194 != gimplify_omp_ctxp->loop_iter_var[2 * i])
12196 error_at (OMP_CLAUSE_LOCATION (c),
12197 "variable %qE is not an iteration "
12198 "of outermost loop %d, expected %qE",
12199 TREE_VALUE (decls), i + 1,
12200 gimplify_omp_ctxp->loop_iter_var[2 * i]);
12201 fail = true;
12202 failures++;
12204 else
12205 TREE_VALUE (decls)
12206 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
12207 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
12209 error_at (OMP_CLAUSE_LOCATION (c),
12210 "number of variables in %<depend%> clause with "
12211 "%<sink%> modifier does not match number of "
12212 "iteration variables");
12213 failures++;
12215 sink_c = c;
12217 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
12218 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
12220 if (source_c)
12222 error_at (OMP_CLAUSE_LOCATION (c),
12223 "more than one %<depend%> clause with %<source%> "
12224 "modifier on an %<ordered%> construct");
12225 failures++;
12227 else
12228 source_c = c;
12231 if (source_c && sink_c)
12233 error_at (OMP_CLAUSE_LOCATION (source_c),
12234 "%<depend%> clause with %<source%> modifier specified "
12235 "together with %<depend%> clauses with %<sink%> modifier "
12236 "on the same construct");
12237 failures++;
12240 if (failures)
12241 return gimple_build_nop ();
12242 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
12245 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
12246 expression produces a value to be used as an operand inside a GIMPLE
12247 statement, the value will be stored back in *EXPR_P. This value will
12248 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
12249 an SSA_NAME. The corresponding sequence of GIMPLE statements is
12250 emitted in PRE_P and POST_P.
12252 Additionally, this process may overwrite parts of the input
12253 expression during gimplification. Ideally, it should be
12254 possible to do non-destructive gimplification.
12256 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
12257 the expression needs to evaluate to a value to be used as
12258 an operand in a GIMPLE statement, this value will be stored in
12259 *EXPR_P on exit. This happens when the caller specifies one
12260 of fb_lvalue or fb_rvalue fallback flags.
12262 PRE_P will contain the sequence of GIMPLE statements corresponding
12263 to the evaluation of EXPR and all the side-effects that must
12264 be executed before the main expression. On exit, the last
12265 statement of PRE_P is the core statement being gimplified. For
12266 instance, when gimplifying 'if (++a)' the last statement in
12267 PRE_P will be 'if (t.1)' where t.1 is the result of
12268 pre-incrementing 'a'.
12270 POST_P will contain the sequence of GIMPLE statements corresponding
12271 to the evaluation of all the side-effects that must be executed
12272 after the main expression. If this is NULL, the post
12273 side-effects are stored at the end of PRE_P.
12275 The reason why the output is split in two is to handle post
12276 side-effects explicitly. In some cases, an expression may have
12277 inner and outer post side-effects which need to be emitted in
12278 an order different from the one given by the recursive
12279 traversal. For instance, for the expression (*p--)++ the post
12280 side-effects of '--' must actually occur *after* the post
12281 side-effects of '++'. However, gimplification will first visit
12282 the inner expression, so if a separate POST sequence was not
12283 used, the resulting sequence would be:
12285 1 t.1 = *p
12286 2 p = p - 1
12287 3 t.2 = t.1 + 1
12288 4 *p = t.2
12290 However, the post-decrement operation in line #2 must not be
12291 evaluated until after the store to *p at line #4, so the
12292 correct sequence should be:
12294 1 t.1 = *p
12295 2 t.2 = t.1 + 1
12296 3 *p = t.2
12297 4 p = p - 1
12299 So, by specifying a separate post queue, it is possible
12300 to emit the post side-effects in the correct order.
12301 If POST_P is NULL, an internal queue will be used. Before
12302 returning to the caller, the sequence POST_P is appended to
12303 the main output sequence PRE_P.
12305 GIMPLE_TEST_F points to a function that takes a tree T and
12306 returns nonzero if T is in the GIMPLE form requested by the
12307 caller. The GIMPLE predicates are in gimple.c.
12309 FALLBACK tells the function what sort of a temporary we want if
12310 gimplification cannot produce an expression that complies with
12311 GIMPLE_TEST_F.
12313 fb_none means that no temporary should be generated
12314 fb_rvalue means that an rvalue is OK to generate
12315 fb_lvalue means that an lvalue is OK to generate
12316 fb_either means that either is OK, but an lvalue is preferable.
12317 fb_mayfail means that gimplification may fail (in which case
12318 GS_ERROR will be returned)
12320 The return value is either GS_ERROR or GS_ALL_DONE, since this
12321 function iterates until EXPR is completely gimplified or an error
12322 occurs. */
12324 enum gimplify_status
12325 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
12326 bool (*gimple_test_f) (tree), fallback_t fallback)
12328 tree tmp;
12329 gimple_seq internal_pre = NULL;
12330 gimple_seq internal_post = NULL;
12331 tree save_expr;
12332 bool is_statement;
12333 location_t saved_location;
12334 enum gimplify_status ret;
12335 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
12336 tree label;
12338 save_expr = *expr_p;
12339 if (save_expr == NULL_TREE)
12340 return GS_ALL_DONE;
12342 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
12343 is_statement = gimple_test_f == is_gimple_stmt;
12344 if (is_statement)
12345 gcc_assert (pre_p);
12347 /* Consistency checks. */
12348 if (gimple_test_f == is_gimple_reg)
12349 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
12350 else if (gimple_test_f == is_gimple_val
12351 || gimple_test_f == is_gimple_call_addr
12352 || gimple_test_f == is_gimple_condexpr
12353 || gimple_test_f == is_gimple_mem_rhs
12354 || gimple_test_f == is_gimple_mem_rhs_or_call
12355 || gimple_test_f == is_gimple_reg_rhs
12356 || gimple_test_f == is_gimple_reg_rhs_or_call
12357 || gimple_test_f == is_gimple_asm_val
12358 || gimple_test_f == is_gimple_mem_ref_addr)
12359 gcc_assert (fallback & fb_rvalue);
12360 else if (gimple_test_f == is_gimple_min_lval
12361 || gimple_test_f == is_gimple_lvalue)
12362 gcc_assert (fallback & fb_lvalue);
12363 else if (gimple_test_f == is_gimple_addressable)
12364 gcc_assert (fallback & fb_either);
12365 else if (gimple_test_f == is_gimple_stmt)
12366 gcc_assert (fallback == fb_none);
12367 else
12369 /* We should have recognized the GIMPLE_TEST_F predicate to
12370 know what kind of fallback to use in case a temporary is
12371 needed to hold the value or address of *EXPR_P. */
12372 gcc_unreachable ();
12375 /* We used to check the predicate here and return immediately if it
12376 succeeds. This is wrong; the design is for gimplification to be
12377 idempotent, and for the predicates to only test for valid forms, not
12378 whether they are fully simplified. */
12379 if (pre_p == NULL)
12380 pre_p = &internal_pre;
12382 if (post_p == NULL)
12383 post_p = &internal_post;
12385 /* Remember the last statements added to PRE_P and POST_P. Every
12386 new statement added by the gimplification helpers needs to be
12387 annotated with location information. To centralize the
12388 responsibility, we remember the last statement that had been
12389 added to both queues before gimplifying *EXPR_P. If
12390 gimplification produces new statements in PRE_P and POST_P, those
12391 statements will be annotated with the same location information
12392 as *EXPR_P. */
12393 pre_last_gsi = gsi_last (*pre_p);
12394 post_last_gsi = gsi_last (*post_p);
12396 saved_location = input_location;
12397 if (save_expr != error_mark_node
12398 && EXPR_HAS_LOCATION (*expr_p))
12399 input_location = EXPR_LOCATION (*expr_p);
12401 /* Loop over the specific gimplifiers until the toplevel node
12402 remains the same. */
12405 /* Strip away as many useless type conversions as possible
12406 at the toplevel. */
12407 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
12409 /* Remember the expr. */
12410 save_expr = *expr_p;
12412 /* Die, die, die, my darling. */
12413 if (error_operand_p (save_expr))
12415 ret = GS_ERROR;
12416 break;
12419 /* Do any language-specific gimplification. */
12420 ret = ((enum gimplify_status)
12421 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
12422 if (ret == GS_OK)
12424 if (*expr_p == NULL_TREE)
12425 break;
12426 if (*expr_p != save_expr)
12427 continue;
12429 else if (ret != GS_UNHANDLED)
12430 break;
12432 /* Make sure that all the cases set 'ret' appropriately. */
12433 ret = GS_UNHANDLED;
12434 switch (TREE_CODE (*expr_p))
12436 /* First deal with the special cases. */
12438 case POSTINCREMENT_EXPR:
12439 case POSTDECREMENT_EXPR:
12440 case PREINCREMENT_EXPR:
12441 case PREDECREMENT_EXPR:
12442 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
12443 fallback != fb_none,
12444 TREE_TYPE (*expr_p));
12445 break;
12447 case VIEW_CONVERT_EXPR:
12448 if ((fallback & fb_rvalue)
12449 && is_gimple_reg_type (TREE_TYPE (*expr_p))
12450 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
12452 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
12453 post_p, is_gimple_val, fb_rvalue);
12454 recalculate_side_effects (*expr_p);
12455 break;
12457 /* Fallthru. */
12459 case ARRAY_REF:
12460 case ARRAY_RANGE_REF:
12461 case REALPART_EXPR:
12462 case IMAGPART_EXPR:
12463 case COMPONENT_REF:
12464 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
12465 fallback ? fallback : fb_rvalue);
12466 break;
12468 case COND_EXPR:
12469 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
12471 /* C99 code may assign to an array in a structure value of a
12472 conditional expression, and this has undefined behavior
12473 only on execution, so create a temporary if an lvalue is
12474 required. */
12475 if (fallback == fb_lvalue)
12477 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
12478 mark_addressable (*expr_p);
12479 ret = GS_OK;
12481 break;
12483 case CALL_EXPR:
12484 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
12486 /* C99 code may assign to an array in a structure returned
12487 from a function, and this has undefined behavior only on
12488 execution, so create a temporary if an lvalue is
12489 required. */
12490 if (fallback == fb_lvalue)
12492 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
12493 mark_addressable (*expr_p);
12494 ret = GS_OK;
12496 break;
12498 case TREE_LIST:
12499 gcc_unreachable ();
12501 case COMPOUND_EXPR:
12502 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
12503 break;
12505 case COMPOUND_LITERAL_EXPR:
12506 ret = gimplify_compound_literal_expr (expr_p, pre_p,
12507 gimple_test_f, fallback);
12508 break;
12510 case MODIFY_EXPR:
12511 case INIT_EXPR:
12512 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
12513 fallback != fb_none);
12514 break;
12516 case TRUTH_ANDIF_EXPR:
12517 case TRUTH_ORIF_EXPR:
12519 /* Preserve the original type of the expression and the
12520 source location of the outer expression. */
12521 tree org_type = TREE_TYPE (*expr_p);
12522 *expr_p = gimple_boolify (*expr_p);
12523 *expr_p = build3_loc (input_location, COND_EXPR,
12524 org_type, *expr_p,
12525 fold_convert_loc
12526 (input_location,
12527 org_type, boolean_true_node),
12528 fold_convert_loc
12529 (input_location,
12530 org_type, boolean_false_node));
12531 ret = GS_OK;
12532 break;
12535 case TRUTH_NOT_EXPR:
12537 tree type = TREE_TYPE (*expr_p);
12538 /* The parsers are careful to generate TRUTH_NOT_EXPR
12539 only with operands that are always zero or one.
12540 We do not fold here but handle the only interesting case
12541 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
12542 *expr_p = gimple_boolify (*expr_p);
12543 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
12544 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
12545 TREE_TYPE (*expr_p),
12546 TREE_OPERAND (*expr_p, 0));
12547 else
12548 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
12549 TREE_TYPE (*expr_p),
12550 TREE_OPERAND (*expr_p, 0),
12551 build_int_cst (TREE_TYPE (*expr_p), 1));
12552 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
12553 *expr_p = fold_convert_loc (input_location, type, *expr_p);
12554 ret = GS_OK;
12555 break;
12558 case ADDR_EXPR:
12559 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
12560 break;
12562 case ANNOTATE_EXPR:
12564 tree cond = TREE_OPERAND (*expr_p, 0);
12565 tree kind = TREE_OPERAND (*expr_p, 1);
12566 tree data = TREE_OPERAND (*expr_p, 2);
12567 tree type = TREE_TYPE (cond);
12568 if (!INTEGRAL_TYPE_P (type))
12570 *expr_p = cond;
12571 ret = GS_OK;
12572 break;
12574 tree tmp = create_tmp_var (type);
12575 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
12576 gcall *call
12577 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
12578 gimple_call_set_lhs (call, tmp);
12579 gimplify_seq_add_stmt (pre_p, call);
12580 *expr_p = tmp;
12581 ret = GS_ALL_DONE;
12582 break;
12585 case VA_ARG_EXPR:
12586 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
12587 break;
12589 CASE_CONVERT:
12590 if (IS_EMPTY_STMT (*expr_p))
12592 ret = GS_ALL_DONE;
12593 break;
12596 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
12597 || fallback == fb_none)
12599 /* Just strip a conversion to void (or in void context) and
12600 try again. */
12601 *expr_p = TREE_OPERAND (*expr_p, 0);
12602 ret = GS_OK;
12603 break;
12606 ret = gimplify_conversion (expr_p);
12607 if (ret == GS_ERROR)
12608 break;
12609 if (*expr_p != save_expr)
12610 break;
12611 /* FALLTHRU */
12613 case FIX_TRUNC_EXPR:
12614 /* unary_expr: ... | '(' cast ')' val | ... */
12615 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
12616 is_gimple_val, fb_rvalue);
12617 recalculate_side_effects (*expr_p);
12618 break;
12620 case INDIRECT_REF:
12622 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
12623 bool notrap = TREE_THIS_NOTRAP (*expr_p);
12624 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
12626 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
12627 if (*expr_p != save_expr)
12629 ret = GS_OK;
12630 break;
12633 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
12634 is_gimple_reg, fb_rvalue);
12635 if (ret == GS_ERROR)
12636 break;
12638 recalculate_side_effects (*expr_p);
12639 *expr_p = fold_build2_loc (input_location, MEM_REF,
12640 TREE_TYPE (*expr_p),
12641 TREE_OPERAND (*expr_p, 0),
12642 build_int_cst (saved_ptr_type, 0));
12643 TREE_THIS_VOLATILE (*expr_p) = volatilep;
12644 TREE_THIS_NOTRAP (*expr_p) = notrap;
12645 ret = GS_OK;
12646 break;
12649 /* We arrive here through the various re-gimplifcation paths. */
12650 case MEM_REF:
12651 /* First try re-folding the whole thing. */
12652 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
12653 TREE_OPERAND (*expr_p, 0),
12654 TREE_OPERAND (*expr_p, 1));
12655 if (tmp)
12657 REF_REVERSE_STORAGE_ORDER (tmp)
12658 = REF_REVERSE_STORAGE_ORDER (*expr_p);
12659 *expr_p = tmp;
12660 recalculate_side_effects (*expr_p);
12661 ret = GS_OK;
12662 break;
12664 /* Avoid re-gimplifying the address operand if it is already
12665 in suitable form. Re-gimplifying would mark the address
12666 operand addressable. Always gimplify when not in SSA form
12667 as we still may have to gimplify decls with value-exprs. */
12668 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
12669 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
12671 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
12672 is_gimple_mem_ref_addr, fb_rvalue);
12673 if (ret == GS_ERROR)
12674 break;
12676 recalculate_side_effects (*expr_p);
12677 ret = GS_ALL_DONE;
12678 break;
12680 /* Constants need not be gimplified. */
12681 case INTEGER_CST:
12682 case REAL_CST:
12683 case FIXED_CST:
12684 case STRING_CST:
12685 case COMPLEX_CST:
12686 case VECTOR_CST:
12687 /* Drop the overflow flag on constants, we do not want
12688 that in the GIMPLE IL. */
12689 if (TREE_OVERFLOW_P (*expr_p))
12690 *expr_p = drop_tree_overflow (*expr_p);
12691 ret = GS_ALL_DONE;
12692 break;
12694 case CONST_DECL:
12695 /* If we require an lvalue, such as for ADDR_EXPR, retain the
12696 CONST_DECL node. Otherwise the decl is replaceable by its
12697 value. */
12698 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
12699 if (fallback & fb_lvalue)
12700 ret = GS_ALL_DONE;
12701 else
12703 *expr_p = DECL_INITIAL (*expr_p);
12704 ret = GS_OK;
12706 break;
12708 case DECL_EXPR:
12709 ret = gimplify_decl_expr (expr_p, pre_p);
12710 break;
12712 case BIND_EXPR:
12713 ret = gimplify_bind_expr (expr_p, pre_p);
12714 break;
12716 case LOOP_EXPR:
12717 ret = gimplify_loop_expr (expr_p, pre_p);
12718 break;
12720 case SWITCH_EXPR:
12721 ret = gimplify_switch_expr (expr_p, pre_p);
12722 break;
12724 case EXIT_EXPR:
12725 ret = gimplify_exit_expr (expr_p);
12726 break;
12728 case GOTO_EXPR:
12729 /* If the target is not LABEL, then it is a computed jump
12730 and the target needs to be gimplified. */
12731 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
12733 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
12734 NULL, is_gimple_val, fb_rvalue);
12735 if (ret == GS_ERROR)
12736 break;
12738 gimplify_seq_add_stmt (pre_p,
12739 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
12740 ret = GS_ALL_DONE;
12741 break;
12743 case PREDICT_EXPR:
12744 gimplify_seq_add_stmt (pre_p,
12745 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
12746 PREDICT_EXPR_OUTCOME (*expr_p)));
12747 ret = GS_ALL_DONE;
12748 break;
12750 case LABEL_EXPR:
12751 ret = gimplify_label_expr (expr_p, pre_p);
12752 label = LABEL_EXPR_LABEL (*expr_p);
12753 gcc_assert (decl_function_context (label) == current_function_decl);
12755 /* If the label is used in a goto statement, or address of the label
12756 is taken, we need to unpoison all variables that were seen so far.
12757 Doing so would prevent us from reporting a false positives. */
12758 if (asan_poisoned_variables
12759 && asan_used_labels != NULL
12760 && asan_used_labels->contains (label))
12761 asan_poison_variables (asan_poisoned_variables, false, pre_p);
12762 break;
12764 case CASE_LABEL_EXPR:
12765 ret = gimplify_case_label_expr (expr_p, pre_p);
12767 if (gimplify_ctxp->live_switch_vars)
12768 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
12769 pre_p);
12770 break;
12772 case RETURN_EXPR:
12773 ret = gimplify_return_expr (*expr_p, pre_p);
12774 break;
12776 case CONSTRUCTOR:
12777 /* Don't reduce this in place; let gimplify_init_constructor work its
12778 magic. Buf if we're just elaborating this for side effects, just
12779 gimplify any element that has side-effects. */
12780 if (fallback == fb_none)
12782 unsigned HOST_WIDE_INT ix;
12783 tree val;
12784 tree temp = NULL_TREE;
12785 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
12786 if (TREE_SIDE_EFFECTS (val))
12787 append_to_statement_list (val, &temp);
12789 *expr_p = temp;
12790 ret = temp ? GS_OK : GS_ALL_DONE;
12792 /* C99 code may assign to an array in a constructed
12793 structure or union, and this has undefined behavior only
12794 on execution, so create a temporary if an lvalue is
12795 required. */
12796 else if (fallback == fb_lvalue)
12798 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
12799 mark_addressable (*expr_p);
12800 ret = GS_OK;
12802 else
12803 ret = GS_ALL_DONE;
12804 break;
12806 /* The following are special cases that are not handled by the
12807 original GIMPLE grammar. */
12809 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
12810 eliminated. */
12811 case SAVE_EXPR:
12812 ret = gimplify_save_expr (expr_p, pre_p, post_p);
12813 break;
12815 case BIT_FIELD_REF:
12816 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
12817 post_p, is_gimple_lvalue, fb_either);
12818 recalculate_side_effects (*expr_p);
12819 break;
12821 case TARGET_MEM_REF:
12823 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
12825 if (TMR_BASE (*expr_p))
12826 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
12827 post_p, is_gimple_mem_ref_addr, fb_either);
12828 if (TMR_INDEX (*expr_p))
12829 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
12830 post_p, is_gimple_val, fb_rvalue);
12831 if (TMR_INDEX2 (*expr_p))
12832 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
12833 post_p, is_gimple_val, fb_rvalue);
12834 /* TMR_STEP and TMR_OFFSET are always integer constants. */
12835 ret = MIN (r0, r1);
12837 break;
12839 case NON_LVALUE_EXPR:
12840 /* This should have been stripped above. */
12841 gcc_unreachable ();
12843 case ASM_EXPR:
12844 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
12845 break;
12847 case TRY_FINALLY_EXPR:
12848 case TRY_CATCH_EXPR:
12850 gimple_seq eval, cleanup;
12851 gtry *try_;
12853 /* Calls to destructors are generated automatically in FINALLY/CATCH
12854 block. They should have location as UNKNOWN_LOCATION. However,
12855 gimplify_call_expr will reset these call stmts to input_location
12856 if it finds stmt's location is unknown. To prevent resetting for
12857 destructors, we set the input_location to unknown.
12858 Note that this only affects the destructor calls in FINALLY/CATCH
12859 block, and will automatically reset to its original value by the
12860 end of gimplify_expr. */
12861 input_location = UNKNOWN_LOCATION;
12862 eval = cleanup = NULL;
12863 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
12864 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
12865 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
12866 if (gimple_seq_empty_p (cleanup))
12868 gimple_seq_add_seq (pre_p, eval);
12869 ret = GS_ALL_DONE;
12870 break;
12872 try_ = gimple_build_try (eval, cleanup,
12873 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
12874 ? GIMPLE_TRY_FINALLY
12875 : GIMPLE_TRY_CATCH);
12876 if (EXPR_HAS_LOCATION (save_expr))
12877 gimple_set_location (try_, EXPR_LOCATION (save_expr));
12878 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
12879 gimple_set_location (try_, saved_location);
12880 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
12881 gimple_try_set_catch_is_cleanup (try_,
12882 TRY_CATCH_IS_CLEANUP (*expr_p));
12883 gimplify_seq_add_stmt (pre_p, try_);
12884 ret = GS_ALL_DONE;
12885 break;
12888 case CLEANUP_POINT_EXPR:
12889 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
12890 break;
12892 case TARGET_EXPR:
12893 ret = gimplify_target_expr (expr_p, pre_p, post_p);
12894 break;
12896 case CATCH_EXPR:
12898 gimple *c;
12899 gimple_seq handler = NULL;
12900 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
12901 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
12902 gimplify_seq_add_stmt (pre_p, c);
12903 ret = GS_ALL_DONE;
12904 break;
12907 case EH_FILTER_EXPR:
12909 gimple *ehf;
12910 gimple_seq failure = NULL;
12912 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
12913 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
12914 gimple_set_no_warning (ehf, TREE_NO_WARNING (*expr_p));
12915 gimplify_seq_add_stmt (pre_p, ehf);
12916 ret = GS_ALL_DONE;
12917 break;
12920 case OBJ_TYPE_REF:
12922 enum gimplify_status r0, r1;
12923 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
12924 post_p, is_gimple_val, fb_rvalue);
12925 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
12926 post_p, is_gimple_val, fb_rvalue);
12927 TREE_SIDE_EFFECTS (*expr_p) = 0;
12928 ret = MIN (r0, r1);
12930 break;
12932 case LABEL_DECL:
12933 /* We get here when taking the address of a label. We mark
12934 the label as "forced"; meaning it can never be removed and
12935 it is a potential target for any computed goto. */
12936 FORCED_LABEL (*expr_p) = 1;
12937 ret = GS_ALL_DONE;
12938 break;
12940 case STATEMENT_LIST:
12941 ret = gimplify_statement_list (expr_p, pre_p);
12942 break;
12944 case WITH_SIZE_EXPR:
12946 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
12947 post_p == &internal_post ? NULL : post_p,
12948 gimple_test_f, fallback);
12949 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
12950 is_gimple_val, fb_rvalue);
12951 ret = GS_ALL_DONE;
12953 break;
12955 case VAR_DECL:
12956 case PARM_DECL:
12957 ret = gimplify_var_or_parm_decl (expr_p);
12958 break;
12960 case RESULT_DECL:
12961 /* When within an OMP context, notice uses of variables. */
12962 if (gimplify_omp_ctxp)
12963 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
12964 ret = GS_ALL_DONE;
12965 break;
12967 case DEBUG_EXPR_DECL:
12968 gcc_unreachable ();
12970 case DEBUG_BEGIN_STMT:
12971 gimplify_seq_add_stmt (pre_p,
12972 gimple_build_debug_begin_stmt
12973 (TREE_BLOCK (*expr_p),
12974 EXPR_LOCATION (*expr_p)));
12975 ret = GS_ALL_DONE;
12976 *expr_p = NULL;
12977 break;
12979 case SSA_NAME:
12980 /* Allow callbacks into the gimplifier during optimization. */
12981 ret = GS_ALL_DONE;
12982 break;
12984 case OMP_PARALLEL:
12985 gimplify_omp_parallel (expr_p, pre_p);
12986 ret = GS_ALL_DONE;
12987 break;
12989 case OMP_TASK:
12990 gimplify_omp_task (expr_p, pre_p);
12991 ret = GS_ALL_DONE;
12992 break;
12994 case OMP_FOR:
12995 case OMP_SIMD:
12996 case OMP_DISTRIBUTE:
12997 case OMP_TASKLOOP:
12998 case OACC_LOOP:
12999 ret = gimplify_omp_for (expr_p, pre_p);
13000 break;
13002 case OACC_CACHE:
13003 gimplify_oacc_cache (expr_p, pre_p);
13004 ret = GS_ALL_DONE;
13005 break;
13007 case OACC_DECLARE:
13008 gimplify_oacc_declare (expr_p, pre_p);
13009 ret = GS_ALL_DONE;
13010 break;
13012 case OACC_HOST_DATA:
13013 case OACC_DATA:
13014 case OACC_KERNELS:
13015 case OACC_PARALLEL:
13016 case OMP_SECTIONS:
13017 case OMP_SINGLE:
13018 case OMP_TARGET:
13019 case OMP_TARGET_DATA:
13020 case OMP_TEAMS:
13021 gimplify_omp_workshare (expr_p, pre_p);
13022 ret = GS_ALL_DONE;
13023 break;
13025 case OACC_ENTER_DATA:
13026 case OACC_EXIT_DATA:
13027 case OACC_UPDATE:
13028 case OMP_TARGET_UPDATE:
13029 case OMP_TARGET_ENTER_DATA:
13030 case OMP_TARGET_EXIT_DATA:
13031 gimplify_omp_target_update (expr_p, pre_p);
13032 ret = GS_ALL_DONE;
13033 break;
13035 case OMP_SECTION:
13036 case OMP_MASTER:
13037 case OMP_ORDERED:
13038 case OMP_CRITICAL:
13040 gimple_seq body = NULL;
13041 gimple *g;
13043 gimplify_and_add (OMP_BODY (*expr_p), &body);
13044 switch (TREE_CODE (*expr_p))
13046 case OMP_SECTION:
13047 g = gimple_build_omp_section (body);
13048 break;
13049 case OMP_MASTER:
13050 g = gimple_build_omp_master (body);
13051 break;
13052 case OMP_ORDERED:
13053 g = gimplify_omp_ordered (*expr_p, body);
13054 break;
13055 case OMP_CRITICAL:
13056 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
13057 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
13058 gimplify_adjust_omp_clauses (pre_p, body,
13059 &OMP_CRITICAL_CLAUSES (*expr_p),
13060 OMP_CRITICAL);
13061 g = gimple_build_omp_critical (body,
13062 OMP_CRITICAL_NAME (*expr_p),
13063 OMP_CRITICAL_CLAUSES (*expr_p));
13064 break;
13065 default:
13066 gcc_unreachable ();
13068 gimplify_seq_add_stmt (pre_p, g);
13069 ret = GS_ALL_DONE;
13070 break;
13073 case OMP_TASKGROUP:
13075 gimple_seq body = NULL;
13077 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
13078 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
13079 OMP_TASKGROUP);
13080 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
13081 gimplify_and_add (OMP_BODY (*expr_p), &body);
13082 gimple_seq cleanup = NULL;
13083 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
13084 gimple *g = gimple_build_call (fn, 0);
13085 gimple_seq_add_stmt (&cleanup, g);
13086 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
13087 body = NULL;
13088 gimple_seq_add_stmt (&body, g);
13089 g = gimple_build_omp_taskgroup (body, *pclauses);
13090 gimplify_seq_add_stmt (pre_p, g);
13091 ret = GS_ALL_DONE;
13092 break;
13095 case OMP_ATOMIC:
13096 case OMP_ATOMIC_READ:
13097 case OMP_ATOMIC_CAPTURE_OLD:
13098 case OMP_ATOMIC_CAPTURE_NEW:
13099 ret = gimplify_omp_atomic (expr_p, pre_p);
13100 break;
13102 case TRANSACTION_EXPR:
13103 ret = gimplify_transaction (expr_p, pre_p);
13104 break;
13106 case TRUTH_AND_EXPR:
13107 case TRUTH_OR_EXPR:
13108 case TRUTH_XOR_EXPR:
13110 tree orig_type = TREE_TYPE (*expr_p);
13111 tree new_type, xop0, xop1;
13112 *expr_p = gimple_boolify (*expr_p);
13113 new_type = TREE_TYPE (*expr_p);
13114 if (!useless_type_conversion_p (orig_type, new_type))
13116 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
13117 ret = GS_OK;
13118 break;
13121 /* Boolified binary truth expressions are semantically equivalent
13122 to bitwise binary expressions. Canonicalize them to the
13123 bitwise variant. */
13124 switch (TREE_CODE (*expr_p))
13126 case TRUTH_AND_EXPR:
13127 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
13128 break;
13129 case TRUTH_OR_EXPR:
13130 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
13131 break;
13132 case TRUTH_XOR_EXPR:
13133 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
13134 break;
13135 default:
13136 break;
13138 /* Now make sure that operands have compatible type to
13139 expression's new_type. */
13140 xop0 = TREE_OPERAND (*expr_p, 0);
13141 xop1 = TREE_OPERAND (*expr_p, 1);
13142 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
13143 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
13144 new_type,
13145 xop0);
13146 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
13147 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
13148 new_type,
13149 xop1);
13150 /* Continue classified as tcc_binary. */
13151 goto expr_2;
13154 case VEC_COND_EXPR:
13156 enum gimplify_status r0, r1, r2;
13158 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13159 post_p, is_gimple_condexpr, fb_rvalue);
13160 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
13161 post_p, is_gimple_val, fb_rvalue);
13162 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
13163 post_p, is_gimple_val, fb_rvalue);
13165 ret = MIN (MIN (r0, r1), r2);
13166 recalculate_side_effects (*expr_p);
13168 break;
13170 case VEC_PERM_EXPR:
13171 /* Classified as tcc_expression. */
13172 goto expr_3;
13174 case BIT_INSERT_EXPR:
13175 /* Argument 3 is a constant. */
13176 goto expr_2;
13178 case POINTER_PLUS_EXPR:
13180 enum gimplify_status r0, r1;
13181 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13182 post_p, is_gimple_val, fb_rvalue);
13183 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
13184 post_p, is_gimple_val, fb_rvalue);
13185 recalculate_side_effects (*expr_p);
13186 ret = MIN (r0, r1);
13187 break;
13190 default:
13191 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
13193 case tcc_comparison:
13194 /* Handle comparison of objects of non scalar mode aggregates
13195 with a call to memcmp. It would be nice to only have to do
13196 this for variable-sized objects, but then we'd have to allow
13197 the same nest of reference nodes we allow for MODIFY_EXPR and
13198 that's too complex.
13200 Compare scalar mode aggregates as scalar mode values. Using
13201 memcmp for them would be very inefficient at best, and is
13202 plain wrong if bitfields are involved. */
13204 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
13206 /* Vector comparisons need no boolification. */
13207 if (TREE_CODE (type) == VECTOR_TYPE)
13208 goto expr_2;
13209 else if (!AGGREGATE_TYPE_P (type))
13211 tree org_type = TREE_TYPE (*expr_p);
13212 *expr_p = gimple_boolify (*expr_p);
13213 if (!useless_type_conversion_p (org_type,
13214 TREE_TYPE (*expr_p)))
13216 *expr_p = fold_convert_loc (input_location,
13217 org_type, *expr_p);
13218 ret = GS_OK;
13220 else
13221 goto expr_2;
13223 else if (TYPE_MODE (type) != BLKmode)
13224 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
13225 else
13226 ret = gimplify_variable_sized_compare (expr_p);
13228 break;
13231 /* If *EXPR_P does not need to be special-cased, handle it
13232 according to its class. */
13233 case tcc_unary:
13234 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13235 post_p, is_gimple_val, fb_rvalue);
13236 break;
13238 case tcc_binary:
13239 expr_2:
13241 enum gimplify_status r0, r1;
13243 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13244 post_p, is_gimple_val, fb_rvalue);
13245 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
13246 post_p, is_gimple_val, fb_rvalue);
13248 ret = MIN (r0, r1);
13249 break;
13252 expr_3:
13254 enum gimplify_status r0, r1, r2;
13256 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13257 post_p, is_gimple_val, fb_rvalue);
13258 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
13259 post_p, is_gimple_val, fb_rvalue);
13260 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
13261 post_p, is_gimple_val, fb_rvalue);
13263 ret = MIN (MIN (r0, r1), r2);
13264 break;
13267 case tcc_declaration:
13268 case tcc_constant:
13269 ret = GS_ALL_DONE;
13270 goto dont_recalculate;
13272 default:
13273 gcc_unreachable ();
13276 recalculate_side_effects (*expr_p);
13278 dont_recalculate:
13279 break;
13282 gcc_assert (*expr_p || ret != GS_OK);
13284 while (ret == GS_OK);
13286 /* If we encountered an error_mark somewhere nested inside, either
13287 stub out the statement or propagate the error back out. */
13288 if (ret == GS_ERROR)
13290 if (is_statement)
13291 *expr_p = NULL;
13292 goto out;
13295 /* This was only valid as a return value from the langhook, which
13296 we handled. Make sure it doesn't escape from any other context. */
13297 gcc_assert (ret != GS_UNHANDLED);
13299 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
13301 /* We aren't looking for a value, and we don't have a valid
13302 statement. If it doesn't have side-effects, throw it away.
13303 We can also get here with code such as "*&&L;", where L is
13304 a LABEL_DECL that is marked as FORCED_LABEL. */
13305 if (TREE_CODE (*expr_p) == LABEL_DECL
13306 || !TREE_SIDE_EFFECTS (*expr_p))
13307 *expr_p = NULL;
13308 else if (!TREE_THIS_VOLATILE (*expr_p))
13310 /* This is probably a _REF that contains something nested that
13311 has side effects. Recurse through the operands to find it. */
13312 enum tree_code code = TREE_CODE (*expr_p);
13314 switch (code)
13316 case COMPONENT_REF:
13317 case REALPART_EXPR:
13318 case IMAGPART_EXPR:
13319 case VIEW_CONVERT_EXPR:
13320 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13321 gimple_test_f, fallback);
13322 break;
13324 case ARRAY_REF:
13325 case ARRAY_RANGE_REF:
13326 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13327 gimple_test_f, fallback);
13328 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
13329 gimple_test_f, fallback);
13330 break;
13332 default:
13333 /* Anything else with side-effects must be converted to
13334 a valid statement before we get here. */
13335 gcc_unreachable ();
13338 *expr_p = NULL;
13340 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
13341 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode)
13343 /* Historically, the compiler has treated a bare reference
13344 to a non-BLKmode volatile lvalue as forcing a load. */
13345 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
13347 /* Normally, we do not want to create a temporary for a
13348 TREE_ADDRESSABLE type because such a type should not be
13349 copied by bitwise-assignment. However, we make an
13350 exception here, as all we are doing here is ensuring that
13351 we read the bytes that make up the type. We use
13352 create_tmp_var_raw because create_tmp_var will abort when
13353 given a TREE_ADDRESSABLE type. */
13354 tree tmp = create_tmp_var_raw (type, "vol");
13355 gimple_add_tmp_var (tmp);
13356 gimplify_assign (tmp, *expr_p, pre_p);
13357 *expr_p = NULL;
13359 else
13360 /* We can't do anything useful with a volatile reference to
13361 an incomplete type, so just throw it away. Likewise for
13362 a BLKmode type, since any implicit inner load should
13363 already have been turned into an explicit one by the
13364 gimplification process. */
13365 *expr_p = NULL;
13368 /* If we are gimplifying at the statement level, we're done. Tack
13369 everything together and return. */
13370 if (fallback == fb_none || is_statement)
13372 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
13373 it out for GC to reclaim it. */
13374 *expr_p = NULL_TREE;
13376 if (!gimple_seq_empty_p (internal_pre)
13377 || !gimple_seq_empty_p (internal_post))
13379 gimplify_seq_add_seq (&internal_pre, internal_post);
13380 gimplify_seq_add_seq (pre_p, internal_pre);
13383 /* The result of gimplifying *EXPR_P is going to be the last few
13384 statements in *PRE_P and *POST_P. Add location information
13385 to all the statements that were added by the gimplification
13386 helpers. */
13387 if (!gimple_seq_empty_p (*pre_p))
13388 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
13390 if (!gimple_seq_empty_p (*post_p))
13391 annotate_all_with_location_after (*post_p, post_last_gsi,
13392 input_location);
13394 goto out;
13397 #ifdef ENABLE_GIMPLE_CHECKING
13398 if (*expr_p)
13400 enum tree_code code = TREE_CODE (*expr_p);
13401 /* These expressions should already be in gimple IR form. */
13402 gcc_assert (code != MODIFY_EXPR
13403 && code != ASM_EXPR
13404 && code != BIND_EXPR
13405 && code != CATCH_EXPR
13406 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
13407 && code != EH_FILTER_EXPR
13408 && code != GOTO_EXPR
13409 && code != LABEL_EXPR
13410 && code != LOOP_EXPR
13411 && code != SWITCH_EXPR
13412 && code != TRY_FINALLY_EXPR
13413 && code != OACC_PARALLEL
13414 && code != OACC_KERNELS
13415 && code != OACC_DATA
13416 && code != OACC_HOST_DATA
13417 && code != OACC_DECLARE
13418 && code != OACC_UPDATE
13419 && code != OACC_ENTER_DATA
13420 && code != OACC_EXIT_DATA
13421 && code != OACC_CACHE
13422 && code != OMP_CRITICAL
13423 && code != OMP_FOR
13424 && code != OACC_LOOP
13425 && code != OMP_MASTER
13426 && code != OMP_TASKGROUP
13427 && code != OMP_ORDERED
13428 && code != OMP_PARALLEL
13429 && code != OMP_SECTIONS
13430 && code != OMP_SECTION
13431 && code != OMP_SINGLE);
13433 #endif
13435 /* Otherwise we're gimplifying a subexpression, so the resulting
13436 value is interesting. If it's a valid operand that matches
13437 GIMPLE_TEST_F, we're done. Unless we are handling some
13438 post-effects internally; if that's the case, we need to copy into
13439 a temporary before adding the post-effects to POST_P. */
13440 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
13441 goto out;
13443 /* Otherwise, we need to create a new temporary for the gimplified
13444 expression. */
13446 /* We can't return an lvalue if we have an internal postqueue. The
13447 object the lvalue refers to would (probably) be modified by the
13448 postqueue; we need to copy the value out first, which means an
13449 rvalue. */
13450 if ((fallback & fb_lvalue)
13451 && gimple_seq_empty_p (internal_post)
13452 && is_gimple_addressable (*expr_p))
13454 /* An lvalue will do. Take the address of the expression, store it
13455 in a temporary, and replace the expression with an INDIRECT_REF of
13456 that temporary. */
13457 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
13458 unsigned int ref_align = get_object_alignment (*expr_p);
13459 tree ref_type = TREE_TYPE (*expr_p);
13460 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
13461 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
13462 if (TYPE_ALIGN (ref_type) != ref_align)
13463 ref_type = build_aligned_type (ref_type, ref_align);
13464 *expr_p = build2 (MEM_REF, ref_type,
13465 tmp, build_zero_cst (ref_alias_type));
13467 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
13469 /* An rvalue will do. Assign the gimplified expression into a
13470 new temporary TMP and replace the original expression with
13471 TMP. First, make sure that the expression has a type so that
13472 it can be assigned into a temporary. */
13473 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
13474 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
13476 else
13478 #ifdef ENABLE_GIMPLE_CHECKING
13479 if (!(fallback & fb_mayfail))
13481 fprintf (stderr, "gimplification failed:\n");
13482 print_generic_expr (stderr, *expr_p);
13483 debug_tree (*expr_p);
13484 internal_error ("gimplification failed");
13486 #endif
13487 gcc_assert (fallback & fb_mayfail);
13489 /* If this is an asm statement, and the user asked for the
13490 impossible, don't die. Fail and let gimplify_asm_expr
13491 issue an error. */
13492 ret = GS_ERROR;
13493 goto out;
13496 /* Make sure the temporary matches our predicate. */
13497 gcc_assert ((*gimple_test_f) (*expr_p));
13499 if (!gimple_seq_empty_p (internal_post))
13501 annotate_all_with_location (internal_post, input_location);
13502 gimplify_seq_add_seq (pre_p, internal_post);
13505 out:
13506 input_location = saved_location;
13507 return ret;
13510 /* Like gimplify_expr but make sure the gimplified result is not itself
13511 a SSA name (but a decl if it were). Temporaries required by
13512 evaluating *EXPR_P may be still SSA names. */
13514 static enum gimplify_status
13515 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
13516 bool (*gimple_test_f) (tree), fallback_t fallback,
13517 bool allow_ssa)
13519 bool was_ssa_name_p = TREE_CODE (*expr_p) == SSA_NAME;
13520 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
13521 gimple_test_f, fallback);
13522 if (! allow_ssa
13523 && TREE_CODE (*expr_p) == SSA_NAME)
13525 tree name = *expr_p;
13526 if (was_ssa_name_p)
13527 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
13528 else
13530 /* Avoid the extra copy if possible. */
13531 *expr_p = create_tmp_reg (TREE_TYPE (name));
13532 gimple_set_lhs (SSA_NAME_DEF_STMT (name), *expr_p);
13533 release_ssa_name (name);
13536 return ret;
13539 /* Look through TYPE for variable-sized objects and gimplify each such
13540 size that we find. Add to LIST_P any statements generated. */
13542 void
13543 gimplify_type_sizes (tree type, gimple_seq *list_p)
13545 tree field, t;
13547 if (type == NULL || type == error_mark_node)
13548 return;
13550 /* We first do the main variant, then copy into any other variants. */
13551 type = TYPE_MAIN_VARIANT (type);
13553 /* Avoid infinite recursion. */
13554 if (TYPE_SIZES_GIMPLIFIED (type))
13555 return;
13557 TYPE_SIZES_GIMPLIFIED (type) = 1;
13559 switch (TREE_CODE (type))
13561 case INTEGER_TYPE:
13562 case ENUMERAL_TYPE:
13563 case BOOLEAN_TYPE:
13564 case REAL_TYPE:
13565 case FIXED_POINT_TYPE:
13566 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
13567 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
13569 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
13571 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
13572 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
13574 break;
13576 case ARRAY_TYPE:
13577 /* These types may not have declarations, so handle them here. */
13578 gimplify_type_sizes (TREE_TYPE (type), list_p);
13579 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
13580 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
13581 with assigned stack slots, for -O1+ -g they should be tracked
13582 by VTA. */
13583 if (!(TYPE_NAME (type)
13584 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
13585 && DECL_IGNORED_P (TYPE_NAME (type)))
13586 && TYPE_DOMAIN (type)
13587 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
13589 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
13590 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
13591 DECL_IGNORED_P (t) = 0;
13592 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
13593 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
13594 DECL_IGNORED_P (t) = 0;
13596 break;
13598 case RECORD_TYPE:
13599 case UNION_TYPE:
13600 case QUAL_UNION_TYPE:
13601 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
13602 if (TREE_CODE (field) == FIELD_DECL)
13604 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
13605 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
13606 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
13607 gimplify_type_sizes (TREE_TYPE (field), list_p);
13609 break;
13611 case POINTER_TYPE:
13612 case REFERENCE_TYPE:
13613 /* We used to recurse on the pointed-to type here, which turned out to
13614 be incorrect because its definition might refer to variables not
13615 yet initialized at this point if a forward declaration is involved.
13617 It was actually useful for anonymous pointed-to types to ensure
13618 that the sizes evaluation dominates every possible later use of the
13619 values. Restricting to such types here would be safe since there
13620 is no possible forward declaration around, but would introduce an
13621 undesirable middle-end semantic to anonymity. We then defer to
13622 front-ends the responsibility of ensuring that the sizes are
13623 evaluated both early and late enough, e.g. by attaching artificial
13624 type declarations to the tree. */
13625 break;
13627 default:
13628 break;
13631 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
13632 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
13634 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
13636 TYPE_SIZE (t) = TYPE_SIZE (type);
13637 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
13638 TYPE_SIZES_GIMPLIFIED (t) = 1;
13642 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
13643 a size or position, has had all of its SAVE_EXPRs evaluated.
13644 We add any required statements to *STMT_P. */
13646 void
13647 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
13649 tree expr = *expr_p;
13651 /* We don't do anything if the value isn't there, is constant, or contains
13652 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
13653 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
13654 will want to replace it with a new variable, but that will cause problems
13655 if this type is from outside the function. It's OK to have that here. */
13656 if (expr == NULL_TREE
13657 || is_gimple_constant (expr)
13658 || TREE_CODE (expr) == VAR_DECL
13659 || CONTAINS_PLACEHOLDER_P (expr))
13660 return;
13662 *expr_p = unshare_expr (expr);
13664 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
13665 if the def vanishes. */
13666 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
13668 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
13669 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
13670 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
13671 if (is_gimple_constant (*expr_p))
13672 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
13675 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
13676 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
13677 is true, also gimplify the parameters. */
13679 gbind *
13680 gimplify_body (tree fndecl, bool do_parms)
13682 location_t saved_location = input_location;
13683 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
13684 gimple *outer_stmt;
13685 gbind *outer_bind;
13687 timevar_push (TV_TREE_GIMPLIFY);
13689 init_tree_ssa (cfun);
13691 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
13692 gimplification. */
13693 default_rtl_profile ();
13695 gcc_assert (gimplify_ctxp == NULL);
13696 push_gimplify_context (true);
13698 if (flag_openacc || flag_openmp)
13700 gcc_assert (gimplify_omp_ctxp == NULL);
13701 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
13702 gimplify_omp_ctxp = new_omp_context (ORT_TARGET);
13705 /* Unshare most shared trees in the body and in that of any nested functions.
13706 It would seem we don't have to do this for nested functions because
13707 they are supposed to be output and then the outer function gimplified
13708 first, but the g++ front end doesn't always do it that way. */
13709 unshare_body (fndecl);
13710 unvisit_body (fndecl);
13712 /* Make sure input_location isn't set to something weird. */
13713 input_location = DECL_SOURCE_LOCATION (fndecl);
13715 /* Resolve callee-copies. This has to be done before processing
13716 the body so that DECL_VALUE_EXPR gets processed correctly. */
13717 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
13719 /* Gimplify the function's body. */
13720 seq = NULL;
13721 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
13722 outer_stmt = gimple_seq_first_stmt (seq);
13723 if (!outer_stmt)
13725 outer_stmt = gimple_build_nop ();
13726 gimplify_seq_add_stmt (&seq, outer_stmt);
13729 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
13730 not the case, wrap everything in a GIMPLE_BIND to make it so. */
13731 if (gimple_code (outer_stmt) == GIMPLE_BIND
13732 && gimple_seq_first (seq) == gimple_seq_last (seq))
13733 outer_bind = as_a <gbind *> (outer_stmt);
13734 else
13735 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
13737 DECL_SAVED_TREE (fndecl) = NULL_TREE;
13739 /* If we had callee-copies statements, insert them at the beginning
13740 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
13741 if (!gimple_seq_empty_p (parm_stmts))
13743 tree parm;
13745 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
13746 if (parm_cleanup)
13748 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
13749 GIMPLE_TRY_FINALLY);
13750 parm_stmts = NULL;
13751 gimple_seq_add_stmt (&parm_stmts, g);
13753 gimple_bind_set_body (outer_bind, parm_stmts);
13755 for (parm = DECL_ARGUMENTS (current_function_decl);
13756 parm; parm = DECL_CHAIN (parm))
13757 if (DECL_HAS_VALUE_EXPR_P (parm))
13759 DECL_HAS_VALUE_EXPR_P (parm) = 0;
13760 DECL_IGNORED_P (parm) = 0;
13764 if ((flag_openacc || flag_openmp || flag_openmp_simd)
13765 && gimplify_omp_ctxp)
13767 delete_omp_context (gimplify_omp_ctxp);
13768 gimplify_omp_ctxp = NULL;
13771 pop_gimplify_context (outer_bind);
13772 gcc_assert (gimplify_ctxp == NULL);
13774 if (flag_checking && !seen_error ())
13775 verify_gimple_in_seq (gimple_bind_body (outer_bind));
13777 timevar_pop (TV_TREE_GIMPLIFY);
13778 input_location = saved_location;
13780 return outer_bind;
13783 typedef char *char_p; /* For DEF_VEC_P. */
13785 /* Return whether we should exclude FNDECL from instrumentation. */
13787 static bool
13788 flag_instrument_functions_exclude_p (tree fndecl)
13790 vec<char_p> *v;
13792 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
13793 if (v && v->length () > 0)
13795 const char *name;
13796 int i;
13797 char *s;
13799 name = lang_hooks.decl_printable_name (fndecl, 0);
13800 FOR_EACH_VEC_ELT (*v, i, s)
13801 if (strstr (name, s) != NULL)
13802 return true;
13805 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
13806 if (v && v->length () > 0)
13808 const char *name;
13809 int i;
13810 char *s;
13812 name = DECL_SOURCE_FILE (fndecl);
13813 FOR_EACH_VEC_ELT (*v, i, s)
13814 if (strstr (name, s) != NULL)
13815 return true;
13818 return false;
13821 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
13822 node for the function we want to gimplify.
13824 Return the sequence of GIMPLE statements corresponding to the body
13825 of FNDECL. */
13827 void
13828 gimplify_function_tree (tree fndecl)
13830 tree parm, ret;
13831 gimple_seq seq;
13832 gbind *bind;
13834 gcc_assert (!gimple_body (fndecl));
13836 if (DECL_STRUCT_FUNCTION (fndecl))
13837 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
13838 else
13839 push_struct_function (fndecl);
13841 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
13842 if necessary. */
13843 cfun->curr_properties |= PROP_gimple_lva;
13845 for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = DECL_CHAIN (parm))
13847 /* Preliminarily mark non-addressed complex variables as eligible
13848 for promotion to gimple registers. We'll transform their uses
13849 as we find them. */
13850 if ((TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
13851 || TREE_CODE (TREE_TYPE (parm)) == VECTOR_TYPE)
13852 && !TREE_THIS_VOLATILE (parm)
13853 && !needs_to_live_in_memory (parm))
13854 DECL_GIMPLE_REG_P (parm) = 1;
13857 ret = DECL_RESULT (fndecl);
13858 if ((TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE
13859 || TREE_CODE (TREE_TYPE (ret)) == VECTOR_TYPE)
13860 && !needs_to_live_in_memory (ret))
13861 DECL_GIMPLE_REG_P (ret) = 1;
13863 if (asan_sanitize_use_after_scope () && sanitize_flags_p (SANITIZE_ADDRESS))
13864 asan_poisoned_variables = new hash_set<tree> ();
13865 bind = gimplify_body (fndecl, true);
13866 if (asan_poisoned_variables)
13868 delete asan_poisoned_variables;
13869 asan_poisoned_variables = NULL;
13872 /* The tree body of the function is no longer needed, replace it
13873 with the new GIMPLE body. */
13874 seq = NULL;
13875 gimple_seq_add_stmt (&seq, bind);
13876 gimple_set_body (fndecl, seq);
13878 /* If we're instrumenting function entry/exit, then prepend the call to
13879 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
13880 catch the exit hook. */
13881 /* ??? Add some way to ignore exceptions for this TFE. */
13882 if (flag_instrument_function_entry_exit
13883 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
13884 /* Do not instrument extern inline functions. */
13885 && !(DECL_DECLARED_INLINE_P (fndecl)
13886 && DECL_EXTERNAL (fndecl)
13887 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
13888 && !flag_instrument_functions_exclude_p (fndecl))
13890 tree x;
13891 gbind *new_bind;
13892 gimple *tf;
13893 gimple_seq cleanup = NULL, body = NULL;
13894 tree tmp_var, this_fn_addr;
13895 gcall *call;
13897 /* The instrumentation hooks aren't going to call the instrumented
13898 function and the address they receive is expected to be matchable
13899 against symbol addresses. Make sure we don't create a trampoline,
13900 in case the current function is nested. */
13901 this_fn_addr = build_fold_addr_expr (current_function_decl);
13902 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
13904 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
13905 call = gimple_build_call (x, 1, integer_zero_node);
13906 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
13907 gimple_call_set_lhs (call, tmp_var);
13908 gimplify_seq_add_stmt (&cleanup, call);
13909 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
13910 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
13911 gimplify_seq_add_stmt (&cleanup, call);
13912 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
13914 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
13915 call = gimple_build_call (x, 1, integer_zero_node);
13916 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
13917 gimple_call_set_lhs (call, tmp_var);
13918 gimplify_seq_add_stmt (&body, call);
13919 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
13920 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
13921 gimplify_seq_add_stmt (&body, call);
13922 gimplify_seq_add_stmt (&body, tf);
13923 new_bind = gimple_build_bind (NULL, body, NULL);
13925 /* Replace the current function body with the body
13926 wrapped in the try/finally TF. */
13927 seq = NULL;
13928 gimple_seq_add_stmt (&seq, new_bind);
13929 gimple_set_body (fndecl, seq);
13930 bind = new_bind;
13933 if (sanitize_flags_p (SANITIZE_THREAD))
13935 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
13936 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
13937 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
13938 /* Replace the current function body with the body
13939 wrapped in the try/finally TF. */
13940 seq = NULL;
13941 gimple_seq_add_stmt (&seq, new_bind);
13942 gimple_set_body (fndecl, seq);
13945 DECL_SAVED_TREE (fndecl) = NULL_TREE;
13946 cfun->curr_properties |= PROP_gimple_any;
13948 pop_cfun ();
13950 dump_function (TDI_gimple, fndecl);
13953 /* Return a dummy expression of type TYPE in order to keep going after an
13954 error. */
13956 static tree
13957 dummy_object (tree type)
13959 tree t = build_int_cst (build_pointer_type (type), 0);
13960 return build2 (MEM_REF, type, t, t);
13963 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
13964 builtin function, but a very special sort of operator. */
13966 enum gimplify_status
13967 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
13968 gimple_seq *post_p ATTRIBUTE_UNUSED)
13970 tree promoted_type, have_va_type;
13971 tree valist = TREE_OPERAND (*expr_p, 0);
13972 tree type = TREE_TYPE (*expr_p);
13973 tree t, tag, aptag;
13974 location_t loc = EXPR_LOCATION (*expr_p);
13976 /* Verify that valist is of the proper type. */
13977 have_va_type = TREE_TYPE (valist);
13978 if (have_va_type == error_mark_node)
13979 return GS_ERROR;
13980 have_va_type = targetm.canonical_va_list_type (have_va_type);
13981 if (have_va_type == NULL_TREE
13982 && POINTER_TYPE_P (TREE_TYPE (valist)))
13983 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
13984 have_va_type
13985 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
13986 gcc_assert (have_va_type != NULL_TREE);
13988 /* Generate a diagnostic for requesting data of a type that cannot
13989 be passed through `...' due to type promotion at the call site. */
13990 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
13991 != type)
13993 static bool gave_help;
13994 bool warned;
13995 /* Use the expansion point to handle cases such as passing bool (defined
13996 in a system header) through `...'. */
13997 location_t xloc
13998 = expansion_point_location_if_in_system_header (loc);
14000 /* Unfortunately, this is merely undefined, rather than a constraint
14001 violation, so we cannot make this an error. If this call is never
14002 executed, the program is still strictly conforming. */
14003 auto_diagnostic_group d;
14004 warned = warning_at (xloc, 0,
14005 "%qT is promoted to %qT when passed through %<...%>",
14006 type, promoted_type);
14007 if (!gave_help && warned)
14009 gave_help = true;
14010 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
14011 promoted_type, type);
14014 /* We can, however, treat "undefined" any way we please.
14015 Call abort to encourage the user to fix the program. */
14016 if (warned)
14017 inform (xloc, "if this code is reached, the program will abort");
14018 /* Before the abort, allow the evaluation of the va_list
14019 expression to exit or longjmp. */
14020 gimplify_and_add (valist, pre_p);
14021 t = build_call_expr_loc (loc,
14022 builtin_decl_implicit (BUILT_IN_TRAP), 0);
14023 gimplify_and_add (t, pre_p);
14025 /* This is dead code, but go ahead and finish so that the
14026 mode of the result comes out right. */
14027 *expr_p = dummy_object (type);
14028 return GS_ALL_DONE;
14031 tag = build_int_cst (build_pointer_type (type), 0);
14032 aptag = build_int_cst (TREE_TYPE (valist), 0);
14034 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
14035 valist, tag, aptag);
14037 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
14038 needs to be expanded. */
14039 cfun->curr_properties &= ~PROP_gimple_lva;
14041 return GS_OK;
14044 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
14046 DST/SRC are the destination and source respectively. You can pass
14047 ungimplified trees in DST or SRC, in which case they will be
14048 converted to a gimple operand if necessary.
14050 This function returns the newly created GIMPLE_ASSIGN tuple. */
14052 gimple *
14053 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
14055 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
14056 gimplify_and_add (t, seq_p);
14057 ggc_free (t);
14058 return gimple_seq_last_stmt (*seq_p);
14061 inline hashval_t
14062 gimplify_hasher::hash (const elt_t *p)
14064 tree t = p->val;
14065 return iterative_hash_expr (t, 0);
14068 inline bool
14069 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
14071 tree t1 = p1->val;
14072 tree t2 = p2->val;
14073 enum tree_code code = TREE_CODE (t1);
14075 if (TREE_CODE (t2) != code
14076 || TREE_TYPE (t1) != TREE_TYPE (t2))
14077 return false;
14079 if (!operand_equal_p (t1, t2, 0))
14080 return false;
14082 /* Only allow them to compare equal if they also hash equal; otherwise
14083 results are nondeterminate, and we fail bootstrap comparison. */
14084 gcc_checking_assert (hash (p1) == hash (p2));
14086 return true;