testsuite: Correct vec-rlmi-rlnm.c testsuite expected result
[official-gcc.git] / gcc / gimplify.c
blob29f385c9368a30935b3b84b78b42eb786b88b6ab
1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2020 Free Software Foundation, Inc.
4 Major work done by Sebastian Pop <s.pop@laposte.net>,
5 Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "backend.h"
27 #include "target.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "memmodel.h"
31 #include "tm_p.h"
32 #include "gimple.h"
33 #include "gimple-predict.h"
34 #include "tree-pass.h" /* FIXME: only for PROP_gimple_any */
35 #include "ssa.h"
36 #include "cgraph.h"
37 #include "tree-pretty-print.h"
38 #include "diagnostic-core.h"
39 #include "alias.h"
40 #include "fold-const.h"
41 #include "calls.h"
42 #include "varasm.h"
43 #include "stmt.h"
44 #include "expr.h"
45 #include "gimple-fold.h"
46 #include "tree-eh.h"
47 #include "gimplify.h"
48 #include "gimple-iterator.h"
49 #include "stor-layout.h"
50 #include "print-tree.h"
51 #include "tree-iterator.h"
52 #include "tree-inline.h"
53 #include "langhooks.h"
54 #include "tree-cfg.h"
55 #include "tree-ssa.h"
56 #include "omp-general.h"
57 #include "omp-low.h"
58 #include "gimple-low.h"
59 #include "gomp-constants.h"
60 #include "splay-tree.h"
61 #include "gimple-walk.h"
62 #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
63 #include "builtins.h"
64 #include "stringpool.h"
65 #include "attribs.h"
66 #include "asan.h"
67 #include "dbgcnt.h"
68 #include "omp-offload.h"
69 #include "context.h"
70 #include "tree-nested.h"
72 /* Hash set of poisoned variables in a bind expr. */
73 static hash_set<tree> *asan_poisoned_variables = NULL;
75 enum gimplify_omp_var_data
77 GOVD_SEEN = 0x000001,
78 GOVD_EXPLICIT = 0x000002,
79 GOVD_SHARED = 0x000004,
80 GOVD_PRIVATE = 0x000008,
81 GOVD_FIRSTPRIVATE = 0x000010,
82 GOVD_LASTPRIVATE = 0x000020,
83 GOVD_REDUCTION = 0x000040,
84 GOVD_LOCAL = 0x00080,
85 GOVD_MAP = 0x000100,
86 GOVD_DEBUG_PRIVATE = 0x000200,
87 GOVD_PRIVATE_OUTER_REF = 0x000400,
88 GOVD_LINEAR = 0x000800,
89 GOVD_ALIGNED = 0x001000,
91 /* Flag for GOVD_MAP: don't copy back. */
92 GOVD_MAP_TO_ONLY = 0x002000,
94 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
95 GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 0x004000,
97 GOVD_MAP_0LEN_ARRAY = 0x008000,
99 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
100 GOVD_MAP_ALWAYS_TO = 0x010000,
102 /* Flag for shared vars that are or might be stored to in the region. */
103 GOVD_WRITTEN = 0x020000,
105 /* Flag for GOVD_MAP, if it is a forced mapping. */
106 GOVD_MAP_FORCE = 0x040000,
108 /* Flag for GOVD_MAP: must be present already. */
109 GOVD_MAP_FORCE_PRESENT = 0x080000,
111 /* Flag for GOVD_MAP: only allocate. */
112 GOVD_MAP_ALLOC_ONLY = 0x100000,
114 /* Flag for GOVD_MAP: only copy back. */
115 GOVD_MAP_FROM_ONLY = 0x200000,
117 GOVD_NONTEMPORAL = 0x400000,
119 /* Flag for GOVD_LASTPRIVATE: conditional modifier. */
120 GOVD_LASTPRIVATE_CONDITIONAL = 0x800000,
122 GOVD_CONDTEMP = 0x1000000,
124 /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause. */
125 GOVD_REDUCTION_INSCAN = 0x2000000,
127 /* Flag for GOVD_MAP: (struct) vars that have pointer attachments for
128 fields. */
129 GOVD_MAP_HAS_ATTACHMENTS = 8388608,
131 GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
132 | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
133 | GOVD_LOCAL)
137 enum omp_region_type
139 ORT_WORKSHARE = 0x00,
140 ORT_TASKGROUP = 0x01,
141 ORT_SIMD = 0x04,
143 ORT_PARALLEL = 0x08,
144 ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1,
146 ORT_TASK = 0x10,
147 ORT_UNTIED_TASK = ORT_TASK | 1,
148 ORT_TASKLOOP = ORT_TASK | 2,
149 ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2,
151 ORT_TEAMS = 0x20,
152 ORT_COMBINED_TEAMS = ORT_TEAMS | 1,
153 ORT_HOST_TEAMS = ORT_TEAMS | 2,
154 ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2,
156 /* Data region. */
157 ORT_TARGET_DATA = 0x40,
159 /* Data region with offloading. */
160 ORT_TARGET = 0x80,
161 ORT_COMBINED_TARGET = ORT_TARGET | 1,
162 ORT_IMPLICIT_TARGET = ORT_TARGET | 2,
164 /* OpenACC variants. */
165 ORT_ACC = 0x100, /* A generic OpenACC region. */
166 ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */
167 ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */
168 ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 2, /* Kernels construct. */
169 ORT_ACC_SERIAL = ORT_ACC | ORT_TARGET | 4, /* Serial construct. */
170 ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2, /* Host data. */
172 /* Dummy OpenMP region, used to disable expansion of
173 DECL_VALUE_EXPRs in taskloop pre body. */
174 ORT_NONE = 0x200
177 /* Gimplify hashtable helper. */
179 struct gimplify_hasher : free_ptr_hash <elt_t>
181 static inline hashval_t hash (const elt_t *);
182 static inline bool equal (const elt_t *, const elt_t *);
185 struct gimplify_ctx
187 struct gimplify_ctx *prev_context;
189 vec<gbind *> bind_expr_stack;
190 tree temps;
191 gimple_seq conditional_cleanups;
192 tree exit_label;
193 tree return_temp;
195 vec<tree> case_labels;
196 hash_set<tree> *live_switch_vars;
197 /* The formal temporary table. Should this be persistent? */
198 hash_table<gimplify_hasher> *temp_htab;
200 int conditions;
201 unsigned into_ssa : 1;
202 unsigned allow_rhs_cond_expr : 1;
203 unsigned in_cleanup_point_expr : 1;
204 unsigned keep_stack : 1;
205 unsigned save_stack : 1;
206 unsigned in_switch_expr : 1;
209 enum gimplify_defaultmap_kind
211 GDMK_SCALAR,
212 GDMK_AGGREGATE,
213 GDMK_ALLOCATABLE,
214 GDMK_POINTER
217 struct gimplify_omp_ctx
219 struct gimplify_omp_ctx *outer_context;
220 splay_tree variables;
221 hash_set<tree> *privatized_types;
222 tree clauses;
223 /* Iteration variables in an OMP_FOR. */
224 vec<tree> loop_iter_var;
225 location_t location;
226 enum omp_clause_default_kind default_kind;
227 enum omp_region_type region_type;
228 enum tree_code code;
229 bool combined_loop;
230 bool distribute;
231 bool target_firstprivatize_array_bases;
232 bool add_safelen1;
233 bool order_concurrent;
234 int defaultmap[4];
237 static struct gimplify_ctx *gimplify_ctxp;
238 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
239 static bool in_omp_construct;
241 /* Forward declaration. */
242 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
243 static hash_map<tree, tree> *oacc_declare_returns;
244 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
245 bool (*) (tree), fallback_t, bool);
247 /* Shorter alias name for the above function for use in gimplify.c
248 only. */
250 static inline void
251 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
253 gimple_seq_add_stmt_without_update (seq_p, gs);
256 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
257 NULL, a new sequence is allocated. This function is
258 similar to gimple_seq_add_seq, but does not scan the operands.
259 During gimplification, we need to manipulate statement sequences
260 before the def/use vectors have been constructed. */
262 static void
263 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
265 gimple_stmt_iterator si;
267 if (src == NULL)
268 return;
270 si = gsi_last (*dst_p);
271 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
275 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
276 and popping gimplify contexts. */
278 static struct gimplify_ctx *ctx_pool = NULL;
280 /* Return a gimplify context struct from the pool. */
282 static inline struct gimplify_ctx *
283 ctx_alloc (void)
285 struct gimplify_ctx * c = ctx_pool;
287 if (c)
288 ctx_pool = c->prev_context;
289 else
290 c = XNEW (struct gimplify_ctx);
292 memset (c, '\0', sizeof (*c));
293 return c;
296 /* Put gimplify context C back into the pool. */
298 static inline void
299 ctx_free (struct gimplify_ctx *c)
301 c->prev_context = ctx_pool;
302 ctx_pool = c;
305 /* Free allocated ctx stack memory. */
307 void
308 free_gimplify_stack (void)
310 struct gimplify_ctx *c;
312 while ((c = ctx_pool))
314 ctx_pool = c->prev_context;
315 free (c);
320 /* Set up a context for the gimplifier. */
322 void
323 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
325 struct gimplify_ctx *c = ctx_alloc ();
327 c->prev_context = gimplify_ctxp;
328 gimplify_ctxp = c;
329 gimplify_ctxp->into_ssa = in_ssa;
330 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
333 /* Tear down a context for the gimplifier. If BODY is non-null, then
334 put the temporaries into the outer BIND_EXPR. Otherwise, put them
335 in the local_decls.
337 BODY is not a sequence, but the first tuple in a sequence. */
339 void
340 pop_gimplify_context (gimple *body)
342 struct gimplify_ctx *c = gimplify_ctxp;
344 gcc_assert (c
345 && (!c->bind_expr_stack.exists ()
346 || c->bind_expr_stack.is_empty ()));
347 c->bind_expr_stack.release ();
348 gimplify_ctxp = c->prev_context;
350 if (body)
351 declare_vars (c->temps, body, false);
352 else
353 record_vars (c->temps);
355 delete c->temp_htab;
356 c->temp_htab = NULL;
357 ctx_free (c);
360 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
362 static void
363 gimple_push_bind_expr (gbind *bind_stmt)
365 gimplify_ctxp->bind_expr_stack.reserve (8);
366 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
369 /* Pop the first element off the stack of bindings. */
371 static void
372 gimple_pop_bind_expr (void)
374 gimplify_ctxp->bind_expr_stack.pop ();
377 /* Return the first element of the stack of bindings. */
379 gbind *
380 gimple_current_bind_expr (void)
382 return gimplify_ctxp->bind_expr_stack.last ();
385 /* Return the stack of bindings created during gimplification. */
387 vec<gbind *>
388 gimple_bind_expr_stack (void)
390 return gimplify_ctxp->bind_expr_stack;
393 /* Return true iff there is a COND_EXPR between us and the innermost
394 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
396 static bool
397 gimple_conditional_context (void)
399 return gimplify_ctxp->conditions > 0;
402 /* Note that we've entered a COND_EXPR. */
404 static void
405 gimple_push_condition (void)
407 #ifdef ENABLE_GIMPLE_CHECKING
408 if (gimplify_ctxp->conditions == 0)
409 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
410 #endif
411 ++(gimplify_ctxp->conditions);
414 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
415 now, add any conditional cleanups we've seen to the prequeue. */
417 static void
418 gimple_pop_condition (gimple_seq *pre_p)
420 int conds = --(gimplify_ctxp->conditions);
422 gcc_assert (conds >= 0);
423 if (conds == 0)
425 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
426 gimplify_ctxp->conditional_cleanups = NULL;
430 /* A stable comparison routine for use with splay trees and DECLs. */
432 static int
433 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
435 tree a = (tree) xa;
436 tree b = (tree) xb;
438 return DECL_UID (a) - DECL_UID (b);
441 /* Create a new omp construct that deals with variable remapping. */
443 static struct gimplify_omp_ctx *
444 new_omp_context (enum omp_region_type region_type)
446 struct gimplify_omp_ctx *c;
448 c = XCNEW (struct gimplify_omp_ctx);
449 c->outer_context = gimplify_omp_ctxp;
450 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
451 c->privatized_types = new hash_set<tree>;
452 c->location = input_location;
453 c->region_type = region_type;
454 if ((region_type & ORT_TASK) == 0)
455 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
456 else
457 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
458 c->defaultmap[GDMK_SCALAR] = GOVD_MAP;
459 c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
460 c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
461 c->defaultmap[GDMK_POINTER] = GOVD_MAP;
463 return c;
466 /* Destroy an omp construct that deals with variable remapping. */
468 static void
469 delete_omp_context (struct gimplify_omp_ctx *c)
471 splay_tree_delete (c->variables);
472 delete c->privatized_types;
473 c->loop_iter_var.release ();
474 XDELETE (c);
477 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
478 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
480 /* Both gimplify the statement T and append it to *SEQ_P. This function
481 behaves exactly as gimplify_stmt, but you don't have to pass T as a
482 reference. */
484 void
485 gimplify_and_add (tree t, gimple_seq *seq_p)
487 gimplify_stmt (&t, seq_p);
490 /* Gimplify statement T into sequence *SEQ_P, and return the first
491 tuple in the sequence of generated tuples for this statement.
492 Return NULL if gimplifying T produced no tuples. */
494 static gimple *
495 gimplify_and_return_first (tree t, gimple_seq *seq_p)
497 gimple_stmt_iterator last = gsi_last (*seq_p);
499 gimplify_and_add (t, seq_p);
501 if (!gsi_end_p (last))
503 gsi_next (&last);
504 return gsi_stmt (last);
506 else
507 return gimple_seq_first_stmt (*seq_p);
510 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
511 LHS, or for a call argument. */
513 static bool
514 is_gimple_mem_rhs (tree t)
516 /* If we're dealing with a renamable type, either source or dest must be
517 a renamed variable. */
518 if (is_gimple_reg_type (TREE_TYPE (t)))
519 return is_gimple_val (t);
520 else
521 return is_gimple_val (t) || is_gimple_lvalue (t);
524 /* Return true if T is a CALL_EXPR or an expression that can be
525 assigned to a temporary. Note that this predicate should only be
526 used during gimplification. See the rationale for this in
527 gimplify_modify_expr. */
529 static bool
530 is_gimple_reg_rhs_or_call (tree t)
532 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
533 || TREE_CODE (t) == CALL_EXPR);
536 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
537 this predicate should only be used during gimplification. See the
538 rationale for this in gimplify_modify_expr. */
540 static bool
541 is_gimple_mem_rhs_or_call (tree t)
543 /* If we're dealing with a renamable type, either source or dest must be
544 a renamed variable. */
545 if (is_gimple_reg_type (TREE_TYPE (t)))
546 return is_gimple_val (t);
547 else
548 return (is_gimple_val (t)
549 || is_gimple_lvalue (t)
550 || TREE_CLOBBER_P (t)
551 || TREE_CODE (t) == CALL_EXPR);
554 /* Create a temporary with a name derived from VAL. Subroutine of
555 lookup_tmp_var; nobody else should call this function. */
557 static inline tree
558 create_tmp_from_val (tree val)
560 /* Drop all qualifiers and address-space information from the value type. */
561 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
562 tree var = create_tmp_var (type, get_name (val));
563 return var;
566 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
567 an existing expression temporary. */
569 static tree
570 lookup_tmp_var (tree val, bool is_formal)
572 tree ret;
574 /* If not optimizing, never really reuse a temporary. local-alloc
575 won't allocate any variable that is used in more than one basic
576 block, which means it will go into memory, causing much extra
577 work in reload and final and poorer code generation, outweighing
578 the extra memory allocation here. */
579 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
580 ret = create_tmp_from_val (val);
581 else
583 elt_t elt, *elt_p;
584 elt_t **slot;
586 elt.val = val;
587 if (!gimplify_ctxp->temp_htab)
588 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
589 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
590 if (*slot == NULL)
592 elt_p = XNEW (elt_t);
593 elt_p->val = val;
594 elt_p->temp = ret = create_tmp_from_val (val);
595 *slot = elt_p;
597 else
599 elt_p = *slot;
600 ret = elt_p->temp;
604 return ret;
607 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
609 static tree
610 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
611 bool is_formal, bool allow_ssa)
613 tree t, mod;
615 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
616 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
617 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
618 fb_rvalue);
620 if (allow_ssa
621 && gimplify_ctxp->into_ssa
622 && is_gimple_reg_type (TREE_TYPE (val)))
624 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
625 if (! gimple_in_ssa_p (cfun))
627 const char *name = get_name (val);
628 if (name)
629 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
632 else
633 t = lookup_tmp_var (val, is_formal);
635 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
637 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
639 /* gimplify_modify_expr might want to reduce this further. */
640 gimplify_and_add (mod, pre_p);
641 ggc_free (mod);
643 return t;
646 /* Return a formal temporary variable initialized with VAL. PRE_P is as
647 in gimplify_expr. Only use this function if:
649 1) The value of the unfactored expression represented by VAL will not
650 change between the initialization and use of the temporary, and
651 2) The temporary will not be otherwise modified.
653 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
654 and #2 means it is inappropriate for && temps.
656 For other cases, use get_initialized_tmp_var instead. */
658 tree
659 get_formal_tmp_var (tree val, gimple_seq *pre_p)
661 return internal_get_tmp_var (val, pre_p, NULL, true, true);
664 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
665 are as in gimplify_expr. */
667 tree
668 get_initialized_tmp_var (tree val, gimple_seq *pre_p,
669 gimple_seq *post_p /* = NULL */,
670 bool allow_ssa /* = true */)
672 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
675 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
676 generate debug info for them; otherwise don't. */
678 void
679 declare_vars (tree vars, gimple *gs, bool debug_info)
681 tree last = vars;
682 if (last)
684 tree temps, block;
686 gbind *scope = as_a <gbind *> (gs);
688 temps = nreverse (last);
690 block = gimple_bind_block (scope);
691 gcc_assert (!block || TREE_CODE (block) == BLOCK);
692 if (!block || !debug_info)
694 DECL_CHAIN (last) = gimple_bind_vars (scope);
695 gimple_bind_set_vars (scope, temps);
697 else
699 /* We need to attach the nodes both to the BIND_EXPR and to its
700 associated BLOCK for debugging purposes. The key point here
701 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
702 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
703 if (BLOCK_VARS (block))
704 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
705 else
707 gimple_bind_set_vars (scope,
708 chainon (gimple_bind_vars (scope), temps));
709 BLOCK_VARS (block) = temps;
715 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
716 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
717 no such upper bound can be obtained. */
719 static void
720 force_constant_size (tree var)
722 /* The only attempt we make is by querying the maximum size of objects
723 of the variable's type. */
725 HOST_WIDE_INT max_size;
727 gcc_assert (VAR_P (var));
729 max_size = max_int_size_in_bytes (TREE_TYPE (var));
731 gcc_assert (max_size >= 0);
733 DECL_SIZE_UNIT (var)
734 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
735 DECL_SIZE (var)
736 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
739 /* Push the temporary variable TMP into the current binding. */
741 void
742 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
744 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
746 /* Later processing assumes that the object size is constant, which might
747 not be true at this point. Force the use of a constant upper bound in
748 this case. */
749 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
750 force_constant_size (tmp);
752 DECL_CONTEXT (tmp) = fn->decl;
753 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
755 record_vars_into (tmp, fn->decl);
758 /* Push the temporary variable TMP into the current binding. */
760 void
761 gimple_add_tmp_var (tree tmp)
763 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
765 /* Later processing assumes that the object size is constant, which might
766 not be true at this point. Force the use of a constant upper bound in
767 this case. */
768 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
769 force_constant_size (tmp);
771 DECL_CONTEXT (tmp) = current_function_decl;
772 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
774 if (gimplify_ctxp)
776 DECL_CHAIN (tmp) = gimplify_ctxp->temps;
777 gimplify_ctxp->temps = tmp;
779 /* Mark temporaries local within the nearest enclosing parallel. */
780 if (gimplify_omp_ctxp)
782 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
783 int flag = GOVD_LOCAL;
784 while (ctx
785 && (ctx->region_type == ORT_WORKSHARE
786 || ctx->region_type == ORT_TASKGROUP
787 || ctx->region_type == ORT_SIMD
788 || ctx->region_type == ORT_ACC))
790 if (ctx->region_type == ORT_SIMD
791 && TREE_ADDRESSABLE (tmp)
792 && !TREE_STATIC (tmp))
794 if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
795 ctx->add_safelen1 = true;
796 else
797 flag = GOVD_PRIVATE;
798 break;
800 ctx = ctx->outer_context;
802 if (ctx)
803 omp_add_variable (ctx, tmp, flag | GOVD_SEEN);
806 else if (cfun)
807 record_vars (tmp);
808 else
810 gimple_seq body_seq;
812 /* This case is for nested functions. We need to expose the locals
813 they create. */
814 body_seq = gimple_body (current_function_decl);
815 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
821 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
822 nodes that are referenced more than once in GENERIC functions. This is
823 necessary because gimplification (translation into GIMPLE) is performed
824 by modifying tree nodes in-place, so gimplication of a shared node in a
825 first context could generate an invalid GIMPLE form in a second context.
827 This is achieved with a simple mark/copy/unmark algorithm that walks the
828 GENERIC representation top-down, marks nodes with TREE_VISITED the first
829 time it encounters them, duplicates them if they already have TREE_VISITED
830 set, and finally removes the TREE_VISITED marks it has set.
832 The algorithm works only at the function level, i.e. it generates a GENERIC
833 representation of a function with no nodes shared within the function when
834 passed a GENERIC function (except for nodes that are allowed to be shared).
836 At the global level, it is also necessary to unshare tree nodes that are
837 referenced in more than one function, for the same aforementioned reason.
838 This requires some cooperation from the front-end. There are 2 strategies:
840 1. Manual unsharing. The front-end needs to call unshare_expr on every
841 expression that might end up being shared across functions.
843 2. Deep unsharing. This is an extension of regular unsharing. Instead
844 of calling unshare_expr on expressions that might be shared across
845 functions, the front-end pre-marks them with TREE_VISITED. This will
846 ensure that they are unshared on the first reference within functions
847 when the regular unsharing algorithm runs. The counterpart is that
848 this algorithm must look deeper than for manual unsharing, which is
849 specified by LANG_HOOKS_DEEP_UNSHARING.
851 If there are only few specific cases of node sharing across functions, it is
852 probably easier for a front-end to unshare the expressions manually. On the
853 contrary, if the expressions generated at the global level are as widespread
854 as expressions generated within functions, deep unsharing is very likely the
855 way to go. */
857 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
858 These nodes model computations that must be done once. If we were to
859 unshare something like SAVE_EXPR(i++), the gimplification process would
860 create wrong code. However, if DATA is non-null, it must hold a pointer
861 set that is used to unshare the subtrees of these nodes. */
863 static tree
864 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
866 tree t = *tp;
867 enum tree_code code = TREE_CODE (t);
869 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
870 copy their subtrees if we can make sure to do it only once. */
871 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
873 if (data && !((hash_set<tree> *)data)->add (t))
875 else
876 *walk_subtrees = 0;
879 /* Stop at types, decls, constants like copy_tree_r. */
880 else if (TREE_CODE_CLASS (code) == tcc_type
881 || TREE_CODE_CLASS (code) == tcc_declaration
882 || TREE_CODE_CLASS (code) == tcc_constant)
883 *walk_subtrees = 0;
885 /* Cope with the statement expression extension. */
886 else if (code == STATEMENT_LIST)
889 /* Leave the bulk of the work to copy_tree_r itself. */
890 else
891 copy_tree_r (tp, walk_subtrees, NULL);
893 return NULL_TREE;
896 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
897 If *TP has been visited already, then *TP is deeply copied by calling
898 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
900 static tree
901 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
903 tree t = *tp;
904 enum tree_code code = TREE_CODE (t);
906 /* Skip types, decls, and constants. But we do want to look at their
907 types and the bounds of types. Mark them as visited so we properly
908 unmark their subtrees on the unmark pass. If we've already seen them,
909 don't look down further. */
910 if (TREE_CODE_CLASS (code) == tcc_type
911 || TREE_CODE_CLASS (code) == tcc_declaration
912 || TREE_CODE_CLASS (code) == tcc_constant)
914 if (TREE_VISITED (t))
915 *walk_subtrees = 0;
916 else
917 TREE_VISITED (t) = 1;
920 /* If this node has been visited already, unshare it and don't look
921 any deeper. */
922 else if (TREE_VISITED (t))
924 walk_tree (tp, mostly_copy_tree_r, data, NULL);
925 *walk_subtrees = 0;
928 /* Otherwise, mark the node as visited and keep looking. */
929 else
930 TREE_VISITED (t) = 1;
932 return NULL_TREE;
935 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
936 copy_if_shared_r callback unmodified. */
938 void
939 copy_if_shared (tree *tp, void *data)
941 walk_tree (tp, copy_if_shared_r, data, NULL);
944 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
945 any nested functions. */
947 static void
948 unshare_body (tree fndecl)
950 struct cgraph_node *cgn = cgraph_node::get (fndecl);
951 /* If the language requires deep unsharing, we need a pointer set to make
952 sure we don't repeatedly unshare subtrees of unshareable nodes. */
953 hash_set<tree> *visited
954 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
956 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
957 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
958 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
960 delete visited;
962 if (cgn)
963 for (cgn = first_nested_function (cgn); cgn;
964 cgn = next_nested_function (cgn))
965 unshare_body (cgn->decl);
968 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
969 Subtrees are walked until the first unvisited node is encountered. */
971 static tree
972 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
974 tree t = *tp;
976 /* If this node has been visited, unmark it and keep looking. */
977 if (TREE_VISITED (t))
978 TREE_VISITED (t) = 0;
980 /* Otherwise, don't look any deeper. */
981 else
982 *walk_subtrees = 0;
984 return NULL_TREE;
987 /* Unmark the visited trees rooted at *TP. */
989 static inline void
990 unmark_visited (tree *tp)
992 walk_tree (tp, unmark_visited_r, NULL, NULL);
995 /* Likewise, but mark all trees as not visited. */
997 static void
998 unvisit_body (tree fndecl)
1000 struct cgraph_node *cgn = cgraph_node::get (fndecl);
1002 unmark_visited (&DECL_SAVED_TREE (fndecl));
1003 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
1004 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
1006 if (cgn)
1007 for (cgn = first_nested_function (cgn);
1008 cgn; cgn = next_nested_function (cgn))
1009 unvisit_body (cgn->decl);
1012 /* Unconditionally make an unshared copy of EXPR. This is used when using
1013 stored expressions which span multiple functions, such as BINFO_VTABLE,
1014 as the normal unsharing process can't tell that they're shared. */
1016 tree
1017 unshare_expr (tree expr)
1019 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1020 return expr;
1023 /* Worker for unshare_expr_without_location. */
1025 static tree
1026 prune_expr_location (tree *tp, int *walk_subtrees, void *)
1028 if (EXPR_P (*tp))
1029 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
1030 else
1031 *walk_subtrees = 0;
1032 return NULL_TREE;
1035 /* Similar to unshare_expr but also prune all expression locations
1036 from EXPR. */
1038 tree
1039 unshare_expr_without_location (tree expr)
1041 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1042 if (EXPR_P (expr))
1043 walk_tree (&expr, prune_expr_location, NULL, NULL);
1044 return expr;
1047 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1048 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1049 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1050 EXPR is the location of the EXPR. */
1052 static location_t
1053 rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION)
1055 if (!expr)
1056 return or_else;
1058 if (EXPR_HAS_LOCATION (expr))
1059 return EXPR_LOCATION (expr);
1061 if (TREE_CODE (expr) != STATEMENT_LIST)
1062 return or_else;
1064 tree_stmt_iterator i = tsi_start (expr);
1066 bool found = false;
1067 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
1069 found = true;
1070 tsi_next (&i);
1073 if (!found || !tsi_one_before_end_p (i))
1074 return or_else;
1076 return rexpr_location (tsi_stmt (i), or_else);
1079 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1080 rexpr_location for the potential recursion. */
1082 static inline bool
1083 rexpr_has_location (tree expr)
1085 return rexpr_location (expr) != UNKNOWN_LOCATION;
1089 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1090 contain statements and have a value. Assign its value to a temporary
1091 and give it void_type_node. Return the temporary, or NULL_TREE if
1092 WRAPPER was already void. */
1094 tree
1095 voidify_wrapper_expr (tree wrapper, tree temp)
1097 tree type = TREE_TYPE (wrapper);
1098 if (type && !VOID_TYPE_P (type))
1100 tree *p;
1102 /* Set p to point to the body of the wrapper. Loop until we find
1103 something that isn't a wrapper. */
1104 for (p = &wrapper; p && *p; )
1106 switch (TREE_CODE (*p))
1108 case BIND_EXPR:
1109 TREE_SIDE_EFFECTS (*p) = 1;
1110 TREE_TYPE (*p) = void_type_node;
1111 /* For a BIND_EXPR, the body is operand 1. */
1112 p = &BIND_EXPR_BODY (*p);
1113 break;
1115 case CLEANUP_POINT_EXPR:
1116 case TRY_FINALLY_EXPR:
1117 case TRY_CATCH_EXPR:
1118 TREE_SIDE_EFFECTS (*p) = 1;
1119 TREE_TYPE (*p) = void_type_node;
1120 p = &TREE_OPERAND (*p, 0);
1121 break;
1123 case STATEMENT_LIST:
1125 tree_stmt_iterator i = tsi_last (*p);
1126 TREE_SIDE_EFFECTS (*p) = 1;
1127 TREE_TYPE (*p) = void_type_node;
1128 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1130 break;
1132 case COMPOUND_EXPR:
1133 /* Advance to the last statement. Set all container types to
1134 void. */
1135 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1137 TREE_SIDE_EFFECTS (*p) = 1;
1138 TREE_TYPE (*p) = void_type_node;
1140 break;
1142 case TRANSACTION_EXPR:
1143 TREE_SIDE_EFFECTS (*p) = 1;
1144 TREE_TYPE (*p) = void_type_node;
1145 p = &TRANSACTION_EXPR_BODY (*p);
1146 break;
1148 default:
1149 /* Assume that any tree upon which voidify_wrapper_expr is
1150 directly called is a wrapper, and that its body is op0. */
1151 if (p == &wrapper)
1153 TREE_SIDE_EFFECTS (*p) = 1;
1154 TREE_TYPE (*p) = void_type_node;
1155 p = &TREE_OPERAND (*p, 0);
1156 break;
1158 goto out;
1162 out:
1163 if (p == NULL || IS_EMPTY_STMT (*p))
1164 temp = NULL_TREE;
1165 else if (temp)
1167 /* The wrapper is on the RHS of an assignment that we're pushing
1168 down. */
1169 gcc_assert (TREE_CODE (temp) == INIT_EXPR
1170 || TREE_CODE (temp) == MODIFY_EXPR);
1171 TREE_OPERAND (temp, 1) = *p;
1172 *p = temp;
1174 else
1176 temp = create_tmp_var (type, "retval");
1177 *p = build2 (INIT_EXPR, type, temp, *p);
1180 return temp;
1183 return NULL_TREE;
1186 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1187 a temporary through which they communicate. */
1189 static void
1190 build_stack_save_restore (gcall **save, gcall **restore)
1192 tree tmp_var;
1194 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1195 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1196 gimple_call_set_lhs (*save, tmp_var);
1198 *restore
1199 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1200 1, tmp_var);
1203 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1205 static tree
1206 build_asan_poison_call_expr (tree decl)
1208 /* Do not poison variables that have size equal to zero. */
1209 tree unit_size = DECL_SIZE_UNIT (decl);
1210 if (zerop (unit_size))
1211 return NULL_TREE;
1213 tree base = build_fold_addr_expr (decl);
1215 return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
1216 void_type_node, 3,
1217 build_int_cst (integer_type_node,
1218 ASAN_MARK_POISON),
1219 base, unit_size);
1222 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1223 on POISON flag, shadow memory of a DECL variable. The call will be
1224 put on location identified by IT iterator, where BEFORE flag drives
1225 position where the stmt will be put. */
1227 static void
1228 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
1229 bool before)
1231 tree unit_size = DECL_SIZE_UNIT (decl);
1232 tree base = build_fold_addr_expr (decl);
1234 /* Do not poison variables that have size equal to zero. */
1235 if (zerop (unit_size))
1236 return;
1238 /* It's necessary to have all stack variables aligned to ASAN granularity
1239 bytes. */
1240 if (DECL_ALIGN_UNIT (decl) <= ASAN_SHADOW_GRANULARITY)
1241 SET_DECL_ALIGN (decl, BITS_PER_UNIT * ASAN_SHADOW_GRANULARITY);
1243 HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
1245 gimple *g
1246 = gimple_build_call_internal (IFN_ASAN_MARK, 3,
1247 build_int_cst (integer_type_node, flags),
1248 base, unit_size);
1250 if (before)
1251 gsi_insert_before (it, g, GSI_NEW_STMT);
1252 else
1253 gsi_insert_after (it, g, GSI_NEW_STMT);
1256 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1257 either poisons or unpoisons a DECL. Created statement is appended
1258 to SEQ_P gimple sequence. */
1260 static void
1261 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
1263 gimple_stmt_iterator it = gsi_last (*seq_p);
1264 bool before = false;
1266 if (gsi_end_p (it))
1267 before = true;
1269 asan_poison_variable (decl, poison, &it, before);
1272 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1274 static int
1275 sort_by_decl_uid (const void *a, const void *b)
1277 const tree *t1 = (const tree *)a;
1278 const tree *t2 = (const tree *)b;
1280 int uid1 = DECL_UID (*t1);
1281 int uid2 = DECL_UID (*t2);
1283 if (uid1 < uid2)
1284 return -1;
1285 else if (uid1 > uid2)
1286 return 1;
1287 else
1288 return 0;
1291 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1292 depending on POISON flag. Created statement is appended
1293 to SEQ_P gimple sequence. */
1295 static void
1296 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
1298 unsigned c = variables->elements ();
1299 if (c == 0)
1300 return;
1302 auto_vec<tree> sorted_variables (c);
1304 for (hash_set<tree>::iterator it = variables->begin ();
1305 it != variables->end (); ++it)
1306 sorted_variables.safe_push (*it);
1308 sorted_variables.qsort (sort_by_decl_uid);
1310 unsigned i;
1311 tree var;
1312 FOR_EACH_VEC_ELT (sorted_variables, i, var)
1314 asan_poison_variable (var, poison, seq_p);
1316 /* Add use_after_scope_memory attribute for the variable in order
1317 to prevent re-written into SSA. */
1318 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
1319 DECL_ATTRIBUTES (var)))
1320 DECL_ATTRIBUTES (var)
1321 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
1322 integer_one_node,
1323 DECL_ATTRIBUTES (var));
1327 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1329 static enum gimplify_status
1330 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1332 tree bind_expr = *expr_p;
1333 bool old_keep_stack = gimplify_ctxp->keep_stack;
1334 bool old_save_stack = gimplify_ctxp->save_stack;
1335 tree t;
1336 gbind *bind_stmt;
1337 gimple_seq body, cleanup;
1338 gcall *stack_save;
1339 location_t start_locus = 0, end_locus = 0;
1340 tree ret_clauses = NULL;
1342 tree temp = voidify_wrapper_expr (bind_expr, NULL);
1344 /* Mark variables seen in this bind expr. */
1345 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1347 if (VAR_P (t))
1349 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1351 /* Mark variable as local. */
1352 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t))
1354 if (! DECL_SEEN_IN_BIND_EXPR_P (t)
1355 || splay_tree_lookup (ctx->variables,
1356 (splay_tree_key) t) == NULL)
1358 int flag = GOVD_LOCAL;
1359 if (ctx->region_type == ORT_SIMD
1360 && TREE_ADDRESSABLE (t)
1361 && !TREE_STATIC (t))
1363 if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST)
1364 ctx->add_safelen1 = true;
1365 else
1366 flag = GOVD_PRIVATE;
1368 omp_add_variable (ctx, t, flag | GOVD_SEEN);
1370 /* Static locals inside of target construct or offloaded
1371 routines need to be "omp declare target". */
1372 if (TREE_STATIC (t))
1373 for (; ctx; ctx = ctx->outer_context)
1374 if ((ctx->region_type & ORT_TARGET) != 0)
1376 if (!lookup_attribute ("omp declare target",
1377 DECL_ATTRIBUTES (t)))
1379 tree id = get_identifier ("omp declare target");
1380 DECL_ATTRIBUTES (t)
1381 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
1382 varpool_node *node = varpool_node::get (t);
1383 if (node)
1385 node->offloadable = 1;
1386 if (ENABLE_OFFLOADING && !DECL_EXTERNAL (t))
1388 g->have_offload = true;
1389 if (!in_lto_p)
1390 vec_safe_push (offload_vars, t);
1394 break;
1398 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1400 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1401 cfun->has_local_explicit_reg_vars = true;
1405 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1406 BIND_EXPR_BLOCK (bind_expr));
1407 gimple_push_bind_expr (bind_stmt);
1409 gimplify_ctxp->keep_stack = false;
1410 gimplify_ctxp->save_stack = false;
1412 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1413 body = NULL;
1414 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1415 gimple_bind_set_body (bind_stmt, body);
1417 /* Source location wise, the cleanup code (stack_restore and clobbers)
1418 belongs to the end of the block, so propagate what we have. The
1419 stack_save operation belongs to the beginning of block, which we can
1420 infer from the bind_expr directly if the block has no explicit
1421 assignment. */
1422 if (BIND_EXPR_BLOCK (bind_expr))
1424 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1425 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1427 if (start_locus == 0)
1428 start_locus = EXPR_LOCATION (bind_expr);
1430 cleanup = NULL;
1431 stack_save = NULL;
1433 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1434 the stack space allocated to the VLAs. */
1435 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1437 gcall *stack_restore;
1439 /* Save stack on entry and restore it on exit. Add a try_finally
1440 block to achieve this. */
1441 build_stack_save_restore (&stack_save, &stack_restore);
1443 gimple_set_location (stack_save, start_locus);
1444 gimple_set_location (stack_restore, end_locus);
1446 gimplify_seq_add_stmt (&cleanup, stack_restore);
1449 /* Add clobbers for all variables that go out of scope. */
1450 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1452 if (VAR_P (t)
1453 && !is_global_var (t)
1454 && DECL_CONTEXT (t) == current_function_decl)
1456 if (!DECL_HARD_REGISTER (t)
1457 && !TREE_THIS_VOLATILE (t)
1458 && !DECL_HAS_VALUE_EXPR_P (t)
1459 /* Only care for variables that have to be in memory. Others
1460 will be rewritten into SSA names, hence moved to the
1461 top-level. */
1462 && !is_gimple_reg (t)
1463 && flag_stack_reuse != SR_NONE)
1465 tree clobber = build_clobber (TREE_TYPE (t));
1466 gimple *clobber_stmt;
1467 clobber_stmt = gimple_build_assign (t, clobber);
1468 gimple_set_location (clobber_stmt, end_locus);
1469 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1472 if (flag_openacc && oacc_declare_returns != NULL)
1474 tree key = t;
1475 if (DECL_HAS_VALUE_EXPR_P (key))
1477 key = DECL_VALUE_EXPR (key);
1478 if (TREE_CODE (key) == INDIRECT_REF)
1479 key = TREE_OPERAND (key, 0);
1481 tree *c = oacc_declare_returns->get (key);
1482 if (c != NULL)
1484 if (ret_clauses)
1485 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1487 ret_clauses = unshare_expr (*c);
1489 oacc_declare_returns->remove (key);
1491 if (oacc_declare_returns->is_empty ())
1493 delete oacc_declare_returns;
1494 oacc_declare_returns = NULL;
1500 if (asan_poisoned_variables != NULL
1501 && asan_poisoned_variables->contains (t))
1503 asan_poisoned_variables->remove (t);
1504 asan_poison_variable (t, true, &cleanup);
1507 if (gimplify_ctxp->live_switch_vars != NULL
1508 && gimplify_ctxp->live_switch_vars->contains (t))
1509 gimplify_ctxp->live_switch_vars->remove (t);
1512 if (ret_clauses)
1514 gomp_target *stmt;
1515 gimple_stmt_iterator si = gsi_start (cleanup);
1517 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1518 ret_clauses);
1519 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1522 if (cleanup)
1524 gtry *gs;
1525 gimple_seq new_body;
1527 new_body = NULL;
1528 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1529 GIMPLE_TRY_FINALLY);
1531 if (stack_save)
1532 gimplify_seq_add_stmt (&new_body, stack_save);
1533 gimplify_seq_add_stmt (&new_body, gs);
1534 gimple_bind_set_body (bind_stmt, new_body);
1537 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1538 if (!gimplify_ctxp->keep_stack)
1539 gimplify_ctxp->keep_stack = old_keep_stack;
1540 gimplify_ctxp->save_stack = old_save_stack;
1542 gimple_pop_bind_expr ();
1544 gimplify_seq_add_stmt (pre_p, bind_stmt);
1546 if (temp)
1548 *expr_p = temp;
1549 return GS_OK;
1552 *expr_p = NULL_TREE;
1553 return GS_ALL_DONE;
1556 /* Maybe add early return predict statement to PRE_P sequence. */
1558 static void
1559 maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
1561 /* If we are not in a conditional context, add PREDICT statement. */
1562 if (gimple_conditional_context ())
1564 gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
1565 NOT_TAKEN);
1566 gimplify_seq_add_stmt (pre_p, predict);
1570 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1571 GIMPLE value, it is assigned to a new temporary and the statement is
1572 re-written to return the temporary.
1574 PRE_P points to the sequence where side effects that must happen before
1575 STMT should be stored. */
1577 static enum gimplify_status
1578 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1580 greturn *ret;
1581 tree ret_expr = TREE_OPERAND (stmt, 0);
1582 tree result_decl, result;
1584 if (ret_expr == error_mark_node)
1585 return GS_ERROR;
1587 if (!ret_expr
1588 || TREE_CODE (ret_expr) == RESULT_DECL)
1590 maybe_add_early_return_predict_stmt (pre_p);
1591 greturn *ret = gimple_build_return (ret_expr);
1592 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1593 gimplify_seq_add_stmt (pre_p, ret);
1594 return GS_ALL_DONE;
1597 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1598 result_decl = NULL_TREE;
1599 else if (TREE_CODE (ret_expr) == COMPOUND_EXPR)
1601 /* Used in C++ for handling EH cleanup of the return value if a local
1602 cleanup throws. Assume the front-end knows what it's doing. */
1603 result_decl = DECL_RESULT (current_function_decl);
1604 /* But crash if we end up trying to modify ret_expr below. */
1605 ret_expr = NULL_TREE;
1607 else
1609 result_decl = TREE_OPERAND (ret_expr, 0);
1611 /* See through a return by reference. */
1612 if (TREE_CODE (result_decl) == INDIRECT_REF)
1613 result_decl = TREE_OPERAND (result_decl, 0);
1615 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1616 || TREE_CODE (ret_expr) == INIT_EXPR)
1617 && TREE_CODE (result_decl) == RESULT_DECL);
1620 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1621 Recall that aggregate_value_p is FALSE for any aggregate type that is
1622 returned in registers. If we're returning values in registers, then
1623 we don't want to extend the lifetime of the RESULT_DECL, particularly
1624 across another call. In addition, for those aggregates for which
1625 hard_function_value generates a PARALLEL, we'll die during normal
1626 expansion of structure assignments; there's special code in expand_return
1627 to handle this case that does not exist in expand_expr. */
1628 if (!result_decl)
1629 result = NULL_TREE;
1630 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1632 if (!poly_int_tree_p (DECL_SIZE (result_decl)))
1634 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1635 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1636 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1637 should be effectively allocated by the caller, i.e. all calls to
1638 this function must be subject to the Return Slot Optimization. */
1639 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1640 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1642 result = result_decl;
1644 else if (gimplify_ctxp->return_temp)
1645 result = gimplify_ctxp->return_temp;
1646 else
1648 result = create_tmp_reg (TREE_TYPE (result_decl));
1650 /* ??? With complex control flow (usually involving abnormal edges),
1651 we can wind up warning about an uninitialized value for this. Due
1652 to how this variable is constructed and initialized, this is never
1653 true. Give up and never warn. */
1654 TREE_NO_WARNING (result) = 1;
1656 gimplify_ctxp->return_temp = result;
1659 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1660 Then gimplify the whole thing. */
1661 if (result != result_decl)
1662 TREE_OPERAND (ret_expr, 0) = result;
1664 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1666 maybe_add_early_return_predict_stmt (pre_p);
1667 ret = gimple_build_return (result);
1668 gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
1669 gimplify_seq_add_stmt (pre_p, ret);
1671 return GS_ALL_DONE;
1674 /* Gimplify a variable-length array DECL. */
1676 static void
1677 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1679 /* This is a variable-sized decl. Simplify its size and mark it
1680 for deferred expansion. */
1681 tree t, addr, ptr_type;
1683 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1684 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1686 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1687 if (DECL_HAS_VALUE_EXPR_P (decl))
1688 return;
1690 /* All occurrences of this decl in final gimplified code will be
1691 replaced by indirection. Setting DECL_VALUE_EXPR does two
1692 things: First, it lets the rest of the gimplifier know what
1693 replacement to use. Second, it lets the debug info know
1694 where to find the value. */
1695 ptr_type = build_pointer_type (TREE_TYPE (decl));
1696 addr = create_tmp_var (ptr_type, get_name (decl));
1697 DECL_IGNORED_P (addr) = 0;
1698 t = build_fold_indirect_ref (addr);
1699 TREE_THIS_NOTRAP (t) = 1;
1700 SET_DECL_VALUE_EXPR (decl, t);
1701 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1703 t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
1704 max_int_size_in_bytes (TREE_TYPE (decl)));
1705 /* The call has been built for a variable-sized object. */
1706 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1707 t = fold_convert (ptr_type, t);
1708 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1710 gimplify_and_add (t, seq_p);
1712 /* Record the dynamic allocation associated with DECL if requested. */
1713 if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)
1714 record_dynamic_alloc (decl);
1717 /* A helper function to be called via walk_tree. Mark all labels under *TP
1718 as being forced. To be called for DECL_INITIAL of static variables. */
1720 static tree
1721 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1723 if (TYPE_P (*tp))
1724 *walk_subtrees = 0;
1725 if (TREE_CODE (*tp) == LABEL_DECL)
1727 FORCED_LABEL (*tp) = 1;
1728 cfun->has_forced_label_in_static = 1;
1731 return NULL_TREE;
1734 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1735 and initialization explicit. */
1737 static enum gimplify_status
1738 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1740 tree stmt = *stmt_p;
1741 tree decl = DECL_EXPR_DECL (stmt);
1743 *stmt_p = NULL_TREE;
1745 if (TREE_TYPE (decl) == error_mark_node)
1746 return GS_ERROR;
1748 if ((TREE_CODE (decl) == TYPE_DECL
1749 || VAR_P (decl))
1750 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1752 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1753 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1754 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1757 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1758 in case its size expressions contain problematic nodes like CALL_EXPR. */
1759 if (TREE_CODE (decl) == TYPE_DECL
1760 && DECL_ORIGINAL_TYPE (decl)
1761 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1763 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1764 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1765 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1768 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1770 tree init = DECL_INITIAL (decl);
1771 bool is_vla = false;
1773 poly_uint64 size;
1774 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
1775 || (!TREE_STATIC (decl)
1776 && flag_stack_check == GENERIC_STACK_CHECK
1777 && maybe_gt (size,
1778 (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
1780 gimplify_vla_decl (decl, seq_p);
1781 is_vla = true;
1784 if (asan_poisoned_variables
1785 && !is_vla
1786 && TREE_ADDRESSABLE (decl)
1787 && !TREE_STATIC (decl)
1788 && !DECL_HAS_VALUE_EXPR_P (decl)
1789 && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
1790 && dbg_cnt (asan_use_after_scope)
1791 && !gimplify_omp_ctxp)
1793 asan_poisoned_variables->add (decl);
1794 asan_poison_variable (decl, false, seq_p);
1795 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
1796 gimplify_ctxp->live_switch_vars->add (decl);
1799 /* Some front ends do not explicitly declare all anonymous
1800 artificial variables. We compensate here by declaring the
1801 variables, though it would be better if the front ends would
1802 explicitly declare them. */
1803 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1804 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1805 gimple_add_tmp_var (decl);
1807 if (init && init != error_mark_node)
1809 if (!TREE_STATIC (decl))
1811 DECL_INITIAL (decl) = NULL_TREE;
1812 init = build2 (INIT_EXPR, void_type_node, decl, init);
1813 gimplify_and_add (init, seq_p);
1814 ggc_free (init);
1816 else
1817 /* We must still examine initializers for static variables
1818 as they may contain a label address. */
1819 walk_tree (&init, force_labels_r, NULL, NULL);
1823 return GS_ALL_DONE;
1826 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1827 and replacing the LOOP_EXPR with goto, but if the loop contains an
1828 EXIT_EXPR, we need to append a label for it to jump to. */
1830 static enum gimplify_status
1831 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1833 tree saved_label = gimplify_ctxp->exit_label;
1834 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1836 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1838 gimplify_ctxp->exit_label = NULL_TREE;
1840 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1842 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
1844 if (gimplify_ctxp->exit_label)
1845 gimplify_seq_add_stmt (pre_p,
1846 gimple_build_label (gimplify_ctxp->exit_label));
1848 gimplify_ctxp->exit_label = saved_label;
1850 *expr_p = NULL;
1851 return GS_ALL_DONE;
1854 /* Gimplify a statement list onto a sequence. These may be created either
1855 by an enlightened front-end, or by shortcut_cond_expr. */
1857 static enum gimplify_status
1858 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
1860 tree temp = voidify_wrapper_expr (*expr_p, NULL);
1862 tree_stmt_iterator i = tsi_start (*expr_p);
1864 while (!tsi_end_p (i))
1866 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
1867 tsi_delink (&i);
1870 if (temp)
1872 *expr_p = temp;
1873 return GS_OK;
1876 return GS_ALL_DONE;
1879 /* Callback for walk_gimple_seq. */
1881 static tree
1882 warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
1883 struct walk_stmt_info *wi)
1885 gimple *stmt = gsi_stmt (*gsi_p);
1887 *handled_ops_p = true;
1888 switch (gimple_code (stmt))
1890 case GIMPLE_TRY:
1891 /* A compiler-generated cleanup or a user-written try block.
1892 If it's empty, don't dive into it--that would result in
1893 worse location info. */
1894 if (gimple_try_eval (stmt) == NULL)
1896 wi->info = stmt;
1897 return integer_zero_node;
1899 /* Fall through. */
1900 case GIMPLE_BIND:
1901 case GIMPLE_CATCH:
1902 case GIMPLE_EH_FILTER:
1903 case GIMPLE_TRANSACTION:
1904 /* Walk the sub-statements. */
1905 *handled_ops_p = false;
1906 break;
1908 case GIMPLE_DEBUG:
1909 /* Ignore these. We may generate them before declarations that
1910 are never executed. If there's something to warn about,
1911 there will be non-debug stmts too, and we'll catch those. */
1912 break;
1914 case GIMPLE_CALL:
1915 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
1917 *handled_ops_p = false;
1918 break;
1920 /* Fall through. */
1921 default:
1922 /* Save the first "real" statement (not a decl/lexical scope/...). */
1923 wi->info = stmt;
1924 return integer_zero_node;
1926 return NULL_TREE;
1929 /* Possibly warn about unreachable statements between switch's controlling
1930 expression and the first case. SEQ is the body of a switch expression. */
1932 static void
1933 maybe_warn_switch_unreachable (gimple_seq seq)
1935 if (!warn_switch_unreachable
1936 /* This warning doesn't play well with Fortran when optimizations
1937 are on. */
1938 || lang_GNU_Fortran ()
1939 || seq == NULL)
1940 return;
1942 struct walk_stmt_info wi;
1943 memset (&wi, 0, sizeof (wi));
1944 walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi);
1945 gimple *stmt = (gimple *) wi.info;
1947 if (stmt && gimple_code (stmt) != GIMPLE_LABEL)
1949 if (gimple_code (stmt) == GIMPLE_GOTO
1950 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
1951 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
1952 /* Don't warn for compiler-generated gotos. These occur
1953 in Duff's devices, for example. */;
1954 else
1955 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
1956 "statement will never be executed");
1961 /* A label entry that pairs label and a location. */
1962 struct label_entry
1964 tree label;
1965 location_t loc;
1968 /* Find LABEL in vector of label entries VEC. */
1970 static struct label_entry *
1971 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
1973 unsigned int i;
1974 struct label_entry *l;
1976 FOR_EACH_VEC_ELT (*vec, i, l)
1977 if (l->label == label)
1978 return l;
1979 return NULL;
1982 /* Return true if LABEL, a LABEL_DECL, represents a case label
1983 in a vector of labels CASES. */
1985 static bool
1986 case_label_p (const vec<tree> *cases, tree label)
1988 unsigned int i;
1989 tree l;
1991 FOR_EACH_VEC_ELT (*cases, i, l)
1992 if (CASE_LABEL (l) == label)
1993 return true;
1994 return false;
1997 /* Find the last nondebug statement in a scope STMT. */
1999 static gimple *
2000 last_stmt_in_scope (gimple *stmt)
2002 if (!stmt)
2003 return NULL;
2005 switch (gimple_code (stmt))
2007 case GIMPLE_BIND:
2009 gbind *bind = as_a <gbind *> (stmt);
2010 stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
2011 return last_stmt_in_scope (stmt);
2014 case GIMPLE_TRY:
2016 gtry *try_stmt = as_a <gtry *> (stmt);
2017 stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
2018 gimple *last_eval = last_stmt_in_scope (stmt);
2019 if (gimple_stmt_may_fallthru (last_eval)
2020 && (last_eval == NULL
2021 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
2022 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
2024 stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
2025 return last_stmt_in_scope (stmt);
2027 else
2028 return last_eval;
2031 case GIMPLE_DEBUG:
2032 gcc_unreachable ();
2034 default:
2035 return stmt;
2039 /* Collect interesting labels in LABELS and return the statement preceding
2040 another case label, or a user-defined label. Store a location useful
2041 to give warnings at *PREVLOC (usually the location of the returned
2042 statement or of its surrounding scope). */
2044 static gimple *
2045 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
2046 auto_vec <struct label_entry> *labels,
2047 location_t *prevloc)
2049 gimple *prev = NULL;
2051 *prevloc = UNKNOWN_LOCATION;
2054 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
2056 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2057 which starts on a GIMPLE_SWITCH and ends with a break label.
2058 Handle that as a single statement that can fall through. */
2059 gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
2060 gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
2061 gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
2062 if (last
2063 && gimple_code (first) == GIMPLE_SWITCH
2064 && gimple_code (last) == GIMPLE_LABEL)
2066 tree label = gimple_label_label (as_a <glabel *> (last));
2067 if (SWITCH_BREAK_LABEL_P (label))
2069 prev = bind;
2070 gsi_next (gsi_p);
2071 continue;
2075 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
2076 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
2078 /* Nested scope. Only look at the last statement of
2079 the innermost scope. */
2080 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
2081 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
2082 if (last)
2084 prev = last;
2085 /* It might be a label without a location. Use the
2086 location of the scope then. */
2087 if (!gimple_has_location (prev))
2088 *prevloc = bind_loc;
2090 gsi_next (gsi_p);
2091 continue;
2094 /* Ifs are tricky. */
2095 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
2097 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
2098 tree false_lab = gimple_cond_false_label (cond_stmt);
2099 location_t if_loc = gimple_location (cond_stmt);
2101 /* If we have e.g.
2102 if (i > 1) goto <D.2259>; else goto D;
2103 we can't do much with the else-branch. */
2104 if (!DECL_ARTIFICIAL (false_lab))
2105 break;
2107 /* Go on until the false label, then one step back. */
2108 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
2110 gimple *stmt = gsi_stmt (*gsi_p);
2111 if (gimple_code (stmt) == GIMPLE_LABEL
2112 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
2113 break;
2116 /* Not found? Oops. */
2117 if (gsi_end_p (*gsi_p))
2118 break;
2120 struct label_entry l = { false_lab, if_loc };
2121 labels->safe_push (l);
2123 /* Go to the last statement of the then branch. */
2124 gsi_prev (gsi_p);
2126 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2127 <D.1759>:
2128 <stmt>;
2129 goto <D.1761>;
2130 <D.1760>:
2132 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2133 && !gimple_has_location (gsi_stmt (*gsi_p)))
2135 /* Look at the statement before, it might be
2136 attribute fallthrough, in which case don't warn. */
2137 gsi_prev (gsi_p);
2138 bool fallthru_before_dest
2139 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2140 gsi_next (gsi_p);
2141 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2142 if (!fallthru_before_dest)
2144 struct label_entry l = { goto_dest, if_loc };
2145 labels->safe_push (l);
2148 /* And move back. */
2149 gsi_next (gsi_p);
2152 /* Remember the last statement. Skip labels that are of no interest
2153 to us. */
2154 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2156 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2157 if (find_label_entry (labels, label))
2158 prev = gsi_stmt (*gsi_p);
2160 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2162 else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
2164 else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2165 prev = gsi_stmt (*gsi_p);
2166 gsi_next (gsi_p);
2168 while (!gsi_end_p (*gsi_p)
2169 /* Stop if we find a case or a user-defined label. */
2170 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2171 || !gimple_has_location (gsi_stmt (*gsi_p))));
2173 if (prev && gimple_has_location (prev))
2174 *prevloc = gimple_location (prev);
2175 return prev;
2178 /* Return true if the switch fallthough warning should occur. LABEL is
2179 the label statement that we're falling through to. */
2181 static bool
2182 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2184 gimple_stmt_iterator gsi = *gsi_p;
2186 /* Don't warn if the label is marked with a "falls through" comment. */
2187 if (FALLTHROUGH_LABEL_P (label))
2188 return false;
2190 /* Don't warn for non-case labels followed by a statement:
2191 case 0:
2192 foo ();
2193 label:
2194 bar ();
2195 as these are likely intentional. */
2196 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2198 tree l;
2199 while (!gsi_end_p (gsi)
2200 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2201 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2202 && !case_label_p (&gimplify_ctxp->case_labels, l))
2203 gsi_next_nondebug (&gsi);
2204 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2205 return false;
2208 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2209 immediately breaks. */
2210 gsi = *gsi_p;
2212 /* Skip all immediately following labels. */
2213 while (!gsi_end_p (gsi)
2214 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2215 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2216 gsi_next_nondebug (&gsi);
2218 /* { ... something; default:; } */
2219 if (gsi_end_p (gsi)
2220 /* { ... something; default: break; } or
2221 { ... something; default: goto L; } */
2222 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2223 /* { ... something; default: return; } */
2224 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2225 return false;
2227 return true;
2230 /* Callback for walk_gimple_seq. */
2232 static tree
2233 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2234 struct walk_stmt_info *)
2236 gimple *stmt = gsi_stmt (*gsi_p);
2238 *handled_ops_p = true;
2239 switch (gimple_code (stmt))
2241 case GIMPLE_TRY:
2242 case GIMPLE_BIND:
2243 case GIMPLE_CATCH:
2244 case GIMPLE_EH_FILTER:
2245 case GIMPLE_TRANSACTION:
2246 /* Walk the sub-statements. */
2247 *handled_ops_p = false;
2248 break;
2250 /* Find a sequence of form:
2252 GIMPLE_LABEL
2253 [...]
2254 <may fallthru stmt>
2255 GIMPLE_LABEL
2257 and possibly warn. */
2258 case GIMPLE_LABEL:
2260 /* Found a label. Skip all immediately following labels. */
2261 while (!gsi_end_p (*gsi_p)
2262 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2263 gsi_next_nondebug (gsi_p);
2265 /* There might be no more statements. */
2266 if (gsi_end_p (*gsi_p))
2267 return integer_zero_node;
2269 /* Vector of labels that fall through. */
2270 auto_vec <struct label_entry> labels;
2271 location_t prevloc;
2272 gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
2274 /* There might be no more statements. */
2275 if (gsi_end_p (*gsi_p))
2276 return integer_zero_node;
2278 gimple *next = gsi_stmt (*gsi_p);
2279 tree label;
2280 /* If what follows is a label, then we may have a fallthrough. */
2281 if (gimple_code (next) == GIMPLE_LABEL
2282 && gimple_has_location (next)
2283 && (label = gimple_label_label (as_a <glabel *> (next)))
2284 && prev != NULL)
2286 struct label_entry *l;
2287 bool warned_p = false;
2288 auto_diagnostic_group d;
2289 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2290 /* Quiet. */;
2291 else if (gimple_code (prev) == GIMPLE_LABEL
2292 && (label = gimple_label_label (as_a <glabel *> (prev)))
2293 && (l = find_label_entry (&labels, label)))
2294 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2295 "this statement may fall through");
2296 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2297 /* Try to be clever and don't warn when the statement
2298 can't actually fall through. */
2299 && gimple_stmt_may_fallthru (prev)
2300 && prevloc != UNKNOWN_LOCATION)
2301 warned_p = warning_at (prevloc,
2302 OPT_Wimplicit_fallthrough_,
2303 "this statement may fall through");
2304 if (warned_p)
2305 inform (gimple_location (next), "here");
2307 /* Mark this label as processed so as to prevent multiple
2308 warnings in nested switches. */
2309 FALLTHROUGH_LABEL_P (label) = true;
2311 /* So that next warn_implicit_fallthrough_r will start looking for
2312 a new sequence starting with this label. */
2313 gsi_prev (gsi_p);
2316 break;
2317 default:
2318 break;
2320 return NULL_TREE;
2323 /* Warn when a switch case falls through. */
2325 static void
2326 maybe_warn_implicit_fallthrough (gimple_seq seq)
2328 if (!warn_implicit_fallthrough)
2329 return;
2331 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2332 if (!(lang_GNU_C ()
2333 || lang_GNU_CXX ()
2334 || lang_GNU_OBJC ()))
2335 return;
2337 struct walk_stmt_info wi;
2338 memset (&wi, 0, sizeof (wi));
2339 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2342 /* Callback for walk_gimple_seq. */
2344 static tree
2345 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2346 struct walk_stmt_info *wi)
2348 gimple *stmt = gsi_stmt (*gsi_p);
2350 *handled_ops_p = true;
2351 switch (gimple_code (stmt))
2353 case GIMPLE_TRY:
2354 case GIMPLE_BIND:
2355 case GIMPLE_CATCH:
2356 case GIMPLE_EH_FILTER:
2357 case GIMPLE_TRANSACTION:
2358 /* Walk the sub-statements. */
2359 *handled_ops_p = false;
2360 break;
2361 case GIMPLE_CALL:
2362 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2364 gsi_remove (gsi_p, true);
2365 if (gsi_end_p (*gsi_p))
2367 *static_cast<location_t *>(wi->info) = gimple_location (stmt);
2368 return integer_zero_node;
2371 bool found = false;
2372 location_t loc = gimple_location (stmt);
2374 gimple_stmt_iterator gsi2 = *gsi_p;
2375 stmt = gsi_stmt (gsi2);
2376 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2378 /* Go on until the artificial label. */
2379 tree goto_dest = gimple_goto_dest (stmt);
2380 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2382 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2383 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2384 == goto_dest)
2385 break;
2388 /* Not found? Stop. */
2389 if (gsi_end_p (gsi2))
2390 break;
2392 /* Look one past it. */
2393 gsi_next (&gsi2);
2396 /* We're looking for a case label or default label here. */
2397 while (!gsi_end_p (gsi2))
2399 stmt = gsi_stmt (gsi2);
2400 if (gimple_code (stmt) == GIMPLE_LABEL)
2402 tree label = gimple_label_label (as_a <glabel *> (stmt));
2403 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2405 found = true;
2406 break;
2409 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2411 else if (!is_gimple_debug (stmt))
2412 /* Anything else is not expected. */
2413 break;
2414 gsi_next (&gsi2);
2416 if (!found)
2417 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2418 "a case label or default label");
2420 break;
2421 default:
2422 break;
2424 return NULL_TREE;
2427 /* Expand all FALLTHROUGH () calls in SEQ. */
2429 static void
2430 expand_FALLTHROUGH (gimple_seq *seq_p)
2432 struct walk_stmt_info wi;
2433 location_t loc;
2434 memset (&wi, 0, sizeof (wi));
2435 wi.info = (void *) &loc;
2436 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2437 if (wi.callback_result == integer_zero_node)
2438 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2439 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2440 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2441 "a case label or default label");
2445 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2446 branch to. */
2448 static enum gimplify_status
2449 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2451 tree switch_expr = *expr_p;
2452 gimple_seq switch_body_seq = NULL;
2453 enum gimplify_status ret;
2454 tree index_type = TREE_TYPE (switch_expr);
2455 if (index_type == NULL_TREE)
2456 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2458 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2459 fb_rvalue);
2460 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2461 return ret;
2463 if (SWITCH_BODY (switch_expr))
2465 vec<tree> labels;
2466 vec<tree> saved_labels;
2467 hash_set<tree> *saved_live_switch_vars = NULL;
2468 tree default_case = NULL_TREE;
2469 gswitch *switch_stmt;
2471 /* Save old labels, get new ones from body, then restore the old
2472 labels. Save all the things from the switch body to append after. */
2473 saved_labels = gimplify_ctxp->case_labels;
2474 gimplify_ctxp->case_labels.create (8);
2476 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2477 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2478 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2479 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2480 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2481 else
2482 gimplify_ctxp->live_switch_vars = NULL;
2484 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2485 gimplify_ctxp->in_switch_expr = true;
2487 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2489 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2490 maybe_warn_switch_unreachable (switch_body_seq);
2491 maybe_warn_implicit_fallthrough (switch_body_seq);
2492 /* Only do this for the outermost GIMPLE_SWITCH. */
2493 if (!gimplify_ctxp->in_switch_expr)
2494 expand_FALLTHROUGH (&switch_body_seq);
2496 labels = gimplify_ctxp->case_labels;
2497 gimplify_ctxp->case_labels = saved_labels;
2499 if (gimplify_ctxp->live_switch_vars)
2501 gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
2502 delete gimplify_ctxp->live_switch_vars;
2504 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2506 preprocess_case_label_vec_for_gimple (labels, index_type,
2507 &default_case);
2509 bool add_bind = false;
2510 if (!default_case)
2512 glabel *new_default;
2514 default_case
2515 = build_case_label (NULL_TREE, NULL_TREE,
2516 create_artificial_label (UNKNOWN_LOCATION));
2517 if (old_in_switch_expr)
2519 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2520 add_bind = true;
2522 new_default = gimple_build_label (CASE_LABEL (default_case));
2523 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2525 else if (old_in_switch_expr)
2527 gimple *last = gimple_seq_last_stmt (switch_body_seq);
2528 if (last && gimple_code (last) == GIMPLE_LABEL)
2530 tree label = gimple_label_label (as_a <glabel *> (last));
2531 if (SWITCH_BREAK_LABEL_P (label))
2532 add_bind = true;
2536 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2537 default_case, labels);
2538 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2539 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2540 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2541 so that we can easily find the start and end of the switch
2542 statement. */
2543 if (add_bind)
2545 gimple_seq bind_body = NULL;
2546 gimplify_seq_add_stmt (&bind_body, switch_stmt);
2547 gimple_seq_add_seq (&bind_body, switch_body_seq);
2548 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
2549 gimple_set_location (bind, EXPR_LOCATION (switch_expr));
2550 gimplify_seq_add_stmt (pre_p, bind);
2552 else
2554 gimplify_seq_add_stmt (pre_p, switch_stmt);
2555 gimplify_seq_add_seq (pre_p, switch_body_seq);
2557 labels.release ();
2559 else
2560 gcc_unreachable ();
2562 return GS_ALL_DONE;
2565 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2567 static enum gimplify_status
2568 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2570 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2571 == current_function_decl);
2573 tree label = LABEL_EXPR_LABEL (*expr_p);
2574 glabel *label_stmt = gimple_build_label (label);
2575 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2576 gimplify_seq_add_stmt (pre_p, label_stmt);
2578 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2579 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2580 NOT_TAKEN));
2581 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2582 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2583 TAKEN));
2585 return GS_ALL_DONE;
2588 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2590 static enum gimplify_status
2591 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2593 struct gimplify_ctx *ctxp;
2594 glabel *label_stmt;
2596 /* Invalid programs can play Duff's Device type games with, for example,
2597 #pragma omp parallel. At least in the C front end, we don't
2598 detect such invalid branches until after gimplification, in the
2599 diagnose_omp_blocks pass. */
2600 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2601 if (ctxp->case_labels.exists ())
2602 break;
2604 tree label = CASE_LABEL (*expr_p);
2605 label_stmt = gimple_build_label (label);
2606 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2607 ctxp->case_labels.safe_push (*expr_p);
2608 gimplify_seq_add_stmt (pre_p, label_stmt);
2610 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2611 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2612 NOT_TAKEN));
2613 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2614 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2615 TAKEN));
2617 return GS_ALL_DONE;
2620 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2621 if necessary. */
2623 tree
2624 build_and_jump (tree *label_p)
2626 if (label_p == NULL)
2627 /* If there's nowhere to jump, just fall through. */
2628 return NULL_TREE;
2630 if (*label_p == NULL_TREE)
2632 tree label = create_artificial_label (UNKNOWN_LOCATION);
2633 *label_p = label;
2636 return build1 (GOTO_EXPR, void_type_node, *label_p);
2639 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2640 This also involves building a label to jump to and communicating it to
2641 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2643 static enum gimplify_status
2644 gimplify_exit_expr (tree *expr_p)
2646 tree cond = TREE_OPERAND (*expr_p, 0);
2647 tree expr;
2649 expr = build_and_jump (&gimplify_ctxp->exit_label);
2650 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2651 *expr_p = expr;
2653 return GS_OK;
2656 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2657 different from its canonical type, wrap the whole thing inside a
2658 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2659 type.
2661 The canonical type of a COMPONENT_REF is the type of the field being
2662 referenced--unless the field is a bit-field which can be read directly
2663 in a smaller mode, in which case the canonical type is the
2664 sign-appropriate type corresponding to that mode. */
2666 static void
2667 canonicalize_component_ref (tree *expr_p)
2669 tree expr = *expr_p;
2670 tree type;
2672 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2674 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2675 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2676 else
2677 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2679 /* One could argue that all the stuff below is not necessary for
2680 the non-bitfield case and declare it a FE error if type
2681 adjustment would be needed. */
2682 if (TREE_TYPE (expr) != type)
2684 #ifdef ENABLE_TYPES_CHECKING
2685 tree old_type = TREE_TYPE (expr);
2686 #endif
2687 int type_quals;
2689 /* We need to preserve qualifiers and propagate them from
2690 operand 0. */
2691 type_quals = TYPE_QUALS (type)
2692 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2693 if (TYPE_QUALS (type) != type_quals)
2694 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2696 /* Set the type of the COMPONENT_REF to the underlying type. */
2697 TREE_TYPE (expr) = type;
2699 #ifdef ENABLE_TYPES_CHECKING
2700 /* It is now a FE error, if the conversion from the canonical
2701 type to the original expression type is not useless. */
2702 gcc_assert (useless_type_conversion_p (old_type, type));
2703 #endif
2707 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2708 to foo, embed that change in the ADDR_EXPR by converting
2709 T array[U];
2710 (T *)&array
2712 &array[L]
2713 where L is the lower bound. For simplicity, only do this for constant
2714 lower bound.
2715 The constraint is that the type of &array[L] is trivially convertible
2716 to T *. */
2718 static void
2719 canonicalize_addr_expr (tree *expr_p)
2721 tree expr = *expr_p;
2722 tree addr_expr = TREE_OPERAND (expr, 0);
2723 tree datype, ddatype, pddatype;
2725 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2726 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2727 || TREE_CODE (addr_expr) != ADDR_EXPR)
2728 return;
2730 /* The addr_expr type should be a pointer to an array. */
2731 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2732 if (TREE_CODE (datype) != ARRAY_TYPE)
2733 return;
2735 /* The pointer to element type shall be trivially convertible to
2736 the expression pointer type. */
2737 ddatype = TREE_TYPE (datype);
2738 pddatype = build_pointer_type (ddatype);
2739 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2740 pddatype))
2741 return;
2743 /* The lower bound and element sizes must be constant. */
2744 if (!TYPE_SIZE_UNIT (ddatype)
2745 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2746 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2747 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2748 return;
2750 /* All checks succeeded. Build a new node to merge the cast. */
2751 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2752 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2753 NULL_TREE, NULL_TREE);
2754 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2756 /* We can have stripped a required restrict qualifier above. */
2757 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2758 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2761 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2762 underneath as appropriate. */
2764 static enum gimplify_status
2765 gimplify_conversion (tree *expr_p)
2767 location_t loc = EXPR_LOCATION (*expr_p);
2768 gcc_assert (CONVERT_EXPR_P (*expr_p));
2770 /* Then strip away all but the outermost conversion. */
2771 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
2773 /* And remove the outermost conversion if it's useless. */
2774 if (tree_ssa_useless_type_conversion (*expr_p))
2775 *expr_p = TREE_OPERAND (*expr_p, 0);
2777 /* If we still have a conversion at the toplevel,
2778 then canonicalize some constructs. */
2779 if (CONVERT_EXPR_P (*expr_p))
2781 tree sub = TREE_OPERAND (*expr_p, 0);
2783 /* If a NOP conversion is changing the type of a COMPONENT_REF
2784 expression, then canonicalize its type now in order to expose more
2785 redundant conversions. */
2786 if (TREE_CODE (sub) == COMPONENT_REF)
2787 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
2789 /* If a NOP conversion is changing a pointer to array of foo
2790 to a pointer to foo, embed that change in the ADDR_EXPR. */
2791 else if (TREE_CODE (sub) == ADDR_EXPR)
2792 canonicalize_addr_expr (expr_p);
2795 /* If we have a conversion to a non-register type force the
2796 use of a VIEW_CONVERT_EXPR instead. */
2797 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
2798 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
2799 TREE_OPERAND (*expr_p, 0));
2801 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2802 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
2803 TREE_SET_CODE (*expr_p, NOP_EXPR);
2805 return GS_OK;
2808 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2809 DECL_VALUE_EXPR, and it's worth re-examining things. */
2811 static enum gimplify_status
2812 gimplify_var_or_parm_decl (tree *expr_p)
2814 tree decl = *expr_p;
2816 /* ??? If this is a local variable, and it has not been seen in any
2817 outer BIND_EXPR, then it's probably the result of a duplicate
2818 declaration, for which we've already issued an error. It would
2819 be really nice if the front end wouldn't leak these at all.
2820 Currently the only known culprit is C++ destructors, as seen
2821 in g++.old-deja/g++.jason/binding.C. */
2822 if (VAR_P (decl)
2823 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
2824 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
2825 && decl_function_context (decl) == current_function_decl)
2827 gcc_assert (seen_error ());
2828 return GS_ERROR;
2831 /* When within an OMP context, notice uses of variables. */
2832 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
2833 return GS_ALL_DONE;
2835 /* If the decl is an alias for another expression, substitute it now. */
2836 if (DECL_HAS_VALUE_EXPR_P (decl))
2838 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
2839 return GS_OK;
2842 return GS_ALL_DONE;
2845 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2847 static void
2848 recalculate_side_effects (tree t)
2850 enum tree_code code = TREE_CODE (t);
2851 int len = TREE_OPERAND_LENGTH (t);
2852 int i;
2854 switch (TREE_CODE_CLASS (code))
2856 case tcc_expression:
2857 switch (code)
2859 case INIT_EXPR:
2860 case MODIFY_EXPR:
2861 case VA_ARG_EXPR:
2862 case PREDECREMENT_EXPR:
2863 case PREINCREMENT_EXPR:
2864 case POSTDECREMENT_EXPR:
2865 case POSTINCREMENT_EXPR:
2866 /* All of these have side-effects, no matter what their
2867 operands are. */
2868 return;
2870 default:
2871 break;
2873 /* Fall through. */
2875 case tcc_comparison: /* a comparison expression */
2876 case tcc_unary: /* a unary arithmetic expression */
2877 case tcc_binary: /* a binary arithmetic expression */
2878 case tcc_reference: /* a reference */
2879 case tcc_vl_exp: /* a function call */
2880 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
2881 for (i = 0; i < len; ++i)
2883 tree op = TREE_OPERAND (t, i);
2884 if (op && TREE_SIDE_EFFECTS (op))
2885 TREE_SIDE_EFFECTS (t) = 1;
2887 break;
2889 case tcc_constant:
2890 /* No side-effects. */
2891 return;
2893 default:
2894 gcc_unreachable ();
2898 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
2899 node *EXPR_P.
2901 compound_lval
2902 : min_lval '[' val ']'
2903 | min_lval '.' ID
2904 | compound_lval '[' val ']'
2905 | compound_lval '.' ID
2907 This is not part of the original SIMPLE definition, which separates
2908 array and member references, but it seems reasonable to handle them
2909 together. Also, this way we don't run into problems with union
2910 aliasing; gcc requires that for accesses through a union to alias, the
2911 union reference must be explicit, which was not always the case when we
2912 were splitting up array and member refs.
2914 PRE_P points to the sequence where side effects that must happen before
2915 *EXPR_P should be stored.
2917 POST_P points to the sequence where side effects that must happen after
2918 *EXPR_P should be stored. */
2920 static enum gimplify_status
2921 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2922 fallback_t fallback)
2924 tree *p;
2925 enum gimplify_status ret = GS_ALL_DONE, tret;
2926 int i;
2927 location_t loc = EXPR_LOCATION (*expr_p);
2928 tree expr = *expr_p;
2930 /* Create a stack of the subexpressions so later we can walk them in
2931 order from inner to outer. */
2932 auto_vec<tree, 10> expr_stack;
2934 /* We can handle anything that get_inner_reference can deal with. */
2935 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
2937 restart:
2938 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
2939 if (TREE_CODE (*p) == INDIRECT_REF)
2940 *p = fold_indirect_ref_loc (loc, *p);
2942 if (handled_component_p (*p))
2944 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
2945 additional COMPONENT_REFs. */
2946 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
2947 && gimplify_var_or_parm_decl (p) == GS_OK)
2948 goto restart;
2949 else
2950 break;
2952 expr_stack.safe_push (*p);
2955 gcc_assert (expr_stack.length ());
2957 /* Now EXPR_STACK is a stack of pointers to all the refs we've
2958 walked through and P points to the innermost expression.
2960 Java requires that we elaborated nodes in source order. That
2961 means we must gimplify the inner expression followed by each of
2962 the indices, in order. But we can't gimplify the inner
2963 expression until we deal with any variable bounds, sizes, or
2964 positions in order to deal with PLACEHOLDER_EXPRs.
2966 So we do this in three steps. First we deal with the annotations
2967 for any variables in the components, then we gimplify the base,
2968 then we gimplify any indices, from left to right. */
2969 for (i = expr_stack.length () - 1; i >= 0; i--)
2971 tree t = expr_stack[i];
2973 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2975 /* Gimplify the low bound and element type size and put them into
2976 the ARRAY_REF. If these values are set, they have already been
2977 gimplified. */
2978 if (TREE_OPERAND (t, 2) == NULL_TREE)
2980 tree low = unshare_expr (array_ref_low_bound (t));
2981 if (!is_gimple_min_invariant (low))
2983 TREE_OPERAND (t, 2) = low;
2984 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
2985 post_p, is_gimple_reg,
2986 fb_rvalue);
2987 ret = MIN (ret, tret);
2990 else
2992 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
2993 is_gimple_reg, fb_rvalue);
2994 ret = MIN (ret, tret);
2997 if (TREE_OPERAND (t, 3) == NULL_TREE)
2999 tree elmt_size = array_ref_element_size (t);
3000 if (!is_gimple_min_invariant (elmt_size))
3002 elmt_size = unshare_expr (elmt_size);
3003 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
3004 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
3006 /* Divide the element size by the alignment of the element
3007 type (above). */
3008 elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR,
3009 elmt_size, factor);
3011 TREE_OPERAND (t, 3) = elmt_size;
3012 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
3013 post_p, is_gimple_reg,
3014 fb_rvalue);
3015 ret = MIN (ret, tret);
3018 else
3020 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
3021 is_gimple_reg, fb_rvalue);
3022 ret = MIN (ret, tret);
3025 else if (TREE_CODE (t) == COMPONENT_REF)
3027 /* Set the field offset into T and gimplify it. */
3028 if (TREE_OPERAND (t, 2) == NULL_TREE)
3030 tree offset = component_ref_field_offset (t);
3031 if (!is_gimple_min_invariant (offset))
3033 offset = unshare_expr (offset);
3034 tree field = TREE_OPERAND (t, 1);
3035 tree factor
3036 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
3038 /* Divide the offset by its alignment. */
3039 offset = size_binop_loc (loc, EXACT_DIV_EXPR,
3040 offset, factor);
3042 TREE_OPERAND (t, 2) = offset;
3043 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
3044 post_p, is_gimple_reg,
3045 fb_rvalue);
3046 ret = MIN (ret, tret);
3049 else
3051 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3052 is_gimple_reg, fb_rvalue);
3053 ret = MIN (ret, tret);
3058 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3059 so as to match the min_lval predicate. Failure to do so may result
3060 in the creation of large aggregate temporaries. */
3061 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
3062 fallback | fb_lvalue);
3063 ret = MIN (ret, tret);
3065 /* And finally, the indices and operands of ARRAY_REF. During this
3066 loop we also remove any useless conversions. */
3067 for (; expr_stack.length () > 0; )
3069 tree t = expr_stack.pop ();
3071 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3073 /* Gimplify the dimension. */
3074 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
3076 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
3077 is_gimple_val, fb_rvalue);
3078 ret = MIN (ret, tret);
3082 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
3084 /* The innermost expression P may have originally had
3085 TREE_SIDE_EFFECTS set which would have caused all the outer
3086 expressions in *EXPR_P leading to P to also have had
3087 TREE_SIDE_EFFECTS set. */
3088 recalculate_side_effects (t);
3091 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3092 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
3094 canonicalize_component_ref (expr_p);
3097 expr_stack.release ();
3099 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
3101 return ret;
3104 /* Gimplify the self modifying expression pointed to by EXPR_P
3105 (++, --, +=, -=).
3107 PRE_P points to the list where side effects that must happen before
3108 *EXPR_P should be stored.
3110 POST_P points to the list where side effects that must happen after
3111 *EXPR_P should be stored.
3113 WANT_VALUE is nonzero iff we want to use the value of this expression
3114 in another expression.
3116 ARITH_TYPE is the type the computation should be performed in. */
3118 enum gimplify_status
3119 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3120 bool want_value, tree arith_type)
3122 enum tree_code code;
3123 tree lhs, lvalue, rhs, t1;
3124 gimple_seq post = NULL, *orig_post_p = post_p;
3125 bool postfix;
3126 enum tree_code arith_code;
3127 enum gimplify_status ret;
3128 location_t loc = EXPR_LOCATION (*expr_p);
3130 code = TREE_CODE (*expr_p);
3132 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3133 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3135 /* Prefix or postfix? */
3136 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3137 /* Faster to treat as prefix if result is not used. */
3138 postfix = want_value;
3139 else
3140 postfix = false;
3142 /* For postfix, make sure the inner expression's post side effects
3143 are executed after side effects from this expression. */
3144 if (postfix)
3145 post_p = &post;
3147 /* Add or subtract? */
3148 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3149 arith_code = PLUS_EXPR;
3150 else
3151 arith_code = MINUS_EXPR;
3153 /* Gimplify the LHS into a GIMPLE lvalue. */
3154 lvalue = TREE_OPERAND (*expr_p, 0);
3155 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3156 if (ret == GS_ERROR)
3157 return ret;
3159 /* Extract the operands to the arithmetic operation. */
3160 lhs = lvalue;
3161 rhs = TREE_OPERAND (*expr_p, 1);
3163 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3164 that as the result value and in the postqueue operation. */
3165 if (postfix)
3167 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3168 if (ret == GS_ERROR)
3169 return ret;
3171 lhs = get_initialized_tmp_var (lhs, pre_p);
3174 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3175 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3177 rhs = convert_to_ptrofftype_loc (loc, rhs);
3178 if (arith_code == MINUS_EXPR)
3179 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3180 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3182 else
3183 t1 = fold_convert (TREE_TYPE (*expr_p),
3184 fold_build2 (arith_code, arith_type,
3185 fold_convert (arith_type, lhs),
3186 fold_convert (arith_type, rhs)));
3188 if (postfix)
3190 gimplify_assign (lvalue, t1, pre_p);
3191 gimplify_seq_add_seq (orig_post_p, post);
3192 *expr_p = lhs;
3193 return GS_ALL_DONE;
3195 else
3197 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3198 return GS_OK;
3202 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3204 static void
3205 maybe_with_size_expr (tree *expr_p)
3207 tree expr = *expr_p;
3208 tree type = TREE_TYPE (expr);
3209 tree size;
3211 /* If we've already wrapped this or the type is error_mark_node, we can't do
3212 anything. */
3213 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3214 || type == error_mark_node)
3215 return;
3217 /* If the size isn't known or is a constant, we have nothing to do. */
3218 size = TYPE_SIZE_UNIT (type);
3219 if (!size || poly_int_tree_p (size))
3220 return;
3222 /* Otherwise, make a WITH_SIZE_EXPR. */
3223 size = unshare_expr (size);
3224 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3225 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3228 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3229 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3230 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3231 gimplified to an SSA name. */
3233 enum gimplify_status
3234 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3235 bool allow_ssa)
3237 bool (*test) (tree);
3238 fallback_t fb;
3240 /* In general, we allow lvalues for function arguments to avoid
3241 extra overhead of copying large aggregates out of even larger
3242 aggregates into temporaries only to copy the temporaries to
3243 the argument list. Make optimizers happy by pulling out to
3244 temporaries those types that fit in registers. */
3245 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3246 test = is_gimple_val, fb = fb_rvalue;
3247 else
3249 test = is_gimple_lvalue, fb = fb_either;
3250 /* Also strip a TARGET_EXPR that would force an extra copy. */
3251 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3253 tree init = TARGET_EXPR_INITIAL (*arg_p);
3254 if (init
3255 && !VOID_TYPE_P (TREE_TYPE (init)))
3256 *arg_p = init;
3260 /* If this is a variable sized type, we must remember the size. */
3261 maybe_with_size_expr (arg_p);
3263 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3264 /* Make sure arguments have the same location as the function call
3265 itself. */
3266 protected_set_expr_location (*arg_p, call_location);
3268 /* There is a sequence point before a function call. Side effects in
3269 the argument list must occur before the actual call. So, when
3270 gimplifying arguments, force gimplify_expr to use an internal
3271 post queue which is then appended to the end of PRE_P. */
3272 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3275 /* Don't fold inside offloading or taskreg regions: it can break code by
3276 adding decl references that weren't in the source. We'll do it during
3277 omplower pass instead. */
3279 static bool
3280 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3282 struct gimplify_omp_ctx *ctx;
3283 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3284 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3285 return false;
3286 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3287 return false;
3288 /* Delay folding of builtins until the IL is in consistent state
3289 so the diagnostic machinery can do a better job. */
3290 if (gimple_call_builtin_p (gsi_stmt (*gsi)))
3291 return false;
3292 return fold_stmt (gsi);
3295 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3296 WANT_VALUE is true if the result of the call is desired. */
3298 static enum gimplify_status
3299 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3301 tree fndecl, parms, p, fnptrtype;
3302 enum gimplify_status ret;
3303 int i, nargs;
3304 gcall *call;
3305 bool builtin_va_start_p = false;
3306 location_t loc = EXPR_LOCATION (*expr_p);
3308 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3310 /* For reliable diagnostics during inlining, it is necessary that
3311 every call_expr be annotated with file and line. */
3312 if (! EXPR_HAS_LOCATION (*expr_p))
3313 SET_EXPR_LOCATION (*expr_p, input_location);
3315 /* Gimplify internal functions created in the FEs. */
3316 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3318 if (want_value)
3319 return GS_ALL_DONE;
3321 nargs = call_expr_nargs (*expr_p);
3322 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3323 auto_vec<tree> vargs (nargs);
3325 for (i = 0; i < nargs; i++)
3327 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3328 EXPR_LOCATION (*expr_p));
3329 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3332 gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3333 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3334 gimplify_seq_add_stmt (pre_p, call);
3335 return GS_ALL_DONE;
3338 /* This may be a call to a builtin function.
3340 Builtin function calls may be transformed into different
3341 (and more efficient) builtin function calls under certain
3342 circumstances. Unfortunately, gimplification can muck things
3343 up enough that the builtin expanders are not aware that certain
3344 transformations are still valid.
3346 So we attempt transformation/gimplification of the call before
3347 we gimplify the CALL_EXPR. At this time we do not manage to
3348 transform all calls in the same manner as the expanders do, but
3349 we do transform most of them. */
3350 fndecl = get_callee_fndecl (*expr_p);
3351 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3352 switch (DECL_FUNCTION_CODE (fndecl))
3354 CASE_BUILT_IN_ALLOCA:
3355 /* If the call has been built for a variable-sized object, then we
3356 want to restore the stack level when the enclosing BIND_EXPR is
3357 exited to reclaim the allocated space; otherwise, we precisely
3358 need to do the opposite and preserve the latest stack level. */
3359 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3360 gimplify_ctxp->save_stack = true;
3361 else
3362 gimplify_ctxp->keep_stack = true;
3363 break;
3365 case BUILT_IN_VA_START:
3367 builtin_va_start_p = TRUE;
3368 if (call_expr_nargs (*expr_p) < 2)
3370 error ("too few arguments to function %<va_start%>");
3371 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3372 return GS_OK;
3375 if (fold_builtin_next_arg (*expr_p, true))
3377 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3378 return GS_OK;
3380 break;
3383 case BUILT_IN_EH_RETURN:
3384 cfun->calls_eh_return = true;
3385 break;
3387 default:
3390 if (fndecl && fndecl_built_in_p (fndecl))
3392 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3393 if (new_tree && new_tree != *expr_p)
3395 /* There was a transformation of this call which computes the
3396 same value, but in a more efficient way. Return and try
3397 again. */
3398 *expr_p = new_tree;
3399 return GS_OK;
3403 /* Remember the original function pointer type. */
3404 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3406 if (flag_openmp
3407 && fndecl
3408 && cfun
3409 && (cfun->curr_properties & PROP_gimple_any) == 0)
3411 tree variant = omp_resolve_declare_variant (fndecl);
3412 if (variant != fndecl)
3413 CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
3416 /* There is a sequence point before the call, so any side effects in
3417 the calling expression must occur before the actual call. Force
3418 gimplify_expr to use an internal post queue. */
3419 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3420 is_gimple_call_addr, fb_rvalue);
3422 nargs = call_expr_nargs (*expr_p);
3424 /* Get argument types for verification. */
3425 fndecl = get_callee_fndecl (*expr_p);
3426 parms = NULL_TREE;
3427 if (fndecl)
3428 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3429 else
3430 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3432 if (fndecl && DECL_ARGUMENTS (fndecl))
3433 p = DECL_ARGUMENTS (fndecl);
3434 else if (parms)
3435 p = parms;
3436 else
3437 p = NULL_TREE;
3438 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3441 /* If the last argument is __builtin_va_arg_pack () and it is not
3442 passed as a named argument, decrease the number of CALL_EXPR
3443 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3444 if (!p
3445 && i < nargs
3446 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3448 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3449 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3451 if (last_arg_fndecl
3452 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3454 tree call = *expr_p;
3456 --nargs;
3457 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3458 CALL_EXPR_FN (call),
3459 nargs, CALL_EXPR_ARGP (call));
3461 /* Copy all CALL_EXPR flags, location and block, except
3462 CALL_EXPR_VA_ARG_PACK flag. */
3463 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3464 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3465 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3466 = CALL_EXPR_RETURN_SLOT_OPT (call);
3467 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3468 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3470 /* Set CALL_EXPR_VA_ARG_PACK. */
3471 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3475 /* If the call returns twice then after building the CFG the call
3476 argument computations will no longer dominate the call because
3477 we add an abnormal incoming edge to the call. So do not use SSA
3478 vars there. */
3479 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3481 /* Gimplify the function arguments. */
3482 if (nargs > 0)
3484 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3485 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3486 PUSH_ARGS_REVERSED ? i-- : i++)
3488 enum gimplify_status t;
3490 /* Avoid gimplifying the second argument to va_start, which needs to
3491 be the plain PARM_DECL. */
3492 if ((i != 1) || !builtin_va_start_p)
3494 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3495 EXPR_LOCATION (*expr_p), ! returns_twice);
3497 if (t == GS_ERROR)
3498 ret = GS_ERROR;
3503 /* Gimplify the static chain. */
3504 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3506 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3507 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3508 else
3510 enum gimplify_status t;
3511 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3512 EXPR_LOCATION (*expr_p), ! returns_twice);
3513 if (t == GS_ERROR)
3514 ret = GS_ERROR;
3518 /* Verify the function result. */
3519 if (want_value && fndecl
3520 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3522 error_at (loc, "using result of function returning %<void%>");
3523 ret = GS_ERROR;
3526 /* Try this again in case gimplification exposed something. */
3527 if (ret != GS_ERROR)
3529 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3531 if (new_tree && new_tree != *expr_p)
3533 /* There was a transformation of this call which computes the
3534 same value, but in a more efficient way. Return and try
3535 again. */
3536 *expr_p = new_tree;
3537 return GS_OK;
3540 else
3542 *expr_p = error_mark_node;
3543 return GS_ERROR;
3546 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3547 decl. This allows us to eliminate redundant or useless
3548 calls to "const" functions. */
3549 if (TREE_CODE (*expr_p) == CALL_EXPR)
3551 int flags = call_expr_flags (*expr_p);
3552 if (flags & (ECF_CONST | ECF_PURE)
3553 /* An infinite loop is considered a side effect. */
3554 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3555 TREE_SIDE_EFFECTS (*expr_p) = 0;
3558 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3559 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3560 form and delegate the creation of a GIMPLE_CALL to
3561 gimplify_modify_expr. This is always possible because when
3562 WANT_VALUE is true, the caller wants the result of this call into
3563 a temporary, which means that we will emit an INIT_EXPR in
3564 internal_get_tmp_var which will then be handled by
3565 gimplify_modify_expr. */
3566 if (!want_value)
3568 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3569 have to do is replicate it as a GIMPLE_CALL tuple. */
3570 gimple_stmt_iterator gsi;
3571 call = gimple_build_call_from_tree (*expr_p, fnptrtype);
3572 notice_special_calls (call);
3573 gimplify_seq_add_stmt (pre_p, call);
3574 gsi = gsi_last (*pre_p);
3575 maybe_fold_stmt (&gsi);
3576 *expr_p = NULL_TREE;
3578 else
3579 /* Remember the original function type. */
3580 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3581 CALL_EXPR_FN (*expr_p));
3583 return ret;
3586 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3587 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3589 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3590 condition is true or false, respectively. If null, we should generate
3591 our own to skip over the evaluation of this specific expression.
3593 LOCUS is the source location of the COND_EXPR.
3595 This function is the tree equivalent of do_jump.
3597 shortcut_cond_r should only be called by shortcut_cond_expr. */
3599 static tree
3600 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3601 location_t locus)
3603 tree local_label = NULL_TREE;
3604 tree t, expr = NULL;
3606 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3607 retain the shortcut semantics. Just insert the gotos here;
3608 shortcut_cond_expr will append the real blocks later. */
3609 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3611 location_t new_locus;
3613 /* Turn if (a && b) into
3615 if (a); else goto no;
3616 if (b) goto yes; else goto no;
3617 (no:) */
3619 if (false_label_p == NULL)
3620 false_label_p = &local_label;
3622 /* Keep the original source location on the first 'if'. */
3623 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3624 append_to_statement_list (t, &expr);
3626 /* Set the source location of the && on the second 'if'. */
3627 new_locus = rexpr_location (pred, locus);
3628 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3629 new_locus);
3630 append_to_statement_list (t, &expr);
3632 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3634 location_t new_locus;
3636 /* Turn if (a || b) into
3638 if (a) goto yes;
3639 if (b) goto yes; else goto no;
3640 (yes:) */
3642 if (true_label_p == NULL)
3643 true_label_p = &local_label;
3645 /* Keep the original source location on the first 'if'. */
3646 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3647 append_to_statement_list (t, &expr);
3649 /* Set the source location of the || on the second 'if'. */
3650 new_locus = rexpr_location (pred, locus);
3651 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3652 new_locus);
3653 append_to_statement_list (t, &expr);
3655 else if (TREE_CODE (pred) == COND_EXPR
3656 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3657 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3659 location_t new_locus;
3661 /* As long as we're messing with gotos, turn if (a ? b : c) into
3662 if (a)
3663 if (b) goto yes; else goto no;
3664 else
3665 if (c) goto yes; else goto no;
3667 Don't do this if one of the arms has void type, which can happen
3668 in C++ when the arm is throw. */
3670 /* Keep the original source location on the first 'if'. Set the source
3671 location of the ? on the second 'if'. */
3672 new_locus = rexpr_location (pred, locus);
3673 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3674 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3675 false_label_p, locus),
3676 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3677 false_label_p, new_locus));
3679 else
3681 expr = build3 (COND_EXPR, void_type_node, pred,
3682 build_and_jump (true_label_p),
3683 build_and_jump (false_label_p));
3684 SET_EXPR_LOCATION (expr, locus);
3687 if (local_label)
3689 t = build1 (LABEL_EXPR, void_type_node, local_label);
3690 append_to_statement_list (t, &expr);
3693 return expr;
3696 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3697 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3698 statement, if it is the last one. Otherwise, return NULL. */
3700 static tree
3701 find_goto (tree expr)
3703 if (!expr)
3704 return NULL_TREE;
3706 if (TREE_CODE (expr) == GOTO_EXPR)
3707 return expr;
3709 if (TREE_CODE (expr) != STATEMENT_LIST)
3710 return NULL_TREE;
3712 tree_stmt_iterator i = tsi_start (expr);
3714 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
3715 tsi_next (&i);
3717 if (!tsi_one_before_end_p (i))
3718 return NULL_TREE;
3720 return find_goto (tsi_stmt (i));
3723 /* Same as find_goto, except that it returns NULL if the destination
3724 is not a LABEL_DECL. */
3726 static inline tree
3727 find_goto_label (tree expr)
3729 tree dest = find_goto (expr);
3730 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
3731 return dest;
3732 return NULL_TREE;
3735 /* Given a conditional expression EXPR with short-circuit boolean
3736 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3737 predicate apart into the equivalent sequence of conditionals. */
3739 static tree
3740 shortcut_cond_expr (tree expr)
3742 tree pred = TREE_OPERAND (expr, 0);
3743 tree then_ = TREE_OPERAND (expr, 1);
3744 tree else_ = TREE_OPERAND (expr, 2);
3745 tree true_label, false_label, end_label, t;
3746 tree *true_label_p;
3747 tree *false_label_p;
3748 bool emit_end, emit_false, jump_over_else;
3749 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3750 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3752 /* First do simple transformations. */
3753 if (!else_se)
3755 /* If there is no 'else', turn
3756 if (a && b) then c
3757 into
3758 if (a) if (b) then c. */
3759 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3761 /* Keep the original source location on the first 'if'. */
3762 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3763 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3764 /* Set the source location of the && on the second 'if'. */
3765 if (rexpr_has_location (pred))
3766 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3767 then_ = shortcut_cond_expr (expr);
3768 then_se = then_ && TREE_SIDE_EFFECTS (then_);
3769 pred = TREE_OPERAND (pred, 0);
3770 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
3771 SET_EXPR_LOCATION (expr, locus);
3775 if (!then_se)
3777 /* If there is no 'then', turn
3778 if (a || b); else d
3779 into
3780 if (a); else if (b); else d. */
3781 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3783 /* Keep the original source location on the first 'if'. */
3784 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3785 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3786 /* Set the source location of the || on the second 'if'. */
3787 if (rexpr_has_location (pred))
3788 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3789 else_ = shortcut_cond_expr (expr);
3790 else_se = else_ && TREE_SIDE_EFFECTS (else_);
3791 pred = TREE_OPERAND (pred, 0);
3792 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
3793 SET_EXPR_LOCATION (expr, locus);
3797 /* If we're done, great. */
3798 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
3799 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
3800 return expr;
3802 /* Otherwise we need to mess with gotos. Change
3803 if (a) c; else d;
3805 if (a); else goto no;
3806 c; goto end;
3807 no: d; end:
3808 and recursively gimplify the condition. */
3810 true_label = false_label = end_label = NULL_TREE;
3812 /* If our arms just jump somewhere, hijack those labels so we don't
3813 generate jumps to jumps. */
3815 if (tree then_goto = find_goto_label (then_))
3817 true_label = GOTO_DESTINATION (then_goto);
3818 then_ = NULL;
3819 then_se = false;
3822 if (tree else_goto = find_goto_label (else_))
3824 false_label = GOTO_DESTINATION (else_goto);
3825 else_ = NULL;
3826 else_se = false;
3829 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3830 if (true_label)
3831 true_label_p = &true_label;
3832 else
3833 true_label_p = NULL;
3835 /* The 'else' branch also needs a label if it contains interesting code. */
3836 if (false_label || else_se)
3837 false_label_p = &false_label;
3838 else
3839 false_label_p = NULL;
3841 /* If there was nothing else in our arms, just forward the label(s). */
3842 if (!then_se && !else_se)
3843 return shortcut_cond_r (pred, true_label_p, false_label_p,
3844 EXPR_LOC_OR_LOC (expr, input_location));
3846 /* If our last subexpression already has a terminal label, reuse it. */
3847 if (else_se)
3848 t = expr_last (else_);
3849 else if (then_se)
3850 t = expr_last (then_);
3851 else
3852 t = NULL;
3853 if (t && TREE_CODE (t) == LABEL_EXPR)
3854 end_label = LABEL_EXPR_LABEL (t);
3856 /* If we don't care about jumping to the 'else' branch, jump to the end
3857 if the condition is false. */
3858 if (!false_label_p)
3859 false_label_p = &end_label;
3861 /* We only want to emit these labels if we aren't hijacking them. */
3862 emit_end = (end_label == NULL_TREE);
3863 emit_false = (false_label == NULL_TREE);
3865 /* We only emit the jump over the else clause if we have to--if the
3866 then clause may fall through. Otherwise we can wind up with a
3867 useless jump and a useless label at the end of gimplified code,
3868 which will cause us to think that this conditional as a whole
3869 falls through even if it doesn't. If we then inline a function
3870 which ends with such a condition, that can cause us to issue an
3871 inappropriate warning about control reaching the end of a
3872 non-void function. */
3873 jump_over_else = block_may_fallthru (then_);
3875 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
3876 EXPR_LOC_OR_LOC (expr, input_location));
3878 expr = NULL;
3879 append_to_statement_list (pred, &expr);
3881 append_to_statement_list (then_, &expr);
3882 if (else_se)
3884 if (jump_over_else)
3886 tree last = expr_last (expr);
3887 t = build_and_jump (&end_label);
3888 if (rexpr_has_location (last))
3889 SET_EXPR_LOCATION (t, rexpr_location (last));
3890 append_to_statement_list (t, &expr);
3892 if (emit_false)
3894 t = build1 (LABEL_EXPR, void_type_node, false_label);
3895 append_to_statement_list (t, &expr);
3897 append_to_statement_list (else_, &expr);
3899 if (emit_end && end_label)
3901 t = build1 (LABEL_EXPR, void_type_node, end_label);
3902 append_to_statement_list (t, &expr);
3905 return expr;
3908 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
3910 tree
3911 gimple_boolify (tree expr)
3913 tree type = TREE_TYPE (expr);
3914 location_t loc = EXPR_LOCATION (expr);
3916 if (TREE_CODE (expr) == NE_EXPR
3917 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
3918 && integer_zerop (TREE_OPERAND (expr, 1)))
3920 tree call = TREE_OPERAND (expr, 0);
3921 tree fn = get_callee_fndecl (call);
3923 /* For __builtin_expect ((long) (x), y) recurse into x as well
3924 if x is truth_value_p. */
3925 if (fn
3926 && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
3927 && call_expr_nargs (call) == 2)
3929 tree arg = CALL_EXPR_ARG (call, 0);
3930 if (arg)
3932 if (TREE_CODE (arg) == NOP_EXPR
3933 && TREE_TYPE (arg) == TREE_TYPE (call))
3934 arg = TREE_OPERAND (arg, 0);
3935 if (truth_value_p (TREE_CODE (arg)))
3937 arg = gimple_boolify (arg);
3938 CALL_EXPR_ARG (call, 0)
3939 = fold_convert_loc (loc, TREE_TYPE (call), arg);
3945 switch (TREE_CODE (expr))
3947 case TRUTH_AND_EXPR:
3948 case TRUTH_OR_EXPR:
3949 case TRUTH_XOR_EXPR:
3950 case TRUTH_ANDIF_EXPR:
3951 case TRUTH_ORIF_EXPR:
3952 /* Also boolify the arguments of truth exprs. */
3953 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
3954 /* FALLTHRU */
3956 case TRUTH_NOT_EXPR:
3957 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3959 /* These expressions always produce boolean results. */
3960 if (TREE_CODE (type) != BOOLEAN_TYPE)
3961 TREE_TYPE (expr) = boolean_type_node;
3962 return expr;
3964 case ANNOTATE_EXPR:
3965 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
3967 case annot_expr_ivdep_kind:
3968 case annot_expr_unroll_kind:
3969 case annot_expr_no_vector_kind:
3970 case annot_expr_vector_kind:
3971 case annot_expr_parallel_kind:
3972 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3973 if (TREE_CODE (type) != BOOLEAN_TYPE)
3974 TREE_TYPE (expr) = boolean_type_node;
3975 return expr;
3976 default:
3977 gcc_unreachable ();
3980 default:
3981 if (COMPARISON_CLASS_P (expr))
3983 /* There expressions always prduce boolean results. */
3984 if (TREE_CODE (type) != BOOLEAN_TYPE)
3985 TREE_TYPE (expr) = boolean_type_node;
3986 return expr;
3988 /* Other expressions that get here must have boolean values, but
3989 might need to be converted to the appropriate mode. */
3990 if (TREE_CODE (type) == BOOLEAN_TYPE)
3991 return expr;
3992 return fold_convert_loc (loc, boolean_type_node, expr);
3996 /* Given a conditional expression *EXPR_P without side effects, gimplify
3997 its operands. New statements are inserted to PRE_P. */
3999 static enum gimplify_status
4000 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
4002 tree expr = *expr_p, cond;
4003 enum gimplify_status ret, tret;
4004 enum tree_code code;
4006 cond = gimple_boolify (COND_EXPR_COND (expr));
4008 /* We need to handle && and || specially, as their gimplification
4009 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4010 code = TREE_CODE (cond);
4011 if (code == TRUTH_ANDIF_EXPR)
4012 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
4013 else if (code == TRUTH_ORIF_EXPR)
4014 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
4015 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
4016 COND_EXPR_COND (*expr_p) = cond;
4018 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
4019 is_gimple_val, fb_rvalue);
4020 ret = MIN (ret, tret);
4021 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
4022 is_gimple_val, fb_rvalue);
4024 return MIN (ret, tret);
4027 /* Return true if evaluating EXPR could trap.
4028 EXPR is GENERIC, while tree_could_trap_p can be called
4029 only on GIMPLE. */
4031 bool
4032 generic_expr_could_trap_p (tree expr)
4034 unsigned i, n;
4036 if (!expr || is_gimple_val (expr))
4037 return false;
4039 if (!EXPR_P (expr) || tree_could_trap_p (expr))
4040 return true;
4042 n = TREE_OPERAND_LENGTH (expr);
4043 for (i = 0; i < n; i++)
4044 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
4045 return true;
4047 return false;
4050 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4051 into
4053 if (p) if (p)
4054 t1 = a; a;
4055 else or else
4056 t1 = b; b;
4059 The second form is used when *EXPR_P is of type void.
4061 PRE_P points to the list where side effects that must happen before
4062 *EXPR_P should be stored. */
4064 static enum gimplify_status
4065 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
4067 tree expr = *expr_p;
4068 tree type = TREE_TYPE (expr);
4069 location_t loc = EXPR_LOCATION (expr);
4070 tree tmp, arm1, arm2;
4071 enum gimplify_status ret;
4072 tree label_true, label_false, label_cont;
4073 bool have_then_clause_p, have_else_clause_p;
4074 gcond *cond_stmt;
4075 enum tree_code pred_code;
4076 gimple_seq seq = NULL;
4078 /* If this COND_EXPR has a value, copy the values into a temporary within
4079 the arms. */
4080 if (!VOID_TYPE_P (type))
4082 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
4083 tree result;
4085 /* If either an rvalue is ok or we do not require an lvalue, create the
4086 temporary. But we cannot do that if the type is addressable. */
4087 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
4088 && !TREE_ADDRESSABLE (type))
4090 if (gimplify_ctxp->allow_rhs_cond_expr
4091 /* If either branch has side effects or could trap, it can't be
4092 evaluated unconditionally. */
4093 && !TREE_SIDE_EFFECTS (then_)
4094 && !generic_expr_could_trap_p (then_)
4095 && !TREE_SIDE_EFFECTS (else_)
4096 && !generic_expr_could_trap_p (else_))
4097 return gimplify_pure_cond_expr (expr_p, pre_p);
4099 tmp = create_tmp_var (type, "iftmp");
4100 result = tmp;
4103 /* Otherwise, only create and copy references to the values. */
4104 else
4106 type = build_pointer_type (type);
4108 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4109 then_ = build_fold_addr_expr_loc (loc, then_);
4111 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4112 else_ = build_fold_addr_expr_loc (loc, else_);
4114 expr
4115 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
4117 tmp = create_tmp_var (type, "iftmp");
4118 result = build_simple_mem_ref_loc (loc, tmp);
4121 /* Build the new then clause, `tmp = then_;'. But don't build the
4122 assignment if the value is void; in C++ it can be if it's a throw. */
4123 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4124 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
4126 /* Similarly, build the new else clause, `tmp = else_;'. */
4127 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4128 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
4130 TREE_TYPE (expr) = void_type_node;
4131 recalculate_side_effects (expr);
4133 /* Move the COND_EXPR to the prequeue. */
4134 gimplify_stmt (&expr, pre_p);
4136 *expr_p = result;
4137 return GS_ALL_DONE;
4140 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4141 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4142 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4143 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4145 /* Make sure the condition has BOOLEAN_TYPE. */
4146 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4148 /* Break apart && and || conditions. */
4149 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4150 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4152 expr = shortcut_cond_expr (expr);
4154 if (expr != *expr_p)
4156 *expr_p = expr;
4158 /* We can't rely on gimplify_expr to re-gimplify the expanded
4159 form properly, as cleanups might cause the target labels to be
4160 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4161 set up a conditional context. */
4162 gimple_push_condition ();
4163 gimplify_stmt (expr_p, &seq);
4164 gimple_pop_condition (pre_p);
4165 gimple_seq_add_seq (pre_p, seq);
4167 return GS_ALL_DONE;
4171 /* Now do the normal gimplification. */
4173 /* Gimplify condition. */
4174 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
4175 is_gimple_condexpr_for_cond, fb_rvalue);
4176 if (ret == GS_ERROR)
4177 return GS_ERROR;
4178 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4180 gimple_push_condition ();
4182 have_then_clause_p = have_else_clause_p = false;
4183 label_true = find_goto_label (TREE_OPERAND (expr, 1));
4184 if (label_true
4185 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4186 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4187 have different locations, otherwise we end up with incorrect
4188 location information on the branches. */
4189 && (optimize
4190 || !EXPR_HAS_LOCATION (expr)
4191 || !rexpr_has_location (label_true)
4192 || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4194 have_then_clause_p = true;
4195 label_true = GOTO_DESTINATION (label_true);
4197 else
4198 label_true = create_artificial_label (UNKNOWN_LOCATION);
4199 label_false = find_goto_label (TREE_OPERAND (expr, 2));
4200 if (label_false
4201 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4202 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4203 have different locations, otherwise we end up with incorrect
4204 location information on the branches. */
4205 && (optimize
4206 || !EXPR_HAS_LOCATION (expr)
4207 || !rexpr_has_location (label_false)
4208 || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4210 have_else_clause_p = true;
4211 label_false = GOTO_DESTINATION (label_false);
4213 else
4214 label_false = create_artificial_label (UNKNOWN_LOCATION);
4216 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4217 &arm2);
4218 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4219 label_false);
4220 gimple_set_no_warning (cond_stmt, TREE_NO_WARNING (COND_EXPR_COND (expr)));
4221 gimplify_seq_add_stmt (&seq, cond_stmt);
4222 gimple_stmt_iterator gsi = gsi_last (seq);
4223 maybe_fold_stmt (&gsi);
4225 label_cont = NULL_TREE;
4226 if (!have_then_clause_p)
4228 /* For if (...) {} else { code; } put label_true after
4229 the else block. */
4230 if (TREE_OPERAND (expr, 1) == NULL_TREE
4231 && !have_else_clause_p
4232 && TREE_OPERAND (expr, 2) != NULL_TREE)
4233 label_cont = label_true;
4234 else
4236 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4237 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4238 /* For if (...) { code; } else {} or
4239 if (...) { code; } else goto label; or
4240 if (...) { code; return; } else { ... }
4241 label_cont isn't needed. */
4242 if (!have_else_clause_p
4243 && TREE_OPERAND (expr, 2) != NULL_TREE
4244 && gimple_seq_may_fallthru (seq))
4246 gimple *g;
4247 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4249 g = gimple_build_goto (label_cont);
4251 /* GIMPLE_COND's are very low level; they have embedded
4252 gotos. This particular embedded goto should not be marked
4253 with the location of the original COND_EXPR, as it would
4254 correspond to the COND_EXPR's condition, not the ELSE or the
4255 THEN arms. To avoid marking it with the wrong location, flag
4256 it as "no location". */
4257 gimple_set_do_not_emit_location (g);
4259 gimplify_seq_add_stmt (&seq, g);
4263 if (!have_else_clause_p)
4265 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4266 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4268 if (label_cont)
4269 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4271 gimple_pop_condition (pre_p);
4272 gimple_seq_add_seq (pre_p, seq);
4274 if (ret == GS_ERROR)
4275 ; /* Do nothing. */
4276 else if (have_then_clause_p || have_else_clause_p)
4277 ret = GS_ALL_DONE;
4278 else
4280 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4281 expr = TREE_OPERAND (expr, 0);
4282 gimplify_stmt (&expr, pre_p);
4285 *expr_p = NULL;
4286 return ret;
4289 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4290 to be marked addressable.
4292 We cannot rely on such an expression being directly markable if a temporary
4293 has been created by the gimplification. In this case, we create another
4294 temporary and initialize it with a copy, which will become a store after we
4295 mark it addressable. This can happen if the front-end passed us something
4296 that it could not mark addressable yet, like a Fortran pass-by-reference
4297 parameter (int) floatvar. */
4299 static void
4300 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4302 while (handled_component_p (*expr_p))
4303 expr_p = &TREE_OPERAND (*expr_p, 0);
4304 if (is_gimple_reg (*expr_p))
4306 /* Do not allow an SSA name as the temporary. */
4307 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
4308 DECL_NOT_GIMPLE_REG_P (var) = 1;
4309 *expr_p = var;
4313 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4314 a call to __builtin_memcpy. */
4316 static enum gimplify_status
4317 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4318 gimple_seq *seq_p)
4320 tree t, to, to_ptr, from, from_ptr;
4321 gcall *gs;
4322 location_t loc = EXPR_LOCATION (*expr_p);
4324 to = TREE_OPERAND (*expr_p, 0);
4325 from = TREE_OPERAND (*expr_p, 1);
4327 /* Mark the RHS addressable. Beware that it may not be possible to do so
4328 directly if a temporary has been created by the gimplification. */
4329 prepare_gimple_addressable (&from, seq_p);
4331 mark_addressable (from);
4332 from_ptr = build_fold_addr_expr_loc (loc, from);
4333 gimplify_arg (&from_ptr, seq_p, loc);
4335 mark_addressable (to);
4336 to_ptr = build_fold_addr_expr_loc (loc, to);
4337 gimplify_arg (&to_ptr, seq_p, loc);
4339 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4341 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4342 gimple_call_set_alloca_for_var (gs, true);
4344 if (want_value)
4346 /* tmp = memcpy() */
4347 t = create_tmp_var (TREE_TYPE (to_ptr));
4348 gimple_call_set_lhs (gs, t);
4349 gimplify_seq_add_stmt (seq_p, gs);
4351 *expr_p = build_simple_mem_ref (t);
4352 return GS_ALL_DONE;
4355 gimplify_seq_add_stmt (seq_p, gs);
4356 *expr_p = NULL;
4357 return GS_ALL_DONE;
4360 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4361 a call to __builtin_memset. In this case we know that the RHS is
4362 a CONSTRUCTOR with an empty element list. */
4364 static enum gimplify_status
4365 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4366 gimple_seq *seq_p)
4368 tree t, from, to, to_ptr;
4369 gcall *gs;
4370 location_t loc = EXPR_LOCATION (*expr_p);
4372 /* Assert our assumptions, to abort instead of producing wrong code
4373 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4374 not be immediately exposed. */
4375 from = TREE_OPERAND (*expr_p, 1);
4376 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4377 from = TREE_OPERAND (from, 0);
4379 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4380 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4382 /* Now proceed. */
4383 to = TREE_OPERAND (*expr_p, 0);
4385 to_ptr = build_fold_addr_expr_loc (loc, to);
4386 gimplify_arg (&to_ptr, seq_p, loc);
4387 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4389 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4391 if (want_value)
4393 /* tmp = memset() */
4394 t = create_tmp_var (TREE_TYPE (to_ptr));
4395 gimple_call_set_lhs (gs, t);
4396 gimplify_seq_add_stmt (seq_p, gs);
4398 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4399 return GS_ALL_DONE;
4402 gimplify_seq_add_stmt (seq_p, gs);
4403 *expr_p = NULL;
4404 return GS_ALL_DONE;
4407 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4408 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4409 assignment. Return non-null if we detect a potential overlap. */
4411 struct gimplify_init_ctor_preeval_data
4413 /* The base decl of the lhs object. May be NULL, in which case we
4414 have to assume the lhs is indirect. */
4415 tree lhs_base_decl;
4417 /* The alias set of the lhs object. */
4418 alias_set_type lhs_alias_set;
4421 static tree
4422 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4424 struct gimplify_init_ctor_preeval_data *data
4425 = (struct gimplify_init_ctor_preeval_data *) xdata;
4426 tree t = *tp;
4428 /* If we find the base object, obviously we have overlap. */
4429 if (data->lhs_base_decl == t)
4430 return t;
4432 /* If the constructor component is indirect, determine if we have a
4433 potential overlap with the lhs. The only bits of information we
4434 have to go on at this point are addressability and alias sets. */
4435 if ((INDIRECT_REF_P (t)
4436 || TREE_CODE (t) == MEM_REF)
4437 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4438 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4439 return t;
4441 /* If the constructor component is a call, determine if it can hide a
4442 potential overlap with the lhs through an INDIRECT_REF like above.
4443 ??? Ugh - this is completely broken. In fact this whole analysis
4444 doesn't look conservative. */
4445 if (TREE_CODE (t) == CALL_EXPR)
4447 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4449 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4450 if (POINTER_TYPE_P (TREE_VALUE (type))
4451 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4452 && alias_sets_conflict_p (data->lhs_alias_set,
4453 get_alias_set
4454 (TREE_TYPE (TREE_VALUE (type)))))
4455 return t;
4458 if (IS_TYPE_OR_DECL_P (t))
4459 *walk_subtrees = 0;
4460 return NULL;
4463 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4464 force values that overlap with the lhs (as described by *DATA)
4465 into temporaries. */
4467 static void
4468 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4469 struct gimplify_init_ctor_preeval_data *data)
4471 enum gimplify_status one;
4473 /* If the value is constant, then there's nothing to pre-evaluate. */
4474 if (TREE_CONSTANT (*expr_p))
4476 /* Ensure it does not have side effects, it might contain a reference to
4477 the object we're initializing. */
4478 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4479 return;
4482 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4483 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4484 return;
4486 /* Recurse for nested constructors. */
4487 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4489 unsigned HOST_WIDE_INT ix;
4490 constructor_elt *ce;
4491 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4493 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4494 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4496 return;
4499 /* If this is a variable sized type, we must remember the size. */
4500 maybe_with_size_expr (expr_p);
4502 /* Gimplify the constructor element to something appropriate for the rhs
4503 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4504 the gimplifier will consider this a store to memory. Doing this
4505 gimplification now means that we won't have to deal with complicated
4506 language-specific trees, nor trees like SAVE_EXPR that can induce
4507 exponential search behavior. */
4508 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4509 if (one == GS_ERROR)
4511 *expr_p = NULL;
4512 return;
4515 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4516 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4517 always be true for all scalars, since is_gimple_mem_rhs insists on a
4518 temporary variable for them. */
4519 if (DECL_P (*expr_p))
4520 return;
4522 /* If this is of variable size, we have no choice but to assume it doesn't
4523 overlap since we can't make a temporary for it. */
4524 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4525 return;
4527 /* Otherwise, we must search for overlap ... */
4528 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4529 return;
4531 /* ... and if found, force the value into a temporary. */
4532 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4535 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4536 a RANGE_EXPR in a CONSTRUCTOR for an array.
4538 var = lower;
4539 loop_entry:
4540 object[var] = value;
4541 if (var == upper)
4542 goto loop_exit;
4543 var = var + 1;
4544 goto loop_entry;
4545 loop_exit:
4547 We increment var _after_ the loop exit check because we might otherwise
4548 fail if upper == TYPE_MAX_VALUE (type for upper).
4550 Note that we never have to deal with SAVE_EXPRs here, because this has
4551 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4553 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4554 gimple_seq *, bool);
4556 static void
4557 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4558 tree value, tree array_elt_type,
4559 gimple_seq *pre_p, bool cleared)
4561 tree loop_entry_label, loop_exit_label, fall_thru_label;
4562 tree var, var_type, cref, tmp;
4564 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4565 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4566 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4568 /* Create and initialize the index variable. */
4569 var_type = TREE_TYPE (upper);
4570 var = create_tmp_var (var_type);
4571 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4573 /* Add the loop entry label. */
4574 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4576 /* Build the reference. */
4577 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4578 var, NULL_TREE, NULL_TREE);
4580 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4581 the store. Otherwise just assign value to the reference. */
4583 if (TREE_CODE (value) == CONSTRUCTOR)
4584 /* NB we might have to call ourself recursively through
4585 gimplify_init_ctor_eval if the value is a constructor. */
4586 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4587 pre_p, cleared);
4588 else
4589 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4591 /* We exit the loop when the index var is equal to the upper bound. */
4592 gimplify_seq_add_stmt (pre_p,
4593 gimple_build_cond (EQ_EXPR, var, upper,
4594 loop_exit_label, fall_thru_label));
4596 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4598 /* Otherwise, increment the index var... */
4599 tmp = build2 (PLUS_EXPR, var_type, var,
4600 fold_convert (var_type, integer_one_node));
4601 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4603 /* ...and jump back to the loop entry. */
4604 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4606 /* Add the loop exit label. */
4607 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4610 /* Return true if FDECL is accessing a field that is zero sized. */
4612 static bool
4613 zero_sized_field_decl (const_tree fdecl)
4615 if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl)
4616 && integer_zerop (DECL_SIZE (fdecl)))
4617 return true;
4618 return false;
4621 /* Return true if TYPE is zero sized. */
4623 static bool
4624 zero_sized_type (const_tree type)
4626 if (AGGREGATE_TYPE_P (type) && TYPE_SIZE (type)
4627 && integer_zerop (TYPE_SIZE (type)))
4628 return true;
4629 return false;
4632 /* A subroutine of gimplify_init_constructor. Generate individual
4633 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4634 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4635 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4636 zeroed first. */
4638 static void
4639 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4640 gimple_seq *pre_p, bool cleared)
4642 tree array_elt_type = NULL;
4643 unsigned HOST_WIDE_INT ix;
4644 tree purpose, value;
4646 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4647 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4649 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4651 tree cref;
4653 /* NULL values are created above for gimplification errors. */
4654 if (value == NULL)
4655 continue;
4657 if (cleared && initializer_zerop (value))
4658 continue;
4660 /* ??? Here's to hoping the front end fills in all of the indices,
4661 so we don't have to figure out what's missing ourselves. */
4662 gcc_assert (purpose);
4664 /* Skip zero-sized fields, unless value has side-effects. This can
4665 happen with calls to functions returning a zero-sized type, which
4666 we shouldn't discard. As a number of downstream passes don't
4667 expect sets of zero-sized fields, we rely on the gimplification of
4668 the MODIFY_EXPR we make below to drop the assignment statement. */
4669 if (! TREE_SIDE_EFFECTS (value) && zero_sized_field_decl (purpose))
4670 continue;
4672 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4673 whole range. */
4674 if (TREE_CODE (purpose) == RANGE_EXPR)
4676 tree lower = TREE_OPERAND (purpose, 0);
4677 tree upper = TREE_OPERAND (purpose, 1);
4679 /* If the lower bound is equal to upper, just treat it as if
4680 upper was the index. */
4681 if (simple_cst_equal (lower, upper))
4682 purpose = upper;
4683 else
4685 gimplify_init_ctor_eval_range (object, lower, upper, value,
4686 array_elt_type, pre_p, cleared);
4687 continue;
4691 if (array_elt_type)
4693 /* Do not use bitsizetype for ARRAY_REF indices. */
4694 if (TYPE_DOMAIN (TREE_TYPE (object)))
4695 purpose
4696 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4697 purpose);
4698 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4699 purpose, NULL_TREE, NULL_TREE);
4701 else
4703 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4704 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4705 unshare_expr (object), purpose, NULL_TREE);
4708 if (TREE_CODE (value) == CONSTRUCTOR
4709 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4710 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4711 pre_p, cleared);
4712 else
4714 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4715 gimplify_and_add (init, pre_p);
4716 ggc_free (init);
4721 /* Return the appropriate RHS predicate for this LHS. */
4723 gimple_predicate
4724 rhs_predicate_for (tree lhs)
4726 if (is_gimple_reg (lhs))
4727 return is_gimple_reg_rhs_or_call;
4728 else
4729 return is_gimple_mem_rhs_or_call;
4732 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4733 before the LHS has been gimplified. */
4735 static gimple_predicate
4736 initial_rhs_predicate_for (tree lhs)
4738 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4739 return is_gimple_reg_rhs_or_call;
4740 else
4741 return is_gimple_mem_rhs_or_call;
4744 /* Gimplify a C99 compound literal expression. This just means adding
4745 the DECL_EXPR before the current statement and using its anonymous
4746 decl instead. */
4748 static enum gimplify_status
4749 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
4750 bool (*gimple_test_f) (tree),
4751 fallback_t fallback)
4753 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
4754 tree decl = DECL_EXPR_DECL (decl_s);
4755 tree init = DECL_INITIAL (decl);
4756 /* Mark the decl as addressable if the compound literal
4757 expression is addressable now, otherwise it is marked too late
4758 after we gimplify the initialization expression. */
4759 if (TREE_ADDRESSABLE (*expr_p))
4760 TREE_ADDRESSABLE (decl) = 1;
4761 /* Otherwise, if we don't need an lvalue and have a literal directly
4762 substitute it. Check if it matches the gimple predicate, as
4763 otherwise we'd generate a new temporary, and we can as well just
4764 use the decl we already have. */
4765 else if (!TREE_ADDRESSABLE (decl)
4766 && !TREE_THIS_VOLATILE (decl)
4767 && init
4768 && (fallback & fb_lvalue) == 0
4769 && gimple_test_f (init))
4771 *expr_p = init;
4772 return GS_OK;
4775 /* If the decl is not addressable, then it is being used in some
4776 expression or on the right hand side of a statement, and it can
4777 be put into a readonly data section. */
4778 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
4779 TREE_READONLY (decl) = 1;
4781 /* This decl isn't mentioned in the enclosing block, so add it to the
4782 list of temps. FIXME it seems a bit of a kludge to say that
4783 anonymous artificial vars aren't pushed, but everything else is. */
4784 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
4785 gimple_add_tmp_var (decl);
4787 gimplify_and_add (decl_s, pre_p);
4788 *expr_p = decl;
4789 return GS_OK;
4792 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4793 return a new CONSTRUCTOR if something changed. */
4795 static tree
4796 optimize_compound_literals_in_ctor (tree orig_ctor)
4798 tree ctor = orig_ctor;
4799 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
4800 unsigned int idx, num = vec_safe_length (elts);
4802 for (idx = 0; idx < num; idx++)
4804 tree value = (*elts)[idx].value;
4805 tree newval = value;
4806 if (TREE_CODE (value) == CONSTRUCTOR)
4807 newval = optimize_compound_literals_in_ctor (value);
4808 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
4810 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
4811 tree decl = DECL_EXPR_DECL (decl_s);
4812 tree init = DECL_INITIAL (decl);
4814 if (!TREE_ADDRESSABLE (value)
4815 && !TREE_ADDRESSABLE (decl)
4816 && init
4817 && TREE_CODE (init) == CONSTRUCTOR)
4818 newval = optimize_compound_literals_in_ctor (init);
4820 if (newval == value)
4821 continue;
4823 if (ctor == orig_ctor)
4825 ctor = copy_node (orig_ctor);
4826 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
4827 elts = CONSTRUCTOR_ELTS (ctor);
4829 (*elts)[idx].value = newval;
4831 return ctor;
4834 /* A subroutine of gimplify_modify_expr. Break out elements of a
4835 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4837 Note that we still need to clear any elements that don't have explicit
4838 initializers, so if not all elements are initialized we keep the
4839 original MODIFY_EXPR, we just remove all of the constructor elements.
4841 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4842 GS_ERROR if we would have to create a temporary when gimplifying
4843 this constructor. Otherwise, return GS_OK.
4845 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4847 static enum gimplify_status
4848 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4849 bool want_value, bool notify_temp_creation)
4851 tree object, ctor, type;
4852 enum gimplify_status ret;
4853 vec<constructor_elt, va_gc> *elts;
4855 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
4857 if (!notify_temp_creation)
4859 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
4860 is_gimple_lvalue, fb_lvalue);
4861 if (ret == GS_ERROR)
4862 return ret;
4865 object = TREE_OPERAND (*expr_p, 0);
4866 ctor = TREE_OPERAND (*expr_p, 1)
4867 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
4868 type = TREE_TYPE (ctor);
4869 elts = CONSTRUCTOR_ELTS (ctor);
4870 ret = GS_ALL_DONE;
4872 switch (TREE_CODE (type))
4874 case RECORD_TYPE:
4875 case UNION_TYPE:
4876 case QUAL_UNION_TYPE:
4877 case ARRAY_TYPE:
4879 /* Use readonly data for initializers of this or smaller size
4880 regardless of the num_nonzero_elements / num_unique_nonzero_elements
4881 ratio. */
4882 const HOST_WIDE_INT min_unique_size = 64;
4883 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
4884 is smaller than this, use readonly data. */
4885 const int unique_nonzero_ratio = 8;
4886 /* True if a single access of the object must be ensured. This is the
4887 case if the target is volatile, the type is non-addressable and more
4888 than one field need to be assigned. */
4889 const bool ensure_single_access
4890 = TREE_THIS_VOLATILE (object)
4891 && !TREE_ADDRESSABLE (type)
4892 && vec_safe_length (elts) > 1;
4893 struct gimplify_init_ctor_preeval_data preeval_data;
4894 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
4895 HOST_WIDE_INT num_unique_nonzero_elements;
4896 bool cleared, complete_p, valid_const_initializer;
4898 /* Aggregate types must lower constructors to initialization of
4899 individual elements. The exception is that a CONSTRUCTOR node
4900 with no elements indicates zero-initialization of the whole. */
4901 if (vec_safe_is_empty (elts))
4903 if (notify_temp_creation)
4904 return GS_OK;
4905 break;
4908 /* Fetch information about the constructor to direct later processing.
4909 We might want to make static versions of it in various cases, and
4910 can only do so if it known to be a valid constant initializer. */
4911 valid_const_initializer
4912 = categorize_ctor_elements (ctor, &num_nonzero_elements,
4913 &num_unique_nonzero_elements,
4914 &num_ctor_elements, &complete_p);
4916 /* If a const aggregate variable is being initialized, then it
4917 should never be a lose to promote the variable to be static. */
4918 if (valid_const_initializer
4919 && num_nonzero_elements > 1
4920 && TREE_READONLY (object)
4921 && VAR_P (object)
4922 && !DECL_REGISTER (object)
4923 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))
4924 /* For ctors that have many repeated nonzero elements
4925 represented through RANGE_EXPRs, prefer initializing
4926 those through runtime loops over copies of large amounts
4927 of data from readonly data section. */
4928 && (num_unique_nonzero_elements
4929 > num_nonzero_elements / unique_nonzero_ratio
4930 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
4931 <= (unsigned HOST_WIDE_INT) min_unique_size)))
4933 if (notify_temp_creation)
4934 return GS_ERROR;
4936 DECL_INITIAL (object) = ctor;
4937 TREE_STATIC (object) = 1;
4938 if (!DECL_NAME (object))
4939 DECL_NAME (object) = create_tmp_var_name ("C");
4940 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
4942 /* ??? C++ doesn't automatically append a .<number> to the
4943 assembler name, and even when it does, it looks at FE private
4944 data structures to figure out what that number should be,
4945 which are not set for this variable. I suppose this is
4946 important for local statics for inline functions, which aren't
4947 "local" in the object file sense. So in order to get a unique
4948 TU-local symbol, we must invoke the lhd version now. */
4949 lhd_set_decl_assembler_name (object);
4951 *expr_p = NULL_TREE;
4952 break;
4955 /* If there are "lots" of initialized elements, even discounting
4956 those that are not address constants (and thus *must* be
4957 computed at runtime), then partition the constructor into
4958 constant and non-constant parts. Block copy the constant
4959 parts in, then generate code for the non-constant parts. */
4960 /* TODO. There's code in cp/typeck.c to do this. */
4962 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
4963 /* store_constructor will ignore the clearing of variable-sized
4964 objects. Initializers for such objects must explicitly set
4965 every field that needs to be set. */
4966 cleared = false;
4967 else if (!complete_p)
4968 /* If the constructor isn't complete, clear the whole object
4969 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
4971 ??? This ought not to be needed. For any element not present
4972 in the initializer, we should simply set them to zero. Except
4973 we'd need to *find* the elements that are not present, and that
4974 requires trickery to avoid quadratic compile-time behavior in
4975 large cases or excessive memory use in small cases. */
4976 cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
4977 else if (num_ctor_elements - num_nonzero_elements
4978 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
4979 && num_nonzero_elements < num_ctor_elements / 4)
4980 /* If there are "lots" of zeros, it's more efficient to clear
4981 the memory and then set the nonzero elements. */
4982 cleared = true;
4983 else if (ensure_single_access && num_nonzero_elements == 0)
4984 /* If a single access to the target must be ensured and all elements
4985 are zero, then it's optimal to clear whatever their number. */
4986 cleared = true;
4987 else
4988 cleared = false;
4990 /* If there are "lots" of initialized elements, and all of them
4991 are valid address constants, then the entire initializer can
4992 be dropped to memory, and then memcpy'd out. Don't do this
4993 for sparse arrays, though, as it's more efficient to follow
4994 the standard CONSTRUCTOR behavior of memset followed by
4995 individual element initialization. Also don't do this for small
4996 all-zero initializers (which aren't big enough to merit
4997 clearing), and don't try to make bitwise copies of
4998 TREE_ADDRESSABLE types. */
4999 if (valid_const_initializer
5000 && complete_p
5001 && !(cleared || num_nonzero_elements == 0)
5002 && !TREE_ADDRESSABLE (type))
5004 HOST_WIDE_INT size = int_size_in_bytes (type);
5005 unsigned int align;
5007 /* ??? We can still get unbounded array types, at least
5008 from the C++ front end. This seems wrong, but attempt
5009 to work around it for now. */
5010 if (size < 0)
5012 size = int_size_in_bytes (TREE_TYPE (object));
5013 if (size >= 0)
5014 TREE_TYPE (ctor) = type = TREE_TYPE (object);
5017 /* Find the maximum alignment we can assume for the object. */
5018 /* ??? Make use of DECL_OFFSET_ALIGN. */
5019 if (DECL_P (object))
5020 align = DECL_ALIGN (object);
5021 else
5022 align = TYPE_ALIGN (type);
5024 /* Do a block move either if the size is so small as to make
5025 each individual move a sub-unit move on average, or if it
5026 is so large as to make individual moves inefficient. */
5027 if (size > 0
5028 && num_nonzero_elements > 1
5029 /* For ctors that have many repeated nonzero elements
5030 represented through RANGE_EXPRs, prefer initializing
5031 those through runtime loops over copies of large amounts
5032 of data from readonly data section. */
5033 && (num_unique_nonzero_elements
5034 > num_nonzero_elements / unique_nonzero_ratio
5035 || size <= min_unique_size)
5036 && (size < num_nonzero_elements
5037 || !can_move_by_pieces (size, align)))
5039 if (notify_temp_creation)
5040 return GS_ERROR;
5042 walk_tree (&ctor, force_labels_r, NULL, NULL);
5043 ctor = tree_output_constant_def (ctor);
5044 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
5045 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
5046 TREE_OPERAND (*expr_p, 1) = ctor;
5048 /* This is no longer an assignment of a CONSTRUCTOR, but
5049 we still may have processing to do on the LHS. So
5050 pretend we didn't do anything here to let that happen. */
5051 return GS_UNHANDLED;
5055 /* If a single access to the target must be ensured and there are
5056 nonzero elements or the zero elements are not assigned en masse,
5057 initialize the target from a temporary. */
5058 if (ensure_single_access && (num_nonzero_elements > 0 || !cleared))
5060 if (notify_temp_creation)
5061 return GS_ERROR;
5063 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
5064 TREE_OPERAND (*expr_p, 0) = temp;
5065 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
5066 *expr_p,
5067 build2 (MODIFY_EXPR, void_type_node,
5068 object, temp));
5069 return GS_OK;
5072 if (notify_temp_creation)
5073 return GS_OK;
5075 /* If there are nonzero elements and if needed, pre-evaluate to capture
5076 elements overlapping with the lhs into temporaries. We must do this
5077 before clearing to fetch the values before they are zeroed-out. */
5078 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
5080 preeval_data.lhs_base_decl = get_base_address (object);
5081 if (!DECL_P (preeval_data.lhs_base_decl))
5082 preeval_data.lhs_base_decl = NULL;
5083 preeval_data.lhs_alias_set = get_alias_set (object);
5085 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
5086 pre_p, post_p, &preeval_data);
5089 bool ctor_has_side_effects_p
5090 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
5092 if (cleared)
5094 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5095 Note that we still have to gimplify, in order to handle the
5096 case of variable sized types. Avoid shared tree structures. */
5097 CONSTRUCTOR_ELTS (ctor) = NULL;
5098 TREE_SIDE_EFFECTS (ctor) = 0;
5099 object = unshare_expr (object);
5100 gimplify_stmt (expr_p, pre_p);
5103 /* If we have not block cleared the object, or if there are nonzero
5104 elements in the constructor, or if the constructor has side effects,
5105 add assignments to the individual scalar fields of the object. */
5106 if (!cleared
5107 || num_nonzero_elements > 0
5108 || ctor_has_side_effects_p)
5109 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
5111 *expr_p = NULL_TREE;
5113 break;
5115 case COMPLEX_TYPE:
5117 tree r, i;
5119 if (notify_temp_creation)
5120 return GS_OK;
5122 /* Extract the real and imaginary parts out of the ctor. */
5123 gcc_assert (elts->length () == 2);
5124 r = (*elts)[0].value;
5125 i = (*elts)[1].value;
5126 if (r == NULL || i == NULL)
5128 tree zero = build_zero_cst (TREE_TYPE (type));
5129 if (r == NULL)
5130 r = zero;
5131 if (i == NULL)
5132 i = zero;
5135 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5136 represent creation of a complex value. */
5137 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
5139 ctor = build_complex (type, r, i);
5140 TREE_OPERAND (*expr_p, 1) = ctor;
5142 else
5144 ctor = build2 (COMPLEX_EXPR, type, r, i);
5145 TREE_OPERAND (*expr_p, 1) = ctor;
5146 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
5147 pre_p,
5148 post_p,
5149 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
5150 fb_rvalue);
5153 break;
5155 case VECTOR_TYPE:
5157 unsigned HOST_WIDE_INT ix;
5158 constructor_elt *ce;
5160 if (notify_temp_creation)
5161 return GS_OK;
5163 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5164 if (TREE_CONSTANT (ctor))
5166 bool constant_p = true;
5167 tree value;
5169 /* Even when ctor is constant, it might contain non-*_CST
5170 elements, such as addresses or trapping values like
5171 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5172 in VECTOR_CST nodes. */
5173 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5174 if (!CONSTANT_CLASS_P (value))
5176 constant_p = false;
5177 break;
5180 if (constant_p)
5182 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5183 break;
5186 TREE_CONSTANT (ctor) = 0;
5189 /* Vector types use CONSTRUCTOR all the way through gimple
5190 compilation as a general initializer. */
5191 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5193 enum gimplify_status tret;
5194 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5195 fb_rvalue);
5196 if (tret == GS_ERROR)
5197 ret = GS_ERROR;
5198 else if (TREE_STATIC (ctor)
5199 && !initializer_constant_valid_p (ce->value,
5200 TREE_TYPE (ce->value)))
5201 TREE_STATIC (ctor) = 0;
5203 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5204 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5206 break;
5208 default:
5209 /* So how did we get a CONSTRUCTOR for a scalar type? */
5210 gcc_unreachable ();
5213 if (ret == GS_ERROR)
5214 return GS_ERROR;
5215 /* If we have gimplified both sides of the initializer but have
5216 not emitted an assignment, do so now. */
5217 if (*expr_p)
5219 tree lhs = TREE_OPERAND (*expr_p, 0);
5220 tree rhs = TREE_OPERAND (*expr_p, 1);
5221 if (want_value && object == lhs)
5222 lhs = unshare_expr (lhs);
5223 gassign *init = gimple_build_assign (lhs, rhs);
5224 gimplify_seq_add_stmt (pre_p, init);
5226 if (want_value)
5228 *expr_p = object;
5229 return GS_OK;
5231 else
5233 *expr_p = NULL;
5234 return GS_ALL_DONE;
5238 /* Given a pointer value OP0, return a simplified version of an
5239 indirection through OP0, or NULL_TREE if no simplification is
5240 possible. This may only be applied to a rhs of an expression.
5241 Note that the resulting type may be different from the type pointed
5242 to in the sense that it is still compatible from the langhooks
5243 point of view. */
5245 static tree
5246 gimple_fold_indirect_ref_rhs (tree t)
5248 return gimple_fold_indirect_ref (t);
5251 /* Subroutine of gimplify_modify_expr to do simplifications of
5252 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5253 something changes. */
5255 static enum gimplify_status
5256 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5257 gimple_seq *pre_p, gimple_seq *post_p,
5258 bool want_value)
5260 enum gimplify_status ret = GS_UNHANDLED;
5261 bool changed;
5265 changed = false;
5266 switch (TREE_CODE (*from_p))
5268 case VAR_DECL:
5269 /* If we're assigning from a read-only variable initialized with
5270 a constructor and not volatile, do the direct assignment from
5271 the constructor, but only if the target is not volatile either
5272 since this latter assignment might end up being done on a per
5273 field basis. However, if the target is volatile and the type
5274 is aggregate and non-addressable, gimplify_init_constructor
5275 knows that it needs to ensure a single access to the target
5276 and it will return GS_OK only in this case. */
5277 if (TREE_READONLY (*from_p)
5278 && DECL_INITIAL (*from_p)
5279 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR
5280 && !TREE_THIS_VOLATILE (*from_p)
5281 && (!TREE_THIS_VOLATILE (*to_p)
5282 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p))
5283 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p)))))
5285 tree old_from = *from_p;
5286 enum gimplify_status subret;
5288 /* Move the constructor into the RHS. */
5289 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5291 /* Let's see if gimplify_init_constructor will need to put
5292 it in memory. */
5293 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5294 false, true);
5295 if (subret == GS_ERROR)
5297 /* If so, revert the change. */
5298 *from_p = old_from;
5300 else
5302 ret = GS_OK;
5303 changed = true;
5306 break;
5307 case INDIRECT_REF:
5309 /* If we have code like
5311 *(const A*)(A*)&x
5313 where the type of "x" is a (possibly cv-qualified variant
5314 of "A"), treat the entire expression as identical to "x".
5315 This kind of code arises in C++ when an object is bound
5316 to a const reference, and if "x" is a TARGET_EXPR we want
5317 to take advantage of the optimization below. */
5318 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5319 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5320 if (t)
5322 if (TREE_THIS_VOLATILE (t) != volatile_p)
5324 if (DECL_P (t))
5325 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5326 build_fold_addr_expr (t));
5327 if (REFERENCE_CLASS_P (t))
5328 TREE_THIS_VOLATILE (t) = volatile_p;
5330 *from_p = t;
5331 ret = GS_OK;
5332 changed = true;
5334 break;
5337 case TARGET_EXPR:
5339 /* If we are initializing something from a TARGET_EXPR, strip the
5340 TARGET_EXPR and initialize it directly, if possible. This can't
5341 be done if the initializer is void, since that implies that the
5342 temporary is set in some non-trivial way.
5344 ??? What about code that pulls out the temp and uses it
5345 elsewhere? I think that such code never uses the TARGET_EXPR as
5346 an initializer. If I'm wrong, we'll die because the temp won't
5347 have any RTL. In that case, I guess we'll need to replace
5348 references somehow. */
5349 tree init = TARGET_EXPR_INITIAL (*from_p);
5351 if (init
5352 && (TREE_CODE (*expr_p) != MODIFY_EXPR
5353 || !TARGET_EXPR_NO_ELIDE (*from_p))
5354 && !VOID_TYPE_P (TREE_TYPE (init)))
5356 *from_p = init;
5357 ret = GS_OK;
5358 changed = true;
5361 break;
5363 case COMPOUND_EXPR:
5364 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5365 caught. */
5366 gimplify_compound_expr (from_p, pre_p, true);
5367 ret = GS_OK;
5368 changed = true;
5369 break;
5371 case CONSTRUCTOR:
5372 /* If we already made some changes, let the front end have a
5373 crack at this before we break it down. */
5374 if (ret != GS_UNHANDLED)
5375 break;
5376 /* If we're initializing from a CONSTRUCTOR, break this into
5377 individual MODIFY_EXPRs. */
5378 return gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5379 false);
5381 case COND_EXPR:
5382 /* If we're assigning to a non-register type, push the assignment
5383 down into the branches. This is mandatory for ADDRESSABLE types,
5384 since we cannot generate temporaries for such, but it saves a
5385 copy in other cases as well. */
5386 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5388 /* This code should mirror the code in gimplify_cond_expr. */
5389 enum tree_code code = TREE_CODE (*expr_p);
5390 tree cond = *from_p;
5391 tree result = *to_p;
5393 ret = gimplify_expr (&result, pre_p, post_p,
5394 is_gimple_lvalue, fb_lvalue);
5395 if (ret != GS_ERROR)
5396 ret = GS_OK;
5398 /* If we are going to write RESULT more than once, clear
5399 TREE_READONLY flag, otherwise we might incorrectly promote
5400 the variable to static const and initialize it at compile
5401 time in one of the branches. */
5402 if (VAR_P (result)
5403 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5404 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5405 TREE_READONLY (result) = 0;
5406 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5407 TREE_OPERAND (cond, 1)
5408 = build2 (code, void_type_node, result,
5409 TREE_OPERAND (cond, 1));
5410 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5411 TREE_OPERAND (cond, 2)
5412 = build2 (code, void_type_node, unshare_expr (result),
5413 TREE_OPERAND (cond, 2));
5415 TREE_TYPE (cond) = void_type_node;
5416 recalculate_side_effects (cond);
5418 if (want_value)
5420 gimplify_and_add (cond, pre_p);
5421 *expr_p = unshare_expr (result);
5423 else
5424 *expr_p = cond;
5425 return ret;
5427 break;
5429 case CALL_EXPR:
5430 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5431 return slot so that we don't generate a temporary. */
5432 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5433 && aggregate_value_p (*from_p, *from_p))
5435 bool use_target;
5437 if (!(rhs_predicate_for (*to_p))(*from_p))
5438 /* If we need a temporary, *to_p isn't accurate. */
5439 use_target = false;
5440 /* It's OK to use the return slot directly unless it's an NRV. */
5441 else if (TREE_CODE (*to_p) == RESULT_DECL
5442 && DECL_NAME (*to_p) == NULL_TREE
5443 && needs_to_live_in_memory (*to_p))
5444 use_target = true;
5445 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5446 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5447 /* Don't force regs into memory. */
5448 use_target = false;
5449 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5450 /* It's OK to use the target directly if it's being
5451 initialized. */
5452 use_target = true;
5453 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5454 != INTEGER_CST)
5455 /* Always use the target and thus RSO for variable-sized types.
5456 GIMPLE cannot deal with a variable-sized assignment
5457 embedded in a call statement. */
5458 use_target = true;
5459 else if (TREE_CODE (*to_p) != SSA_NAME
5460 && (!is_gimple_variable (*to_p)
5461 || needs_to_live_in_memory (*to_p)))
5462 /* Don't use the original target if it's already addressable;
5463 if its address escapes, and the called function uses the
5464 NRV optimization, a conforming program could see *to_p
5465 change before the called function returns; see c++/19317.
5466 When optimizing, the return_slot pass marks more functions
5467 as safe after we have escape info. */
5468 use_target = false;
5469 else
5470 use_target = true;
5472 if (use_target)
5474 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5475 mark_addressable (*to_p);
5478 break;
5480 case WITH_SIZE_EXPR:
5481 /* Likewise for calls that return an aggregate of non-constant size,
5482 since we would not be able to generate a temporary at all. */
5483 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5485 *from_p = TREE_OPERAND (*from_p, 0);
5486 /* We don't change ret in this case because the
5487 WITH_SIZE_EXPR might have been added in
5488 gimplify_modify_expr, so returning GS_OK would lead to an
5489 infinite loop. */
5490 changed = true;
5492 break;
5494 /* If we're initializing from a container, push the initialization
5495 inside it. */
5496 case CLEANUP_POINT_EXPR:
5497 case BIND_EXPR:
5498 case STATEMENT_LIST:
5500 tree wrap = *from_p;
5501 tree t;
5503 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5504 fb_lvalue);
5505 if (ret != GS_ERROR)
5506 ret = GS_OK;
5508 t = voidify_wrapper_expr (wrap, *expr_p);
5509 gcc_assert (t == *expr_p);
5511 if (want_value)
5513 gimplify_and_add (wrap, pre_p);
5514 *expr_p = unshare_expr (*to_p);
5516 else
5517 *expr_p = wrap;
5518 return GS_OK;
5521 case COMPOUND_LITERAL_EXPR:
5523 tree complit = TREE_OPERAND (*expr_p, 1);
5524 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5525 tree decl = DECL_EXPR_DECL (decl_s);
5526 tree init = DECL_INITIAL (decl);
5528 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5529 into struct T x = { 0, 1, 2 } if the address of the
5530 compound literal has never been taken. */
5531 if (!TREE_ADDRESSABLE (complit)
5532 && !TREE_ADDRESSABLE (decl)
5533 && init)
5535 *expr_p = copy_node (*expr_p);
5536 TREE_OPERAND (*expr_p, 1) = init;
5537 return GS_OK;
5541 default:
5542 break;
5545 while (changed);
5547 return ret;
5551 /* Return true if T looks like a valid GIMPLE statement. */
5553 static bool
5554 is_gimple_stmt (tree t)
5556 const enum tree_code code = TREE_CODE (t);
5558 switch (code)
5560 case NOP_EXPR:
5561 /* The only valid NOP_EXPR is the empty statement. */
5562 return IS_EMPTY_STMT (t);
5564 case BIND_EXPR:
5565 case COND_EXPR:
5566 /* These are only valid if they're void. */
5567 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5569 case SWITCH_EXPR:
5570 case GOTO_EXPR:
5571 case RETURN_EXPR:
5572 case LABEL_EXPR:
5573 case CASE_LABEL_EXPR:
5574 case TRY_CATCH_EXPR:
5575 case TRY_FINALLY_EXPR:
5576 case EH_FILTER_EXPR:
5577 case CATCH_EXPR:
5578 case ASM_EXPR:
5579 case STATEMENT_LIST:
5580 case OACC_PARALLEL:
5581 case OACC_KERNELS:
5582 case OACC_SERIAL:
5583 case OACC_DATA:
5584 case OACC_HOST_DATA:
5585 case OACC_DECLARE:
5586 case OACC_UPDATE:
5587 case OACC_ENTER_DATA:
5588 case OACC_EXIT_DATA:
5589 case OACC_CACHE:
5590 case OMP_PARALLEL:
5591 case OMP_FOR:
5592 case OMP_SIMD:
5593 case OMP_DISTRIBUTE:
5594 case OMP_LOOP:
5595 case OACC_LOOP:
5596 case OMP_SCAN:
5597 case OMP_SECTIONS:
5598 case OMP_SECTION:
5599 case OMP_SINGLE:
5600 case OMP_MASTER:
5601 case OMP_TASKGROUP:
5602 case OMP_ORDERED:
5603 case OMP_CRITICAL:
5604 case OMP_TASK:
5605 case OMP_TARGET:
5606 case OMP_TARGET_DATA:
5607 case OMP_TARGET_UPDATE:
5608 case OMP_TARGET_ENTER_DATA:
5609 case OMP_TARGET_EXIT_DATA:
5610 case OMP_TASKLOOP:
5611 case OMP_TEAMS:
5612 /* These are always void. */
5613 return true;
5615 case CALL_EXPR:
5616 case MODIFY_EXPR:
5617 case PREDICT_EXPR:
5618 /* These are valid regardless of their type. */
5619 return true;
5621 default:
5622 return false;
5627 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5628 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
5630 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5631 other, unmodified part of the complex object just before the total store.
5632 As a consequence, if the object is still uninitialized, an undefined value
5633 will be loaded into a register, which may result in a spurious exception
5634 if the register is floating-point and the value happens to be a signaling
5635 NaN for example. Then the fully-fledged complex operations lowering pass
5636 followed by a DCE pass are necessary in order to fix things up. */
5638 static enum gimplify_status
5639 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5640 bool want_value)
5642 enum tree_code code, ocode;
5643 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5645 lhs = TREE_OPERAND (*expr_p, 0);
5646 rhs = TREE_OPERAND (*expr_p, 1);
5647 code = TREE_CODE (lhs);
5648 lhs = TREE_OPERAND (lhs, 0);
5650 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5651 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5652 TREE_NO_WARNING (other) = 1;
5653 other = get_formal_tmp_var (other, pre_p);
5655 realpart = code == REALPART_EXPR ? rhs : other;
5656 imagpart = code == REALPART_EXPR ? other : rhs;
5658 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5659 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5660 else
5661 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5663 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5664 *expr_p = (want_value) ? rhs : NULL_TREE;
5666 return GS_ALL_DONE;
5669 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5671 modify_expr
5672 : varname '=' rhs
5673 | '*' ID '=' rhs
5675 PRE_P points to the list where side effects that must happen before
5676 *EXPR_P should be stored.
5678 POST_P points to the list where side effects that must happen after
5679 *EXPR_P should be stored.
5681 WANT_VALUE is nonzero iff we want to use the value of this expression
5682 in another expression. */
5684 static enum gimplify_status
5685 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5686 bool want_value)
5688 tree *from_p = &TREE_OPERAND (*expr_p, 1);
5689 tree *to_p = &TREE_OPERAND (*expr_p, 0);
5690 enum gimplify_status ret = GS_UNHANDLED;
5691 gimple *assign;
5692 location_t loc = EXPR_LOCATION (*expr_p);
5693 gimple_stmt_iterator gsi;
5695 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
5696 || TREE_CODE (*expr_p) == INIT_EXPR);
5698 /* Trying to simplify a clobber using normal logic doesn't work,
5699 so handle it here. */
5700 if (TREE_CLOBBER_P (*from_p))
5702 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5703 if (ret == GS_ERROR)
5704 return ret;
5705 gcc_assert (!want_value);
5706 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
5708 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
5709 pre_p, post_p);
5710 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
5712 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
5713 *expr_p = NULL;
5714 return GS_ALL_DONE;
5717 /* Insert pointer conversions required by the middle-end that are not
5718 required by the frontend. This fixes middle-end type checking for
5719 for example gcc.dg/redecl-6.c. */
5720 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
5722 STRIP_USELESS_TYPE_CONVERSION (*from_p);
5723 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
5724 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
5727 /* See if any simplifications can be done based on what the RHS is. */
5728 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5729 want_value);
5730 if (ret != GS_UNHANDLED)
5731 return ret;
5733 /* For zero sized types only gimplify the left hand side and right hand
5734 side as statements and throw away the assignment. Do this after
5735 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5736 types properly. */
5737 if (zero_sized_type (TREE_TYPE (*from_p))
5738 && !want_value
5739 /* Don't do this for calls that return addressable types, expand_call
5740 relies on those having a lhs. */
5741 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
5742 && TREE_CODE (*from_p) == CALL_EXPR))
5744 gimplify_stmt (from_p, pre_p);
5745 gimplify_stmt (to_p, pre_p);
5746 *expr_p = NULL_TREE;
5747 return GS_ALL_DONE;
5750 /* If the value being copied is of variable width, compute the length
5751 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5752 before gimplifying any of the operands so that we can resolve any
5753 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5754 the size of the expression to be copied, not of the destination, so
5755 that is what we must do here. */
5756 maybe_with_size_expr (from_p);
5758 /* As a special case, we have to temporarily allow for assignments
5759 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5760 a toplevel statement, when gimplifying the GENERIC expression
5761 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5762 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5764 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5765 prevent gimplify_expr from trying to create a new temporary for
5766 foo's LHS, we tell it that it should only gimplify until it
5767 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5768 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5769 and all we need to do here is set 'a' to be its LHS. */
5771 /* Gimplify the RHS first for C++17 and bug 71104. */
5772 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
5773 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
5774 if (ret == GS_ERROR)
5775 return ret;
5777 /* Then gimplify the LHS. */
5778 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5779 twice we have to make sure to gimplify into non-SSA as otherwise
5780 the abnormal edge added later will make those defs not dominate
5781 their uses.
5782 ??? Technically this applies only to the registers used in the
5783 resulting non-register *TO_P. */
5784 bool saved_into_ssa = gimplify_ctxp->into_ssa;
5785 if (saved_into_ssa
5786 && TREE_CODE (*from_p) == CALL_EXPR
5787 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
5788 gimplify_ctxp->into_ssa = false;
5789 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5790 gimplify_ctxp->into_ssa = saved_into_ssa;
5791 if (ret == GS_ERROR)
5792 return ret;
5794 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5795 guess for the predicate was wrong. */
5796 gimple_predicate final_pred = rhs_predicate_for (*to_p);
5797 if (final_pred != initial_pred)
5799 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
5800 if (ret == GS_ERROR)
5801 return ret;
5804 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5805 size as argument to the call. */
5806 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5808 tree call = TREE_OPERAND (*from_p, 0);
5809 tree vlasize = TREE_OPERAND (*from_p, 1);
5811 if (TREE_CODE (call) == CALL_EXPR
5812 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
5814 int nargs = call_expr_nargs (call);
5815 tree type = TREE_TYPE (call);
5816 tree ap = CALL_EXPR_ARG (call, 0);
5817 tree tag = CALL_EXPR_ARG (call, 1);
5818 tree aptag = CALL_EXPR_ARG (call, 2);
5819 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
5820 IFN_VA_ARG, type,
5821 nargs + 1, ap, tag,
5822 aptag, vlasize);
5823 TREE_OPERAND (*from_p, 0) = newcall;
5827 /* Now see if the above changed *from_p to something we handle specially. */
5828 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5829 want_value);
5830 if (ret != GS_UNHANDLED)
5831 return ret;
5833 /* If we've got a variable sized assignment between two lvalues (i.e. does
5834 not involve a call), then we can make things a bit more straightforward
5835 by converting the assignment to memcpy or memset. */
5836 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5838 tree from = TREE_OPERAND (*from_p, 0);
5839 tree size = TREE_OPERAND (*from_p, 1);
5841 if (TREE_CODE (from) == CONSTRUCTOR)
5842 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
5844 if (is_gimple_addressable (from))
5846 *from_p = from;
5847 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
5848 pre_p);
5852 /* Transform partial stores to non-addressable complex variables into
5853 total stores. This allows us to use real instead of virtual operands
5854 for these variables, which improves optimization. */
5855 if ((TREE_CODE (*to_p) == REALPART_EXPR
5856 || TREE_CODE (*to_p) == IMAGPART_EXPR)
5857 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
5858 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
5860 /* Try to alleviate the effects of the gimplification creating artificial
5861 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
5862 make sure not to create DECL_DEBUG_EXPR links across functions. */
5863 if (!gimplify_ctxp->into_ssa
5864 && VAR_P (*from_p)
5865 && DECL_IGNORED_P (*from_p)
5866 && DECL_P (*to_p)
5867 && !DECL_IGNORED_P (*to_p)
5868 && decl_function_context (*to_p) == current_function_decl
5869 && decl_function_context (*from_p) == current_function_decl)
5871 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
5872 DECL_NAME (*from_p)
5873 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
5874 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
5875 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
5878 if (want_value && TREE_THIS_VOLATILE (*to_p))
5879 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
5881 if (TREE_CODE (*from_p) == CALL_EXPR)
5883 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
5884 instead of a GIMPLE_ASSIGN. */
5885 gcall *call_stmt;
5886 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
5888 /* Gimplify internal functions created in the FEs. */
5889 int nargs = call_expr_nargs (*from_p), i;
5890 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
5891 auto_vec<tree> vargs (nargs);
5893 for (i = 0; i < nargs; i++)
5895 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
5896 EXPR_LOCATION (*from_p));
5897 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
5899 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
5900 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
5901 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
5903 else
5905 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
5906 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
5907 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
5908 tree fndecl = get_callee_fndecl (*from_p);
5909 if (fndecl
5910 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
5911 && call_expr_nargs (*from_p) == 3)
5912 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
5913 CALL_EXPR_ARG (*from_p, 0),
5914 CALL_EXPR_ARG (*from_p, 1),
5915 CALL_EXPR_ARG (*from_p, 2));
5916 else
5918 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
5921 notice_special_calls (call_stmt);
5922 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
5923 gimple_call_set_lhs (call_stmt, *to_p);
5924 else if (TREE_CODE (*to_p) == SSA_NAME)
5925 /* The above is somewhat premature, avoid ICEing later for a
5926 SSA name w/o a definition. We may have uses in the GIMPLE IL.
5927 ??? This doesn't make it a default-def. */
5928 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
5930 assign = call_stmt;
5932 else
5934 assign = gimple_build_assign (*to_p, *from_p);
5935 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
5936 if (COMPARISON_CLASS_P (*from_p))
5937 gimple_set_no_warning (assign, TREE_NO_WARNING (*from_p));
5940 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
5942 /* We should have got an SSA name from the start. */
5943 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
5944 || ! gimple_in_ssa_p (cfun));
5947 gimplify_seq_add_stmt (pre_p, assign);
5948 gsi = gsi_last (*pre_p);
5949 maybe_fold_stmt (&gsi);
5951 if (want_value)
5953 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
5954 return GS_OK;
5956 else
5957 *expr_p = NULL;
5959 return GS_ALL_DONE;
5962 /* Gimplify a comparison between two variable-sized objects. Do this
5963 with a call to BUILT_IN_MEMCMP. */
5965 static enum gimplify_status
5966 gimplify_variable_sized_compare (tree *expr_p)
5968 location_t loc = EXPR_LOCATION (*expr_p);
5969 tree op0 = TREE_OPERAND (*expr_p, 0);
5970 tree op1 = TREE_OPERAND (*expr_p, 1);
5971 tree t, arg, dest, src, expr;
5973 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
5974 arg = unshare_expr (arg);
5975 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
5976 src = build_fold_addr_expr_loc (loc, op1);
5977 dest = build_fold_addr_expr_loc (loc, op0);
5978 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
5979 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
5981 expr
5982 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
5983 SET_EXPR_LOCATION (expr, loc);
5984 *expr_p = expr;
5986 return GS_OK;
5989 /* Gimplify a comparison between two aggregate objects of integral scalar
5990 mode as a comparison between the bitwise equivalent scalar values. */
5992 static enum gimplify_status
5993 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
5995 location_t loc = EXPR_LOCATION (*expr_p);
5996 tree op0 = TREE_OPERAND (*expr_p, 0);
5997 tree op1 = TREE_OPERAND (*expr_p, 1);
5999 tree type = TREE_TYPE (op0);
6000 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
6002 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
6003 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
6005 *expr_p
6006 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
6008 return GS_OK;
6011 /* Gimplify an expression sequence. This function gimplifies each
6012 expression and rewrites the original expression with the last
6013 expression of the sequence in GIMPLE form.
6015 PRE_P points to the list where the side effects for all the
6016 expressions in the sequence will be emitted.
6018 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6020 static enum gimplify_status
6021 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
6023 tree t = *expr_p;
6027 tree *sub_p = &TREE_OPERAND (t, 0);
6029 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
6030 gimplify_compound_expr (sub_p, pre_p, false);
6031 else
6032 gimplify_stmt (sub_p, pre_p);
6034 t = TREE_OPERAND (t, 1);
6036 while (TREE_CODE (t) == COMPOUND_EXPR);
6038 *expr_p = t;
6039 if (want_value)
6040 return GS_OK;
6041 else
6043 gimplify_stmt (expr_p, pre_p);
6044 return GS_ALL_DONE;
6048 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6049 gimplify. After gimplification, EXPR_P will point to a new temporary
6050 that holds the original value of the SAVE_EXPR node.
6052 PRE_P points to the list where side effects that must happen before
6053 *EXPR_P should be stored. */
6055 static enum gimplify_status
6056 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6058 enum gimplify_status ret = GS_ALL_DONE;
6059 tree val;
6061 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
6062 val = TREE_OPERAND (*expr_p, 0);
6064 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6065 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
6067 /* The operand may be a void-valued expression. It is
6068 being executed only for its side-effects. */
6069 if (TREE_TYPE (val) == void_type_node)
6071 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
6072 is_gimple_stmt, fb_none);
6073 val = NULL;
6075 else
6076 /* The temporary may not be an SSA name as later abnormal and EH
6077 control flow may invalidate use/def domination. When in SSA
6078 form then assume there are no such issues and SAVE_EXPRs only
6079 appear via GENERIC foldings. */
6080 val = get_initialized_tmp_var (val, pre_p, post_p,
6081 gimple_in_ssa_p (cfun));
6083 TREE_OPERAND (*expr_p, 0) = val;
6084 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
6087 *expr_p = val;
6089 return ret;
6092 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6094 unary_expr
6095 : ...
6096 | '&' varname
6099 PRE_P points to the list where side effects that must happen before
6100 *EXPR_P should be stored.
6102 POST_P points to the list where side effects that must happen after
6103 *EXPR_P should be stored. */
6105 static enum gimplify_status
6106 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6108 tree expr = *expr_p;
6109 tree op0 = TREE_OPERAND (expr, 0);
6110 enum gimplify_status ret;
6111 location_t loc = EXPR_LOCATION (*expr_p);
6113 switch (TREE_CODE (op0))
6115 case INDIRECT_REF:
6116 do_indirect_ref:
6117 /* Check if we are dealing with an expression of the form '&*ptr'.
6118 While the front end folds away '&*ptr' into 'ptr', these
6119 expressions may be generated internally by the compiler (e.g.,
6120 builtins like __builtin_va_end). */
6121 /* Caution: the silent array decomposition semantics we allow for
6122 ADDR_EXPR means we can't always discard the pair. */
6123 /* Gimplification of the ADDR_EXPR operand may drop
6124 cv-qualification conversions, so make sure we add them if
6125 needed. */
6127 tree op00 = TREE_OPERAND (op0, 0);
6128 tree t_expr = TREE_TYPE (expr);
6129 tree t_op00 = TREE_TYPE (op00);
6131 if (!useless_type_conversion_p (t_expr, t_op00))
6132 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
6133 *expr_p = op00;
6134 ret = GS_OK;
6136 break;
6138 case VIEW_CONVERT_EXPR:
6139 /* Take the address of our operand and then convert it to the type of
6140 this ADDR_EXPR.
6142 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6143 all clear. The impact of this transformation is even less clear. */
6145 /* If the operand is a useless conversion, look through it. Doing so
6146 guarantees that the ADDR_EXPR and its operand will remain of the
6147 same type. */
6148 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
6149 op0 = TREE_OPERAND (op0, 0);
6151 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
6152 build_fold_addr_expr_loc (loc,
6153 TREE_OPERAND (op0, 0)));
6154 ret = GS_OK;
6155 break;
6157 case MEM_REF:
6158 if (integer_zerop (TREE_OPERAND (op0, 1)))
6159 goto do_indirect_ref;
6161 /* fall through */
6163 default:
6164 /* If we see a call to a declared builtin or see its address
6165 being taken (we can unify those cases here) then we can mark
6166 the builtin for implicit generation by GCC. */
6167 if (TREE_CODE (op0) == FUNCTION_DECL
6168 && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6169 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6170 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6172 /* We use fb_either here because the C frontend sometimes takes
6173 the address of a call that returns a struct; see
6174 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6175 the implied temporary explicit. */
6177 /* Make the operand addressable. */
6178 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6179 is_gimple_addressable, fb_either);
6180 if (ret == GS_ERROR)
6181 break;
6183 /* Then mark it. Beware that it may not be possible to do so directly
6184 if a temporary has been created by the gimplification. */
6185 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6187 op0 = TREE_OPERAND (expr, 0);
6189 /* For various reasons, the gimplification of the expression
6190 may have made a new INDIRECT_REF. */
6191 if (TREE_CODE (op0) == INDIRECT_REF
6192 || (TREE_CODE (op0) == MEM_REF
6193 && integer_zerop (TREE_OPERAND (op0, 1))))
6194 goto do_indirect_ref;
6196 mark_addressable (TREE_OPERAND (expr, 0));
6198 /* The FEs may end up building ADDR_EXPRs early on a decl with
6199 an incomplete type. Re-build ADDR_EXPRs in canonical form
6200 here. */
6201 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6202 *expr_p = build_fold_addr_expr (op0);
6204 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6205 recompute_tree_invariant_for_addr_expr (*expr_p);
6207 /* If we re-built the ADDR_EXPR add a conversion to the original type
6208 if required. */
6209 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6210 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6212 break;
6215 return ret;
6218 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6219 value; output operands should be a gimple lvalue. */
6221 static enum gimplify_status
6222 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6224 tree expr;
6225 int noutputs;
6226 const char **oconstraints;
6227 int i;
6228 tree link;
6229 const char *constraint;
6230 bool allows_mem, allows_reg, is_inout;
6231 enum gimplify_status ret, tret;
6232 gasm *stmt;
6233 vec<tree, va_gc> *inputs;
6234 vec<tree, va_gc> *outputs;
6235 vec<tree, va_gc> *clobbers;
6236 vec<tree, va_gc> *labels;
6237 tree link_next;
6239 expr = *expr_p;
6240 noutputs = list_length (ASM_OUTPUTS (expr));
6241 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6243 inputs = NULL;
6244 outputs = NULL;
6245 clobbers = NULL;
6246 labels = NULL;
6248 ret = GS_ALL_DONE;
6249 link_next = NULL_TREE;
6250 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6252 bool ok;
6253 size_t constraint_len;
6255 link_next = TREE_CHAIN (link);
6257 oconstraints[i]
6258 = constraint
6259 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6260 constraint_len = strlen (constraint);
6261 if (constraint_len == 0)
6262 continue;
6264 ok = parse_output_constraint (&constraint, i, 0, 0,
6265 &allows_mem, &allows_reg, &is_inout);
6266 if (!ok)
6268 ret = GS_ERROR;
6269 is_inout = false;
6272 /* If we can't make copies, we can only accept memory.
6273 Similarly for VLAs. */
6274 tree outtype = TREE_TYPE (TREE_VALUE (link));
6275 if (outtype != error_mark_node
6276 && (TREE_ADDRESSABLE (outtype)
6277 || !COMPLETE_TYPE_P (outtype)
6278 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
6280 if (allows_mem)
6281 allows_reg = 0;
6282 else
6284 error ("impossible constraint in %<asm%>");
6285 error ("non-memory output %d must stay in memory", i);
6286 return GS_ERROR;
6290 if (!allows_reg && allows_mem)
6291 mark_addressable (TREE_VALUE (link));
6293 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6294 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6295 fb_lvalue | fb_mayfail);
6296 if (tret == GS_ERROR)
6298 error ("invalid lvalue in %<asm%> output %d", i);
6299 ret = tret;
6302 /* If the constraint does not allow memory make sure we gimplify
6303 it to a register if it is not already but its base is. This
6304 happens for complex and vector components. */
6305 if (!allows_mem)
6307 tree op = TREE_VALUE (link);
6308 if (! is_gimple_val (op)
6309 && is_gimple_reg_type (TREE_TYPE (op))
6310 && is_gimple_reg (get_base_address (op)))
6312 tree tem = create_tmp_reg (TREE_TYPE (op));
6313 tree ass;
6314 if (is_inout)
6316 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6317 tem, unshare_expr (op));
6318 gimplify_and_add (ass, pre_p);
6320 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6321 gimplify_and_add (ass, post_p);
6323 TREE_VALUE (link) = tem;
6324 tret = GS_OK;
6328 vec_safe_push (outputs, link);
6329 TREE_CHAIN (link) = NULL_TREE;
6331 if (is_inout)
6333 /* An input/output operand. To give the optimizers more
6334 flexibility, split it into separate input and output
6335 operands. */
6336 tree input;
6337 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6338 char buf[11];
6340 /* Turn the in/out constraint into an output constraint. */
6341 char *p = xstrdup (constraint);
6342 p[0] = '=';
6343 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6345 /* And add a matching input constraint. */
6346 if (allows_reg)
6348 sprintf (buf, "%u", i);
6350 /* If there are multiple alternatives in the constraint,
6351 handle each of them individually. Those that allow register
6352 will be replaced with operand number, the others will stay
6353 unchanged. */
6354 if (strchr (p, ',') != NULL)
6356 size_t len = 0, buflen = strlen (buf);
6357 char *beg, *end, *str, *dst;
6359 for (beg = p + 1;;)
6361 end = strchr (beg, ',');
6362 if (end == NULL)
6363 end = strchr (beg, '\0');
6364 if ((size_t) (end - beg) < buflen)
6365 len += buflen + 1;
6366 else
6367 len += end - beg + 1;
6368 if (*end)
6369 beg = end + 1;
6370 else
6371 break;
6374 str = (char *) alloca (len);
6375 for (beg = p + 1, dst = str;;)
6377 const char *tem;
6378 bool mem_p, reg_p, inout_p;
6380 end = strchr (beg, ',');
6381 if (end)
6382 *end = '\0';
6383 beg[-1] = '=';
6384 tem = beg - 1;
6385 parse_output_constraint (&tem, i, 0, 0,
6386 &mem_p, &reg_p, &inout_p);
6387 if (dst != str)
6388 *dst++ = ',';
6389 if (reg_p)
6391 memcpy (dst, buf, buflen);
6392 dst += buflen;
6394 else
6396 if (end)
6397 len = end - beg;
6398 else
6399 len = strlen (beg);
6400 memcpy (dst, beg, len);
6401 dst += len;
6403 if (end)
6404 beg = end + 1;
6405 else
6406 break;
6408 *dst = '\0';
6409 input = build_string (dst - str, str);
6411 else
6412 input = build_string (strlen (buf), buf);
6414 else
6415 input = build_string (constraint_len - 1, constraint + 1);
6417 free (p);
6419 input = build_tree_list (build_tree_list (NULL_TREE, input),
6420 unshare_expr (TREE_VALUE (link)));
6421 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6425 link_next = NULL_TREE;
6426 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6428 link_next = TREE_CHAIN (link);
6429 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6430 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6431 oconstraints, &allows_mem, &allows_reg);
6433 /* If we can't make copies, we can only accept memory. */
6434 tree intype = TREE_TYPE (TREE_VALUE (link));
6435 if (intype != error_mark_node
6436 && (TREE_ADDRESSABLE (intype)
6437 || !COMPLETE_TYPE_P (intype)
6438 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
6440 if (allows_mem)
6441 allows_reg = 0;
6442 else
6444 error ("impossible constraint in %<asm%>");
6445 error ("non-memory input %d must stay in memory", i);
6446 return GS_ERROR;
6450 /* If the operand is a memory input, it should be an lvalue. */
6451 if (!allows_reg && allows_mem)
6453 tree inputv = TREE_VALUE (link);
6454 STRIP_NOPS (inputv);
6455 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6456 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6457 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6458 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6459 || TREE_CODE (inputv) == MODIFY_EXPR)
6460 TREE_VALUE (link) = error_mark_node;
6461 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6462 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6463 if (tret != GS_ERROR)
6465 /* Unlike output operands, memory inputs are not guaranteed
6466 to be lvalues by the FE, and while the expressions are
6467 marked addressable there, if it is e.g. a statement
6468 expression, temporaries in it might not end up being
6469 addressable. They might be already used in the IL and thus
6470 it is too late to make them addressable now though. */
6471 tree x = TREE_VALUE (link);
6472 while (handled_component_p (x))
6473 x = TREE_OPERAND (x, 0);
6474 if (TREE_CODE (x) == MEM_REF
6475 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6476 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6477 if ((VAR_P (x)
6478 || TREE_CODE (x) == PARM_DECL
6479 || TREE_CODE (x) == RESULT_DECL)
6480 && !TREE_ADDRESSABLE (x)
6481 && is_gimple_reg (x))
6483 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6484 input_location), 0,
6485 "memory input %d is not directly addressable",
6487 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6490 mark_addressable (TREE_VALUE (link));
6491 if (tret == GS_ERROR)
6493 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6494 "memory input %d is not directly addressable", i);
6495 ret = tret;
6498 else
6500 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6501 is_gimple_asm_val, fb_rvalue);
6502 if (tret == GS_ERROR)
6503 ret = tret;
6506 TREE_CHAIN (link) = NULL_TREE;
6507 vec_safe_push (inputs, link);
6510 link_next = NULL_TREE;
6511 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6513 link_next = TREE_CHAIN (link);
6514 TREE_CHAIN (link) = NULL_TREE;
6515 vec_safe_push (clobbers, link);
6518 link_next = NULL_TREE;
6519 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6521 link_next = TREE_CHAIN (link);
6522 TREE_CHAIN (link) = NULL_TREE;
6523 vec_safe_push (labels, link);
6526 /* Do not add ASMs with errors to the gimple IL stream. */
6527 if (ret != GS_ERROR)
6529 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6530 inputs, outputs, clobbers, labels);
6532 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
6533 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6534 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
6536 gimplify_seq_add_stmt (pre_p, stmt);
6539 return ret;
6542 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6543 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6544 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6545 return to this function.
6547 FIXME should we complexify the prequeue handling instead? Or use flags
6548 for all the cleanups and let the optimizer tighten them up? The current
6549 code seems pretty fragile; it will break on a cleanup within any
6550 non-conditional nesting. But any such nesting would be broken, anyway;
6551 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6552 and continues out of it. We can do that at the RTL level, though, so
6553 having an optimizer to tighten up try/finally regions would be a Good
6554 Thing. */
6556 static enum gimplify_status
6557 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6559 gimple_stmt_iterator iter;
6560 gimple_seq body_sequence = NULL;
6562 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6564 /* We only care about the number of conditions between the innermost
6565 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6566 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6567 int old_conds = gimplify_ctxp->conditions;
6568 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6569 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6570 gimplify_ctxp->conditions = 0;
6571 gimplify_ctxp->conditional_cleanups = NULL;
6572 gimplify_ctxp->in_cleanup_point_expr = true;
6574 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6576 gimplify_ctxp->conditions = old_conds;
6577 gimplify_ctxp->conditional_cleanups = old_cleanups;
6578 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6580 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6582 gimple *wce = gsi_stmt (iter);
6584 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6586 if (gsi_one_before_end_p (iter))
6588 /* Note that gsi_insert_seq_before and gsi_remove do not
6589 scan operands, unlike some other sequence mutators. */
6590 if (!gimple_wce_cleanup_eh_only (wce))
6591 gsi_insert_seq_before_without_update (&iter,
6592 gimple_wce_cleanup (wce),
6593 GSI_SAME_STMT);
6594 gsi_remove (&iter, true);
6595 break;
6597 else
6599 gtry *gtry;
6600 gimple_seq seq;
6601 enum gimple_try_flags kind;
6603 if (gimple_wce_cleanup_eh_only (wce))
6604 kind = GIMPLE_TRY_CATCH;
6605 else
6606 kind = GIMPLE_TRY_FINALLY;
6607 seq = gsi_split_seq_after (iter);
6609 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6610 /* Do not use gsi_replace here, as it may scan operands.
6611 We want to do a simple structural modification only. */
6612 gsi_set_stmt (&iter, gtry);
6613 iter = gsi_start (gtry->eval);
6616 else
6617 gsi_next (&iter);
6620 gimplify_seq_add_seq (pre_p, body_sequence);
6621 if (temp)
6623 *expr_p = temp;
6624 return GS_OK;
6626 else
6628 *expr_p = NULL;
6629 return GS_ALL_DONE;
6633 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6634 is the cleanup action required. EH_ONLY is true if the cleanup should
6635 only be executed if an exception is thrown, not on normal exit.
6636 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6637 only valid for clobbers. */
6639 static void
6640 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6641 bool force_uncond = false)
6643 gimple *wce;
6644 gimple_seq cleanup_stmts = NULL;
6646 /* Errors can result in improperly nested cleanups. Which results in
6647 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6648 if (seen_error ())
6649 return;
6651 if (gimple_conditional_context ())
6653 /* If we're in a conditional context, this is more complex. We only
6654 want to run the cleanup if we actually ran the initialization that
6655 necessitates it, but we want to run it after the end of the
6656 conditional context. So we wrap the try/finally around the
6657 condition and use a flag to determine whether or not to actually
6658 run the destructor. Thus
6660 test ? f(A()) : 0
6662 becomes (approximately)
6664 flag = 0;
6665 try {
6666 if (test) { A::A(temp); flag = 1; val = f(temp); }
6667 else { val = 0; }
6668 } finally {
6669 if (flag) A::~A(temp);
6673 if (force_uncond)
6675 gimplify_stmt (&cleanup, &cleanup_stmts);
6676 wce = gimple_build_wce (cleanup_stmts);
6677 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6679 else
6681 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6682 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
6683 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
6685 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
6686 gimplify_stmt (&cleanup, &cleanup_stmts);
6687 wce = gimple_build_wce (cleanup_stmts);
6689 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
6690 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6691 gimplify_seq_add_stmt (pre_p, ftrue);
6693 /* Because of this manipulation, and the EH edges that jump
6694 threading cannot redirect, the temporary (VAR) will appear
6695 to be used uninitialized. Don't warn. */
6696 TREE_NO_WARNING (var) = 1;
6699 else
6701 gimplify_stmt (&cleanup, &cleanup_stmts);
6702 wce = gimple_build_wce (cleanup_stmts);
6703 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6704 gimplify_seq_add_stmt (pre_p, wce);
6708 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6710 static enum gimplify_status
6711 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6713 tree targ = *expr_p;
6714 tree temp = TARGET_EXPR_SLOT (targ);
6715 tree init = TARGET_EXPR_INITIAL (targ);
6716 enum gimplify_status ret;
6718 bool unpoison_empty_seq = false;
6719 gimple_stmt_iterator unpoison_it;
6721 if (init)
6723 tree cleanup = NULL_TREE;
6725 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6726 to the temps list. Handle also variable length TARGET_EXPRs. */
6727 if (!poly_int_tree_p (DECL_SIZE (temp)))
6729 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
6730 gimplify_type_sizes (TREE_TYPE (temp), pre_p);
6731 gimplify_vla_decl (temp, pre_p);
6733 else
6735 /* Save location where we need to place unpoisoning. It's possible
6736 that a variable will be converted to needs_to_live_in_memory. */
6737 unpoison_it = gsi_last (*pre_p);
6738 unpoison_empty_seq = gsi_end_p (unpoison_it);
6740 gimple_add_tmp_var (temp);
6743 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6744 expression is supposed to initialize the slot. */
6745 if (VOID_TYPE_P (TREE_TYPE (init)))
6746 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6747 else
6749 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
6750 init = init_expr;
6751 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6752 init = NULL;
6753 ggc_free (init_expr);
6755 if (ret == GS_ERROR)
6757 /* PR c++/28266 Make sure this is expanded only once. */
6758 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6759 return GS_ERROR;
6761 if (init)
6762 gimplify_and_add (init, pre_p);
6764 /* If needed, push the cleanup for the temp. */
6765 if (TARGET_EXPR_CLEANUP (targ))
6767 if (CLEANUP_EH_ONLY (targ))
6768 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
6769 CLEANUP_EH_ONLY (targ), pre_p);
6770 else
6771 cleanup = TARGET_EXPR_CLEANUP (targ);
6774 /* Add a clobber for the temporary going out of scope, like
6775 gimplify_bind_expr. */
6776 if (gimplify_ctxp->in_cleanup_point_expr
6777 && needs_to_live_in_memory (temp))
6779 if (flag_stack_reuse == SR_ALL)
6781 tree clobber = build_clobber (TREE_TYPE (temp));
6782 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
6783 gimple_push_cleanup (temp, clobber, false, pre_p, true);
6785 if (asan_poisoned_variables
6786 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
6787 && !TREE_STATIC (temp)
6788 && dbg_cnt (asan_use_after_scope)
6789 && !gimplify_omp_ctxp)
6791 tree asan_cleanup = build_asan_poison_call_expr (temp);
6792 if (asan_cleanup)
6794 if (unpoison_empty_seq)
6795 unpoison_it = gsi_start (*pre_p);
6797 asan_poison_variable (temp, false, &unpoison_it,
6798 unpoison_empty_seq);
6799 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
6803 if (cleanup)
6804 gimple_push_cleanup (temp, cleanup, false, pre_p);
6806 /* Only expand this once. */
6807 TREE_OPERAND (targ, 3) = init;
6808 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6810 else
6811 /* We should have expanded this before. */
6812 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
6814 *expr_p = temp;
6815 return GS_OK;
6818 /* Gimplification of expression trees. */
6820 /* Gimplify an expression which appears at statement context. The
6821 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
6822 NULL, a new sequence is allocated.
6824 Return true if we actually added a statement to the queue. */
6826 bool
6827 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
6829 gimple_seq_node last;
6831 last = gimple_seq_last (*seq_p);
6832 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
6833 return last != gimple_seq_last (*seq_p);
6836 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
6837 to CTX. If entries already exist, force them to be some flavor of private.
6838 If there is no enclosing parallel, do nothing. */
6840 void
6841 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
6843 splay_tree_node n;
6845 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
6846 return;
6850 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6851 if (n != NULL)
6853 if (n->value & GOVD_SHARED)
6854 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
6855 else if (n->value & GOVD_MAP)
6856 n->value |= GOVD_MAP_TO_ONLY;
6857 else
6858 return;
6860 else if ((ctx->region_type & ORT_TARGET) != 0)
6862 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
6863 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6864 else
6865 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
6867 else if (ctx->region_type != ORT_WORKSHARE
6868 && ctx->region_type != ORT_TASKGROUP
6869 && ctx->region_type != ORT_SIMD
6870 && ctx->region_type != ORT_ACC
6871 && !(ctx->region_type & ORT_TARGET_DATA))
6872 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6874 ctx = ctx->outer_context;
6876 while (ctx);
6879 /* Similarly for each of the type sizes of TYPE. */
6881 static void
6882 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
6884 if (type == NULL || type == error_mark_node)
6885 return;
6886 type = TYPE_MAIN_VARIANT (type);
6888 if (ctx->privatized_types->add (type))
6889 return;
6891 switch (TREE_CODE (type))
6893 case INTEGER_TYPE:
6894 case ENUMERAL_TYPE:
6895 case BOOLEAN_TYPE:
6896 case REAL_TYPE:
6897 case FIXED_POINT_TYPE:
6898 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
6899 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
6900 break;
6902 case ARRAY_TYPE:
6903 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6904 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
6905 break;
6907 case RECORD_TYPE:
6908 case UNION_TYPE:
6909 case QUAL_UNION_TYPE:
6911 tree field;
6912 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
6913 if (TREE_CODE (field) == FIELD_DECL)
6915 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
6916 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
6919 break;
6921 case POINTER_TYPE:
6922 case REFERENCE_TYPE:
6923 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6924 break;
6926 default:
6927 break;
6930 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
6931 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
6932 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
6935 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
6937 static void
6938 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
6940 splay_tree_node n;
6941 unsigned int nflags;
6942 tree t;
6944 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
6945 return;
6947 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
6948 there are constructors involved somewhere. Exception is a shared clause,
6949 there is nothing privatized in that case. */
6950 if ((flags & GOVD_SHARED) == 0
6951 && (TREE_ADDRESSABLE (TREE_TYPE (decl))
6952 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
6953 flags |= GOVD_SEEN;
6955 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6956 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
6958 /* We shouldn't be re-adding the decl with the same data
6959 sharing class. */
6960 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
6961 nflags = n->value | flags;
6962 /* The only combination of data sharing classes we should see is
6963 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
6964 reduction variables to be used in data sharing clauses. */
6965 gcc_assert ((ctx->region_type & ORT_ACC) != 0
6966 || ((nflags & GOVD_DATA_SHARE_CLASS)
6967 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
6968 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
6969 n->value = nflags;
6970 return;
6973 /* When adding a variable-sized variable, we have to handle all sorts
6974 of additional bits of data: the pointer replacement variable, and
6975 the parameters of the type. */
6976 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
6978 /* Add the pointer replacement variable as PRIVATE if the variable
6979 replacement is private, else FIRSTPRIVATE since we'll need the
6980 address of the original variable either for SHARED, or for the
6981 copy into or out of the context. */
6982 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
6984 if (flags & GOVD_MAP)
6985 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
6986 else if (flags & GOVD_PRIVATE)
6987 nflags = GOVD_PRIVATE;
6988 else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
6989 && (flags & GOVD_FIRSTPRIVATE))
6990 || (ctx->region_type == ORT_TARGET_DATA
6991 && (flags & GOVD_DATA_SHARE_CLASS) == 0))
6992 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
6993 else
6994 nflags = GOVD_FIRSTPRIVATE;
6995 nflags |= flags & GOVD_SEEN;
6996 t = DECL_VALUE_EXPR (decl);
6997 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
6998 t = TREE_OPERAND (t, 0);
6999 gcc_assert (DECL_P (t));
7000 omp_add_variable (ctx, t, nflags);
7003 /* Add all of the variable and type parameters (which should have
7004 been gimplified to a formal temporary) as FIRSTPRIVATE. */
7005 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
7006 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
7007 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7009 /* The variable-sized variable itself is never SHARED, only some form
7010 of PRIVATE. The sharing would take place via the pointer variable
7011 which we remapped above. */
7012 if (flags & GOVD_SHARED)
7013 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
7014 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
7016 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7017 alloca statement we generate for the variable, so make sure it
7018 is available. This isn't automatically needed for the SHARED
7019 case, since we won't be allocating local storage then.
7020 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7021 in this case omp_notice_variable will be called later
7022 on when it is gimplified. */
7023 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
7024 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
7025 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
7027 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
7028 && lang_hooks.decls.omp_privatize_by_reference (decl))
7030 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7032 /* Similar to the direct variable sized case above, we'll need the
7033 size of references being privatized. */
7034 if ((flags & GOVD_SHARED) == 0)
7036 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7037 if (DECL_P (t))
7038 omp_notice_variable (ctx, t, true);
7042 if (n != NULL)
7043 n->value |= flags;
7044 else
7045 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
7047 /* For reductions clauses in OpenACC loop directives, by default create a
7048 copy clause on the enclosing parallel construct for carrying back the
7049 results. */
7050 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
7052 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
7053 while (outer_ctx)
7055 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
7056 if (n != NULL)
7058 /* Ignore local variables and explicitly declared clauses. */
7059 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
7060 break;
7061 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
7063 /* According to the OpenACC spec, such a reduction variable
7064 should already have a copy map on a kernels construct,
7065 verify that here. */
7066 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
7067 && (n->value & GOVD_MAP));
7069 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7071 /* Remove firstprivate and make it a copy map. */
7072 n->value &= ~GOVD_FIRSTPRIVATE;
7073 n->value |= GOVD_MAP;
7076 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7078 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
7079 GOVD_MAP | GOVD_SEEN);
7080 break;
7082 outer_ctx = outer_ctx->outer_context;
7087 /* Notice a threadprivate variable DECL used in OMP context CTX.
7088 This just prints out diagnostics about threadprivate variable uses
7089 in untied tasks. If DECL2 is non-NULL, prevent this warning
7090 on that variable. */
7092 static bool
7093 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
7094 tree decl2)
7096 splay_tree_node n;
7097 struct gimplify_omp_ctx *octx;
7099 for (octx = ctx; octx; octx = octx->outer_context)
7100 if ((octx->region_type & ORT_TARGET) != 0
7101 || octx->order_concurrent)
7103 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
7104 if (n == NULL)
7106 if (octx->order_concurrent)
7108 error ("threadprivate variable %qE used in a region with"
7109 " %<order(concurrent)%> clause", DECL_NAME (decl));
7110 inform (octx->location, "enclosing region");
7112 else
7114 error ("threadprivate variable %qE used in target region",
7115 DECL_NAME (decl));
7116 inform (octx->location, "enclosing target region");
7118 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
7120 if (decl2)
7121 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
7124 if (ctx->region_type != ORT_UNTIED_TASK)
7125 return false;
7126 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7127 if (n == NULL)
7129 error ("threadprivate variable %qE used in untied task",
7130 DECL_NAME (decl));
7131 inform (ctx->location, "enclosing task");
7132 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
7134 if (decl2)
7135 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
7136 return false;
7139 /* Return true if global var DECL is device resident. */
7141 static bool
7142 device_resident_p (tree decl)
7144 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
7146 if (!attr)
7147 return false;
7149 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
7151 tree c = TREE_VALUE (t);
7152 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
7153 return true;
7156 return false;
7159 /* Return true if DECL has an ACC DECLARE attribute. */
7161 static bool
7162 is_oacc_declared (tree decl)
7164 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
7165 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
7166 return declared != NULL_TREE;
7169 /* Determine outer default flags for DECL mentioned in an OMP region
7170 but not declared in an enclosing clause.
7172 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7173 remapped firstprivate instead of shared. To some extent this is
7174 addressed in omp_firstprivatize_type_sizes, but not
7175 effectively. */
7177 static unsigned
7178 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
7179 bool in_code, unsigned flags)
7181 enum omp_clause_default_kind default_kind = ctx->default_kind;
7182 enum omp_clause_default_kind kind;
7184 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
7185 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7186 default_kind = kind;
7187 else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
7188 default_kind = OMP_CLAUSE_DEFAULT_SHARED;
7190 switch (default_kind)
7192 case OMP_CLAUSE_DEFAULT_NONE:
7194 const char *rtype;
7196 if (ctx->region_type & ORT_PARALLEL)
7197 rtype = "parallel";
7198 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
7199 rtype = "taskloop";
7200 else if (ctx->region_type & ORT_TASK)
7201 rtype = "task";
7202 else if (ctx->region_type & ORT_TEAMS)
7203 rtype = "teams";
7204 else
7205 gcc_unreachable ();
7207 error ("%qE not specified in enclosing %qs",
7208 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7209 inform (ctx->location, "enclosing %qs", rtype);
7211 /* FALLTHRU */
7212 case OMP_CLAUSE_DEFAULT_SHARED:
7213 flags |= GOVD_SHARED;
7214 break;
7215 case OMP_CLAUSE_DEFAULT_PRIVATE:
7216 flags |= GOVD_PRIVATE;
7217 break;
7218 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7219 flags |= GOVD_FIRSTPRIVATE;
7220 break;
7221 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7222 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7223 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7224 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7226 omp_notice_variable (octx, decl, in_code);
7227 for (; octx; octx = octx->outer_context)
7229 splay_tree_node n2;
7231 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7232 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7233 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7234 continue;
7235 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7237 flags |= GOVD_FIRSTPRIVATE;
7238 goto found_outer;
7240 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7242 flags |= GOVD_SHARED;
7243 goto found_outer;
7248 if (TREE_CODE (decl) == PARM_DECL
7249 || (!is_global_var (decl)
7250 && DECL_CONTEXT (decl) == current_function_decl))
7251 flags |= GOVD_FIRSTPRIVATE;
7252 else
7253 flags |= GOVD_SHARED;
7254 found_outer:
7255 break;
7257 default:
7258 gcc_unreachable ();
7261 return flags;
7265 /* Determine outer default flags for DECL mentioned in an OACC region
7266 but not declared in an enclosing clause. */
7268 static unsigned
7269 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7271 const char *rkind;
7272 bool on_device = false;
7273 bool is_private = false;
7274 bool declared = is_oacc_declared (decl);
7275 tree type = TREE_TYPE (decl);
7277 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7278 type = TREE_TYPE (type);
7280 /* For Fortran COMMON blocks, only used variables in those blocks are
7281 transfered and remapped. The block itself will have a private clause to
7282 avoid transfering the data twice.
7283 The hook evaluates to false by default. For a variable in Fortran's COMMON
7284 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7285 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7286 the whole block. For C++ and Fortran, it can also be true under certain
7287 other conditions, if DECL_HAS_VALUE_EXPR. */
7288 if (RECORD_OR_UNION_TYPE_P (type))
7289 is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
7291 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7292 && is_global_var (decl)
7293 && device_resident_p (decl)
7294 && !is_private)
7296 on_device = true;
7297 flags |= GOVD_MAP_TO_ONLY;
7300 switch (ctx->region_type)
7302 case ORT_ACC_KERNELS:
7303 rkind = "kernels";
7305 if (is_private)
7306 flags |= GOVD_FIRSTPRIVATE;
7307 else if (AGGREGATE_TYPE_P (type))
7309 /* Aggregates default to 'present_or_copy', or 'present'. */
7310 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7311 flags |= GOVD_MAP;
7312 else
7313 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7315 else
7316 /* Scalars default to 'copy'. */
7317 flags |= GOVD_MAP | GOVD_MAP_FORCE;
7319 break;
7321 case ORT_ACC_PARALLEL:
7322 case ORT_ACC_SERIAL:
7323 rkind = ctx->region_type == ORT_ACC_PARALLEL ? "parallel" : "serial";
7325 if (is_private)
7326 flags |= GOVD_FIRSTPRIVATE;
7327 else if (on_device || declared)
7328 flags |= GOVD_MAP;
7329 else if (AGGREGATE_TYPE_P (type))
7331 /* Aggregates default to 'present_or_copy', or 'present'. */
7332 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7333 flags |= GOVD_MAP;
7334 else
7335 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7337 else
7338 /* Scalars default to 'firstprivate'. */
7339 flags |= GOVD_FIRSTPRIVATE;
7341 break;
7343 default:
7344 gcc_unreachable ();
7347 if (DECL_ARTIFICIAL (decl))
7348 ; /* We can get compiler-generated decls, and should not complain
7349 about them. */
7350 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7352 error ("%qE not specified in enclosing OpenACC %qs construct",
7353 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
7354 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
7356 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7357 ; /* Handled above. */
7358 else
7359 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7361 return flags;
7364 /* Record the fact that DECL was used within the OMP context CTX.
7365 IN_CODE is true when real code uses DECL, and false when we should
7366 merely emit default(none) errors. Return true if DECL is going to
7367 be remapped and thus DECL shouldn't be gimplified into its
7368 DECL_VALUE_EXPR (if any). */
7370 static bool
7371 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7373 splay_tree_node n;
7374 unsigned flags = in_code ? GOVD_SEEN : 0;
7375 bool ret = false, shared;
7377 if (error_operand_p (decl))
7378 return false;
7380 if (ctx->region_type == ORT_NONE)
7381 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7383 if (is_global_var (decl))
7385 /* Threadprivate variables are predetermined. */
7386 if (DECL_THREAD_LOCAL_P (decl))
7387 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7389 if (DECL_HAS_VALUE_EXPR_P (decl))
7391 if (ctx->region_type & ORT_ACC)
7392 /* For OpenACC, defer expansion of value to avoid transfering
7393 privatized common block data instead of im-/explicitly transfered
7394 variables which are in common blocks. */
7396 else
7398 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7400 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7401 return omp_notice_threadprivate_variable (ctx, decl, value);
7405 if (gimplify_omp_ctxp->outer_context == NULL
7406 && VAR_P (decl)
7407 && oacc_get_fn_attrib (current_function_decl))
7409 location_t loc = DECL_SOURCE_LOCATION (decl);
7411 if (lookup_attribute ("omp declare target link",
7412 DECL_ATTRIBUTES (decl)))
7414 error_at (loc,
7415 "%qE with %<link%> clause used in %<routine%> function",
7416 DECL_NAME (decl));
7417 return false;
7419 else if (!lookup_attribute ("omp declare target",
7420 DECL_ATTRIBUTES (decl)))
7422 error_at (loc,
7423 "%qE requires a %<declare%> directive for use "
7424 "in a %<routine%> function", DECL_NAME (decl));
7425 return false;
7430 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7431 if ((ctx->region_type & ORT_TARGET) != 0)
7433 if (ctx->region_type & ORT_ACC)
7434 /* For OpenACC, as remarked above, defer expansion. */
7435 shared = false;
7436 else
7437 shared = true;
7439 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7440 if (n == NULL)
7442 unsigned nflags = flags;
7443 if ((ctx->region_type & ORT_ACC) == 0)
7445 bool is_declare_target = false;
7446 if (is_global_var (decl)
7447 && varpool_node::get_create (decl)->offloadable)
7449 struct gimplify_omp_ctx *octx;
7450 for (octx = ctx->outer_context;
7451 octx; octx = octx->outer_context)
7453 n = splay_tree_lookup (octx->variables,
7454 (splay_tree_key)decl);
7455 if (n
7456 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7457 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7458 break;
7460 is_declare_target = octx == NULL;
7462 if (!is_declare_target)
7464 int gdmk;
7465 enum omp_clause_defaultmap_kind kind;
7466 if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7467 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7468 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7469 == POINTER_TYPE)))
7470 gdmk = GDMK_POINTER;
7471 else if (lang_hooks.decls.omp_scalar_p (decl))
7472 gdmk = GDMK_SCALAR;
7473 else
7474 gdmk = GDMK_AGGREGATE;
7475 kind = lang_hooks.decls.omp_predetermined_mapping (decl);
7476 if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
7478 if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
7479 nflags |= GOVD_FIRSTPRIVATE;
7480 else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
7481 nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
7482 else
7483 gcc_unreachable ();
7485 else if (ctx->defaultmap[gdmk] == 0)
7487 tree d = lang_hooks.decls.omp_report_decl (decl);
7488 error ("%qE not specified in enclosing %<target%>",
7489 DECL_NAME (d));
7490 inform (ctx->location, "enclosing %<target%>");
7492 else if (ctx->defaultmap[gdmk]
7493 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
7494 nflags |= ctx->defaultmap[gdmk];
7495 else
7497 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
7498 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
7503 struct gimplify_omp_ctx *octx = ctx->outer_context;
7504 if ((ctx->region_type & ORT_ACC) && octx)
7506 /* Look in outer OpenACC contexts, to see if there's a
7507 data attribute for this variable. */
7508 omp_notice_variable (octx, decl, in_code);
7510 for (; octx; octx = octx->outer_context)
7512 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7513 break;
7514 splay_tree_node n2
7515 = splay_tree_lookup (octx->variables,
7516 (splay_tree_key) decl);
7517 if (n2)
7519 if (octx->region_type == ORT_ACC_HOST_DATA)
7520 error ("variable %qE declared in enclosing "
7521 "%<host_data%> region", DECL_NAME (decl));
7522 nflags |= GOVD_MAP;
7523 if (octx->region_type == ORT_ACC_DATA
7524 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7525 nflags |= GOVD_MAP_0LEN_ARRAY;
7526 goto found_outer;
7531 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
7532 | GOVD_MAP_ALLOC_ONLY)) == flags)
7534 tree type = TREE_TYPE (decl);
7536 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
7537 && lang_hooks.decls.omp_privatize_by_reference (decl))
7538 type = TREE_TYPE (type);
7539 if (!lang_hooks.types.omp_mappable_type (type))
7541 error ("%qD referenced in target region does not have "
7542 "a mappable type", decl);
7543 nflags |= GOVD_MAP | GOVD_EXPLICIT;
7545 else
7547 if ((ctx->region_type & ORT_ACC) != 0)
7548 nflags = oacc_default_clause (ctx, decl, flags);
7549 else
7550 nflags |= GOVD_MAP;
7553 found_outer:
7554 omp_add_variable (ctx, decl, nflags);
7556 else
7558 /* If nothing changed, there's nothing left to do. */
7559 if ((n->value & flags) == flags)
7560 return ret;
7561 flags |= n->value;
7562 n->value = flags;
7564 goto do_outer;
7567 if (n == NULL)
7569 if (ctx->region_type == ORT_WORKSHARE
7570 || ctx->region_type == ORT_TASKGROUP
7571 || ctx->region_type == ORT_SIMD
7572 || ctx->region_type == ORT_ACC
7573 || (ctx->region_type & ORT_TARGET_DATA) != 0)
7574 goto do_outer;
7576 flags = omp_default_clause (ctx, decl, in_code, flags);
7578 if ((flags & GOVD_PRIVATE)
7579 && lang_hooks.decls.omp_private_outer_ref (decl))
7580 flags |= GOVD_PRIVATE_OUTER_REF;
7582 omp_add_variable (ctx, decl, flags);
7584 shared = (flags & GOVD_SHARED) != 0;
7585 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7586 goto do_outer;
7589 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7590 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7591 && DECL_SIZE (decl))
7593 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7595 splay_tree_node n2;
7596 tree t = DECL_VALUE_EXPR (decl);
7597 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7598 t = TREE_OPERAND (t, 0);
7599 gcc_assert (DECL_P (t));
7600 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7601 n2->value |= GOVD_SEEN;
7603 else if (lang_hooks.decls.omp_privatize_by_reference (decl)
7604 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7605 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7606 != INTEGER_CST))
7608 splay_tree_node n2;
7609 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7610 gcc_assert (DECL_P (t));
7611 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7612 if (n2)
7613 omp_notice_variable (ctx, t, true);
7617 if (ctx->region_type & ORT_ACC)
7618 /* For OpenACC, as remarked above, defer expansion. */
7619 shared = false;
7620 else
7621 shared = ((flags | n->value) & GOVD_SHARED) != 0;
7622 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7624 /* If nothing changed, there's nothing left to do. */
7625 if ((n->value & flags) == flags)
7626 return ret;
7627 flags |= n->value;
7628 n->value = flags;
7630 do_outer:
7631 /* If the variable is private in the current context, then we don't
7632 need to propagate anything to an outer context. */
7633 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7634 return ret;
7635 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7636 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7637 return ret;
7638 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7639 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7640 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7641 return ret;
7642 if (ctx->outer_context
7643 && omp_notice_variable (ctx->outer_context, decl, in_code))
7644 return true;
7645 return ret;
7648 /* Verify that DECL is private within CTX. If there's specific information
7649 to the contrary in the innermost scope, generate an error. */
7651 static bool
7652 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
7654 splay_tree_node n;
7656 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7657 if (n != NULL)
7659 if (n->value & GOVD_SHARED)
7661 if (ctx == gimplify_omp_ctxp)
7663 if (simd)
7664 error ("iteration variable %qE is predetermined linear",
7665 DECL_NAME (decl));
7666 else
7667 error ("iteration variable %qE should be private",
7668 DECL_NAME (decl));
7669 n->value = GOVD_PRIVATE;
7670 return true;
7672 else
7673 return false;
7675 else if ((n->value & GOVD_EXPLICIT) != 0
7676 && (ctx == gimplify_omp_ctxp
7677 || (ctx->region_type == ORT_COMBINED_PARALLEL
7678 && gimplify_omp_ctxp->outer_context == ctx)))
7680 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
7681 error ("iteration variable %qE should not be firstprivate",
7682 DECL_NAME (decl));
7683 else if ((n->value & GOVD_REDUCTION) != 0)
7684 error ("iteration variable %qE should not be reduction",
7685 DECL_NAME (decl));
7686 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
7687 error ("iteration variable %qE should not be linear",
7688 DECL_NAME (decl));
7690 return (ctx == gimplify_omp_ctxp
7691 || (ctx->region_type == ORT_COMBINED_PARALLEL
7692 && gimplify_omp_ctxp->outer_context == ctx));
7695 if (ctx->region_type != ORT_WORKSHARE
7696 && ctx->region_type != ORT_TASKGROUP
7697 && ctx->region_type != ORT_SIMD
7698 && ctx->region_type != ORT_ACC)
7699 return false;
7700 else if (ctx->outer_context)
7701 return omp_is_private (ctx->outer_context, decl, simd);
7702 return false;
7705 /* Return true if DECL is private within a parallel region
7706 that binds to the current construct's context or in parallel
7707 region's REDUCTION clause. */
7709 static bool
7710 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
7712 splay_tree_node n;
7716 ctx = ctx->outer_context;
7717 if (ctx == NULL)
7719 if (is_global_var (decl))
7720 return false;
7722 /* References might be private, but might be shared too,
7723 when checking for copyprivate, assume they might be
7724 private, otherwise assume they might be shared. */
7725 if (copyprivate)
7726 return true;
7728 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7729 return false;
7731 /* Treat C++ privatized non-static data members outside
7732 of the privatization the same. */
7733 if (omp_member_access_dummy_var (decl))
7734 return false;
7736 return true;
7739 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
7741 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7742 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
7743 continue;
7745 if (n != NULL)
7747 if ((n->value & GOVD_LOCAL) != 0
7748 && omp_member_access_dummy_var (decl))
7749 return false;
7750 return (n->value & GOVD_SHARED) == 0;
7753 while (ctx->region_type == ORT_WORKSHARE
7754 || ctx->region_type == ORT_TASKGROUP
7755 || ctx->region_type == ORT_SIMD
7756 || ctx->region_type == ORT_ACC);
7757 return false;
7760 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7762 static tree
7763 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
7765 tree t = *tp;
7767 /* If this node has been visited, unmark it and keep looking. */
7768 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
7769 return t;
7771 if (IS_TYPE_OR_DECL_P (t))
7772 *walk_subtrees = 0;
7773 return NULL_TREE;
7776 /* If *LIST_P contains any OpenMP depend clauses with iterators,
7777 lower all the depend clauses by populating corresponding depend
7778 array. Returns 0 if there are no such depend clauses, or
7779 2 if all depend clauses should be removed, 1 otherwise. */
7781 static int
7782 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
7784 tree c;
7785 gimple *g;
7786 size_t n[4] = { 0, 0, 0, 0 };
7787 bool unused[4];
7788 tree counts[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
7789 tree last_iter = NULL_TREE, last_count = NULL_TREE;
7790 size_t i, j;
7791 location_t first_loc = UNKNOWN_LOCATION;
7793 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
7794 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
7796 switch (OMP_CLAUSE_DEPEND_KIND (c))
7798 case OMP_CLAUSE_DEPEND_IN:
7799 i = 2;
7800 break;
7801 case OMP_CLAUSE_DEPEND_OUT:
7802 case OMP_CLAUSE_DEPEND_INOUT:
7803 i = 0;
7804 break;
7805 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
7806 i = 1;
7807 break;
7808 case OMP_CLAUSE_DEPEND_DEPOBJ:
7809 i = 3;
7810 break;
7811 case OMP_CLAUSE_DEPEND_SOURCE:
7812 case OMP_CLAUSE_DEPEND_SINK:
7813 continue;
7814 default:
7815 gcc_unreachable ();
7817 tree t = OMP_CLAUSE_DECL (c);
7818 if (first_loc == UNKNOWN_LOCATION)
7819 first_loc = OMP_CLAUSE_LOCATION (c);
7820 if (TREE_CODE (t) == TREE_LIST
7821 && TREE_PURPOSE (t)
7822 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
7824 if (TREE_PURPOSE (t) != last_iter)
7826 tree tcnt = size_one_node;
7827 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
7829 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
7830 is_gimple_val, fb_rvalue) == GS_ERROR
7831 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
7832 is_gimple_val, fb_rvalue) == GS_ERROR
7833 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
7834 is_gimple_val, fb_rvalue) == GS_ERROR
7835 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
7836 is_gimple_val, fb_rvalue)
7837 == GS_ERROR))
7838 return 2;
7839 tree var = TREE_VEC_ELT (it, 0);
7840 tree begin = TREE_VEC_ELT (it, 1);
7841 tree end = TREE_VEC_ELT (it, 2);
7842 tree step = TREE_VEC_ELT (it, 3);
7843 tree orig_step = TREE_VEC_ELT (it, 4);
7844 tree type = TREE_TYPE (var);
7845 tree stype = TREE_TYPE (step);
7846 location_t loc = DECL_SOURCE_LOCATION (var);
7847 tree endmbegin;
7848 /* Compute count for this iterator as
7849 orig_step > 0
7850 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
7851 : (begin > end ? (end - begin + (step + 1)) / step : 0)
7852 and compute product of those for the entire depend
7853 clause. */
7854 if (POINTER_TYPE_P (type))
7855 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
7856 stype, end, begin);
7857 else
7858 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
7859 end, begin);
7860 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
7861 step,
7862 build_int_cst (stype, 1));
7863 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
7864 build_int_cst (stype, 1));
7865 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
7866 unshare_expr (endmbegin),
7867 stepm1);
7868 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
7869 pos, step);
7870 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
7871 endmbegin, stepp1);
7872 if (TYPE_UNSIGNED (stype))
7874 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
7875 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
7877 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
7878 neg, step);
7879 step = NULL_TREE;
7880 tree cond = fold_build2_loc (loc, LT_EXPR,
7881 boolean_type_node,
7882 begin, end);
7883 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
7884 build_int_cst (stype, 0));
7885 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
7886 end, begin);
7887 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
7888 build_int_cst (stype, 0));
7889 tree osteptype = TREE_TYPE (orig_step);
7890 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
7891 orig_step,
7892 build_int_cst (osteptype, 0));
7893 tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
7894 cond, pos, neg);
7895 cnt = fold_convert_loc (loc, sizetype, cnt);
7896 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
7897 fb_rvalue) == GS_ERROR)
7898 return 2;
7899 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
7901 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
7902 fb_rvalue) == GS_ERROR)
7903 return 2;
7904 last_iter = TREE_PURPOSE (t);
7905 last_count = tcnt;
7907 if (counts[i] == NULL_TREE)
7908 counts[i] = last_count;
7909 else
7910 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
7911 PLUS_EXPR, counts[i], last_count);
7913 else
7914 n[i]++;
7916 for (i = 0; i < 4; i++)
7917 if (counts[i])
7918 break;
7919 if (i == 4)
7920 return 0;
7922 tree total = size_zero_node;
7923 for (i = 0; i < 4; i++)
7925 unused[i] = counts[i] == NULL_TREE && n[i] == 0;
7926 if (counts[i] == NULL_TREE)
7927 counts[i] = size_zero_node;
7928 if (n[i])
7929 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
7930 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
7931 fb_rvalue) == GS_ERROR)
7932 return 2;
7933 total = size_binop (PLUS_EXPR, total, counts[i]);
7936 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
7937 == GS_ERROR)
7938 return 2;
7939 bool is_old = unused[1] && unused[3];
7940 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
7941 size_int (is_old ? 1 : 4));
7942 tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
7943 tree array = create_tmp_var_raw (type);
7944 TREE_ADDRESSABLE (array) = 1;
7945 if (!poly_int_tree_p (totalpx))
7947 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
7948 gimplify_type_sizes (TREE_TYPE (array), pre_p);
7949 if (gimplify_omp_ctxp)
7951 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
7952 while (ctx
7953 && (ctx->region_type == ORT_WORKSHARE
7954 || ctx->region_type == ORT_TASKGROUP
7955 || ctx->region_type == ORT_SIMD
7956 || ctx->region_type == ORT_ACC))
7957 ctx = ctx->outer_context;
7958 if (ctx)
7959 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
7961 gimplify_vla_decl (array, pre_p);
7963 else
7964 gimple_add_tmp_var (array);
7965 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
7966 NULL_TREE);
7967 tree tem;
7968 if (!is_old)
7970 tem = build2 (MODIFY_EXPR, void_type_node, r,
7971 build_int_cst (ptr_type_node, 0));
7972 gimplify_and_add (tem, pre_p);
7973 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
7974 NULL_TREE);
7976 tem = build2 (MODIFY_EXPR, void_type_node, r,
7977 fold_convert (ptr_type_node, total));
7978 gimplify_and_add (tem, pre_p);
7979 for (i = 1; i < (is_old ? 2 : 4); i++)
7981 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
7982 NULL_TREE, NULL_TREE);
7983 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
7984 gimplify_and_add (tem, pre_p);
7987 tree cnts[4];
7988 for (j = 4; j; j--)
7989 if (!unused[j - 1])
7990 break;
7991 for (i = 0; i < 4; i++)
7993 if (i && (i >= j || unused[i - 1]))
7995 cnts[i] = cnts[i - 1];
7996 continue;
7998 cnts[i] = create_tmp_var (sizetype);
7999 if (i == 0)
8000 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
8001 else
8003 tree t;
8004 if (is_old)
8005 t = size_binop (PLUS_EXPR, counts[0], size_int (2));
8006 else
8007 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
8008 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
8009 == GS_ERROR)
8010 return 2;
8011 g = gimple_build_assign (cnts[i], t);
8013 gimple_seq_add_stmt (pre_p, g);
8016 last_iter = NULL_TREE;
8017 tree last_bind = NULL_TREE;
8018 tree *last_body = NULL;
8019 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8020 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8022 switch (OMP_CLAUSE_DEPEND_KIND (c))
8024 case OMP_CLAUSE_DEPEND_IN:
8025 i = 2;
8026 break;
8027 case OMP_CLAUSE_DEPEND_OUT:
8028 case OMP_CLAUSE_DEPEND_INOUT:
8029 i = 0;
8030 break;
8031 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8032 i = 1;
8033 break;
8034 case OMP_CLAUSE_DEPEND_DEPOBJ:
8035 i = 3;
8036 break;
8037 case OMP_CLAUSE_DEPEND_SOURCE:
8038 case OMP_CLAUSE_DEPEND_SINK:
8039 continue;
8040 default:
8041 gcc_unreachable ();
8043 tree t = OMP_CLAUSE_DECL (c);
8044 if (TREE_CODE (t) == TREE_LIST
8045 && TREE_PURPOSE (t)
8046 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8048 if (TREE_PURPOSE (t) != last_iter)
8050 if (last_bind)
8051 gimplify_and_add (last_bind, pre_p);
8052 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8053 last_bind = build3 (BIND_EXPR, void_type_node,
8054 BLOCK_VARS (block), NULL, block);
8055 TREE_SIDE_EFFECTS (last_bind) = 1;
8056 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
8057 tree *p = &BIND_EXPR_BODY (last_bind);
8058 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8060 tree var = TREE_VEC_ELT (it, 0);
8061 tree begin = TREE_VEC_ELT (it, 1);
8062 tree end = TREE_VEC_ELT (it, 2);
8063 tree step = TREE_VEC_ELT (it, 3);
8064 tree orig_step = TREE_VEC_ELT (it, 4);
8065 tree type = TREE_TYPE (var);
8066 location_t loc = DECL_SOURCE_LOCATION (var);
8067 /* Emit:
8068 var = begin;
8069 goto cond_label;
8070 beg_label:
8072 var = var + step;
8073 cond_label:
8074 if (orig_step > 0) {
8075 if (var < end) goto beg_label;
8076 } else {
8077 if (var > end) goto beg_label;
8079 for each iterator, with inner iterators added to
8080 the ... above. */
8081 tree beg_label = create_artificial_label (loc);
8082 tree cond_label = NULL_TREE;
8083 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8084 var, begin);
8085 append_to_statement_list_force (tem, p);
8086 tem = build_and_jump (&cond_label);
8087 append_to_statement_list_force (tem, p);
8088 tem = build1 (LABEL_EXPR, void_type_node, beg_label);
8089 append_to_statement_list (tem, p);
8090 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
8091 NULL_TREE, NULL_TREE);
8092 TREE_SIDE_EFFECTS (bind) = 1;
8093 SET_EXPR_LOCATION (bind, loc);
8094 append_to_statement_list_force (bind, p);
8095 if (POINTER_TYPE_P (type))
8096 tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
8097 var, fold_convert_loc (loc, sizetype,
8098 step));
8099 else
8100 tem = build2_loc (loc, PLUS_EXPR, type, var, step);
8101 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8102 var, tem);
8103 append_to_statement_list_force (tem, p);
8104 tem = build1 (LABEL_EXPR, void_type_node, cond_label);
8105 append_to_statement_list (tem, p);
8106 tree cond = fold_build2_loc (loc, LT_EXPR,
8107 boolean_type_node,
8108 var, end);
8109 tree pos
8110 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8111 cond, build_and_jump (&beg_label),
8112 void_node);
8113 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8114 var, end);
8115 tree neg
8116 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8117 cond, build_and_jump (&beg_label),
8118 void_node);
8119 tree osteptype = TREE_TYPE (orig_step);
8120 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8121 orig_step,
8122 build_int_cst (osteptype, 0));
8123 tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
8124 cond, pos, neg);
8125 append_to_statement_list_force (tem, p);
8126 p = &BIND_EXPR_BODY (bind);
8128 last_body = p;
8130 last_iter = TREE_PURPOSE (t);
8131 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8133 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
8134 0), last_body);
8135 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8137 if (error_operand_p (TREE_VALUE (t)))
8138 return 2;
8139 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
8140 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8141 NULL_TREE, NULL_TREE);
8142 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8143 void_type_node, r, TREE_VALUE (t));
8144 append_to_statement_list_force (tem, last_body);
8145 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8146 void_type_node, cnts[i],
8147 size_binop (PLUS_EXPR, cnts[i], size_int (1)));
8148 append_to_statement_list_force (tem, last_body);
8149 TREE_VALUE (t) = null_pointer_node;
8151 else
8153 if (last_bind)
8155 gimplify_and_add (last_bind, pre_p);
8156 last_bind = NULL_TREE;
8158 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8160 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8161 NULL, is_gimple_val, fb_rvalue);
8162 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8164 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8165 return 2;
8166 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8167 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8168 is_gimple_val, fb_rvalue) == GS_ERROR)
8169 return 2;
8170 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8171 NULL_TREE, NULL_TREE);
8172 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
8173 gimplify_and_add (tem, pre_p);
8174 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, cnts[i],
8175 size_int (1)));
8176 gimple_seq_add_stmt (pre_p, g);
8179 if (last_bind)
8180 gimplify_and_add (last_bind, pre_p);
8181 tree cond = boolean_false_node;
8182 if (is_old)
8184 if (!unused[0])
8185 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
8186 size_binop_loc (first_loc, PLUS_EXPR, counts[0],
8187 size_int (2)));
8188 if (!unused[2])
8189 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8190 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8191 cnts[2],
8192 size_binop_loc (first_loc, PLUS_EXPR,
8193 totalpx,
8194 size_int (1))));
8196 else
8198 tree prev = size_int (5);
8199 for (i = 0; i < 4; i++)
8201 if (unused[i])
8202 continue;
8203 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
8204 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8205 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8206 cnts[i], unshare_expr (prev)));
8209 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
8210 build_call_expr_loc (first_loc,
8211 builtin_decl_explicit (BUILT_IN_TRAP),
8212 0), void_node);
8213 gimplify_and_add (tem, pre_p);
8214 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
8215 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
8216 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
8217 OMP_CLAUSE_CHAIN (c) = *list_p;
8218 *list_p = c;
8219 return 1;
8222 /* Insert a GOMP_MAP_ALLOC or GOMP_MAP_RELEASE node following a
8223 GOMP_MAP_STRUCT mapping. C is an always_pointer mapping. STRUCT_NODE is
8224 the struct node to insert the new mapping after (when the struct node is
8225 initially created). PREV_NODE is the first of two or three mappings for a
8226 pointer, and is either:
8227 - the node before C, when a pair of mappings is used, e.g. for a C/C++
8228 array section.
8229 - not the node before C. This is true when we have a reference-to-pointer
8230 type (with a mapping for the reference and for the pointer), or for
8231 Fortran derived-type mappings with a GOMP_MAP_TO_PSET.
8232 If SCP is non-null, the new node is inserted before *SCP.
8233 if SCP is null, the new node is inserted before PREV_NODE.
8234 The return type is:
8235 - PREV_NODE, if SCP is non-null.
8236 - The newly-created ALLOC or RELEASE node, if SCP is null.
8237 - The second newly-created ALLOC or RELEASE node, if we are mapping a
8238 reference to a pointer. */
8240 static tree
8241 insert_struct_comp_map (enum tree_code code, tree c, tree struct_node,
8242 tree prev_node, tree *scp)
8244 enum gomp_map_kind mkind
8245 = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
8246 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8248 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8249 tree cl = scp ? prev_node : c2;
8250 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8251 OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (c));
8252 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : prev_node;
8253 if (OMP_CLAUSE_CHAIN (prev_node) != c
8254 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8255 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8256 == GOMP_MAP_TO_PSET))
8257 OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (OMP_CLAUSE_CHAIN (prev_node));
8258 else
8259 OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
8260 if (struct_node)
8261 OMP_CLAUSE_CHAIN (struct_node) = c2;
8263 /* We might need to create an additional mapping if we have a reference to a
8264 pointer (in C++). Don't do this if we have something other than a
8265 GOMP_MAP_ALWAYS_POINTER though, i.e. a GOMP_MAP_TO_PSET. */
8266 if (OMP_CLAUSE_CHAIN (prev_node) != c
8267 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8268 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8269 == GOMP_MAP_ALWAYS_POINTER)
8270 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8271 == GOMP_MAP_ATTACH_DETACH)))
8273 tree c4 = OMP_CLAUSE_CHAIN (prev_node);
8274 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8275 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8276 OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (c4));
8277 OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
8278 OMP_CLAUSE_CHAIN (c3) = prev_node;
8279 if (!scp)
8280 OMP_CLAUSE_CHAIN (c2) = c3;
8281 else
8282 cl = c3;
8285 if (scp)
8286 *scp = c2;
8288 return cl;
8291 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
8292 and set *BITPOSP and *POFFSETP to the bit offset of the access.
8293 If BASE_REF is non-NULL and the containing object is a reference, set
8294 *BASE_REF to that reference before dereferencing the object.
8295 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
8296 has array type, else return NULL. */
8298 static tree
8299 extract_base_bit_offset (tree base, tree *base_ref, poly_int64 *bitposp,
8300 poly_offset_int *poffsetp)
8302 tree offset;
8303 poly_int64 bitsize, bitpos;
8304 machine_mode mode;
8305 int unsignedp, reversep, volatilep = 0;
8306 poly_offset_int poffset;
8308 if (base_ref)
8310 *base_ref = NULL_TREE;
8312 while (TREE_CODE (base) == ARRAY_REF)
8313 base = TREE_OPERAND (base, 0);
8315 if (TREE_CODE (base) == INDIRECT_REF)
8316 base = TREE_OPERAND (base, 0);
8318 else
8320 if (TREE_CODE (base) == ARRAY_REF)
8322 while (TREE_CODE (base) == ARRAY_REF)
8323 base = TREE_OPERAND (base, 0);
8324 if (TREE_CODE (base) != COMPONENT_REF
8325 || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
8326 return NULL_TREE;
8328 else if (TREE_CODE (base) == INDIRECT_REF
8329 && TREE_CODE (TREE_OPERAND (base, 0)) == COMPONENT_REF
8330 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
8331 == REFERENCE_TYPE))
8332 base = TREE_OPERAND (base, 0);
8335 base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
8336 &unsignedp, &reversep, &volatilep);
8338 tree orig_base = base;
8340 if ((TREE_CODE (base) == INDIRECT_REF
8341 || (TREE_CODE (base) == MEM_REF
8342 && integer_zerop (TREE_OPERAND (base, 1))))
8343 && DECL_P (TREE_OPERAND (base, 0))
8344 && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == REFERENCE_TYPE)
8345 base = TREE_OPERAND (base, 0);
8347 gcc_assert (offset == NULL_TREE || poly_int_tree_p (offset));
8349 if (offset)
8350 poffset = wi::to_poly_offset (offset);
8351 else
8352 poffset = 0;
8354 if (maybe_ne (bitpos, 0))
8355 poffset += bits_to_bytes_round_down (bitpos);
8357 *bitposp = bitpos;
8358 *poffsetp = poffset;
8360 /* Set *BASE_REF if BASE was a dereferenced reference variable. */
8361 if (base_ref && orig_base != base)
8362 *base_ref = orig_base;
8364 return base;
8367 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
8368 and previous omp contexts. */
8370 static void
8371 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
8372 enum omp_region_type region_type,
8373 enum tree_code code)
8375 struct gimplify_omp_ctx *ctx, *outer_ctx;
8376 tree c;
8377 hash_map<tree, tree> *struct_map_to_clause = NULL;
8378 hash_set<tree> *struct_deref_set = NULL;
8379 tree *prev_list_p = NULL, *orig_list_p = list_p;
8380 int handled_depend_iterators = -1;
8381 int nowait = -1;
8383 ctx = new_omp_context (region_type);
8384 ctx->code = code;
8385 outer_ctx = ctx->outer_context;
8386 if (code == OMP_TARGET)
8388 if (!lang_GNU_Fortran ())
8389 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
8390 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
8392 if (!lang_GNU_Fortran ())
8393 switch (code)
8395 case OMP_TARGET:
8396 case OMP_TARGET_DATA:
8397 case OMP_TARGET_ENTER_DATA:
8398 case OMP_TARGET_EXIT_DATA:
8399 case OACC_DECLARE:
8400 case OACC_HOST_DATA:
8401 case OACC_PARALLEL:
8402 case OACC_KERNELS:
8403 ctx->target_firstprivatize_array_bases = true;
8404 default:
8405 break;
8408 while ((c = *list_p) != NULL)
8410 bool remove = false;
8411 bool notice_outer = true;
8412 const char *check_non_private = NULL;
8413 unsigned int flags;
8414 tree decl;
8416 switch (OMP_CLAUSE_CODE (c))
8418 case OMP_CLAUSE_PRIVATE:
8419 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
8420 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
8422 flags |= GOVD_PRIVATE_OUTER_REF;
8423 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
8425 else
8426 notice_outer = false;
8427 goto do_add;
8428 case OMP_CLAUSE_SHARED:
8429 flags = GOVD_SHARED | GOVD_EXPLICIT;
8430 goto do_add;
8431 case OMP_CLAUSE_FIRSTPRIVATE:
8432 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8433 check_non_private = "firstprivate";
8434 goto do_add;
8435 case OMP_CLAUSE_LASTPRIVATE:
8436 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
8437 switch (code)
8439 case OMP_DISTRIBUTE:
8440 error_at (OMP_CLAUSE_LOCATION (c),
8441 "conditional %<lastprivate%> clause on "
8442 "%qs construct", "distribute");
8443 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8444 break;
8445 case OMP_TASKLOOP:
8446 error_at (OMP_CLAUSE_LOCATION (c),
8447 "conditional %<lastprivate%> clause on "
8448 "%qs construct", "taskloop");
8449 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8450 break;
8451 default:
8452 break;
8454 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
8455 if (code != OMP_LOOP)
8456 check_non_private = "lastprivate";
8457 decl = OMP_CLAUSE_DECL (c);
8458 if (error_operand_p (decl))
8459 goto do_add;
8460 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
8461 && !lang_hooks.decls.omp_scalar_p (decl))
8463 error_at (OMP_CLAUSE_LOCATION (c),
8464 "non-scalar variable %qD in conditional "
8465 "%<lastprivate%> clause", decl);
8466 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8468 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
8469 flags |= GOVD_LASTPRIVATE_CONDITIONAL;
8470 if (outer_ctx
8471 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
8472 || ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
8473 == ORT_COMBINED_TEAMS))
8474 && splay_tree_lookup (outer_ctx->variables,
8475 (splay_tree_key) decl) == NULL)
8477 omp_add_variable (outer_ctx, decl, GOVD_SHARED | GOVD_SEEN);
8478 if (outer_ctx->outer_context)
8479 omp_notice_variable (outer_ctx->outer_context, decl, true);
8481 else if (outer_ctx
8482 && (outer_ctx->region_type & ORT_TASK) != 0
8483 && outer_ctx->combined_loop
8484 && splay_tree_lookup (outer_ctx->variables,
8485 (splay_tree_key) decl) == NULL)
8487 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8488 if (outer_ctx->outer_context)
8489 omp_notice_variable (outer_ctx->outer_context, decl, true);
8491 else if (outer_ctx
8492 && (outer_ctx->region_type == ORT_WORKSHARE
8493 || outer_ctx->region_type == ORT_ACC)
8494 && outer_ctx->combined_loop
8495 && splay_tree_lookup (outer_ctx->variables,
8496 (splay_tree_key) decl) == NULL
8497 && !omp_check_private (outer_ctx, decl, false))
8499 omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8500 if (outer_ctx->outer_context
8501 && (outer_ctx->outer_context->region_type
8502 == ORT_COMBINED_PARALLEL)
8503 && splay_tree_lookup (outer_ctx->outer_context->variables,
8504 (splay_tree_key) decl) == NULL)
8506 struct gimplify_omp_ctx *octx = outer_ctx->outer_context;
8507 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
8508 if (octx->outer_context)
8510 octx = octx->outer_context;
8511 if (octx->region_type == ORT_WORKSHARE
8512 && octx->combined_loop
8513 && splay_tree_lookup (octx->variables,
8514 (splay_tree_key) decl) == NULL
8515 && !omp_check_private (octx, decl, false))
8517 omp_add_variable (octx, decl,
8518 GOVD_LASTPRIVATE | GOVD_SEEN);
8519 octx = octx->outer_context;
8520 if (octx
8521 && ((octx->region_type & ORT_COMBINED_TEAMS)
8522 == ORT_COMBINED_TEAMS)
8523 && (splay_tree_lookup (octx->variables,
8524 (splay_tree_key) decl)
8525 == NULL))
8527 omp_add_variable (octx, decl,
8528 GOVD_SHARED | GOVD_SEEN);
8529 octx = octx->outer_context;
8532 if (octx)
8533 omp_notice_variable (octx, decl, true);
8536 else if (outer_ctx->outer_context)
8537 omp_notice_variable (outer_ctx->outer_context, decl, true);
8539 goto do_add;
8540 case OMP_CLAUSE_REDUCTION:
8541 if (OMP_CLAUSE_REDUCTION_TASK (c))
8543 if (region_type == ORT_WORKSHARE)
8545 if (nowait == -1)
8546 nowait = omp_find_clause (*list_p,
8547 OMP_CLAUSE_NOWAIT) != NULL_TREE;
8548 if (nowait
8549 && (outer_ctx == NULL
8550 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
8552 error_at (OMP_CLAUSE_LOCATION (c),
8553 "%<task%> reduction modifier on a construct "
8554 "with a %<nowait%> clause");
8555 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
8558 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
8560 error_at (OMP_CLAUSE_LOCATION (c),
8561 "invalid %<task%> reduction modifier on construct "
8562 "other than %<parallel%>, %<for%> or %<sections%>");
8563 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
8566 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
8567 switch (code)
8569 case OMP_SECTIONS:
8570 error_at (OMP_CLAUSE_LOCATION (c),
8571 "%<inscan%> %<reduction%> clause on "
8572 "%qs construct", "sections");
8573 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8574 break;
8575 case OMP_PARALLEL:
8576 error_at (OMP_CLAUSE_LOCATION (c),
8577 "%<inscan%> %<reduction%> clause on "
8578 "%qs construct", "parallel");
8579 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8580 break;
8581 case OMP_TEAMS:
8582 error_at (OMP_CLAUSE_LOCATION (c),
8583 "%<inscan%> %<reduction%> clause on "
8584 "%qs construct", "teams");
8585 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8586 break;
8587 case OMP_TASKLOOP:
8588 error_at (OMP_CLAUSE_LOCATION (c),
8589 "%<inscan%> %<reduction%> clause on "
8590 "%qs construct", "taskloop");
8591 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8592 break;
8593 default:
8594 break;
8596 /* FALLTHRU */
8597 case OMP_CLAUSE_IN_REDUCTION:
8598 case OMP_CLAUSE_TASK_REDUCTION:
8599 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
8600 /* OpenACC permits reductions on private variables. */
8601 if (!(region_type & ORT_ACC)
8602 /* taskgroup is actually not a worksharing region. */
8603 && code != OMP_TASKGROUP)
8604 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
8605 decl = OMP_CLAUSE_DECL (c);
8606 if (TREE_CODE (decl) == MEM_REF)
8608 tree type = TREE_TYPE (decl);
8609 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
8610 NULL, is_gimple_val, fb_rvalue, false)
8611 == GS_ERROR)
8613 remove = true;
8614 break;
8616 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
8617 if (DECL_P (v))
8619 omp_firstprivatize_variable (ctx, v);
8620 omp_notice_variable (ctx, v, true);
8622 decl = TREE_OPERAND (decl, 0);
8623 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
8625 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
8626 NULL, is_gimple_val, fb_rvalue, false)
8627 == GS_ERROR)
8629 remove = true;
8630 break;
8632 v = TREE_OPERAND (decl, 1);
8633 if (DECL_P (v))
8635 omp_firstprivatize_variable (ctx, v);
8636 omp_notice_variable (ctx, v, true);
8638 decl = TREE_OPERAND (decl, 0);
8640 if (TREE_CODE (decl) == ADDR_EXPR
8641 || TREE_CODE (decl) == INDIRECT_REF)
8642 decl = TREE_OPERAND (decl, 0);
8644 goto do_add_decl;
8645 case OMP_CLAUSE_LINEAR:
8646 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
8647 is_gimple_val, fb_rvalue) == GS_ERROR)
8649 remove = true;
8650 break;
8652 else
8654 if (code == OMP_SIMD
8655 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
8657 struct gimplify_omp_ctx *octx = outer_ctx;
8658 if (octx
8659 && octx->region_type == ORT_WORKSHARE
8660 && octx->combined_loop
8661 && !octx->distribute)
8663 if (octx->outer_context
8664 && (octx->outer_context->region_type
8665 == ORT_COMBINED_PARALLEL))
8666 octx = octx->outer_context->outer_context;
8667 else
8668 octx = octx->outer_context;
8670 if (octx
8671 && octx->region_type == ORT_WORKSHARE
8672 && octx->combined_loop
8673 && octx->distribute)
8675 error_at (OMP_CLAUSE_LOCATION (c),
8676 "%<linear%> clause for variable other than "
8677 "loop iterator specified on construct "
8678 "combined with %<distribute%>");
8679 remove = true;
8680 break;
8683 /* For combined #pragma omp parallel for simd, need to put
8684 lastprivate and perhaps firstprivate too on the
8685 parallel. Similarly for #pragma omp for simd. */
8686 struct gimplify_omp_ctx *octx = outer_ctx;
8687 decl = NULL_TREE;
8690 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8691 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8692 break;
8693 decl = OMP_CLAUSE_DECL (c);
8694 if (error_operand_p (decl))
8696 decl = NULL_TREE;
8697 break;
8699 flags = GOVD_SEEN;
8700 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
8701 flags |= GOVD_FIRSTPRIVATE;
8702 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8703 flags |= GOVD_LASTPRIVATE;
8704 if (octx
8705 && octx->region_type == ORT_WORKSHARE
8706 && octx->combined_loop)
8708 if (octx->outer_context
8709 && (octx->outer_context->region_type
8710 == ORT_COMBINED_PARALLEL))
8711 octx = octx->outer_context;
8712 else if (omp_check_private (octx, decl, false))
8713 break;
8715 else if (octx
8716 && (octx->region_type & ORT_TASK) != 0
8717 && octx->combined_loop)
8719 else if (octx
8720 && octx->region_type == ORT_COMBINED_PARALLEL
8721 && ctx->region_type == ORT_WORKSHARE
8722 && octx == outer_ctx)
8723 flags = GOVD_SEEN | GOVD_SHARED;
8724 else if (octx
8725 && ((octx->region_type & ORT_COMBINED_TEAMS)
8726 == ORT_COMBINED_TEAMS))
8727 flags = GOVD_SEEN | GOVD_SHARED;
8728 else if (octx
8729 && octx->region_type == ORT_COMBINED_TARGET)
8731 flags &= ~GOVD_LASTPRIVATE;
8732 if (flags == GOVD_SEEN)
8733 break;
8735 else
8736 break;
8737 splay_tree_node on
8738 = splay_tree_lookup (octx->variables,
8739 (splay_tree_key) decl);
8740 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
8742 octx = NULL;
8743 break;
8745 omp_add_variable (octx, decl, flags);
8746 if (octx->outer_context == NULL)
8747 break;
8748 octx = octx->outer_context;
8750 while (1);
8751 if (octx
8752 && decl
8753 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8754 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
8755 omp_notice_variable (octx, decl, true);
8757 flags = GOVD_LINEAR | GOVD_EXPLICIT;
8758 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
8759 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
8761 notice_outer = false;
8762 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
8764 goto do_add;
8766 case OMP_CLAUSE_MAP:
8767 decl = OMP_CLAUSE_DECL (c);
8768 if (error_operand_p (decl))
8769 remove = true;
8770 switch (code)
8772 case OMP_TARGET:
8773 break;
8774 case OACC_DATA:
8775 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
8776 break;
8777 /* FALLTHRU */
8778 case OMP_TARGET_DATA:
8779 case OMP_TARGET_ENTER_DATA:
8780 case OMP_TARGET_EXIT_DATA:
8781 case OACC_ENTER_DATA:
8782 case OACC_EXIT_DATA:
8783 case OACC_HOST_DATA:
8784 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
8785 || (OMP_CLAUSE_MAP_KIND (c)
8786 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8787 /* For target {,enter ,exit }data only the array slice is
8788 mapped, but not the pointer to it. */
8789 remove = true;
8790 break;
8791 default:
8792 break;
8794 /* For Fortran, not only the pointer to the data is mapped but also
8795 the address of the pointer, the array descriptor etc.; for
8796 'exit data' - and in particular for 'delete:' - having an 'alloc:'
8797 does not make sense. Likewise, for 'update' only transferring the
8798 data itself is needed as the rest has been handled in previous
8799 directives. However, for 'exit data', the array descriptor needs
8800 to be delete; hence, we turn the MAP_TO_PSET into a MAP_DELETE.
8802 NOTE: Generally, it is not safe to perform "enter data" operations
8803 on arrays where the data *or the descriptor* may go out of scope
8804 before a corresponding "exit data" operation -- and such a
8805 descriptor may be synthesized temporarily, e.g. to pass an
8806 explicit-shape array to a function expecting an assumed-shape
8807 argument. Performing "enter data" inside the called function
8808 would thus be problematic. */
8809 if (code == OMP_TARGET_EXIT_DATA
8810 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
8811 OMP_CLAUSE_SET_MAP_KIND (c, OMP_CLAUSE_MAP_KIND (*prev_list_p)
8812 == GOMP_MAP_DELETE
8813 ? GOMP_MAP_DELETE : GOMP_MAP_RELEASE);
8814 else if ((code == OMP_TARGET_EXIT_DATA || code == OMP_TARGET_UPDATE)
8815 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
8816 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET))
8817 remove = true;
8819 if (remove)
8820 break;
8821 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
8823 struct gimplify_omp_ctx *octx;
8824 for (octx = outer_ctx; octx; octx = octx->outer_context)
8826 if (octx->region_type != ORT_ACC_HOST_DATA)
8827 break;
8828 splay_tree_node n2
8829 = splay_tree_lookup (octx->variables,
8830 (splay_tree_key) decl);
8831 if (n2)
8832 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
8833 "declared in enclosing %<host_data%> region",
8834 DECL_NAME (decl));
8837 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
8838 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
8839 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
8840 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
8841 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
8843 remove = true;
8844 break;
8846 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
8847 || (OMP_CLAUSE_MAP_KIND (c)
8848 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
8849 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
8851 OMP_CLAUSE_SIZE (c)
8852 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
8853 false);
8854 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
8855 GOVD_FIRSTPRIVATE | GOVD_SEEN);
8857 if (!DECL_P (decl))
8859 tree d = decl, *pd;
8860 if (TREE_CODE (d) == ARRAY_REF)
8862 while (TREE_CODE (d) == ARRAY_REF)
8863 d = TREE_OPERAND (d, 0);
8864 if (TREE_CODE (d) == COMPONENT_REF
8865 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
8866 decl = d;
8868 pd = &OMP_CLAUSE_DECL (c);
8869 if (d == decl
8870 && TREE_CODE (decl) == INDIRECT_REF
8871 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
8872 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8873 == REFERENCE_TYPE))
8875 pd = &TREE_OPERAND (decl, 0);
8876 decl = TREE_OPERAND (decl, 0);
8878 bool indir_p = false;
8879 tree orig_decl = decl;
8880 tree decl_ref = NULL_TREE;
8881 if ((region_type & ORT_ACC) != 0
8882 && TREE_CODE (*pd) == COMPONENT_REF
8883 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
8884 && code != OACC_UPDATE)
8886 while (TREE_CODE (decl) == COMPONENT_REF)
8888 decl = TREE_OPERAND (decl, 0);
8889 if ((TREE_CODE (decl) == MEM_REF
8890 && integer_zerop (TREE_OPERAND (decl, 1)))
8891 || INDIRECT_REF_P (decl))
8893 indir_p = true;
8894 decl = TREE_OPERAND (decl, 0);
8896 if (TREE_CODE (decl) == INDIRECT_REF
8897 && DECL_P (TREE_OPERAND (decl, 0))
8898 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8899 == REFERENCE_TYPE))
8901 decl_ref = decl;
8902 decl = TREE_OPERAND (decl, 0);
8906 else if (TREE_CODE (decl) == COMPONENT_REF)
8908 while (TREE_CODE (decl) == COMPONENT_REF)
8909 decl = TREE_OPERAND (decl, 0);
8910 if (TREE_CODE (decl) == INDIRECT_REF
8911 && DECL_P (TREE_OPERAND (decl, 0))
8912 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
8913 == REFERENCE_TYPE))
8914 decl = TREE_OPERAND (decl, 0);
8916 if (decl != orig_decl && DECL_P (decl) && indir_p)
8918 gomp_map_kind k = (code == OACC_EXIT_DATA) ? GOMP_MAP_DETACH
8919 : GOMP_MAP_ATTACH;
8920 /* We have a dereference of a struct member. Make this an
8921 attach/detach operation, and ensure the base pointer is
8922 mapped as a FIRSTPRIVATE_POINTER. */
8923 OMP_CLAUSE_SET_MAP_KIND (c, k);
8924 flags = GOVD_MAP | GOVD_SEEN | GOVD_EXPLICIT;
8925 tree next_clause = OMP_CLAUSE_CHAIN (c);
8926 if (k == GOMP_MAP_ATTACH
8927 && code != OACC_ENTER_DATA
8928 && (!next_clause
8929 || (OMP_CLAUSE_CODE (next_clause) != OMP_CLAUSE_MAP)
8930 || (OMP_CLAUSE_MAP_KIND (next_clause)
8931 != GOMP_MAP_POINTER)
8932 || OMP_CLAUSE_DECL (next_clause) != decl)
8933 && (!struct_deref_set
8934 || !struct_deref_set->contains (decl)))
8936 if (!struct_deref_set)
8937 struct_deref_set = new hash_set<tree> ();
8938 /* As well as the attach, we also need a
8939 FIRSTPRIVATE_POINTER clause to properly map the
8940 pointer to the struct base. */
8941 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8942 OMP_CLAUSE_MAP);
8943 OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALLOC);
8944 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c2)
8945 = 1;
8946 tree charptr_zero
8947 = build_int_cst (build_pointer_type (char_type_node),
8949 OMP_CLAUSE_DECL (c2)
8950 = build2 (MEM_REF, char_type_node,
8951 decl_ref ? decl_ref : decl, charptr_zero);
8952 OMP_CLAUSE_SIZE (c2) = size_zero_node;
8953 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
8954 OMP_CLAUSE_MAP);
8955 OMP_CLAUSE_SET_MAP_KIND (c3,
8956 GOMP_MAP_FIRSTPRIVATE_POINTER);
8957 OMP_CLAUSE_DECL (c3) = decl;
8958 OMP_CLAUSE_SIZE (c3) = size_zero_node;
8959 tree mapgrp = *prev_list_p;
8960 *prev_list_p = c2;
8961 OMP_CLAUSE_CHAIN (c3) = mapgrp;
8962 OMP_CLAUSE_CHAIN (c2) = c3;
8964 struct_deref_set->add (decl);
8966 goto do_add_decl;
8968 /* An "attach/detach" operation on an update directive should
8969 behave as a GOMP_MAP_ALWAYS_POINTER. Beware that
8970 unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
8971 depends on the previous mapping. */
8972 if (code == OACC_UPDATE
8973 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
8974 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
8975 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, fb_lvalue)
8976 == GS_ERROR)
8978 remove = true;
8979 break;
8981 if (DECL_P (decl)
8982 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
8983 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
8984 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
8985 && code != OACC_UPDATE)
8987 if (error_operand_p (decl))
8989 remove = true;
8990 break;
8993 tree stype = TREE_TYPE (decl);
8994 if (TREE_CODE (stype) == REFERENCE_TYPE)
8995 stype = TREE_TYPE (stype);
8996 if (TYPE_SIZE_UNIT (stype) == NULL
8997 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
8999 error_at (OMP_CLAUSE_LOCATION (c),
9000 "mapping field %qE of variable length "
9001 "structure", OMP_CLAUSE_DECL (c));
9002 remove = true;
9003 break;
9006 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
9007 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9009 /* Error recovery. */
9010 if (prev_list_p == NULL)
9012 remove = true;
9013 break;
9015 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
9017 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
9018 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
9020 remove = true;
9021 break;
9026 poly_offset_int offset1;
9027 poly_int64 bitpos1;
9028 tree base_ref;
9030 tree base
9031 = extract_base_bit_offset (OMP_CLAUSE_DECL (c), &base_ref,
9032 &bitpos1, &offset1);
9034 gcc_assert (base == decl);
9036 splay_tree_node n
9037 = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
9038 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
9039 == GOMP_MAP_ALWAYS_POINTER);
9040 bool attach_detach = (OMP_CLAUSE_MAP_KIND (c)
9041 == GOMP_MAP_ATTACH_DETACH);
9042 bool attach = OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9043 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH;
9044 bool has_attachments = false;
9045 /* For OpenACC, pointers in structs should trigger an
9046 attach action. */
9047 if (attach_detach && (region_type & ORT_ACC) != 0)
9049 /* Turn a GOMP_MAP_ATTACH_DETACH clause into a
9050 GOMP_MAP_ATTACH or GOMP_MAP_DETACH clause after we
9051 have detected a case that needs a GOMP_MAP_STRUCT
9052 mapping added. */
9053 gomp_map_kind k
9054 = (code == OACC_EXIT_DATA) ? GOMP_MAP_DETACH
9055 : GOMP_MAP_ATTACH;
9056 OMP_CLAUSE_SET_MAP_KIND (c, k);
9057 has_attachments = true;
9059 if (n == NULL || (n->value & GOVD_MAP) == 0)
9061 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9062 OMP_CLAUSE_MAP);
9063 gomp_map_kind k = attach ? GOMP_MAP_FORCE_PRESENT
9064 : GOMP_MAP_STRUCT;
9066 OMP_CLAUSE_SET_MAP_KIND (l, k);
9067 if (base_ref)
9068 OMP_CLAUSE_DECL (l) = unshare_expr (base_ref);
9069 else
9070 OMP_CLAUSE_DECL (l) = decl;
9071 OMP_CLAUSE_SIZE (l)
9072 = (!attach
9073 ? size_int (1)
9074 : DECL_P (OMP_CLAUSE_DECL (l))
9075 ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l))
9076 : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l))));
9077 if (struct_map_to_clause == NULL)
9078 struct_map_to_clause = new hash_map<tree, tree>;
9079 struct_map_to_clause->put (decl, l);
9080 if (ptr || attach_detach)
9082 insert_struct_comp_map (code, c, l, *prev_list_p,
9083 NULL);
9084 *prev_list_p = l;
9085 prev_list_p = NULL;
9087 else
9089 OMP_CLAUSE_CHAIN (l) = c;
9090 *list_p = l;
9091 list_p = &OMP_CLAUSE_CHAIN (l);
9093 if (base_ref && code == OMP_TARGET)
9095 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9096 OMP_CLAUSE_MAP);
9097 enum gomp_map_kind mkind
9098 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
9099 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9100 OMP_CLAUSE_DECL (c2) = decl;
9101 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9102 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
9103 OMP_CLAUSE_CHAIN (l) = c2;
9105 flags = GOVD_MAP | GOVD_EXPLICIT;
9106 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9107 || ptr
9108 || attach_detach)
9109 flags |= GOVD_SEEN;
9110 if (has_attachments)
9111 flags |= GOVD_MAP_HAS_ATTACHMENTS;
9112 goto do_add_decl;
9114 else if (struct_map_to_clause)
9116 tree *osc = struct_map_to_clause->get (decl);
9117 tree *sc = NULL, *scp = NULL;
9118 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9119 || ptr
9120 || attach_detach)
9121 n->value |= GOVD_SEEN;
9122 sc = &OMP_CLAUSE_CHAIN (*osc);
9123 if (*sc != c
9124 && (OMP_CLAUSE_MAP_KIND (*sc)
9125 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9126 sc = &OMP_CLAUSE_CHAIN (*sc);
9127 /* Here "prev_list_p" is the end of the inserted
9128 alloc/release nodes after the struct node, OSC. */
9129 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
9130 if ((ptr || attach_detach) && sc == prev_list_p)
9131 break;
9132 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9133 != COMPONENT_REF
9134 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9135 != INDIRECT_REF)
9136 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9137 != ARRAY_REF))
9138 break;
9139 else
9141 tree sc_decl = OMP_CLAUSE_DECL (*sc);
9142 poly_offset_int offsetn;
9143 poly_int64 bitposn;
9144 tree base
9145 = extract_base_bit_offset (sc_decl, NULL,
9146 &bitposn, &offsetn);
9147 if (base != decl)
9148 break;
9149 if (scp)
9150 continue;
9151 tree d1 = OMP_CLAUSE_DECL (*sc);
9152 tree d2 = OMP_CLAUSE_DECL (c);
9153 while (TREE_CODE (d1) == ARRAY_REF)
9154 d1 = TREE_OPERAND (d1, 0);
9155 while (TREE_CODE (d2) == ARRAY_REF)
9156 d2 = TREE_OPERAND (d2, 0);
9157 if (TREE_CODE (d1) == INDIRECT_REF)
9158 d1 = TREE_OPERAND (d1, 0);
9159 if (TREE_CODE (d2) == INDIRECT_REF)
9160 d2 = TREE_OPERAND (d2, 0);
9161 while (TREE_CODE (d1) == COMPONENT_REF)
9162 if (TREE_CODE (d2) == COMPONENT_REF
9163 && TREE_OPERAND (d1, 1)
9164 == TREE_OPERAND (d2, 1))
9166 d1 = TREE_OPERAND (d1, 0);
9167 d2 = TREE_OPERAND (d2, 0);
9169 else
9170 break;
9171 if (d1 == d2)
9173 error_at (OMP_CLAUSE_LOCATION (c),
9174 "%qE appears more than once in map "
9175 "clauses", OMP_CLAUSE_DECL (c));
9176 remove = true;
9177 break;
9179 if (maybe_lt (offset1, offsetn)
9180 || (known_eq (offset1, offsetn)
9181 && maybe_lt (bitpos1, bitposn)))
9183 if (ptr || attach_detach)
9184 scp = sc;
9185 else
9186 break;
9189 if (remove)
9190 break;
9191 if (!attach)
9192 OMP_CLAUSE_SIZE (*osc)
9193 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
9194 size_one_node);
9195 if (ptr || attach_detach)
9197 tree cl = insert_struct_comp_map (code, c, NULL,
9198 *prev_list_p, scp);
9199 if (sc == prev_list_p)
9201 *sc = cl;
9202 prev_list_p = NULL;
9204 else
9206 *prev_list_p = OMP_CLAUSE_CHAIN (c);
9207 list_p = prev_list_p;
9208 prev_list_p = NULL;
9209 OMP_CLAUSE_CHAIN (c) = *sc;
9210 *sc = cl;
9211 continue;
9214 else if (*sc != c)
9216 *list_p = OMP_CLAUSE_CHAIN (c);
9217 OMP_CLAUSE_CHAIN (c) = *sc;
9218 *sc = c;
9219 continue;
9223 if (!remove
9224 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
9225 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
9226 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
9227 && OMP_CLAUSE_CHAIN (c)
9228 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
9229 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9230 == GOMP_MAP_ALWAYS_POINTER)
9231 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9232 == GOMP_MAP_ATTACH_DETACH)
9233 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9234 == GOMP_MAP_TO_PSET)))
9235 prev_list_p = list_p;
9237 break;
9239 flags = GOVD_MAP | GOVD_EXPLICIT;
9240 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
9241 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
9242 flags |= GOVD_MAP_ALWAYS_TO;
9243 goto do_add;
9245 case OMP_CLAUSE_DEPEND:
9246 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
9248 tree deps = OMP_CLAUSE_DECL (c);
9249 while (deps && TREE_CODE (deps) == TREE_LIST)
9251 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
9252 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
9253 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
9254 pre_p, NULL, is_gimple_val, fb_rvalue);
9255 deps = TREE_CHAIN (deps);
9257 break;
9259 else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
9260 break;
9261 if (handled_depend_iterators == -1)
9262 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
9263 if (handled_depend_iterators)
9265 if (handled_depend_iterators == 2)
9266 remove = true;
9267 break;
9269 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
9271 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
9272 NULL, is_gimple_val, fb_rvalue);
9273 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
9275 if (error_operand_p (OMP_CLAUSE_DECL (c)))
9277 remove = true;
9278 break;
9280 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
9281 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
9282 is_gimple_val, fb_rvalue) == GS_ERROR)
9284 remove = true;
9285 break;
9287 break;
9289 case OMP_CLAUSE_TO:
9290 case OMP_CLAUSE_FROM:
9291 case OMP_CLAUSE__CACHE_:
9292 decl = OMP_CLAUSE_DECL (c);
9293 if (error_operand_p (decl))
9295 remove = true;
9296 break;
9298 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9299 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
9300 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
9301 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
9302 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
9304 remove = true;
9305 break;
9307 if (!DECL_P (decl))
9309 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
9310 NULL, is_gimple_lvalue, fb_lvalue)
9311 == GS_ERROR)
9313 remove = true;
9314 break;
9316 break;
9318 goto do_notice;
9320 case OMP_CLAUSE_USE_DEVICE_PTR:
9321 case OMP_CLAUSE_USE_DEVICE_ADDR:
9322 flags = GOVD_EXPLICIT;
9323 goto do_add;
9325 case OMP_CLAUSE_IS_DEVICE_PTR:
9326 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
9327 goto do_add;
9329 do_add:
9330 decl = OMP_CLAUSE_DECL (c);
9331 do_add_decl:
9332 if (error_operand_p (decl))
9334 remove = true;
9335 break;
9337 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
9339 tree t = omp_member_access_dummy_var (decl);
9340 if (t)
9342 tree v = DECL_VALUE_EXPR (decl);
9343 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
9344 if (outer_ctx)
9345 omp_notice_variable (outer_ctx, t, true);
9348 if (code == OACC_DATA
9349 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9350 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
9351 flags |= GOVD_MAP_0LEN_ARRAY;
9352 omp_add_variable (ctx, decl, flags);
9353 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9354 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
9355 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
9356 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
9358 omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
9359 GOVD_LOCAL | GOVD_SEEN);
9360 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
9361 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
9362 find_decl_expr,
9363 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
9364 NULL) == NULL_TREE)
9365 omp_add_variable (ctx,
9366 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
9367 GOVD_LOCAL | GOVD_SEEN);
9368 gimplify_omp_ctxp = ctx;
9369 push_gimplify_context ();
9371 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
9372 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
9374 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
9375 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
9376 pop_gimplify_context
9377 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
9378 push_gimplify_context ();
9379 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
9380 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
9381 pop_gimplify_context
9382 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
9383 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
9384 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
9386 gimplify_omp_ctxp = outer_ctx;
9388 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
9389 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
9391 gimplify_omp_ctxp = ctx;
9392 push_gimplify_context ();
9393 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
9395 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
9396 NULL, NULL);
9397 TREE_SIDE_EFFECTS (bind) = 1;
9398 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
9399 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
9401 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
9402 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
9403 pop_gimplify_context
9404 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
9405 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
9407 gimplify_omp_ctxp = outer_ctx;
9409 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9410 && OMP_CLAUSE_LINEAR_STMT (c))
9412 gimplify_omp_ctxp = ctx;
9413 push_gimplify_context ();
9414 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
9416 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
9417 NULL, NULL);
9418 TREE_SIDE_EFFECTS (bind) = 1;
9419 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
9420 OMP_CLAUSE_LINEAR_STMT (c) = bind;
9422 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
9423 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
9424 pop_gimplify_context
9425 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
9426 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
9428 gimplify_omp_ctxp = outer_ctx;
9430 if (notice_outer)
9431 goto do_notice;
9432 break;
9434 case OMP_CLAUSE_COPYIN:
9435 case OMP_CLAUSE_COPYPRIVATE:
9436 decl = OMP_CLAUSE_DECL (c);
9437 if (error_operand_p (decl))
9439 remove = true;
9440 break;
9442 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
9443 && !remove
9444 && !omp_check_private (ctx, decl, true))
9446 remove = true;
9447 if (is_global_var (decl))
9449 if (DECL_THREAD_LOCAL_P (decl))
9450 remove = false;
9451 else if (DECL_HAS_VALUE_EXPR_P (decl))
9453 tree value = get_base_address (DECL_VALUE_EXPR (decl));
9455 if (value
9456 && DECL_P (value)
9457 && DECL_THREAD_LOCAL_P (value))
9458 remove = false;
9461 if (remove)
9462 error_at (OMP_CLAUSE_LOCATION (c),
9463 "copyprivate variable %qE is not threadprivate"
9464 " or private in outer context", DECL_NAME (decl));
9466 do_notice:
9467 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9468 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
9469 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
9470 && outer_ctx
9471 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
9472 || (region_type == ORT_WORKSHARE
9473 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9474 && (OMP_CLAUSE_REDUCTION_INSCAN (c)
9475 || code == OMP_LOOP)))
9476 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
9477 || (code == OMP_LOOP
9478 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9479 && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
9480 == ORT_COMBINED_TEAMS))))
9482 splay_tree_node on
9483 = splay_tree_lookup (outer_ctx->variables,
9484 (splay_tree_key)decl);
9485 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
9487 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9488 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
9489 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
9490 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
9491 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
9492 == POINTER_TYPE))))
9493 omp_firstprivatize_variable (outer_ctx, decl);
9494 else
9496 omp_add_variable (outer_ctx, decl,
9497 GOVD_SEEN | GOVD_SHARED);
9498 if (outer_ctx->outer_context)
9499 omp_notice_variable (outer_ctx->outer_context, decl,
9500 true);
9504 if (outer_ctx)
9505 omp_notice_variable (outer_ctx, decl, true);
9506 if (check_non_private
9507 && region_type == ORT_WORKSHARE
9508 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
9509 || decl == OMP_CLAUSE_DECL (c)
9510 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
9511 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
9512 == ADDR_EXPR
9513 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
9514 == POINTER_PLUS_EXPR
9515 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
9516 (OMP_CLAUSE_DECL (c), 0), 0))
9517 == ADDR_EXPR)))))
9518 && omp_check_private (ctx, decl, false))
9520 error ("%s variable %qE is private in outer context",
9521 check_non_private, DECL_NAME (decl));
9522 remove = true;
9524 break;
9526 case OMP_CLAUSE_IF:
9527 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
9528 && OMP_CLAUSE_IF_MODIFIER (c) != code)
9530 const char *p[2];
9531 for (int i = 0; i < 2; i++)
9532 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
9534 case VOID_CST: p[i] = "cancel"; break;
9535 case OMP_PARALLEL: p[i] = "parallel"; break;
9536 case OMP_SIMD: p[i] = "simd"; break;
9537 case OMP_TASK: p[i] = "task"; break;
9538 case OMP_TASKLOOP: p[i] = "taskloop"; break;
9539 case OMP_TARGET_DATA: p[i] = "target data"; break;
9540 case OMP_TARGET: p[i] = "target"; break;
9541 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
9542 case OMP_TARGET_ENTER_DATA:
9543 p[i] = "target enter data"; break;
9544 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
9545 default: gcc_unreachable ();
9547 error_at (OMP_CLAUSE_LOCATION (c),
9548 "expected %qs %<if%> clause modifier rather than %qs",
9549 p[0], p[1]);
9550 remove = true;
9552 /* Fall through. */
9554 case OMP_CLAUSE_FINAL:
9555 OMP_CLAUSE_OPERAND (c, 0)
9556 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
9557 /* Fall through. */
9559 case OMP_CLAUSE_SCHEDULE:
9560 case OMP_CLAUSE_NUM_THREADS:
9561 case OMP_CLAUSE_NUM_TEAMS:
9562 case OMP_CLAUSE_THREAD_LIMIT:
9563 case OMP_CLAUSE_DIST_SCHEDULE:
9564 case OMP_CLAUSE_DEVICE:
9565 case OMP_CLAUSE_PRIORITY:
9566 case OMP_CLAUSE_GRAINSIZE:
9567 case OMP_CLAUSE_NUM_TASKS:
9568 case OMP_CLAUSE_HINT:
9569 case OMP_CLAUSE_ASYNC:
9570 case OMP_CLAUSE_WAIT:
9571 case OMP_CLAUSE_NUM_GANGS:
9572 case OMP_CLAUSE_NUM_WORKERS:
9573 case OMP_CLAUSE_VECTOR_LENGTH:
9574 case OMP_CLAUSE_WORKER:
9575 case OMP_CLAUSE_VECTOR:
9576 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
9577 is_gimple_val, fb_rvalue) == GS_ERROR)
9578 remove = true;
9579 break;
9581 case OMP_CLAUSE_GANG:
9582 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
9583 is_gimple_val, fb_rvalue) == GS_ERROR)
9584 remove = true;
9585 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
9586 is_gimple_val, fb_rvalue) == GS_ERROR)
9587 remove = true;
9588 break;
9590 case OMP_CLAUSE_NOWAIT:
9591 nowait = 1;
9592 break;
9594 case OMP_CLAUSE_ORDERED:
9595 case OMP_CLAUSE_UNTIED:
9596 case OMP_CLAUSE_COLLAPSE:
9597 case OMP_CLAUSE_TILE:
9598 case OMP_CLAUSE_AUTO:
9599 case OMP_CLAUSE_SEQ:
9600 case OMP_CLAUSE_INDEPENDENT:
9601 case OMP_CLAUSE_MERGEABLE:
9602 case OMP_CLAUSE_PROC_BIND:
9603 case OMP_CLAUSE_SAFELEN:
9604 case OMP_CLAUSE_SIMDLEN:
9605 case OMP_CLAUSE_NOGROUP:
9606 case OMP_CLAUSE_THREADS:
9607 case OMP_CLAUSE_SIMD:
9608 case OMP_CLAUSE_BIND:
9609 case OMP_CLAUSE_IF_PRESENT:
9610 case OMP_CLAUSE_FINALIZE:
9611 break;
9613 case OMP_CLAUSE_ORDER:
9614 ctx->order_concurrent = true;
9615 break;
9617 case OMP_CLAUSE_DEFAULTMAP:
9618 enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
9619 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
9621 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
9622 gdmkmin = GDMK_SCALAR;
9623 gdmkmax = GDMK_POINTER;
9624 break;
9625 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
9626 gdmkmin = gdmkmax = GDMK_SCALAR;
9627 break;
9628 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
9629 gdmkmin = gdmkmax = GDMK_AGGREGATE;
9630 break;
9631 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
9632 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
9633 break;
9634 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
9635 gdmkmin = gdmkmax = GDMK_POINTER;
9636 break;
9637 default:
9638 gcc_unreachable ();
9640 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
9641 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
9643 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
9644 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
9645 break;
9646 case OMP_CLAUSE_DEFAULTMAP_TO:
9647 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
9648 break;
9649 case OMP_CLAUSE_DEFAULTMAP_FROM:
9650 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
9651 break;
9652 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
9653 ctx->defaultmap[gdmk] = GOVD_MAP;
9654 break;
9655 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
9656 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
9657 break;
9658 case OMP_CLAUSE_DEFAULTMAP_NONE:
9659 ctx->defaultmap[gdmk] = 0;
9660 break;
9661 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
9662 switch (gdmk)
9664 case GDMK_SCALAR:
9665 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
9666 break;
9667 case GDMK_AGGREGATE:
9668 case GDMK_ALLOCATABLE:
9669 ctx->defaultmap[gdmk] = GOVD_MAP;
9670 break;
9671 case GDMK_POINTER:
9672 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
9673 break;
9674 default:
9675 gcc_unreachable ();
9677 break;
9678 default:
9679 gcc_unreachable ();
9681 break;
9683 case OMP_CLAUSE_ALIGNED:
9684 decl = OMP_CLAUSE_DECL (c);
9685 if (error_operand_p (decl))
9687 remove = true;
9688 break;
9690 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
9691 is_gimple_val, fb_rvalue) == GS_ERROR)
9693 remove = true;
9694 break;
9696 if (!is_global_var (decl)
9697 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
9698 omp_add_variable (ctx, decl, GOVD_ALIGNED);
9699 break;
9701 case OMP_CLAUSE_NONTEMPORAL:
9702 decl = OMP_CLAUSE_DECL (c);
9703 if (error_operand_p (decl))
9705 remove = true;
9706 break;
9708 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
9709 break;
9711 case OMP_CLAUSE_DEFAULT:
9712 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
9713 break;
9715 case OMP_CLAUSE_INCLUSIVE:
9716 case OMP_CLAUSE_EXCLUSIVE:
9717 decl = OMP_CLAUSE_DECL (c);
9719 splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
9720 (splay_tree_key) decl);
9721 if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
9723 error_at (OMP_CLAUSE_LOCATION (c),
9724 "%qD specified in %qs clause but not in %<inscan%> "
9725 "%<reduction%> clause on the containing construct",
9726 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9727 remove = true;
9729 else
9731 n->value |= GOVD_REDUCTION_INSCAN;
9732 if (outer_ctx->region_type == ORT_SIMD
9733 && outer_ctx->outer_context
9734 && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
9736 n = splay_tree_lookup (outer_ctx->outer_context->variables,
9737 (splay_tree_key) decl);
9738 if (n && (n->value & GOVD_REDUCTION) != 0)
9739 n->value |= GOVD_REDUCTION_INSCAN;
9743 break;
9745 default:
9746 gcc_unreachable ();
9749 if (code == OACC_DATA
9750 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9751 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9752 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9753 remove = true;
9754 if (remove)
9755 *list_p = OMP_CLAUSE_CHAIN (c);
9756 else
9757 list_p = &OMP_CLAUSE_CHAIN (c);
9760 ctx->clauses = *orig_list_p;
9761 gimplify_omp_ctxp = ctx;
9762 if (struct_map_to_clause)
9763 delete struct_map_to_clause;
9764 if (struct_deref_set)
9765 delete struct_deref_set;
9768 /* Return true if DECL is a candidate for shared to firstprivate
9769 optimization. We only consider non-addressable scalars, not
9770 too big, and not references. */
9772 static bool
9773 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
9775 if (TREE_ADDRESSABLE (decl))
9776 return false;
9777 tree type = TREE_TYPE (decl);
9778 if (!is_gimple_reg_type (type)
9779 || TREE_CODE (type) == REFERENCE_TYPE
9780 || TREE_ADDRESSABLE (type))
9781 return false;
9782 /* Don't optimize too large decls, as each thread/task will have
9783 its own. */
9784 HOST_WIDE_INT len = int_size_in_bytes (type);
9785 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
9786 return false;
9787 if (lang_hooks.decls.omp_privatize_by_reference (decl))
9788 return false;
9789 return true;
9792 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
9793 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
9794 GOVD_WRITTEN in outer contexts. */
9796 static void
9797 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
9799 for (; ctx; ctx = ctx->outer_context)
9801 splay_tree_node n = splay_tree_lookup (ctx->variables,
9802 (splay_tree_key) decl);
9803 if (n == NULL)
9804 continue;
9805 else if (n->value & GOVD_SHARED)
9807 n->value |= GOVD_WRITTEN;
9808 return;
9810 else if (n->value & GOVD_DATA_SHARE_CLASS)
9811 return;
9815 /* Helper callback for walk_gimple_seq to discover possible stores
9816 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
9817 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
9818 for those. */
9820 static tree
9821 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
9823 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
9825 *walk_subtrees = 0;
9826 if (!wi->is_lhs)
9827 return NULL_TREE;
9829 tree op = *tp;
9832 if (handled_component_p (op))
9833 op = TREE_OPERAND (op, 0);
9834 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
9835 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
9836 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
9837 else
9838 break;
9840 while (1);
9841 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
9842 return NULL_TREE;
9844 omp_mark_stores (gimplify_omp_ctxp, op);
9845 return NULL_TREE;
9848 /* Helper callback for walk_gimple_seq to discover possible stores
9849 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
9850 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
9851 for those. */
9853 static tree
9854 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
9855 bool *handled_ops_p,
9856 struct walk_stmt_info *wi)
9858 gimple *stmt = gsi_stmt (*gsi_p);
9859 switch (gimple_code (stmt))
9861 /* Don't recurse on OpenMP constructs for which
9862 gimplify_adjust_omp_clauses already handled the bodies,
9863 except handle gimple_omp_for_pre_body. */
9864 case GIMPLE_OMP_FOR:
9865 *handled_ops_p = true;
9866 if (gimple_omp_for_pre_body (stmt))
9867 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
9868 omp_find_stores_stmt, omp_find_stores_op, wi);
9869 break;
9870 case GIMPLE_OMP_PARALLEL:
9871 case GIMPLE_OMP_TASK:
9872 case GIMPLE_OMP_SECTIONS:
9873 case GIMPLE_OMP_SINGLE:
9874 case GIMPLE_OMP_TARGET:
9875 case GIMPLE_OMP_TEAMS:
9876 case GIMPLE_OMP_CRITICAL:
9877 *handled_ops_p = true;
9878 break;
9879 default:
9880 break;
9882 return NULL_TREE;
9885 struct gimplify_adjust_omp_clauses_data
9887 tree *list_p;
9888 gimple_seq *pre_p;
9891 /* For all variables that were not actually used within the context,
9892 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
9894 static int
9895 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
9897 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
9898 gimple_seq *pre_p
9899 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
9900 tree decl = (tree) n->key;
9901 unsigned flags = n->value;
9902 enum omp_clause_code code;
9903 tree clause;
9904 bool private_debug;
9906 if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
9907 && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
9908 flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
9909 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
9910 return 0;
9911 if ((flags & GOVD_SEEN) == 0)
9912 return 0;
9913 if ((flags & GOVD_MAP_HAS_ATTACHMENTS) != 0)
9914 return 0;
9915 if (flags & GOVD_DEBUG_PRIVATE)
9917 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
9918 private_debug = true;
9920 else if (flags & GOVD_MAP)
9921 private_debug = false;
9922 else
9923 private_debug
9924 = lang_hooks.decls.omp_private_debug_clause (decl,
9925 !!(flags & GOVD_SHARED));
9926 if (private_debug)
9927 code = OMP_CLAUSE_PRIVATE;
9928 else if (flags & GOVD_MAP)
9930 code = OMP_CLAUSE_MAP;
9931 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
9932 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
9934 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
9935 return 0;
9937 if (VAR_P (decl)
9938 && DECL_IN_CONSTANT_POOL (decl)
9939 && !lookup_attribute ("omp declare target",
9940 DECL_ATTRIBUTES (decl)))
9942 tree id = get_identifier ("omp declare target");
9943 DECL_ATTRIBUTES (decl)
9944 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
9945 varpool_node *node = varpool_node::get (decl);
9946 if (node)
9948 node->offloadable = 1;
9949 if (ENABLE_OFFLOADING)
9950 g->have_offload = true;
9954 else if (flags & GOVD_SHARED)
9956 if (is_global_var (decl))
9958 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
9959 while (ctx != NULL)
9961 splay_tree_node on
9962 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
9963 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
9964 | GOVD_PRIVATE | GOVD_REDUCTION
9965 | GOVD_LINEAR | GOVD_MAP)) != 0)
9966 break;
9967 ctx = ctx->outer_context;
9969 if (ctx == NULL)
9970 return 0;
9972 code = OMP_CLAUSE_SHARED;
9974 else if (flags & GOVD_PRIVATE)
9975 code = OMP_CLAUSE_PRIVATE;
9976 else if (flags & GOVD_FIRSTPRIVATE)
9978 code = OMP_CLAUSE_FIRSTPRIVATE;
9979 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
9980 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
9981 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
9983 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
9984 "%<target%> construct", decl);
9985 return 0;
9988 else if (flags & GOVD_LASTPRIVATE)
9989 code = OMP_CLAUSE_LASTPRIVATE;
9990 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
9991 return 0;
9992 else if (flags & GOVD_CONDTEMP)
9994 code = OMP_CLAUSE__CONDTEMP_;
9995 gimple_add_tmp_var (decl);
9997 else
9998 gcc_unreachable ();
10000 if (((flags & GOVD_LASTPRIVATE)
10001 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
10002 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10003 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10005 tree chain = *list_p;
10006 clause = build_omp_clause (input_location, code);
10007 OMP_CLAUSE_DECL (clause) = decl;
10008 OMP_CLAUSE_CHAIN (clause) = chain;
10009 if (private_debug)
10010 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
10011 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
10012 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
10013 else if (code == OMP_CLAUSE_SHARED
10014 && (flags & GOVD_WRITTEN) == 0
10015 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10016 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
10017 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
10018 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
10019 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
10021 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
10022 OMP_CLAUSE_DECL (nc) = decl;
10023 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
10024 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
10025 OMP_CLAUSE_DECL (clause)
10026 = build_simple_mem_ref_loc (input_location, decl);
10027 OMP_CLAUSE_DECL (clause)
10028 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
10029 build_int_cst (build_pointer_type (char_type_node), 0));
10030 OMP_CLAUSE_SIZE (clause) = size_zero_node;
10031 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10032 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
10033 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
10034 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
10035 OMP_CLAUSE_CHAIN (nc) = chain;
10036 OMP_CLAUSE_CHAIN (clause) = nc;
10037 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10038 gimplify_omp_ctxp = ctx->outer_context;
10039 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
10040 pre_p, NULL, is_gimple_val, fb_rvalue);
10041 gimplify_omp_ctxp = ctx;
10043 else if (code == OMP_CLAUSE_MAP)
10045 int kind;
10046 /* Not all combinations of these GOVD_MAP flags are actually valid. */
10047 switch (flags & (GOVD_MAP_TO_ONLY
10048 | GOVD_MAP_FORCE
10049 | GOVD_MAP_FORCE_PRESENT
10050 | GOVD_MAP_ALLOC_ONLY
10051 | GOVD_MAP_FROM_ONLY))
10053 case 0:
10054 kind = GOMP_MAP_TOFROM;
10055 break;
10056 case GOVD_MAP_FORCE:
10057 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
10058 break;
10059 case GOVD_MAP_TO_ONLY:
10060 kind = GOMP_MAP_TO;
10061 break;
10062 case GOVD_MAP_FROM_ONLY:
10063 kind = GOMP_MAP_FROM;
10064 break;
10065 case GOVD_MAP_ALLOC_ONLY:
10066 kind = GOMP_MAP_ALLOC;
10067 break;
10068 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
10069 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
10070 break;
10071 case GOVD_MAP_FORCE_PRESENT:
10072 kind = GOMP_MAP_FORCE_PRESENT;
10073 break;
10074 default:
10075 gcc_unreachable ();
10077 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
10078 if (DECL_SIZE (decl)
10079 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
10081 tree decl2 = DECL_VALUE_EXPR (decl);
10082 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
10083 decl2 = TREE_OPERAND (decl2, 0);
10084 gcc_assert (DECL_P (decl2));
10085 tree mem = build_simple_mem_ref (decl2);
10086 OMP_CLAUSE_DECL (clause) = mem;
10087 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
10088 if (gimplify_omp_ctxp->outer_context)
10090 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
10091 omp_notice_variable (ctx, decl2, true);
10092 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
10094 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
10095 OMP_CLAUSE_MAP);
10096 OMP_CLAUSE_DECL (nc) = decl;
10097 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10098 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
10099 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
10100 else
10101 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
10102 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
10103 OMP_CLAUSE_CHAIN (clause) = nc;
10105 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
10106 && lang_hooks.decls.omp_privatize_by_reference (decl))
10108 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
10109 OMP_CLAUSE_SIZE (clause)
10110 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
10111 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10112 gimplify_omp_ctxp = ctx->outer_context;
10113 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
10114 pre_p, NULL, is_gimple_val, fb_rvalue);
10115 gimplify_omp_ctxp = ctx;
10116 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
10117 OMP_CLAUSE_MAP);
10118 OMP_CLAUSE_DECL (nc) = decl;
10119 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10120 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
10121 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
10122 OMP_CLAUSE_CHAIN (clause) = nc;
10124 else
10125 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
10127 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
10129 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
10130 OMP_CLAUSE_DECL (nc) = decl;
10131 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
10132 OMP_CLAUSE_CHAIN (nc) = chain;
10133 OMP_CLAUSE_CHAIN (clause) = nc;
10134 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10135 gimplify_omp_ctxp = ctx->outer_context;
10136 lang_hooks.decls.omp_finish_clause (nc, pre_p,
10137 (ctx->region_type & ORT_ACC) != 0);
10138 gimplify_omp_ctxp = ctx;
10140 *list_p = clause;
10141 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10142 gimplify_omp_ctxp = ctx->outer_context;
10143 lang_hooks.decls.omp_finish_clause (clause, pre_p,
10144 (ctx->region_type & ORT_ACC) != 0);
10145 if (gimplify_omp_ctxp)
10146 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
10147 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
10148 && DECL_P (OMP_CLAUSE_SIZE (clause)))
10149 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
10150 true);
10151 gimplify_omp_ctxp = ctx;
10152 return 0;
10155 static void
10156 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
10157 enum tree_code code)
10159 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10160 tree *orig_list_p = list_p;
10161 tree c, decl;
10162 bool has_inscan_reductions = false;
10164 if (body)
10166 struct gimplify_omp_ctx *octx;
10167 for (octx = ctx; octx; octx = octx->outer_context)
10168 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
10169 break;
10170 if (octx)
10172 struct walk_stmt_info wi;
10173 memset (&wi, 0, sizeof (wi));
10174 walk_gimple_seq (body, omp_find_stores_stmt,
10175 omp_find_stores_op, &wi);
10179 if (ctx->add_safelen1)
10181 /* If there are VLAs in the body of simd loop, prevent
10182 vectorization. */
10183 gcc_assert (ctx->region_type == ORT_SIMD);
10184 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
10185 OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
10186 OMP_CLAUSE_CHAIN (c) = *list_p;
10187 *list_p = c;
10188 list_p = &OMP_CLAUSE_CHAIN (c);
10191 if (ctx->region_type == ORT_WORKSHARE
10192 && ctx->outer_context
10193 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
10195 for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
10196 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10197 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
10199 decl = OMP_CLAUSE_DECL (c);
10200 splay_tree_node n
10201 = splay_tree_lookup (ctx->outer_context->variables,
10202 (splay_tree_key) decl);
10203 gcc_checking_assert (!splay_tree_lookup (ctx->variables,
10204 (splay_tree_key) decl));
10205 omp_add_variable (ctx, decl, n->value);
10206 tree c2 = copy_node (c);
10207 OMP_CLAUSE_CHAIN (c2) = *list_p;
10208 *list_p = c2;
10209 if ((n->value & GOVD_FIRSTPRIVATE) == 0)
10210 continue;
10211 c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10212 OMP_CLAUSE_FIRSTPRIVATE);
10213 OMP_CLAUSE_DECL (c2) = decl;
10214 OMP_CLAUSE_CHAIN (c2) = *list_p;
10215 *list_p = c2;
10218 while ((c = *list_p) != NULL)
10220 splay_tree_node n;
10221 bool remove = false;
10223 switch (OMP_CLAUSE_CODE (c))
10225 case OMP_CLAUSE_FIRSTPRIVATE:
10226 if ((ctx->region_type & ORT_TARGET)
10227 && (ctx->region_type & ORT_ACC) == 0
10228 && TYPE_ATOMIC (strip_array_types
10229 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
10231 error_at (OMP_CLAUSE_LOCATION (c),
10232 "%<_Atomic%> %qD in %<firstprivate%> clause on "
10233 "%<target%> construct", OMP_CLAUSE_DECL (c));
10234 remove = true;
10235 break;
10237 /* FALLTHRU */
10238 case OMP_CLAUSE_PRIVATE:
10239 case OMP_CLAUSE_SHARED:
10240 case OMP_CLAUSE_LINEAR:
10241 decl = OMP_CLAUSE_DECL (c);
10242 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10243 remove = !(n->value & GOVD_SEEN);
10244 if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
10245 && code == OMP_PARALLEL
10246 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
10247 remove = true;
10248 if (! remove)
10250 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
10251 if ((n->value & GOVD_DEBUG_PRIVATE)
10252 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
10254 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
10255 || ((n->value & GOVD_DATA_SHARE_CLASS)
10256 == GOVD_SHARED));
10257 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
10258 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
10260 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10261 && (n->value & GOVD_WRITTEN) == 0
10262 && DECL_P (decl)
10263 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10264 OMP_CLAUSE_SHARED_READONLY (c) = 1;
10265 else if (DECL_P (decl)
10266 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10267 && (n->value & GOVD_WRITTEN) != 0)
10268 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10269 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
10270 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10271 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10273 break;
10275 case OMP_CLAUSE_LASTPRIVATE:
10276 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
10277 accurately reflect the presence of a FIRSTPRIVATE clause. */
10278 decl = OMP_CLAUSE_DECL (c);
10279 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10280 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
10281 = (n->value & GOVD_FIRSTPRIVATE) != 0;
10282 if (code == OMP_DISTRIBUTE
10283 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
10285 remove = true;
10286 error_at (OMP_CLAUSE_LOCATION (c),
10287 "same variable used in %<firstprivate%> and "
10288 "%<lastprivate%> clauses on %<distribute%> "
10289 "construct");
10291 if (!remove
10292 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10293 && DECL_P (decl)
10294 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10295 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10296 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
10297 remove = true;
10298 break;
10300 case OMP_CLAUSE_ALIGNED:
10301 decl = OMP_CLAUSE_DECL (c);
10302 if (!is_global_var (decl))
10304 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10305 remove = n == NULL || !(n->value & GOVD_SEEN);
10306 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
10308 struct gimplify_omp_ctx *octx;
10309 if (n != NULL
10310 && (n->value & (GOVD_DATA_SHARE_CLASS
10311 & ~GOVD_FIRSTPRIVATE)))
10312 remove = true;
10313 else
10314 for (octx = ctx->outer_context; octx;
10315 octx = octx->outer_context)
10317 n = splay_tree_lookup (octx->variables,
10318 (splay_tree_key) decl);
10319 if (n == NULL)
10320 continue;
10321 if (n->value & GOVD_LOCAL)
10322 break;
10323 /* We have to avoid assigning a shared variable
10324 to itself when trying to add
10325 __builtin_assume_aligned. */
10326 if (n->value & GOVD_SHARED)
10328 remove = true;
10329 break;
10334 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
10336 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10337 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
10338 remove = true;
10340 break;
10342 case OMP_CLAUSE_NONTEMPORAL:
10343 decl = OMP_CLAUSE_DECL (c);
10344 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10345 remove = n == NULL || !(n->value & GOVD_SEEN);
10346 break;
10348 case OMP_CLAUSE_MAP:
10349 if (code == OMP_TARGET_EXIT_DATA
10350 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
10352 remove = true;
10353 break;
10355 decl = OMP_CLAUSE_DECL (c);
10356 /* Data clauses associated with reductions must be
10357 compatible with present_or_copy. Warn and adjust the clause
10358 if that is not the case. */
10359 if (ctx->region_type == ORT_ACC_PARALLEL
10360 || ctx->region_type == ORT_ACC_SERIAL)
10362 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
10363 n = NULL;
10365 if (DECL_P (t))
10366 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
10368 if (n && (n->value & GOVD_REDUCTION))
10370 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
10372 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
10373 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
10374 && kind != GOMP_MAP_FORCE_PRESENT
10375 && kind != GOMP_MAP_POINTER)
10377 warning_at (OMP_CLAUSE_LOCATION (c), 0,
10378 "incompatible data clause with reduction "
10379 "on %qE; promoting to %<present_or_copy%>",
10380 DECL_NAME (t));
10381 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
10385 if (!DECL_P (decl))
10387 if ((ctx->region_type & ORT_TARGET) != 0
10388 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
10390 if (TREE_CODE (decl) == INDIRECT_REF
10391 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
10392 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
10393 == REFERENCE_TYPE))
10394 decl = TREE_OPERAND (decl, 0);
10395 if (TREE_CODE (decl) == COMPONENT_REF)
10397 while (TREE_CODE (decl) == COMPONENT_REF)
10398 decl = TREE_OPERAND (decl, 0);
10399 if (DECL_P (decl))
10401 n = splay_tree_lookup (ctx->variables,
10402 (splay_tree_key) decl);
10403 if (!(n->value & GOVD_SEEN))
10404 remove = true;
10408 break;
10410 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10411 if ((ctx->region_type & ORT_TARGET) != 0
10412 && !(n->value & GOVD_SEEN)
10413 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
10414 && (!is_global_var (decl)
10415 || !lookup_attribute ("omp declare target link",
10416 DECL_ATTRIBUTES (decl))))
10418 remove = true;
10419 /* For struct element mapping, if struct is never referenced
10420 in target block and none of the mapping has always modifier,
10421 remove all the struct element mappings, which immediately
10422 follow the GOMP_MAP_STRUCT map clause. */
10423 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
10425 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
10426 while (cnt--)
10427 OMP_CLAUSE_CHAIN (c)
10428 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
10431 else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
10432 && (code == OMP_TARGET_EXIT_DATA
10433 || code == OACC_EXIT_DATA))
10434 remove = true;
10435 else if (DECL_SIZE (decl)
10436 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
10437 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
10438 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
10439 && (OMP_CLAUSE_MAP_KIND (c)
10440 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
10442 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
10443 for these, TREE_CODE (DECL_SIZE (decl)) will always be
10444 INTEGER_CST. */
10445 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
10447 tree decl2 = DECL_VALUE_EXPR (decl);
10448 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
10449 decl2 = TREE_OPERAND (decl2, 0);
10450 gcc_assert (DECL_P (decl2));
10451 tree mem = build_simple_mem_ref (decl2);
10452 OMP_CLAUSE_DECL (c) = mem;
10453 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
10454 if (ctx->outer_context)
10456 omp_notice_variable (ctx->outer_context, decl2, true);
10457 omp_notice_variable (ctx->outer_context,
10458 OMP_CLAUSE_SIZE (c), true);
10460 if (((ctx->region_type & ORT_TARGET) != 0
10461 || !ctx->target_firstprivatize_array_bases)
10462 && ((n->value & GOVD_SEEN) == 0
10463 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
10465 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10466 OMP_CLAUSE_MAP);
10467 OMP_CLAUSE_DECL (nc) = decl;
10468 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10469 if (ctx->target_firstprivatize_array_bases)
10470 OMP_CLAUSE_SET_MAP_KIND (nc,
10471 GOMP_MAP_FIRSTPRIVATE_POINTER);
10472 else
10473 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
10474 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
10475 OMP_CLAUSE_CHAIN (c) = nc;
10476 c = nc;
10479 else
10481 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10482 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
10483 gcc_assert ((n->value & GOVD_SEEN) == 0
10484 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
10485 == 0));
10487 break;
10489 case OMP_CLAUSE_TO:
10490 case OMP_CLAUSE_FROM:
10491 case OMP_CLAUSE__CACHE_:
10492 decl = OMP_CLAUSE_DECL (c);
10493 if (!DECL_P (decl))
10494 break;
10495 if (DECL_SIZE (decl)
10496 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
10498 tree decl2 = DECL_VALUE_EXPR (decl);
10499 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
10500 decl2 = TREE_OPERAND (decl2, 0);
10501 gcc_assert (DECL_P (decl2));
10502 tree mem = build_simple_mem_ref (decl2);
10503 OMP_CLAUSE_DECL (c) = mem;
10504 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
10505 if (ctx->outer_context)
10507 omp_notice_variable (ctx->outer_context, decl2, true);
10508 omp_notice_variable (ctx->outer_context,
10509 OMP_CLAUSE_SIZE (c), true);
10512 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10513 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
10514 break;
10516 case OMP_CLAUSE_REDUCTION:
10517 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
10519 decl = OMP_CLAUSE_DECL (c);
10520 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10521 if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
10523 remove = true;
10524 error_at (OMP_CLAUSE_LOCATION (c),
10525 "%qD specified in %<inscan%> %<reduction%> clause "
10526 "but not in %<scan%> directive clause", decl);
10527 break;
10529 has_inscan_reductions = true;
10531 /* FALLTHRU */
10532 case OMP_CLAUSE_IN_REDUCTION:
10533 case OMP_CLAUSE_TASK_REDUCTION:
10534 decl = OMP_CLAUSE_DECL (c);
10535 /* OpenACC reductions need a present_or_copy data clause.
10536 Add one if necessary. Emit error when the reduction is private. */
10537 if (ctx->region_type == ORT_ACC_PARALLEL
10538 || ctx->region_type == ORT_ACC_SERIAL)
10540 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10541 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
10543 remove = true;
10544 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
10545 "reduction on %qE", DECL_NAME (decl));
10547 else if ((n->value & GOVD_MAP) == 0)
10549 tree next = OMP_CLAUSE_CHAIN (c);
10550 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
10551 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
10552 OMP_CLAUSE_DECL (nc) = decl;
10553 OMP_CLAUSE_CHAIN (c) = nc;
10554 lang_hooks.decls.omp_finish_clause (nc, pre_p,
10555 (ctx->region_type
10556 & ORT_ACC) != 0);
10557 while (1)
10559 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
10560 if (OMP_CLAUSE_CHAIN (nc) == NULL)
10561 break;
10562 nc = OMP_CLAUSE_CHAIN (nc);
10564 OMP_CLAUSE_CHAIN (nc) = next;
10565 n->value |= GOVD_MAP;
10568 if (DECL_P (decl)
10569 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10570 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10571 break;
10572 case OMP_CLAUSE_COPYIN:
10573 case OMP_CLAUSE_COPYPRIVATE:
10574 case OMP_CLAUSE_IF:
10575 case OMP_CLAUSE_NUM_THREADS:
10576 case OMP_CLAUSE_NUM_TEAMS:
10577 case OMP_CLAUSE_THREAD_LIMIT:
10578 case OMP_CLAUSE_DIST_SCHEDULE:
10579 case OMP_CLAUSE_DEVICE:
10580 case OMP_CLAUSE_SCHEDULE:
10581 case OMP_CLAUSE_NOWAIT:
10582 case OMP_CLAUSE_ORDERED:
10583 case OMP_CLAUSE_DEFAULT:
10584 case OMP_CLAUSE_UNTIED:
10585 case OMP_CLAUSE_COLLAPSE:
10586 case OMP_CLAUSE_FINAL:
10587 case OMP_CLAUSE_MERGEABLE:
10588 case OMP_CLAUSE_PROC_BIND:
10589 case OMP_CLAUSE_SAFELEN:
10590 case OMP_CLAUSE_SIMDLEN:
10591 case OMP_CLAUSE_DEPEND:
10592 case OMP_CLAUSE_PRIORITY:
10593 case OMP_CLAUSE_GRAINSIZE:
10594 case OMP_CLAUSE_NUM_TASKS:
10595 case OMP_CLAUSE_NOGROUP:
10596 case OMP_CLAUSE_THREADS:
10597 case OMP_CLAUSE_SIMD:
10598 case OMP_CLAUSE_HINT:
10599 case OMP_CLAUSE_DEFAULTMAP:
10600 case OMP_CLAUSE_ORDER:
10601 case OMP_CLAUSE_BIND:
10602 case OMP_CLAUSE_USE_DEVICE_PTR:
10603 case OMP_CLAUSE_USE_DEVICE_ADDR:
10604 case OMP_CLAUSE_IS_DEVICE_PTR:
10605 case OMP_CLAUSE_ASYNC:
10606 case OMP_CLAUSE_WAIT:
10607 case OMP_CLAUSE_INDEPENDENT:
10608 case OMP_CLAUSE_NUM_GANGS:
10609 case OMP_CLAUSE_NUM_WORKERS:
10610 case OMP_CLAUSE_VECTOR_LENGTH:
10611 case OMP_CLAUSE_GANG:
10612 case OMP_CLAUSE_WORKER:
10613 case OMP_CLAUSE_VECTOR:
10614 case OMP_CLAUSE_AUTO:
10615 case OMP_CLAUSE_SEQ:
10616 case OMP_CLAUSE_TILE:
10617 case OMP_CLAUSE_IF_PRESENT:
10618 case OMP_CLAUSE_FINALIZE:
10619 case OMP_CLAUSE_INCLUSIVE:
10620 case OMP_CLAUSE_EXCLUSIVE:
10621 break;
10623 default:
10624 gcc_unreachable ();
10627 if (remove)
10628 *list_p = OMP_CLAUSE_CHAIN (c);
10629 else
10630 list_p = &OMP_CLAUSE_CHAIN (c);
10633 /* Add in any implicit data sharing. */
10634 struct gimplify_adjust_omp_clauses_data data;
10635 data.list_p = list_p;
10636 data.pre_p = pre_p;
10637 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
10639 if (has_inscan_reductions)
10640 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
10641 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10642 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
10644 error_at (OMP_CLAUSE_LOCATION (c),
10645 "%<inscan%> %<reduction%> clause used together with "
10646 "%<linear%> clause for a variable other than loop "
10647 "iterator");
10648 break;
10651 gimplify_omp_ctxp = ctx->outer_context;
10652 delete_omp_context (ctx);
10655 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
10656 -1 if unknown yet (simd is involved, won't be known until vectorization)
10657 and 1 if they do. If SCORES is non-NULL, it should point to an array
10658 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
10659 of the CONSTRUCTS (position -1 if it will never match) followed by
10660 number of constructs in the OpenMP context construct trait. If the
10661 score depends on whether it will be in a declare simd clone or not,
10662 the function returns 2 and there will be two sets of the scores, the first
10663 one for the case that it is not in a declare simd clone, the other
10664 that it is in a declare simd clone. */
10667 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
10668 int *scores)
10670 int matched = 0, cnt = 0;
10671 bool simd_seen = false;
10672 bool target_seen = false;
10673 int declare_simd_cnt = -1;
10674 auto_vec<enum tree_code, 16> codes;
10675 for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
10677 if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
10678 || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
10679 == ORT_TARGET && ctx->code == OMP_TARGET)
10680 || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
10681 || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
10682 || (ctx->region_type == ORT_SIMD
10683 && ctx->code == OMP_SIMD
10684 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
10686 ++cnt;
10687 if (scores)
10688 codes.safe_push (ctx->code);
10689 else if (matched < nconstructs && ctx->code == constructs[matched])
10691 if (ctx->code == OMP_SIMD)
10693 if (matched)
10694 return 0;
10695 simd_seen = true;
10697 ++matched;
10699 if (ctx->code == OMP_TARGET)
10701 if (scores == NULL)
10702 return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
10703 target_seen = true;
10704 break;
10707 else if (ctx->region_type == ORT_WORKSHARE
10708 && ctx->code == OMP_LOOP
10709 && ctx->outer_context
10710 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
10711 && ctx->outer_context->outer_context
10712 && ctx->outer_context->outer_context->code == OMP_LOOP
10713 && ctx->outer_context->outer_context->distribute)
10714 ctx = ctx->outer_context->outer_context;
10715 ctx = ctx->outer_context;
10717 if (!target_seen
10718 && lookup_attribute ("omp declare simd",
10719 DECL_ATTRIBUTES (current_function_decl)))
10721 /* Declare simd is a maybe case, it is supposed to be added only to the
10722 omp-simd-clone.c added clones and not to the base function. */
10723 declare_simd_cnt = cnt++;
10724 if (scores)
10725 codes.safe_push (OMP_SIMD);
10726 else if (cnt == 0
10727 && constructs[0] == OMP_SIMD)
10729 gcc_assert (matched == 0);
10730 simd_seen = true;
10731 if (++matched == nconstructs)
10732 return -1;
10735 if (tree attr = lookup_attribute ("omp declare variant variant",
10736 DECL_ATTRIBUTES (current_function_decl)))
10738 enum tree_code variant_constructs[5];
10739 int variant_nconstructs = 0;
10740 if (!target_seen)
10741 variant_nconstructs
10742 = omp_constructor_traits_to_codes (TREE_VALUE (attr),
10743 variant_constructs);
10744 for (int i = 0; i < variant_nconstructs; i++)
10746 ++cnt;
10747 if (scores)
10748 codes.safe_push (variant_constructs[i]);
10749 else if (matched < nconstructs
10750 && variant_constructs[i] == constructs[matched])
10752 if (variant_constructs[i] == OMP_SIMD)
10754 if (matched)
10755 return 0;
10756 simd_seen = true;
10758 ++matched;
10762 if (!target_seen
10763 && lookup_attribute ("omp declare target block",
10764 DECL_ATTRIBUTES (current_function_decl)))
10766 if (scores)
10767 codes.safe_push (OMP_TARGET);
10768 else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
10769 ++matched;
10771 if (scores)
10773 for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
10775 int j = codes.length () - 1;
10776 for (int i = nconstructs - 1; i >= 0; i--)
10778 while (j >= 0
10779 && (pass != 0 || declare_simd_cnt != j)
10780 && constructs[i] != codes[j])
10781 --j;
10782 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
10783 *scores++ = j - 1;
10784 else
10785 *scores++ = j;
10787 *scores++ = ((pass == 0 && declare_simd_cnt != -1)
10788 ? codes.length () - 1 : codes.length ());
10790 return declare_simd_cnt == -1 ? 1 : 2;
10792 if (matched == nconstructs)
10793 return simd_seen ? -1 : 1;
10794 return 0;
10797 /* Gimplify OACC_CACHE. */
10799 static void
10800 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
10802 tree expr = *expr_p;
10804 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
10805 OACC_CACHE);
10806 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
10807 OACC_CACHE);
10809 /* TODO: Do something sensible with this information. */
10811 *expr_p = NULL_TREE;
10814 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
10815 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
10816 kind. The entry kind will replace the one in CLAUSE, while the exit
10817 kind will be used in a new omp_clause and returned to the caller. */
10819 static tree
10820 gimplify_oacc_declare_1 (tree clause)
10822 HOST_WIDE_INT kind, new_op;
10823 bool ret = false;
10824 tree c = NULL;
10826 kind = OMP_CLAUSE_MAP_KIND (clause);
10828 switch (kind)
10830 case GOMP_MAP_ALLOC:
10831 new_op = GOMP_MAP_RELEASE;
10832 ret = true;
10833 break;
10835 case GOMP_MAP_FROM:
10836 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
10837 new_op = GOMP_MAP_FROM;
10838 ret = true;
10839 break;
10841 case GOMP_MAP_TOFROM:
10842 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
10843 new_op = GOMP_MAP_FROM;
10844 ret = true;
10845 break;
10847 case GOMP_MAP_DEVICE_RESIDENT:
10848 case GOMP_MAP_FORCE_DEVICEPTR:
10849 case GOMP_MAP_FORCE_PRESENT:
10850 case GOMP_MAP_LINK:
10851 case GOMP_MAP_POINTER:
10852 case GOMP_MAP_TO:
10853 break;
10855 default:
10856 gcc_unreachable ();
10857 break;
10860 if (ret)
10862 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
10863 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
10864 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
10867 return c;
10870 /* Gimplify OACC_DECLARE. */
10872 static void
10873 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
10875 tree expr = *expr_p;
10876 gomp_target *stmt;
10877 tree clauses, t, decl;
10879 clauses = OACC_DECLARE_CLAUSES (expr);
10881 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
10882 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
10884 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
10886 decl = OMP_CLAUSE_DECL (t);
10888 if (TREE_CODE (decl) == MEM_REF)
10889 decl = TREE_OPERAND (decl, 0);
10891 if (VAR_P (decl) && !is_oacc_declared (decl))
10893 tree attr = get_identifier ("oacc declare target");
10894 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
10895 DECL_ATTRIBUTES (decl));
10898 if (VAR_P (decl)
10899 && !is_global_var (decl)
10900 && DECL_CONTEXT (decl) == current_function_decl)
10902 tree c = gimplify_oacc_declare_1 (t);
10903 if (c)
10905 if (oacc_declare_returns == NULL)
10906 oacc_declare_returns = new hash_map<tree, tree>;
10908 oacc_declare_returns->put (decl, c);
10912 if (gimplify_omp_ctxp)
10913 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
10916 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
10917 clauses);
10919 gimplify_seq_add_stmt (pre_p, stmt);
10921 *expr_p = NULL_TREE;
10924 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
10925 gimplification of the body, as well as scanning the body for used
10926 variables. We need to do this scan now, because variable-sized
10927 decls will be decomposed during gimplification. */
10929 static void
10930 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
10932 tree expr = *expr_p;
10933 gimple *g;
10934 gimple_seq body = NULL;
10936 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
10937 OMP_PARALLEL_COMBINED (expr)
10938 ? ORT_COMBINED_PARALLEL
10939 : ORT_PARALLEL, OMP_PARALLEL);
10941 push_gimplify_context ();
10943 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
10944 if (gimple_code (g) == GIMPLE_BIND)
10945 pop_gimplify_context (g);
10946 else
10947 pop_gimplify_context (NULL);
10949 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
10950 OMP_PARALLEL);
10952 g = gimple_build_omp_parallel (body,
10953 OMP_PARALLEL_CLAUSES (expr),
10954 NULL_TREE, NULL_TREE);
10955 if (OMP_PARALLEL_COMBINED (expr))
10956 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
10957 gimplify_seq_add_stmt (pre_p, g);
10958 *expr_p = NULL_TREE;
10961 /* Gimplify the contents of an OMP_TASK statement. This involves
10962 gimplification of the body, as well as scanning the body for used
10963 variables. We need to do this scan now, because variable-sized
10964 decls will be decomposed during gimplification. */
10966 static void
10967 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
10969 tree expr = *expr_p;
10970 gimple *g;
10971 gimple_seq body = NULL;
10973 if (OMP_TASK_BODY (expr) == NULL_TREE)
10974 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
10975 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
10976 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
10978 error_at (OMP_CLAUSE_LOCATION (c),
10979 "%<mutexinoutset%> kind in %<depend%> clause on a "
10980 "%<taskwait%> construct");
10981 break;
10984 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
10985 omp_find_clause (OMP_TASK_CLAUSES (expr),
10986 OMP_CLAUSE_UNTIED)
10987 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
10989 if (OMP_TASK_BODY (expr))
10991 push_gimplify_context ();
10993 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
10994 if (gimple_code (g) == GIMPLE_BIND)
10995 pop_gimplify_context (g);
10996 else
10997 pop_gimplify_context (NULL);
11000 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
11001 OMP_TASK);
11003 g = gimple_build_omp_task (body,
11004 OMP_TASK_CLAUSES (expr),
11005 NULL_TREE, NULL_TREE,
11006 NULL_TREE, NULL_TREE, NULL_TREE);
11007 if (OMP_TASK_BODY (expr) == NULL_TREE)
11008 gimple_omp_task_set_taskwait_p (g, true);
11009 gimplify_seq_add_stmt (pre_p, g);
11010 *expr_p = NULL_TREE;
11013 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
11014 force it into a temporary initialized in PRE_P and add firstprivate clause
11015 to ORIG_FOR_STMT. */
11017 static void
11018 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
11019 tree orig_for_stmt)
11021 if (*tp == NULL || is_gimple_constant (*tp))
11022 return;
11024 *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
11025 /* Reference to pointer conversion is considered useless,
11026 but is significant for firstprivate clause. Force it
11027 here. */
11028 if (type
11029 && TREE_CODE (type) == POINTER_TYPE
11030 && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
11032 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
11033 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
11034 gimplify_and_add (m, pre_p);
11035 *tp = v;
11038 tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
11039 OMP_CLAUSE_DECL (c) = *tp;
11040 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
11041 OMP_FOR_CLAUSES (orig_for_stmt) = c;
11044 /* Gimplify the gross structure of an OMP_FOR statement. */
11046 static enum gimplify_status
11047 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
11049 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
11050 enum gimplify_status ret = GS_ALL_DONE;
11051 enum gimplify_status tret;
11052 gomp_for *gfor;
11053 gimple_seq for_body, for_pre_body;
11054 int i;
11055 bitmap has_decl_expr = NULL;
11056 enum omp_region_type ort = ORT_WORKSHARE;
11057 bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
11059 orig_for_stmt = for_stmt = *expr_p;
11061 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
11062 != NULL_TREE);
11063 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
11065 tree *data[4] = { NULL, NULL, NULL, NULL };
11066 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
11067 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
11068 find_combined_omp_for, data, NULL);
11069 if (inner_for_stmt == NULL_TREE)
11071 gcc_assert (seen_error ());
11072 *expr_p = NULL_TREE;
11073 return GS_ERROR;
11075 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
11077 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
11078 &OMP_FOR_PRE_BODY (for_stmt));
11079 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
11081 if (OMP_FOR_PRE_BODY (inner_for_stmt))
11083 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
11084 &OMP_FOR_PRE_BODY (for_stmt));
11085 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
11088 if (data[0])
11090 /* We have some statements or variable declarations in between
11091 the composite construct directives. Move them around the
11092 inner_for_stmt. */
11093 data[0] = expr_p;
11094 for (i = 0; i < 3; i++)
11095 if (data[i])
11097 tree t = *data[i];
11098 if (i < 2 && data[i + 1] == &OMP_BODY (t))
11099 data[i + 1] = data[i];
11100 *data[i] = OMP_BODY (t);
11101 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
11102 NULL_TREE, make_node (BLOCK));
11103 OMP_BODY (t) = body;
11104 append_to_statement_list_force (inner_for_stmt,
11105 &BIND_EXPR_BODY (body));
11106 *data[3] = t;
11107 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
11108 gcc_assert (*data[3] == inner_for_stmt);
11110 return GS_OK;
11113 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
11114 if (!loop_p
11115 && OMP_FOR_ORIG_DECLS (inner_for_stmt)
11116 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11117 i)) == TREE_LIST
11118 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11119 i)))
11121 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
11122 /* Class iterators aren't allowed on OMP_SIMD, so the only
11123 case we need to solve is distribute parallel for. They are
11124 allowed on the loop construct, but that is already handled
11125 in gimplify_omp_loop. */
11126 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
11127 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
11128 && data[1]);
11129 tree orig_decl = TREE_PURPOSE (orig);
11130 tree last = TREE_VALUE (orig);
11131 tree *pc;
11132 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
11133 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
11134 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
11135 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
11136 && OMP_CLAUSE_DECL (*pc) == orig_decl)
11137 break;
11138 if (*pc == NULL_TREE)
11140 tree *spc;
11141 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
11142 *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
11143 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
11144 && OMP_CLAUSE_DECL (*spc) == orig_decl)
11145 break;
11146 if (*spc)
11148 tree c = *spc;
11149 *spc = OMP_CLAUSE_CHAIN (c);
11150 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
11151 *pc = c;
11154 if (*pc == NULL_TREE)
11156 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
11158 /* private clause will appear only on inner_for_stmt.
11159 Change it into firstprivate, and add private clause
11160 on for_stmt. */
11161 tree c = copy_node (*pc);
11162 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
11163 OMP_FOR_CLAUSES (for_stmt) = c;
11164 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
11165 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
11167 else
11169 /* lastprivate clause will appear on both inner_for_stmt
11170 and for_stmt. Add firstprivate clause to
11171 inner_for_stmt. */
11172 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
11173 OMP_CLAUSE_FIRSTPRIVATE);
11174 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
11175 OMP_CLAUSE_CHAIN (c) = *pc;
11176 *pc = c;
11177 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
11179 tree c = build_omp_clause (UNKNOWN_LOCATION,
11180 OMP_CLAUSE_FIRSTPRIVATE);
11181 OMP_CLAUSE_DECL (c) = last;
11182 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
11183 OMP_PARALLEL_CLAUSES (*data[1]) = c;
11184 c = build_omp_clause (UNKNOWN_LOCATION,
11185 *pc ? OMP_CLAUSE_SHARED
11186 : OMP_CLAUSE_FIRSTPRIVATE);
11187 OMP_CLAUSE_DECL (c) = orig_decl;
11188 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
11189 OMP_PARALLEL_CLAUSES (*data[1]) = c;
11191 /* Similarly, take care of C++ range for temporaries, those should
11192 be firstprivate on OMP_PARALLEL if any. */
11193 if (data[1])
11194 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
11195 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
11196 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11197 i)) == TREE_LIST
11198 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11199 i)))
11201 tree orig
11202 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
11203 tree v = TREE_CHAIN (orig);
11204 tree c = build_omp_clause (UNKNOWN_LOCATION,
11205 OMP_CLAUSE_FIRSTPRIVATE);
11206 /* First add firstprivate clause for the __for_end artificial
11207 decl. */
11208 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
11209 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
11210 == REFERENCE_TYPE)
11211 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
11212 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
11213 OMP_PARALLEL_CLAUSES (*data[1]) = c;
11214 if (TREE_VEC_ELT (v, 0))
11216 /* And now the same for __for_range artificial decl if it
11217 exists. */
11218 c = build_omp_clause (UNKNOWN_LOCATION,
11219 OMP_CLAUSE_FIRSTPRIVATE);
11220 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
11221 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
11222 == REFERENCE_TYPE)
11223 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
11224 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
11225 OMP_PARALLEL_CLAUSES (*data[1]) = c;
11230 switch (TREE_CODE (for_stmt))
11232 case OMP_FOR:
11233 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
11235 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
11236 OMP_CLAUSE_SCHEDULE))
11237 error_at (EXPR_LOCATION (for_stmt),
11238 "%qs clause may not appear on non-rectangular %qs",
11239 "schedule", "for");
11240 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
11241 error_at (EXPR_LOCATION (for_stmt),
11242 "%qs clause may not appear on non-rectangular %qs",
11243 "ordered", "for");
11245 break;
11246 case OMP_DISTRIBUTE:
11247 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
11248 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
11249 OMP_CLAUSE_DIST_SCHEDULE))
11250 error_at (EXPR_LOCATION (for_stmt),
11251 "%qs clause may not appear on non-rectangular %qs",
11252 "dist_schedule", "distribute");
11253 break;
11254 case OACC_LOOP:
11255 ort = ORT_ACC;
11256 break;
11257 case OMP_TASKLOOP:
11258 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
11259 ort = ORT_UNTIED_TASKLOOP;
11260 else
11261 ort = ORT_TASKLOOP;
11262 break;
11263 case OMP_SIMD:
11264 ort = ORT_SIMD;
11265 break;
11266 default:
11267 gcc_unreachable ();
11270 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
11271 clause for the IV. */
11272 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
11274 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
11275 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
11276 decl = TREE_OPERAND (t, 0);
11277 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
11278 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11279 && OMP_CLAUSE_DECL (c) == decl)
11281 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
11282 break;
11286 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
11287 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
11288 loop_p && TREE_CODE (for_stmt) != OMP_SIMD
11289 ? OMP_LOOP : TREE_CODE (for_stmt));
11291 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
11292 gimplify_omp_ctxp->distribute = true;
11294 /* Handle OMP_FOR_INIT. */
11295 for_pre_body = NULL;
11296 if ((ort == ORT_SIMD
11297 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
11298 && OMP_FOR_PRE_BODY (for_stmt))
11300 has_decl_expr = BITMAP_ALLOC (NULL);
11301 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
11302 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
11303 == VAR_DECL)
11305 t = OMP_FOR_PRE_BODY (for_stmt);
11306 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
11308 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
11310 tree_stmt_iterator si;
11311 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
11312 tsi_next (&si))
11314 t = tsi_stmt (si);
11315 if (TREE_CODE (t) == DECL_EXPR
11316 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
11317 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
11321 if (OMP_FOR_PRE_BODY (for_stmt))
11323 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
11324 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
11325 else
11327 struct gimplify_omp_ctx ctx;
11328 memset (&ctx, 0, sizeof (ctx));
11329 ctx.region_type = ORT_NONE;
11330 gimplify_omp_ctxp = &ctx;
11331 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
11332 gimplify_omp_ctxp = NULL;
11335 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
11337 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
11338 for_stmt = inner_for_stmt;
11340 /* For taskloop, need to gimplify the start, end and step before the
11341 taskloop, outside of the taskloop omp context. */
11342 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11344 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11346 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11347 gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
11348 ? pre_p : &for_pre_body);
11349 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
11350 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
11352 tree v = TREE_OPERAND (t, 1);
11353 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
11354 for_pre_p, orig_for_stmt);
11355 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
11356 for_pre_p, orig_for_stmt);
11358 else
11359 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
11360 orig_for_stmt);
11362 /* Handle OMP_FOR_COND. */
11363 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
11364 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
11366 tree v = TREE_OPERAND (t, 1);
11367 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
11368 for_pre_p, orig_for_stmt);
11369 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
11370 for_pre_p, orig_for_stmt);
11372 else
11373 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
11374 orig_for_stmt);
11376 /* Handle OMP_FOR_INCR. */
11377 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11378 if (TREE_CODE (t) == MODIFY_EXPR)
11380 decl = TREE_OPERAND (t, 0);
11381 t = TREE_OPERAND (t, 1);
11382 tree *tp = &TREE_OPERAND (t, 1);
11383 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
11384 tp = &TREE_OPERAND (t, 0);
11386 gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
11387 orig_for_stmt);
11391 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
11392 OMP_TASKLOOP);
11395 if (orig_for_stmt != for_stmt)
11396 gimplify_omp_ctxp->combined_loop = true;
11398 for_body = NULL;
11399 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
11400 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
11401 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
11402 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
11404 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
11405 bool is_doacross = false;
11406 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
11408 is_doacross = true;
11409 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
11410 (OMP_FOR_INIT (for_stmt))
11411 * 2);
11413 int collapse = 1, tile = 0;
11414 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
11415 if (c)
11416 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
11417 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
11418 if (c)
11419 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
11420 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11422 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11423 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
11424 decl = TREE_OPERAND (t, 0);
11425 gcc_assert (DECL_P (decl));
11426 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
11427 || POINTER_TYPE_P (TREE_TYPE (decl)));
11428 if (is_doacross)
11430 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
11432 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
11433 if (TREE_CODE (orig_decl) == TREE_LIST)
11435 orig_decl = TREE_PURPOSE (orig_decl);
11436 if (!orig_decl)
11437 orig_decl = decl;
11439 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
11441 else
11442 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
11443 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
11446 /* Make sure the iteration variable is private. */
11447 tree c = NULL_TREE;
11448 tree c2 = NULL_TREE;
11449 if (orig_for_stmt != for_stmt)
11451 /* Preserve this information until we gimplify the inner simd. */
11452 if (has_decl_expr
11453 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
11454 TREE_PRIVATE (t) = 1;
11456 else if (ort == ORT_SIMD)
11458 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
11459 (splay_tree_key) decl);
11460 omp_is_private (gimplify_omp_ctxp, decl,
11461 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
11462 != 1));
11463 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
11465 omp_notice_variable (gimplify_omp_ctxp, decl, true);
11466 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
11467 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
11468 OMP_CLAUSE_LASTPRIVATE);
11469 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
11470 OMP_CLAUSE_LASTPRIVATE))
11471 if (OMP_CLAUSE_DECL (c3) == decl)
11473 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
11474 "conditional %<lastprivate%> on loop "
11475 "iterator %qD ignored", decl);
11476 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
11477 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
11480 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
11482 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
11483 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
11484 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
11485 if ((has_decl_expr
11486 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
11487 || TREE_PRIVATE (t))
11489 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
11490 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
11492 struct gimplify_omp_ctx *outer
11493 = gimplify_omp_ctxp->outer_context;
11494 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
11496 if (outer->region_type == ORT_WORKSHARE
11497 && outer->combined_loop)
11499 n = splay_tree_lookup (outer->variables,
11500 (splay_tree_key)decl);
11501 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
11503 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
11504 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
11506 else
11508 struct gimplify_omp_ctx *octx = outer->outer_context;
11509 if (octx
11510 && octx->region_type == ORT_COMBINED_PARALLEL
11511 && octx->outer_context
11512 && (octx->outer_context->region_type
11513 == ORT_WORKSHARE)
11514 && octx->outer_context->combined_loop)
11516 octx = octx->outer_context;
11517 n = splay_tree_lookup (octx->variables,
11518 (splay_tree_key)decl);
11519 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
11521 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
11522 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
11529 OMP_CLAUSE_DECL (c) = decl;
11530 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
11531 OMP_FOR_CLAUSES (for_stmt) = c;
11532 omp_add_variable (gimplify_omp_ctxp, decl, flags);
11533 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
11535 if (outer->region_type == ORT_WORKSHARE
11536 && outer->combined_loop)
11538 if (outer->outer_context
11539 && (outer->outer_context->region_type
11540 == ORT_COMBINED_PARALLEL))
11541 outer = outer->outer_context;
11542 else if (omp_check_private (outer, decl, false))
11543 outer = NULL;
11545 else if (((outer->region_type & ORT_TASKLOOP)
11546 == ORT_TASKLOOP)
11547 && outer->combined_loop
11548 && !omp_check_private (gimplify_omp_ctxp,
11549 decl, false))
11551 else if (outer->region_type != ORT_COMBINED_PARALLEL)
11553 omp_notice_variable (outer, decl, true);
11554 outer = NULL;
11556 if (outer)
11558 n = splay_tree_lookup (outer->variables,
11559 (splay_tree_key)decl);
11560 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11562 omp_add_variable (outer, decl,
11563 GOVD_LASTPRIVATE | GOVD_SEEN);
11564 if (outer->region_type == ORT_COMBINED_PARALLEL
11565 && outer->outer_context
11566 && (outer->outer_context->region_type
11567 == ORT_WORKSHARE)
11568 && outer->outer_context->combined_loop)
11570 outer = outer->outer_context;
11571 n = splay_tree_lookup (outer->variables,
11572 (splay_tree_key)decl);
11573 if (omp_check_private (outer, decl, false))
11574 outer = NULL;
11575 else if (n == NULL
11576 || ((n->value & GOVD_DATA_SHARE_CLASS)
11577 == 0))
11578 omp_add_variable (outer, decl,
11579 GOVD_LASTPRIVATE
11580 | GOVD_SEEN);
11581 else
11582 outer = NULL;
11584 if (outer && outer->outer_context
11585 && ((outer->outer_context->region_type
11586 & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS
11587 || (((outer->region_type & ORT_TASKLOOP)
11588 == ORT_TASKLOOP)
11589 && (outer->outer_context->region_type
11590 == ORT_COMBINED_PARALLEL))))
11592 outer = outer->outer_context;
11593 n = splay_tree_lookup (outer->variables,
11594 (splay_tree_key)decl);
11595 if (n == NULL
11596 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11597 omp_add_variable (outer, decl,
11598 GOVD_SHARED | GOVD_SEEN);
11599 else
11600 outer = NULL;
11602 if (outer && outer->outer_context)
11603 omp_notice_variable (outer->outer_context, decl,
11604 true);
11609 else
11611 bool lastprivate
11612 = (!has_decl_expr
11613 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
11614 if (TREE_PRIVATE (t))
11615 lastprivate = false;
11616 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
11618 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
11619 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
11620 lastprivate = false;
11623 struct gimplify_omp_ctx *outer
11624 = gimplify_omp_ctxp->outer_context;
11625 if (outer && lastprivate)
11627 if (outer->region_type == ORT_WORKSHARE
11628 && outer->combined_loop)
11630 n = splay_tree_lookup (outer->variables,
11631 (splay_tree_key)decl);
11632 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
11634 lastprivate = false;
11635 outer = NULL;
11637 else if (outer->outer_context
11638 && (outer->outer_context->region_type
11639 == ORT_COMBINED_PARALLEL))
11640 outer = outer->outer_context;
11641 else if (omp_check_private (outer, decl, false))
11642 outer = NULL;
11644 else if (((outer->region_type & ORT_TASKLOOP)
11645 == ORT_TASKLOOP)
11646 && outer->combined_loop
11647 && !omp_check_private (gimplify_omp_ctxp,
11648 decl, false))
11650 else if (outer->region_type != ORT_COMBINED_PARALLEL)
11652 omp_notice_variable (outer, decl, true);
11653 outer = NULL;
11655 if (outer)
11657 n = splay_tree_lookup (outer->variables,
11658 (splay_tree_key)decl);
11659 if (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11661 omp_add_variable (outer, decl,
11662 GOVD_LASTPRIVATE | GOVD_SEEN);
11663 if (outer->region_type == ORT_COMBINED_PARALLEL
11664 && outer->outer_context
11665 && (outer->outer_context->region_type
11666 == ORT_WORKSHARE)
11667 && outer->outer_context->combined_loop)
11669 outer = outer->outer_context;
11670 n = splay_tree_lookup (outer->variables,
11671 (splay_tree_key)decl);
11672 if (omp_check_private (outer, decl, false))
11673 outer = NULL;
11674 else if (n == NULL
11675 || ((n->value & GOVD_DATA_SHARE_CLASS)
11676 == 0))
11677 omp_add_variable (outer, decl,
11678 GOVD_LASTPRIVATE
11679 | GOVD_SEEN);
11680 else
11681 outer = NULL;
11683 if (outer && outer->outer_context
11684 && ((outer->outer_context->region_type
11685 & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS
11686 || (((outer->region_type & ORT_TASKLOOP)
11687 == ORT_TASKLOOP)
11688 && (outer->outer_context->region_type
11689 == ORT_COMBINED_PARALLEL))))
11691 outer = outer->outer_context;
11692 n = splay_tree_lookup (outer->variables,
11693 (splay_tree_key)decl);
11694 if (n == NULL
11695 || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
11696 omp_add_variable (outer, decl,
11697 GOVD_SHARED | GOVD_SEEN);
11698 else
11699 outer = NULL;
11701 if (outer && outer->outer_context)
11702 omp_notice_variable (outer->outer_context, decl,
11703 true);
11708 c = build_omp_clause (input_location,
11709 lastprivate ? OMP_CLAUSE_LASTPRIVATE
11710 : OMP_CLAUSE_PRIVATE);
11711 OMP_CLAUSE_DECL (c) = decl;
11712 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
11713 OMP_FOR_CLAUSES (for_stmt) = c;
11714 omp_add_variable (gimplify_omp_ctxp, decl,
11715 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
11716 | GOVD_EXPLICIT | GOVD_SEEN);
11717 c = NULL_TREE;
11720 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
11722 omp_notice_variable (gimplify_omp_ctxp, decl, true);
11723 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
11724 (splay_tree_key) decl);
11725 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
11726 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
11727 OMP_CLAUSE_LASTPRIVATE);
11728 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
11729 OMP_CLAUSE_LASTPRIVATE))
11730 if (OMP_CLAUSE_DECL (c3) == decl)
11732 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
11733 "conditional %<lastprivate%> on loop "
11734 "iterator %qD ignored", decl);
11735 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
11736 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
11739 else
11740 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
11742 /* If DECL is not a gimple register, create a temporary variable to act
11743 as an iteration counter. This is valid, since DECL cannot be
11744 modified in the body of the loop. Similarly for any iteration vars
11745 in simd with collapse > 1 where the iterator vars must be
11746 lastprivate. */
11747 if (orig_for_stmt != for_stmt)
11748 var = decl;
11749 else if (!is_gimple_reg (decl)
11750 || (ort == ORT_SIMD
11751 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1))
11753 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11754 /* Make sure omp_add_variable is not called on it prematurely.
11755 We call it ourselves a few lines later. */
11756 gimplify_omp_ctxp = NULL;
11757 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
11758 gimplify_omp_ctxp = ctx;
11759 TREE_OPERAND (t, 0) = var;
11761 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
11763 if (ort == ORT_SIMD
11764 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
11766 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
11767 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
11768 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
11769 OMP_CLAUSE_DECL (c2) = var;
11770 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
11771 OMP_FOR_CLAUSES (for_stmt) = c2;
11772 omp_add_variable (gimplify_omp_ctxp, var,
11773 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
11774 if (c == NULL_TREE)
11776 c = c2;
11777 c2 = NULL_TREE;
11780 else
11781 omp_add_variable (gimplify_omp_ctxp, var,
11782 GOVD_PRIVATE | GOVD_SEEN);
11784 else
11785 var = decl;
11787 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
11789 tree lb = TREE_OPERAND (t, 1);
11790 tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
11791 is_gimple_val, fb_rvalue, false);
11792 ret = MIN (ret, tret);
11793 tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
11794 is_gimple_val, fb_rvalue, false);
11796 else
11797 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
11798 is_gimple_val, fb_rvalue, false);
11799 ret = MIN (ret, tret);
11800 if (ret == GS_ERROR)
11801 return ret;
11803 /* Handle OMP_FOR_COND. */
11804 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
11805 gcc_assert (COMPARISON_CLASS_P (t));
11806 gcc_assert (TREE_OPERAND (t, 0) == decl);
11808 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
11810 tree ub = TREE_OPERAND (t, 1);
11811 tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
11812 is_gimple_val, fb_rvalue, false);
11813 ret = MIN (ret, tret);
11814 tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
11815 is_gimple_val, fb_rvalue, false);
11817 else
11818 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
11819 is_gimple_val, fb_rvalue, false);
11820 ret = MIN (ret, tret);
11822 /* Handle OMP_FOR_INCR. */
11823 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11824 switch (TREE_CODE (t))
11826 case PREINCREMENT_EXPR:
11827 case POSTINCREMENT_EXPR:
11829 tree decl = TREE_OPERAND (t, 0);
11830 /* c_omp_for_incr_canonicalize_ptr() should have been
11831 called to massage things appropriately. */
11832 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
11834 if (orig_for_stmt != for_stmt)
11835 break;
11836 t = build_int_cst (TREE_TYPE (decl), 1);
11837 if (c)
11838 OMP_CLAUSE_LINEAR_STEP (c) = t;
11839 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
11840 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
11841 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
11842 break;
11845 case PREDECREMENT_EXPR:
11846 case POSTDECREMENT_EXPR:
11847 /* c_omp_for_incr_canonicalize_ptr() should have been
11848 called to massage things appropriately. */
11849 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
11850 if (orig_for_stmt != for_stmt)
11851 break;
11852 t = build_int_cst (TREE_TYPE (decl), -1);
11853 if (c)
11854 OMP_CLAUSE_LINEAR_STEP (c) = t;
11855 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
11856 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
11857 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
11858 break;
11860 case MODIFY_EXPR:
11861 gcc_assert (TREE_OPERAND (t, 0) == decl);
11862 TREE_OPERAND (t, 0) = var;
11864 t = TREE_OPERAND (t, 1);
11865 switch (TREE_CODE (t))
11867 case PLUS_EXPR:
11868 if (TREE_OPERAND (t, 1) == decl)
11870 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
11871 TREE_OPERAND (t, 0) = var;
11872 break;
11875 /* Fallthru. */
11876 case MINUS_EXPR:
11877 case POINTER_PLUS_EXPR:
11878 gcc_assert (TREE_OPERAND (t, 0) == decl);
11879 TREE_OPERAND (t, 0) = var;
11880 break;
11881 default:
11882 gcc_unreachable ();
11885 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
11886 is_gimple_val, fb_rvalue, false);
11887 ret = MIN (ret, tret);
11888 if (c)
11890 tree step = TREE_OPERAND (t, 1);
11891 tree stept = TREE_TYPE (decl);
11892 if (POINTER_TYPE_P (stept))
11893 stept = sizetype;
11894 step = fold_convert (stept, step);
11895 if (TREE_CODE (t) == MINUS_EXPR)
11896 step = fold_build1 (NEGATE_EXPR, stept, step);
11897 OMP_CLAUSE_LINEAR_STEP (c) = step;
11898 if (step != TREE_OPERAND (t, 1))
11900 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
11901 &for_pre_body, NULL,
11902 is_gimple_val, fb_rvalue, false);
11903 ret = MIN (ret, tret);
11906 break;
11908 default:
11909 gcc_unreachable ();
11912 if (c2)
11914 gcc_assert (c);
11915 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
11918 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
11920 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
11921 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11922 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
11923 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11924 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
11925 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
11926 && OMP_CLAUSE_DECL (c) == decl)
11928 if (is_doacross && (collapse == 1 || i >= collapse))
11929 t = var;
11930 else
11932 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
11933 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
11934 gcc_assert (TREE_OPERAND (t, 0) == var);
11935 t = TREE_OPERAND (t, 1);
11936 gcc_assert (TREE_CODE (t) == PLUS_EXPR
11937 || TREE_CODE (t) == MINUS_EXPR
11938 || TREE_CODE (t) == POINTER_PLUS_EXPR);
11939 gcc_assert (TREE_OPERAND (t, 0) == var);
11940 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
11941 is_doacross ? var : decl,
11942 TREE_OPERAND (t, 1));
11944 gimple_seq *seq;
11945 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
11946 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
11947 else
11948 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
11949 push_gimplify_context ();
11950 gimplify_assign (decl, t, seq);
11951 gimple *bind = NULL;
11952 if (gimplify_ctxp->temps)
11954 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
11955 *seq = NULL;
11956 gimplify_seq_add_stmt (seq, bind);
11958 pop_gimplify_context (bind);
11961 if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
11962 for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
11964 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
11965 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
11966 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
11967 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
11968 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
11969 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
11970 gcc_assert (COMPARISON_CLASS_P (t));
11971 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
11972 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
11973 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
11977 BITMAP_FREE (has_decl_expr);
11979 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
11980 || (loop_p && orig_for_stmt == for_stmt))
11982 push_gimplify_context ();
11983 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
11985 OMP_FOR_BODY (orig_for_stmt)
11986 = build3 (BIND_EXPR, void_type_node, NULL,
11987 OMP_FOR_BODY (orig_for_stmt), NULL);
11988 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
11992 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
11993 &for_body);
11995 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
11996 || (loop_p && orig_for_stmt == for_stmt))
11998 if (gimple_code (g) == GIMPLE_BIND)
11999 pop_gimplify_context (g);
12000 else
12001 pop_gimplify_context (NULL);
12004 if (orig_for_stmt != for_stmt)
12005 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12007 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12008 decl = TREE_OPERAND (t, 0);
12009 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12010 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12011 gimplify_omp_ctxp = ctx->outer_context;
12012 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
12013 gimplify_omp_ctxp = ctx;
12014 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
12015 TREE_OPERAND (t, 0) = var;
12016 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12017 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12018 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
12019 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
12020 for (int j = i + 1;
12021 j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
12023 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
12024 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12025 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12026 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12028 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12029 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12031 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
12032 gcc_assert (COMPARISON_CLASS_P (t));
12033 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12034 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12036 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12037 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12042 gimplify_adjust_omp_clauses (pre_p, for_body,
12043 &OMP_FOR_CLAUSES (orig_for_stmt),
12044 TREE_CODE (orig_for_stmt));
12046 int kind;
12047 switch (TREE_CODE (orig_for_stmt))
12049 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
12050 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
12051 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
12052 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
12053 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
12054 default:
12055 gcc_unreachable ();
12057 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
12059 gimplify_seq_add_seq (pre_p, for_pre_body);
12060 for_pre_body = NULL;
12062 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
12063 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
12064 for_pre_body);
12065 if (orig_for_stmt != for_stmt)
12066 gimple_omp_for_set_combined_p (gfor, true);
12067 if (gimplify_omp_ctxp
12068 && (gimplify_omp_ctxp->combined_loop
12069 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
12070 && gimplify_omp_ctxp->outer_context
12071 && gimplify_omp_ctxp->outer_context->combined_loop)))
12073 gimple_omp_for_set_combined_into_p (gfor, true);
12074 if (gimplify_omp_ctxp->combined_loop)
12075 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
12076 else
12077 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
12080 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12082 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12083 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
12084 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
12085 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12086 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
12087 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
12088 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12089 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
12092 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
12093 constructs with GIMPLE_OMP_TASK sandwiched in between them.
12094 The outer taskloop stands for computing the number of iterations,
12095 counts for collapsed loops and holding taskloop specific clauses.
12096 The task construct stands for the effect of data sharing on the
12097 explicit task it creates and the inner taskloop stands for expansion
12098 of the static loop inside of the explicit task construct. */
12099 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12101 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
12102 tree task_clauses = NULL_TREE;
12103 tree c = *gfor_clauses_ptr;
12104 tree *gtask_clauses_ptr = &task_clauses;
12105 tree outer_for_clauses = NULL_TREE;
12106 tree *gforo_clauses_ptr = &outer_for_clauses;
12107 for (; c; c = OMP_CLAUSE_CHAIN (c))
12108 switch (OMP_CLAUSE_CODE (c))
12110 /* These clauses are allowed on task, move them there. */
12111 case OMP_CLAUSE_SHARED:
12112 case OMP_CLAUSE_FIRSTPRIVATE:
12113 case OMP_CLAUSE_DEFAULT:
12114 case OMP_CLAUSE_IF:
12115 case OMP_CLAUSE_UNTIED:
12116 case OMP_CLAUSE_FINAL:
12117 case OMP_CLAUSE_MERGEABLE:
12118 case OMP_CLAUSE_PRIORITY:
12119 case OMP_CLAUSE_REDUCTION:
12120 case OMP_CLAUSE_IN_REDUCTION:
12121 *gtask_clauses_ptr = c;
12122 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12123 break;
12124 case OMP_CLAUSE_PRIVATE:
12125 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
12127 /* We want private on outer for and firstprivate
12128 on task. */
12129 *gtask_clauses_ptr
12130 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12131 OMP_CLAUSE_FIRSTPRIVATE);
12132 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12133 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
12134 openacc);
12135 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12136 *gforo_clauses_ptr = c;
12137 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12139 else
12141 *gtask_clauses_ptr = c;
12142 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12144 break;
12145 /* These clauses go into outer taskloop clauses. */
12146 case OMP_CLAUSE_GRAINSIZE:
12147 case OMP_CLAUSE_NUM_TASKS:
12148 case OMP_CLAUSE_NOGROUP:
12149 *gforo_clauses_ptr = c;
12150 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12151 break;
12152 /* Taskloop clause we duplicate on both taskloops. */
12153 case OMP_CLAUSE_COLLAPSE:
12154 *gfor_clauses_ptr = c;
12155 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12156 *gforo_clauses_ptr = copy_node (c);
12157 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
12158 break;
12159 /* For lastprivate, keep the clause on inner taskloop, and add
12160 a shared clause on task. If the same decl is also firstprivate,
12161 add also firstprivate clause on the inner taskloop. */
12162 case OMP_CLAUSE_LASTPRIVATE:
12163 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
12165 /* For taskloop C++ lastprivate IVs, we want:
12166 1) private on outer taskloop
12167 2) firstprivate and shared on task
12168 3) lastprivate on inner taskloop */
12169 *gtask_clauses_ptr
12170 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12171 OMP_CLAUSE_FIRSTPRIVATE);
12172 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12173 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
12174 openacc);
12175 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12176 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
12177 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12178 OMP_CLAUSE_PRIVATE);
12179 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
12180 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
12181 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
12182 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
12184 *gfor_clauses_ptr = c;
12185 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12186 *gtask_clauses_ptr
12187 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
12188 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12189 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
12190 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
12191 gtask_clauses_ptr
12192 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12193 break;
12194 default:
12195 gcc_unreachable ();
12197 *gfor_clauses_ptr = NULL_TREE;
12198 *gtask_clauses_ptr = NULL_TREE;
12199 *gforo_clauses_ptr = NULL_TREE;
12200 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
12201 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
12202 NULL_TREE, NULL_TREE, NULL_TREE);
12203 gimple_omp_task_set_taskloop_p (g, true);
12204 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
12205 gomp_for *gforo
12206 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
12207 gimple_omp_for_collapse (gfor),
12208 gimple_omp_for_pre_body (gfor));
12209 gimple_omp_for_set_pre_body (gfor, NULL);
12210 gimple_omp_for_set_combined_p (gforo, true);
12211 gimple_omp_for_set_combined_into_p (gfor, true);
12212 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
12214 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
12215 tree v = create_tmp_var (type);
12216 gimple_omp_for_set_index (gforo, i, v);
12217 t = unshare_expr (gimple_omp_for_initial (gfor, i));
12218 gimple_omp_for_set_initial (gforo, i, t);
12219 gimple_omp_for_set_cond (gforo, i,
12220 gimple_omp_for_cond (gfor, i));
12221 t = unshare_expr (gimple_omp_for_final (gfor, i));
12222 gimple_omp_for_set_final (gforo, i, t);
12223 t = unshare_expr (gimple_omp_for_incr (gfor, i));
12224 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
12225 TREE_OPERAND (t, 0) = v;
12226 gimple_omp_for_set_incr (gforo, i, t);
12227 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
12228 OMP_CLAUSE_DECL (t) = v;
12229 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
12230 gimple_omp_for_set_clauses (gforo, t);
12231 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
12233 tree *p1 = NULL, *p2 = NULL;
12234 t = gimple_omp_for_initial (gforo, i);
12235 if (TREE_CODE (t) == TREE_VEC)
12236 p1 = &TREE_VEC_ELT (t, 0);
12237 t = gimple_omp_for_final (gforo, i);
12238 if (TREE_CODE (t) == TREE_VEC)
12240 if (p1)
12241 p2 = &TREE_VEC_ELT (t, 0);
12242 else
12243 p1 = &TREE_VEC_ELT (t, 0);
12245 if (p1)
12247 int j;
12248 for (j = 0; j < i; j++)
12249 if (*p1 == gimple_omp_for_index (gfor, j))
12251 *p1 = gimple_omp_for_index (gforo, j);
12252 if (p2)
12253 *p2 = *p1;
12254 break;
12256 gcc_assert (j < i);
12260 gimplify_seq_add_stmt (pre_p, gforo);
12262 else
12263 gimplify_seq_add_stmt (pre_p, gfor);
12265 if (TREE_CODE (orig_for_stmt) == OMP_FOR)
12267 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12268 unsigned lastprivate_conditional = 0;
12269 while (ctx
12270 && (ctx->region_type == ORT_TARGET_DATA
12271 || ctx->region_type == ORT_TASKGROUP))
12272 ctx = ctx->outer_context;
12273 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
12274 for (tree c = gimple_omp_for_clauses (gfor);
12275 c; c = OMP_CLAUSE_CHAIN (c))
12276 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12277 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
12278 ++lastprivate_conditional;
12279 if (lastprivate_conditional)
12281 struct omp_for_data fd;
12282 omp_extract_for_data (gfor, &fd, NULL);
12283 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
12284 lastprivate_conditional);
12285 tree var = create_tmp_var_raw (type);
12286 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
12287 OMP_CLAUSE_DECL (c) = var;
12288 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
12289 gimple_omp_for_set_clauses (gfor, c);
12290 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
12293 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
12295 unsigned lastprivate_conditional = 0;
12296 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
12297 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12298 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
12299 ++lastprivate_conditional;
12300 if (lastprivate_conditional)
12302 struct omp_for_data fd;
12303 omp_extract_for_data (gfor, &fd, NULL);
12304 tree type = unsigned_type_for (fd.iter_type);
12305 while (lastprivate_conditional--)
12307 tree c = build_omp_clause (UNKNOWN_LOCATION,
12308 OMP_CLAUSE__CONDTEMP_);
12309 OMP_CLAUSE_DECL (c) = create_tmp_var (type);
12310 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
12311 gimple_omp_for_set_clauses (gfor, c);
12316 if (ret != GS_ALL_DONE)
12317 return GS_ERROR;
12318 *expr_p = NULL_TREE;
12319 return GS_ALL_DONE;
12322 /* Helper for gimplify_omp_loop, called through walk_tree. */
12324 static tree
12325 replace_reduction_placeholders (tree *tp, int *walk_subtrees, void *data)
12327 if (DECL_P (*tp))
12329 tree *d = (tree *) data;
12330 if (*tp == OMP_CLAUSE_REDUCTION_PLACEHOLDER (d[0]))
12332 *tp = OMP_CLAUSE_REDUCTION_PLACEHOLDER (d[1]);
12333 *walk_subtrees = 0;
12335 else if (*tp == OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d[0]))
12337 *tp = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d[1]);
12338 *walk_subtrees = 0;
12341 return NULL_TREE;
12344 /* Gimplify the gross structure of an OMP_LOOP statement. */
12346 static enum gimplify_status
12347 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
12349 tree for_stmt = *expr_p;
12350 tree clauses = OMP_FOR_CLAUSES (for_stmt);
12351 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
12352 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
12353 int i;
12355 /* If order is not present, the behavior is as if order(concurrent)
12356 appeared. */
12357 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
12358 if (order == NULL_TREE)
12360 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
12361 OMP_CLAUSE_CHAIN (order) = clauses;
12362 OMP_FOR_CLAUSES (for_stmt) = clauses = order;
12365 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
12366 if (bind == NULL_TREE)
12368 if (!flag_openmp) /* flag_openmp_simd */
12370 else if (octx && (octx->region_type & ORT_TEAMS) != 0)
12371 kind = OMP_CLAUSE_BIND_TEAMS;
12372 else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
12373 kind = OMP_CLAUSE_BIND_PARALLEL;
12374 else
12376 for (; octx; octx = octx->outer_context)
12378 if ((octx->region_type & ORT_ACC) != 0
12379 || octx->region_type == ORT_NONE
12380 || octx->region_type == ORT_IMPLICIT_TARGET)
12381 continue;
12382 break;
12384 if (octx == NULL && !in_omp_construct)
12385 error_at (EXPR_LOCATION (for_stmt),
12386 "%<bind%> clause not specified on a %<loop%> "
12387 "construct not nested inside another OpenMP construct");
12389 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
12390 OMP_CLAUSE_CHAIN (bind) = clauses;
12391 OMP_CLAUSE_BIND_KIND (bind) = kind;
12392 OMP_FOR_CLAUSES (for_stmt) = bind;
12394 else
12395 switch (OMP_CLAUSE_BIND_KIND (bind))
12397 case OMP_CLAUSE_BIND_THREAD:
12398 break;
12399 case OMP_CLAUSE_BIND_PARALLEL:
12400 if (!flag_openmp) /* flag_openmp_simd */
12402 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12403 break;
12405 for (; octx; octx = octx->outer_context)
12406 if (octx->region_type == ORT_SIMD
12407 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
12409 error_at (EXPR_LOCATION (for_stmt),
12410 "%<bind(parallel)%> on a %<loop%> construct nested "
12411 "inside %<simd%> construct");
12412 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12413 break;
12415 kind = OMP_CLAUSE_BIND_PARALLEL;
12416 break;
12417 case OMP_CLAUSE_BIND_TEAMS:
12418 if (!flag_openmp) /* flag_openmp_simd */
12420 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12421 break;
12423 if ((octx
12424 && octx->region_type != ORT_IMPLICIT_TARGET
12425 && octx->region_type != ORT_NONE
12426 && (octx->region_type & ORT_TEAMS) == 0)
12427 || in_omp_construct)
12429 error_at (EXPR_LOCATION (for_stmt),
12430 "%<bind(teams)%> on a %<loop%> region not strictly "
12431 "nested inside of a %<teams%> region");
12432 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12433 break;
12435 kind = OMP_CLAUSE_BIND_TEAMS;
12436 break;
12437 default:
12438 gcc_unreachable ();
12441 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
12442 switch (OMP_CLAUSE_CODE (*pc))
12444 case OMP_CLAUSE_REDUCTION:
12445 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
12447 error_at (OMP_CLAUSE_LOCATION (*pc),
12448 "%<inscan%> %<reduction%> clause on "
12449 "%qs construct", "loop");
12450 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
12452 if (OMP_CLAUSE_REDUCTION_TASK (*pc))
12454 error_at (OMP_CLAUSE_LOCATION (*pc),
12455 "invalid %<task%> reduction modifier on construct "
12456 "other than %<parallel%>, %<for%> or %<sections%>");
12457 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
12459 pc = &OMP_CLAUSE_CHAIN (*pc);
12460 break;
12461 case OMP_CLAUSE_LASTPRIVATE:
12462 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12464 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12465 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12466 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
12467 break;
12468 if (OMP_FOR_ORIG_DECLS (for_stmt)
12469 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
12470 i)) == TREE_LIST
12471 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
12472 i)))
12474 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12475 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
12476 break;
12479 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
12481 error_at (OMP_CLAUSE_LOCATION (*pc),
12482 "%<lastprivate%> clause on a %<loop%> construct refers "
12483 "to a variable %qD which is not the loop iterator",
12484 OMP_CLAUSE_DECL (*pc));
12485 *pc = OMP_CLAUSE_CHAIN (*pc);
12486 break;
12488 pc = &OMP_CLAUSE_CHAIN (*pc);
12489 break;
12490 default:
12491 pc = &OMP_CLAUSE_CHAIN (*pc);
12492 break;
12495 TREE_SET_CODE (for_stmt, OMP_SIMD);
12497 int last;
12498 switch (kind)
12500 case OMP_CLAUSE_BIND_THREAD: last = 0; break;
12501 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
12502 case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
12504 for (int pass = 1; pass <= last; pass++)
12506 if (pass == 2)
12508 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
12509 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
12510 *expr_p = make_node (OMP_PARALLEL);
12511 TREE_TYPE (*expr_p) = void_type_node;
12512 OMP_PARALLEL_BODY (*expr_p) = bind;
12513 OMP_PARALLEL_COMBINED (*expr_p) = 1;
12514 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
12515 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
12516 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12517 if (OMP_FOR_ORIG_DECLS (for_stmt)
12518 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
12519 == TREE_LIST))
12521 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12522 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
12524 *pc = build_omp_clause (UNKNOWN_LOCATION,
12525 OMP_CLAUSE_FIRSTPRIVATE);
12526 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
12527 pc = &OMP_CLAUSE_CHAIN (*pc);
12531 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
12532 tree *pc = &OMP_FOR_CLAUSES (t);
12533 TREE_TYPE (t) = void_type_node;
12534 OMP_FOR_BODY (t) = *expr_p;
12535 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
12536 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
12537 switch (OMP_CLAUSE_CODE (c))
12539 case OMP_CLAUSE_BIND:
12540 case OMP_CLAUSE_ORDER:
12541 case OMP_CLAUSE_COLLAPSE:
12542 *pc = copy_node (c);
12543 pc = &OMP_CLAUSE_CHAIN (*pc);
12544 break;
12545 case OMP_CLAUSE_PRIVATE:
12546 case OMP_CLAUSE_FIRSTPRIVATE:
12547 /* Only needed on innermost. */
12548 break;
12549 case OMP_CLAUSE_LASTPRIVATE:
12550 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
12552 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12553 OMP_CLAUSE_FIRSTPRIVATE);
12554 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
12555 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
12556 pc = &OMP_CLAUSE_CHAIN (*pc);
12558 *pc = copy_node (c);
12559 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
12560 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
12561 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
12563 if (pass != last)
12564 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
12565 else
12566 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
12567 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
12569 pc = &OMP_CLAUSE_CHAIN (*pc);
12570 break;
12571 case OMP_CLAUSE_REDUCTION:
12572 *pc = copy_node (c);
12573 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
12574 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
12575 OMP_CLAUSE_REDUCTION_INIT (*pc)
12576 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
12577 OMP_CLAUSE_REDUCTION_MERGE (*pc)
12578 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
12579 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
12581 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
12582 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
12583 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
12584 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
12585 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
12586 tree nc = *pc;
12587 tree data[2] = { c, nc };
12588 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (nc),
12589 replace_reduction_placeholders,
12590 data);
12591 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (nc),
12592 replace_reduction_placeholders,
12593 data);
12595 pc = &OMP_CLAUSE_CHAIN (*pc);
12596 break;
12597 default:
12598 gcc_unreachable ();
12600 *pc = NULL_TREE;
12601 *expr_p = t;
12603 return gimplify_omp_for (expr_p, pre_p);
12607 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
12608 of OMP_TARGET's body. */
12610 static tree
12611 find_omp_teams (tree *tp, int *walk_subtrees, void *)
12613 *walk_subtrees = 0;
12614 switch (TREE_CODE (*tp))
12616 case OMP_TEAMS:
12617 return *tp;
12618 case BIND_EXPR:
12619 case STATEMENT_LIST:
12620 *walk_subtrees = 1;
12621 break;
12622 default:
12623 break;
12625 return NULL_TREE;
12628 /* Helper function of optimize_target_teams, determine if the expression
12629 can be computed safely before the target construct on the host. */
12631 static tree
12632 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
12634 splay_tree_node n;
12636 if (TYPE_P (*tp))
12638 *walk_subtrees = 0;
12639 return NULL_TREE;
12641 switch (TREE_CODE (*tp))
12643 case VAR_DECL:
12644 case PARM_DECL:
12645 case RESULT_DECL:
12646 *walk_subtrees = 0;
12647 if (error_operand_p (*tp)
12648 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
12649 || DECL_HAS_VALUE_EXPR_P (*tp)
12650 || DECL_THREAD_LOCAL_P (*tp)
12651 || TREE_SIDE_EFFECTS (*tp)
12652 || TREE_THIS_VOLATILE (*tp))
12653 return *tp;
12654 if (is_global_var (*tp)
12655 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
12656 || lookup_attribute ("omp declare target link",
12657 DECL_ATTRIBUTES (*tp))))
12658 return *tp;
12659 if (VAR_P (*tp)
12660 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
12661 && !is_global_var (*tp)
12662 && decl_function_context (*tp) == current_function_decl)
12663 return *tp;
12664 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12665 (splay_tree_key) *tp);
12666 if (n == NULL)
12668 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
12669 return NULL_TREE;
12670 return *tp;
12672 else if (n->value & GOVD_LOCAL)
12673 return *tp;
12674 else if (n->value & GOVD_FIRSTPRIVATE)
12675 return NULL_TREE;
12676 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
12677 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
12678 return NULL_TREE;
12679 return *tp;
12680 case INTEGER_CST:
12681 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
12682 return *tp;
12683 return NULL_TREE;
12684 case TARGET_EXPR:
12685 if (TARGET_EXPR_INITIAL (*tp)
12686 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
12687 return *tp;
12688 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
12689 walk_subtrees, NULL);
12690 /* Allow some reasonable subset of integral arithmetics. */
12691 case PLUS_EXPR:
12692 case MINUS_EXPR:
12693 case MULT_EXPR:
12694 case TRUNC_DIV_EXPR:
12695 case CEIL_DIV_EXPR:
12696 case FLOOR_DIV_EXPR:
12697 case ROUND_DIV_EXPR:
12698 case TRUNC_MOD_EXPR:
12699 case CEIL_MOD_EXPR:
12700 case FLOOR_MOD_EXPR:
12701 case ROUND_MOD_EXPR:
12702 case RDIV_EXPR:
12703 case EXACT_DIV_EXPR:
12704 case MIN_EXPR:
12705 case MAX_EXPR:
12706 case LSHIFT_EXPR:
12707 case RSHIFT_EXPR:
12708 case BIT_IOR_EXPR:
12709 case BIT_XOR_EXPR:
12710 case BIT_AND_EXPR:
12711 case NEGATE_EXPR:
12712 case ABS_EXPR:
12713 case BIT_NOT_EXPR:
12714 case NON_LVALUE_EXPR:
12715 CASE_CONVERT:
12716 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
12717 return *tp;
12718 return NULL_TREE;
12719 /* And disallow anything else, except for comparisons. */
12720 default:
12721 if (COMPARISON_CLASS_P (*tp))
12722 return NULL_TREE;
12723 return *tp;
12727 /* Try to determine if the num_teams and/or thread_limit expressions
12728 can have their values determined already before entering the
12729 target construct.
12730 INTEGER_CSTs trivially are,
12731 integral decls that are firstprivate (explicitly or implicitly)
12732 or explicitly map(always, to:) or map(always, tofrom:) on the target
12733 region too, and expressions involving simple arithmetics on those
12734 too, function calls are not ok, dereferencing something neither etc.
12735 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
12736 EXPR based on what we find:
12737 0 stands for clause not specified at all, use implementation default
12738 -1 stands for value that can't be determined easily before entering
12739 the target construct.
12740 If teams construct is not present at all, use 1 for num_teams
12741 and 0 for thread_limit (only one team is involved, and the thread
12742 limit is implementation defined. */
12744 static void
12745 optimize_target_teams (tree target, gimple_seq *pre_p)
12747 tree body = OMP_BODY (target);
12748 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
12749 tree num_teams = integer_zero_node;
12750 tree thread_limit = integer_zero_node;
12751 location_t num_teams_loc = EXPR_LOCATION (target);
12752 location_t thread_limit_loc = EXPR_LOCATION (target);
12753 tree c, *p, expr;
12754 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
12756 if (teams == NULL_TREE)
12757 num_teams = integer_one_node;
12758 else
12759 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
12761 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
12763 p = &num_teams;
12764 num_teams_loc = OMP_CLAUSE_LOCATION (c);
12766 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
12768 p = &thread_limit;
12769 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
12771 else
12772 continue;
12773 expr = OMP_CLAUSE_OPERAND (c, 0);
12774 if (TREE_CODE (expr) == INTEGER_CST)
12776 *p = expr;
12777 continue;
12779 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
12781 *p = integer_minus_one_node;
12782 continue;
12784 *p = expr;
12785 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
12786 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
12787 == GS_ERROR)
12789 gimplify_omp_ctxp = target_ctx;
12790 *p = integer_minus_one_node;
12791 continue;
12793 gimplify_omp_ctxp = target_ctx;
12794 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
12795 OMP_CLAUSE_OPERAND (c, 0) = *p;
12797 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
12798 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
12799 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
12800 OMP_TARGET_CLAUSES (target) = c;
12801 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
12802 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
12803 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
12804 OMP_TARGET_CLAUSES (target) = c;
12807 /* Gimplify the gross structure of several OMP constructs. */
12809 static void
12810 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
12812 tree expr = *expr_p;
12813 gimple *stmt;
12814 gimple_seq body = NULL;
12815 enum omp_region_type ort;
12817 switch (TREE_CODE (expr))
12819 case OMP_SECTIONS:
12820 case OMP_SINGLE:
12821 ort = ORT_WORKSHARE;
12822 break;
12823 case OMP_TARGET:
12824 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
12825 break;
12826 case OACC_KERNELS:
12827 ort = ORT_ACC_KERNELS;
12828 break;
12829 case OACC_PARALLEL:
12830 ort = ORT_ACC_PARALLEL;
12831 break;
12832 case OACC_SERIAL:
12833 ort = ORT_ACC_SERIAL;
12834 break;
12835 case OACC_DATA:
12836 ort = ORT_ACC_DATA;
12837 break;
12838 case OMP_TARGET_DATA:
12839 ort = ORT_TARGET_DATA;
12840 break;
12841 case OMP_TEAMS:
12842 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
12843 if (gimplify_omp_ctxp == NULL
12844 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
12845 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
12846 break;
12847 case OACC_HOST_DATA:
12848 ort = ORT_ACC_HOST_DATA;
12849 break;
12850 default:
12851 gcc_unreachable ();
12854 bool save_in_omp_construct = in_omp_construct;
12855 if ((ort & ORT_ACC) == 0)
12856 in_omp_construct = false;
12857 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
12858 TREE_CODE (expr));
12859 if (TREE_CODE (expr) == OMP_TARGET)
12860 optimize_target_teams (expr, pre_p);
12861 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
12862 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
12864 push_gimplify_context ();
12865 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
12866 if (gimple_code (g) == GIMPLE_BIND)
12867 pop_gimplify_context (g);
12868 else
12869 pop_gimplify_context (NULL);
12870 if ((ort & ORT_TARGET_DATA) != 0)
12872 enum built_in_function end_ix;
12873 switch (TREE_CODE (expr))
12875 case OACC_DATA:
12876 case OACC_HOST_DATA:
12877 end_ix = BUILT_IN_GOACC_DATA_END;
12878 break;
12879 case OMP_TARGET_DATA:
12880 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
12881 break;
12882 default:
12883 gcc_unreachable ();
12885 tree fn = builtin_decl_explicit (end_ix);
12886 g = gimple_build_call (fn, 0);
12887 gimple_seq cleanup = NULL;
12888 gimple_seq_add_stmt (&cleanup, g);
12889 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
12890 body = NULL;
12891 gimple_seq_add_stmt (&body, g);
12894 else
12895 gimplify_and_add (OMP_BODY (expr), &body);
12896 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
12897 TREE_CODE (expr));
12898 in_omp_construct = save_in_omp_construct;
12900 switch (TREE_CODE (expr))
12902 case OACC_DATA:
12903 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
12904 OMP_CLAUSES (expr));
12905 break;
12906 case OACC_HOST_DATA:
12907 if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
12909 for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
12910 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
12911 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
12914 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
12915 OMP_CLAUSES (expr));
12916 break;
12917 case OACC_KERNELS:
12918 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
12919 OMP_CLAUSES (expr));
12920 break;
12921 case OACC_PARALLEL:
12922 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
12923 OMP_CLAUSES (expr));
12924 break;
12925 case OACC_SERIAL:
12926 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
12927 OMP_CLAUSES (expr));
12928 break;
12929 case OMP_SECTIONS:
12930 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
12931 break;
12932 case OMP_SINGLE:
12933 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
12934 break;
12935 case OMP_TARGET:
12936 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
12937 OMP_CLAUSES (expr));
12938 break;
12939 case OMP_TARGET_DATA:
12940 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
12941 to be evaluated before the use_device_{ptr,addr} clauses if they
12942 refer to the same variables. */
12944 tree use_device_clauses;
12945 tree *pc, *uc = &use_device_clauses;
12946 for (pc = &OMP_CLAUSES (expr); *pc; )
12947 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
12948 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
12950 *uc = *pc;
12951 *pc = OMP_CLAUSE_CHAIN (*pc);
12952 uc = &OMP_CLAUSE_CHAIN (*uc);
12954 else
12955 pc = &OMP_CLAUSE_CHAIN (*pc);
12956 *uc = NULL_TREE;
12957 *pc = use_device_clauses;
12958 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
12959 OMP_CLAUSES (expr));
12961 break;
12962 case OMP_TEAMS:
12963 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
12964 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
12965 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
12966 break;
12967 default:
12968 gcc_unreachable ();
12971 gimplify_seq_add_stmt (pre_p, stmt);
12972 *expr_p = NULL_TREE;
12975 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
12976 target update constructs. */
12978 static void
12979 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
12981 tree expr = *expr_p;
12982 int kind;
12983 gomp_target *stmt;
12984 enum omp_region_type ort = ORT_WORKSHARE;
12986 switch (TREE_CODE (expr))
12988 case OACC_ENTER_DATA:
12989 case OACC_EXIT_DATA:
12990 kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
12991 ort = ORT_ACC;
12992 break;
12993 case OACC_UPDATE:
12994 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
12995 ort = ORT_ACC;
12996 break;
12997 case OMP_TARGET_UPDATE:
12998 kind = GF_OMP_TARGET_KIND_UPDATE;
12999 break;
13000 case OMP_TARGET_ENTER_DATA:
13001 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
13002 break;
13003 case OMP_TARGET_EXIT_DATA:
13004 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
13005 break;
13006 default:
13007 gcc_unreachable ();
13009 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
13010 ort, TREE_CODE (expr));
13011 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
13012 TREE_CODE (expr));
13013 if (TREE_CODE (expr) == OACC_UPDATE
13014 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
13015 OMP_CLAUSE_IF_PRESENT))
13017 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
13018 clause. */
13019 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13020 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
13021 switch (OMP_CLAUSE_MAP_KIND (c))
13023 case GOMP_MAP_FORCE_TO:
13024 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
13025 break;
13026 case GOMP_MAP_FORCE_FROM:
13027 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
13028 break;
13029 default:
13030 break;
13033 else if (TREE_CODE (expr) == OACC_EXIT_DATA
13034 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
13035 OMP_CLAUSE_FINALIZE))
13037 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
13038 semantics. */
13039 bool have_clause = false;
13040 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13041 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
13042 switch (OMP_CLAUSE_MAP_KIND (c))
13044 case GOMP_MAP_FROM:
13045 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
13046 have_clause = true;
13047 break;
13048 case GOMP_MAP_RELEASE:
13049 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
13050 have_clause = true;
13051 break;
13052 case GOMP_MAP_TO_PSET:
13053 /* Fortran arrays with descriptors must map that descriptor when
13054 doing standalone "attach" operations (in OpenACC). In that
13055 case GOMP_MAP_TO_PSET appears by itself with no preceding
13056 clause (see trans-openmp.c:gfc_trans_omp_clauses). */
13057 break;
13058 case GOMP_MAP_POINTER:
13059 /* TODO PR92929: we may see these here, but they'll always follow
13060 one of the clauses above, and will be handled by libgomp as
13061 one group, so no handling required here. */
13062 gcc_assert (have_clause);
13063 break;
13064 case GOMP_MAP_DETACH:
13065 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
13066 have_clause = false;
13067 break;
13068 case GOMP_MAP_STRUCT:
13069 have_clause = false;
13070 break;
13071 default:
13072 gcc_unreachable ();
13075 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
13077 gimplify_seq_add_stmt (pre_p, stmt);
13078 *expr_p = NULL_TREE;
13081 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
13082 stabilized the lhs of the atomic operation as *ADDR. Return true if
13083 EXPR is this stabilized form. */
13085 static bool
13086 goa_lhs_expr_p (tree expr, tree addr)
13088 /* Also include casts to other type variants. The C front end is fond
13089 of adding these for e.g. volatile variables. This is like
13090 STRIP_TYPE_NOPS but includes the main variant lookup. */
13091 STRIP_USELESS_TYPE_CONVERSION (expr);
13093 if (TREE_CODE (expr) == INDIRECT_REF)
13095 expr = TREE_OPERAND (expr, 0);
13096 while (expr != addr
13097 && (CONVERT_EXPR_P (expr)
13098 || TREE_CODE (expr) == NON_LVALUE_EXPR)
13099 && TREE_CODE (expr) == TREE_CODE (addr)
13100 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
13102 expr = TREE_OPERAND (expr, 0);
13103 addr = TREE_OPERAND (addr, 0);
13105 if (expr == addr)
13106 return true;
13107 return (TREE_CODE (addr) == ADDR_EXPR
13108 && TREE_CODE (expr) == ADDR_EXPR
13109 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
13111 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
13112 return true;
13113 return false;
13116 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
13117 expression does not involve the lhs, evaluate it into a temporary.
13118 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
13119 or -1 if an error was encountered. */
13121 static int
13122 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
13123 tree lhs_var)
13125 tree expr = *expr_p;
13126 int saw_lhs;
13128 if (goa_lhs_expr_p (expr, lhs_addr))
13130 *expr_p = lhs_var;
13131 return 1;
13133 if (is_gimple_val (expr))
13134 return 0;
13136 saw_lhs = 0;
13137 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
13139 case tcc_binary:
13140 case tcc_comparison:
13141 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
13142 lhs_var);
13143 /* FALLTHRU */
13144 case tcc_unary:
13145 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
13146 lhs_var);
13147 break;
13148 case tcc_expression:
13149 switch (TREE_CODE (expr))
13151 case TRUTH_ANDIF_EXPR:
13152 case TRUTH_ORIF_EXPR:
13153 case TRUTH_AND_EXPR:
13154 case TRUTH_OR_EXPR:
13155 case TRUTH_XOR_EXPR:
13156 case BIT_INSERT_EXPR:
13157 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
13158 lhs_addr, lhs_var);
13159 /* FALLTHRU */
13160 case TRUTH_NOT_EXPR:
13161 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
13162 lhs_addr, lhs_var);
13163 break;
13164 case COMPOUND_EXPR:
13165 /* Break out any preevaluations from cp_build_modify_expr. */
13166 for (; TREE_CODE (expr) == COMPOUND_EXPR;
13167 expr = TREE_OPERAND (expr, 1))
13168 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
13169 *expr_p = expr;
13170 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var);
13171 default:
13172 break;
13174 break;
13175 case tcc_reference:
13176 if (TREE_CODE (expr) == BIT_FIELD_REF)
13177 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
13178 lhs_addr, lhs_var);
13179 break;
13180 default:
13181 break;
13184 if (saw_lhs == 0)
13186 enum gimplify_status gs;
13187 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
13188 if (gs != GS_ALL_DONE)
13189 saw_lhs = -1;
13192 return saw_lhs;
13195 /* Gimplify an OMP_ATOMIC statement. */
13197 static enum gimplify_status
13198 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
13200 tree addr = TREE_OPERAND (*expr_p, 0);
13201 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
13202 ? NULL : TREE_OPERAND (*expr_p, 1);
13203 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
13204 tree tmp_load;
13205 gomp_atomic_load *loadstmt;
13206 gomp_atomic_store *storestmt;
13208 tmp_load = create_tmp_reg (type);
13209 if (rhs && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load) < 0)
13210 return GS_ERROR;
13212 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
13213 != GS_ALL_DONE)
13214 return GS_ERROR;
13216 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
13217 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
13218 gimplify_seq_add_stmt (pre_p, loadstmt);
13219 if (rhs)
13221 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
13222 representatives. Use BIT_FIELD_REF on the lhs instead. */
13223 if (TREE_CODE (rhs) == BIT_INSERT_EXPR
13224 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
13226 tree bitpos = TREE_OPERAND (rhs, 2);
13227 tree op1 = TREE_OPERAND (rhs, 1);
13228 tree bitsize;
13229 tree tmp_store = tmp_load;
13230 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
13231 tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
13232 if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
13233 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
13234 else
13235 bitsize = TYPE_SIZE (TREE_TYPE (op1));
13236 gcc_assert (TREE_OPERAND (rhs, 0) == tmp_load);
13237 tree t = build2_loc (EXPR_LOCATION (rhs),
13238 MODIFY_EXPR, void_type_node,
13239 build3_loc (EXPR_LOCATION (rhs), BIT_FIELD_REF,
13240 TREE_TYPE (op1), tmp_store, bitsize,
13241 bitpos), op1);
13242 gimplify_and_add (t, pre_p);
13243 rhs = tmp_store;
13245 if (gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
13246 != GS_ALL_DONE)
13247 return GS_ERROR;
13250 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
13251 rhs = tmp_load;
13252 storestmt
13253 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
13254 gimplify_seq_add_stmt (pre_p, storestmt);
13255 switch (TREE_CODE (*expr_p))
13257 case OMP_ATOMIC_READ:
13258 case OMP_ATOMIC_CAPTURE_OLD:
13259 *expr_p = tmp_load;
13260 gimple_omp_atomic_set_need_value (loadstmt);
13261 break;
13262 case OMP_ATOMIC_CAPTURE_NEW:
13263 *expr_p = rhs;
13264 gimple_omp_atomic_set_need_value (storestmt);
13265 break;
13266 default:
13267 *expr_p = NULL;
13268 break;
13271 return GS_ALL_DONE;
13274 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
13275 body, and adding some EH bits. */
13277 static enum gimplify_status
13278 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
13280 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
13281 gimple *body_stmt;
13282 gtransaction *trans_stmt;
13283 gimple_seq body = NULL;
13284 int subcode = 0;
13286 /* Wrap the transaction body in a BIND_EXPR so we have a context
13287 where to put decls for OMP. */
13288 if (TREE_CODE (tbody) != BIND_EXPR)
13290 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
13291 TREE_SIDE_EFFECTS (bind) = 1;
13292 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
13293 TRANSACTION_EXPR_BODY (expr) = bind;
13296 push_gimplify_context ();
13297 temp = voidify_wrapper_expr (*expr_p, NULL);
13299 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
13300 pop_gimplify_context (body_stmt);
13302 trans_stmt = gimple_build_transaction (body);
13303 if (TRANSACTION_EXPR_OUTER (expr))
13304 subcode = GTMA_IS_OUTER;
13305 else if (TRANSACTION_EXPR_RELAXED (expr))
13306 subcode = GTMA_IS_RELAXED;
13307 gimple_transaction_set_subcode (trans_stmt, subcode);
13309 gimplify_seq_add_stmt (pre_p, trans_stmt);
13311 if (temp)
13313 *expr_p = temp;
13314 return GS_OK;
13317 *expr_p = NULL_TREE;
13318 return GS_ALL_DONE;
13321 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
13322 is the OMP_BODY of the original EXPR (which has already been
13323 gimplified so it's not present in the EXPR).
13325 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
13327 static gimple *
13328 gimplify_omp_ordered (tree expr, gimple_seq body)
13330 tree c, decls;
13331 int failures = 0;
13332 unsigned int i;
13333 tree source_c = NULL_TREE;
13334 tree sink_c = NULL_TREE;
13336 if (gimplify_omp_ctxp)
13338 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13339 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
13340 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
13341 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
13342 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
13344 error_at (OMP_CLAUSE_LOCATION (c),
13345 "%<ordered%> construct with %<depend%> clause must be "
13346 "closely nested inside a loop with %<ordered%> clause "
13347 "with a parameter");
13348 failures++;
13350 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
13351 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
13353 bool fail = false;
13354 for (decls = OMP_CLAUSE_DECL (c), i = 0;
13355 decls && TREE_CODE (decls) == TREE_LIST;
13356 decls = TREE_CHAIN (decls), ++i)
13357 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
13358 continue;
13359 else if (TREE_VALUE (decls)
13360 != gimplify_omp_ctxp->loop_iter_var[2 * i])
13362 error_at (OMP_CLAUSE_LOCATION (c),
13363 "variable %qE is not an iteration "
13364 "of outermost loop %d, expected %qE",
13365 TREE_VALUE (decls), i + 1,
13366 gimplify_omp_ctxp->loop_iter_var[2 * i]);
13367 fail = true;
13368 failures++;
13370 else
13371 TREE_VALUE (decls)
13372 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
13373 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
13375 error_at (OMP_CLAUSE_LOCATION (c),
13376 "number of variables in %<depend%> clause with "
13377 "%<sink%> modifier does not match number of "
13378 "iteration variables");
13379 failures++;
13381 sink_c = c;
13383 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
13384 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
13386 if (source_c)
13388 error_at (OMP_CLAUSE_LOCATION (c),
13389 "more than one %<depend%> clause with %<source%> "
13390 "modifier on an %<ordered%> construct");
13391 failures++;
13393 else
13394 source_c = c;
13397 if (source_c && sink_c)
13399 error_at (OMP_CLAUSE_LOCATION (source_c),
13400 "%<depend%> clause with %<source%> modifier specified "
13401 "together with %<depend%> clauses with %<sink%> modifier "
13402 "on the same construct");
13403 failures++;
13406 if (failures)
13407 return gimple_build_nop ();
13408 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
13411 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
13412 expression produces a value to be used as an operand inside a GIMPLE
13413 statement, the value will be stored back in *EXPR_P. This value will
13414 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
13415 an SSA_NAME. The corresponding sequence of GIMPLE statements is
13416 emitted in PRE_P and POST_P.
13418 Additionally, this process may overwrite parts of the input
13419 expression during gimplification. Ideally, it should be
13420 possible to do non-destructive gimplification.
13422 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
13423 the expression needs to evaluate to a value to be used as
13424 an operand in a GIMPLE statement, this value will be stored in
13425 *EXPR_P on exit. This happens when the caller specifies one
13426 of fb_lvalue or fb_rvalue fallback flags.
13428 PRE_P will contain the sequence of GIMPLE statements corresponding
13429 to the evaluation of EXPR and all the side-effects that must
13430 be executed before the main expression. On exit, the last
13431 statement of PRE_P is the core statement being gimplified. For
13432 instance, when gimplifying 'if (++a)' the last statement in
13433 PRE_P will be 'if (t.1)' where t.1 is the result of
13434 pre-incrementing 'a'.
13436 POST_P will contain the sequence of GIMPLE statements corresponding
13437 to the evaluation of all the side-effects that must be executed
13438 after the main expression. If this is NULL, the post
13439 side-effects are stored at the end of PRE_P.
13441 The reason why the output is split in two is to handle post
13442 side-effects explicitly. In some cases, an expression may have
13443 inner and outer post side-effects which need to be emitted in
13444 an order different from the one given by the recursive
13445 traversal. For instance, for the expression (*p--)++ the post
13446 side-effects of '--' must actually occur *after* the post
13447 side-effects of '++'. However, gimplification will first visit
13448 the inner expression, so if a separate POST sequence was not
13449 used, the resulting sequence would be:
13451 1 t.1 = *p
13452 2 p = p - 1
13453 3 t.2 = t.1 + 1
13454 4 *p = t.2
13456 However, the post-decrement operation in line #2 must not be
13457 evaluated until after the store to *p at line #4, so the
13458 correct sequence should be:
13460 1 t.1 = *p
13461 2 t.2 = t.1 + 1
13462 3 *p = t.2
13463 4 p = p - 1
13465 So, by specifying a separate post queue, it is possible
13466 to emit the post side-effects in the correct order.
13467 If POST_P is NULL, an internal queue will be used. Before
13468 returning to the caller, the sequence POST_P is appended to
13469 the main output sequence PRE_P.
13471 GIMPLE_TEST_F points to a function that takes a tree T and
13472 returns nonzero if T is in the GIMPLE form requested by the
13473 caller. The GIMPLE predicates are in gimple.c.
13475 FALLBACK tells the function what sort of a temporary we want if
13476 gimplification cannot produce an expression that complies with
13477 GIMPLE_TEST_F.
13479 fb_none means that no temporary should be generated
13480 fb_rvalue means that an rvalue is OK to generate
13481 fb_lvalue means that an lvalue is OK to generate
13482 fb_either means that either is OK, but an lvalue is preferable.
13483 fb_mayfail means that gimplification may fail (in which case
13484 GS_ERROR will be returned)
13486 The return value is either GS_ERROR or GS_ALL_DONE, since this
13487 function iterates until EXPR is completely gimplified or an error
13488 occurs. */
13490 enum gimplify_status
13491 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
13492 bool (*gimple_test_f) (tree), fallback_t fallback)
13494 tree tmp;
13495 gimple_seq internal_pre = NULL;
13496 gimple_seq internal_post = NULL;
13497 tree save_expr;
13498 bool is_statement;
13499 location_t saved_location;
13500 enum gimplify_status ret;
13501 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
13502 tree label;
13504 save_expr = *expr_p;
13505 if (save_expr == NULL_TREE)
13506 return GS_ALL_DONE;
13508 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
13509 is_statement = gimple_test_f == is_gimple_stmt;
13510 if (is_statement)
13511 gcc_assert (pre_p);
13513 /* Consistency checks. */
13514 if (gimple_test_f == is_gimple_reg)
13515 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
13516 else if (gimple_test_f == is_gimple_val
13517 || gimple_test_f == is_gimple_call_addr
13518 || gimple_test_f == is_gimple_condexpr
13519 || gimple_test_f == is_gimple_condexpr_for_cond
13520 || gimple_test_f == is_gimple_mem_rhs
13521 || gimple_test_f == is_gimple_mem_rhs_or_call
13522 || gimple_test_f == is_gimple_reg_rhs
13523 || gimple_test_f == is_gimple_reg_rhs_or_call
13524 || gimple_test_f == is_gimple_asm_val
13525 || gimple_test_f == is_gimple_mem_ref_addr)
13526 gcc_assert (fallback & fb_rvalue);
13527 else if (gimple_test_f == is_gimple_min_lval
13528 || gimple_test_f == is_gimple_lvalue)
13529 gcc_assert (fallback & fb_lvalue);
13530 else if (gimple_test_f == is_gimple_addressable)
13531 gcc_assert (fallback & fb_either);
13532 else if (gimple_test_f == is_gimple_stmt)
13533 gcc_assert (fallback == fb_none);
13534 else
13536 /* We should have recognized the GIMPLE_TEST_F predicate to
13537 know what kind of fallback to use in case a temporary is
13538 needed to hold the value or address of *EXPR_P. */
13539 gcc_unreachable ();
13542 /* We used to check the predicate here and return immediately if it
13543 succeeds. This is wrong; the design is for gimplification to be
13544 idempotent, and for the predicates to only test for valid forms, not
13545 whether they are fully simplified. */
13546 if (pre_p == NULL)
13547 pre_p = &internal_pre;
13549 if (post_p == NULL)
13550 post_p = &internal_post;
13552 /* Remember the last statements added to PRE_P and POST_P. Every
13553 new statement added by the gimplification helpers needs to be
13554 annotated with location information. To centralize the
13555 responsibility, we remember the last statement that had been
13556 added to both queues before gimplifying *EXPR_P. If
13557 gimplification produces new statements in PRE_P and POST_P, those
13558 statements will be annotated with the same location information
13559 as *EXPR_P. */
13560 pre_last_gsi = gsi_last (*pre_p);
13561 post_last_gsi = gsi_last (*post_p);
13563 saved_location = input_location;
13564 if (save_expr != error_mark_node
13565 && EXPR_HAS_LOCATION (*expr_p))
13566 input_location = EXPR_LOCATION (*expr_p);
13568 /* Loop over the specific gimplifiers until the toplevel node
13569 remains the same. */
13572 /* Strip away as many useless type conversions as possible
13573 at the toplevel. */
13574 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
13576 /* Remember the expr. */
13577 save_expr = *expr_p;
13579 /* Die, die, die, my darling. */
13580 if (error_operand_p (save_expr))
13582 ret = GS_ERROR;
13583 break;
13586 /* Do any language-specific gimplification. */
13587 ret = ((enum gimplify_status)
13588 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
13589 if (ret == GS_OK)
13591 if (*expr_p == NULL_TREE)
13592 break;
13593 if (*expr_p != save_expr)
13594 continue;
13596 else if (ret != GS_UNHANDLED)
13597 break;
13599 /* Make sure that all the cases set 'ret' appropriately. */
13600 ret = GS_UNHANDLED;
13601 switch (TREE_CODE (*expr_p))
13603 /* First deal with the special cases. */
13605 case POSTINCREMENT_EXPR:
13606 case POSTDECREMENT_EXPR:
13607 case PREINCREMENT_EXPR:
13608 case PREDECREMENT_EXPR:
13609 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
13610 fallback != fb_none,
13611 TREE_TYPE (*expr_p));
13612 break;
13614 case VIEW_CONVERT_EXPR:
13615 if ((fallback & fb_rvalue)
13616 && is_gimple_reg_type (TREE_TYPE (*expr_p))
13617 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
13619 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13620 post_p, is_gimple_val, fb_rvalue);
13621 recalculate_side_effects (*expr_p);
13622 break;
13624 /* Fallthru. */
13626 case ARRAY_REF:
13627 case ARRAY_RANGE_REF:
13628 case REALPART_EXPR:
13629 case IMAGPART_EXPR:
13630 case COMPONENT_REF:
13631 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
13632 fallback ? fallback : fb_rvalue);
13633 break;
13635 case COND_EXPR:
13636 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
13638 /* C99 code may assign to an array in a structure value of a
13639 conditional expression, and this has undefined behavior
13640 only on execution, so create a temporary if an lvalue is
13641 required. */
13642 if (fallback == fb_lvalue)
13644 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
13645 mark_addressable (*expr_p);
13646 ret = GS_OK;
13648 break;
13650 case CALL_EXPR:
13651 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
13653 /* C99 code may assign to an array in a structure returned
13654 from a function, and this has undefined behavior only on
13655 execution, so create a temporary if an lvalue is
13656 required. */
13657 if (fallback == fb_lvalue)
13659 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
13660 mark_addressable (*expr_p);
13661 ret = GS_OK;
13663 break;
13665 case TREE_LIST:
13666 gcc_unreachable ();
13668 case COMPOUND_EXPR:
13669 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
13670 break;
13672 case COMPOUND_LITERAL_EXPR:
13673 ret = gimplify_compound_literal_expr (expr_p, pre_p,
13674 gimple_test_f, fallback);
13675 break;
13677 case MODIFY_EXPR:
13678 case INIT_EXPR:
13679 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
13680 fallback != fb_none);
13681 break;
13683 case TRUTH_ANDIF_EXPR:
13684 case TRUTH_ORIF_EXPR:
13686 /* Preserve the original type of the expression and the
13687 source location of the outer expression. */
13688 tree org_type = TREE_TYPE (*expr_p);
13689 *expr_p = gimple_boolify (*expr_p);
13690 *expr_p = build3_loc (input_location, COND_EXPR,
13691 org_type, *expr_p,
13692 fold_convert_loc
13693 (input_location,
13694 org_type, boolean_true_node),
13695 fold_convert_loc
13696 (input_location,
13697 org_type, boolean_false_node));
13698 ret = GS_OK;
13699 break;
13702 case TRUTH_NOT_EXPR:
13704 tree type = TREE_TYPE (*expr_p);
13705 /* The parsers are careful to generate TRUTH_NOT_EXPR
13706 only with operands that are always zero or one.
13707 We do not fold here but handle the only interesting case
13708 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
13709 *expr_p = gimple_boolify (*expr_p);
13710 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
13711 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
13712 TREE_TYPE (*expr_p),
13713 TREE_OPERAND (*expr_p, 0));
13714 else
13715 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
13716 TREE_TYPE (*expr_p),
13717 TREE_OPERAND (*expr_p, 0),
13718 build_int_cst (TREE_TYPE (*expr_p), 1));
13719 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
13720 *expr_p = fold_convert_loc (input_location, type, *expr_p);
13721 ret = GS_OK;
13722 break;
13725 case ADDR_EXPR:
13726 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
13727 break;
13729 case ANNOTATE_EXPR:
13731 tree cond = TREE_OPERAND (*expr_p, 0);
13732 tree kind = TREE_OPERAND (*expr_p, 1);
13733 tree data = TREE_OPERAND (*expr_p, 2);
13734 tree type = TREE_TYPE (cond);
13735 if (!INTEGRAL_TYPE_P (type))
13737 *expr_p = cond;
13738 ret = GS_OK;
13739 break;
13741 tree tmp = create_tmp_var (type);
13742 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
13743 gcall *call
13744 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
13745 gimple_call_set_lhs (call, tmp);
13746 gimplify_seq_add_stmt (pre_p, call);
13747 *expr_p = tmp;
13748 ret = GS_ALL_DONE;
13749 break;
13752 case VA_ARG_EXPR:
13753 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
13754 break;
13756 CASE_CONVERT:
13757 if (IS_EMPTY_STMT (*expr_p))
13759 ret = GS_ALL_DONE;
13760 break;
13763 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
13764 || fallback == fb_none)
13766 /* Just strip a conversion to void (or in void context) and
13767 try again. */
13768 *expr_p = TREE_OPERAND (*expr_p, 0);
13769 ret = GS_OK;
13770 break;
13773 ret = gimplify_conversion (expr_p);
13774 if (ret == GS_ERROR)
13775 break;
13776 if (*expr_p != save_expr)
13777 break;
13778 /* FALLTHRU */
13780 case FIX_TRUNC_EXPR:
13781 /* unary_expr: ... | '(' cast ')' val | ... */
13782 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13783 is_gimple_val, fb_rvalue);
13784 recalculate_side_effects (*expr_p);
13785 break;
13787 case INDIRECT_REF:
13789 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
13790 bool notrap = TREE_THIS_NOTRAP (*expr_p);
13791 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
13793 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
13794 if (*expr_p != save_expr)
13796 ret = GS_OK;
13797 break;
13800 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13801 is_gimple_reg, fb_rvalue);
13802 if (ret == GS_ERROR)
13803 break;
13805 recalculate_side_effects (*expr_p);
13806 *expr_p = fold_build2_loc (input_location, MEM_REF,
13807 TREE_TYPE (*expr_p),
13808 TREE_OPERAND (*expr_p, 0),
13809 build_int_cst (saved_ptr_type, 0));
13810 TREE_THIS_VOLATILE (*expr_p) = volatilep;
13811 TREE_THIS_NOTRAP (*expr_p) = notrap;
13812 ret = GS_OK;
13813 break;
13816 /* We arrive here through the various re-gimplifcation paths. */
13817 case MEM_REF:
13818 /* First try re-folding the whole thing. */
13819 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
13820 TREE_OPERAND (*expr_p, 0),
13821 TREE_OPERAND (*expr_p, 1));
13822 if (tmp)
13824 REF_REVERSE_STORAGE_ORDER (tmp)
13825 = REF_REVERSE_STORAGE_ORDER (*expr_p);
13826 *expr_p = tmp;
13827 recalculate_side_effects (*expr_p);
13828 ret = GS_OK;
13829 break;
13831 /* Avoid re-gimplifying the address operand if it is already
13832 in suitable form. Re-gimplifying would mark the address
13833 operand addressable. Always gimplify when not in SSA form
13834 as we still may have to gimplify decls with value-exprs. */
13835 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
13836 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
13838 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
13839 is_gimple_mem_ref_addr, fb_rvalue);
13840 if (ret == GS_ERROR)
13841 break;
13843 recalculate_side_effects (*expr_p);
13844 ret = GS_ALL_DONE;
13845 break;
13847 /* Constants need not be gimplified. */
13848 case INTEGER_CST:
13849 case REAL_CST:
13850 case FIXED_CST:
13851 case STRING_CST:
13852 case COMPLEX_CST:
13853 case VECTOR_CST:
13854 /* Drop the overflow flag on constants, we do not want
13855 that in the GIMPLE IL. */
13856 if (TREE_OVERFLOW_P (*expr_p))
13857 *expr_p = drop_tree_overflow (*expr_p);
13858 ret = GS_ALL_DONE;
13859 break;
13861 case CONST_DECL:
13862 /* If we require an lvalue, such as for ADDR_EXPR, retain the
13863 CONST_DECL node. Otherwise the decl is replaceable by its
13864 value. */
13865 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
13866 if (fallback & fb_lvalue)
13867 ret = GS_ALL_DONE;
13868 else
13870 *expr_p = DECL_INITIAL (*expr_p);
13871 ret = GS_OK;
13873 break;
13875 case DECL_EXPR:
13876 ret = gimplify_decl_expr (expr_p, pre_p);
13877 break;
13879 case BIND_EXPR:
13880 ret = gimplify_bind_expr (expr_p, pre_p);
13881 break;
13883 case LOOP_EXPR:
13884 ret = gimplify_loop_expr (expr_p, pre_p);
13885 break;
13887 case SWITCH_EXPR:
13888 ret = gimplify_switch_expr (expr_p, pre_p);
13889 break;
13891 case EXIT_EXPR:
13892 ret = gimplify_exit_expr (expr_p);
13893 break;
13895 case GOTO_EXPR:
13896 /* If the target is not LABEL, then it is a computed jump
13897 and the target needs to be gimplified. */
13898 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
13900 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
13901 NULL, is_gimple_val, fb_rvalue);
13902 if (ret == GS_ERROR)
13903 break;
13905 gimplify_seq_add_stmt (pre_p,
13906 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
13907 ret = GS_ALL_DONE;
13908 break;
13910 case PREDICT_EXPR:
13911 gimplify_seq_add_stmt (pre_p,
13912 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
13913 PREDICT_EXPR_OUTCOME (*expr_p)));
13914 ret = GS_ALL_DONE;
13915 break;
13917 case LABEL_EXPR:
13918 ret = gimplify_label_expr (expr_p, pre_p);
13919 label = LABEL_EXPR_LABEL (*expr_p);
13920 gcc_assert (decl_function_context (label) == current_function_decl);
13922 /* If the label is used in a goto statement, or address of the label
13923 is taken, we need to unpoison all variables that were seen so far.
13924 Doing so would prevent us from reporting a false positives. */
13925 if (asan_poisoned_variables
13926 && asan_used_labels != NULL
13927 && asan_used_labels->contains (label))
13928 asan_poison_variables (asan_poisoned_variables, false, pre_p);
13929 break;
13931 case CASE_LABEL_EXPR:
13932 ret = gimplify_case_label_expr (expr_p, pre_p);
13934 if (gimplify_ctxp->live_switch_vars)
13935 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
13936 pre_p);
13937 break;
13939 case RETURN_EXPR:
13940 ret = gimplify_return_expr (*expr_p, pre_p);
13941 break;
13943 case CONSTRUCTOR:
13944 /* Don't reduce this in place; let gimplify_init_constructor work its
13945 magic. Buf if we're just elaborating this for side effects, just
13946 gimplify any element that has side-effects. */
13947 if (fallback == fb_none)
13949 unsigned HOST_WIDE_INT ix;
13950 tree val;
13951 tree temp = NULL_TREE;
13952 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
13953 if (TREE_SIDE_EFFECTS (val))
13954 append_to_statement_list (val, &temp);
13956 *expr_p = temp;
13957 ret = temp ? GS_OK : GS_ALL_DONE;
13959 /* C99 code may assign to an array in a constructed
13960 structure or union, and this has undefined behavior only
13961 on execution, so create a temporary if an lvalue is
13962 required. */
13963 else if (fallback == fb_lvalue)
13965 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
13966 mark_addressable (*expr_p);
13967 ret = GS_OK;
13969 else
13970 ret = GS_ALL_DONE;
13971 break;
13973 /* The following are special cases that are not handled by the
13974 original GIMPLE grammar. */
13976 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
13977 eliminated. */
13978 case SAVE_EXPR:
13979 ret = gimplify_save_expr (expr_p, pre_p, post_p);
13980 break;
13982 case BIT_FIELD_REF:
13983 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
13984 post_p, is_gimple_lvalue, fb_either);
13985 recalculate_side_effects (*expr_p);
13986 break;
13988 case TARGET_MEM_REF:
13990 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
13992 if (TMR_BASE (*expr_p))
13993 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
13994 post_p, is_gimple_mem_ref_addr, fb_either);
13995 if (TMR_INDEX (*expr_p))
13996 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
13997 post_p, is_gimple_val, fb_rvalue);
13998 if (TMR_INDEX2 (*expr_p))
13999 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
14000 post_p, is_gimple_val, fb_rvalue);
14001 /* TMR_STEP and TMR_OFFSET are always integer constants. */
14002 ret = MIN (r0, r1);
14004 break;
14006 case NON_LVALUE_EXPR:
14007 /* This should have been stripped above. */
14008 gcc_unreachable ();
14010 case ASM_EXPR:
14011 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
14012 break;
14014 case TRY_FINALLY_EXPR:
14015 case TRY_CATCH_EXPR:
14017 gimple_seq eval, cleanup;
14018 gtry *try_;
14020 /* Calls to destructors are generated automatically in FINALLY/CATCH
14021 block. They should have location as UNKNOWN_LOCATION. However,
14022 gimplify_call_expr will reset these call stmts to input_location
14023 if it finds stmt's location is unknown. To prevent resetting for
14024 destructors, we set the input_location to unknown.
14025 Note that this only affects the destructor calls in FINALLY/CATCH
14026 block, and will automatically reset to its original value by the
14027 end of gimplify_expr. */
14028 input_location = UNKNOWN_LOCATION;
14029 eval = cleanup = NULL;
14030 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
14031 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
14032 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
14034 gimple_seq n = NULL, e = NULL;
14035 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
14036 0), &n);
14037 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
14038 1), &e);
14039 if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
14041 geh_else *stmt = gimple_build_eh_else (n, e);
14042 gimple_seq_add_stmt (&cleanup, stmt);
14045 else
14046 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
14047 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
14048 if (gimple_seq_empty_p (cleanup))
14050 gimple_seq_add_seq (pre_p, eval);
14051 ret = GS_ALL_DONE;
14052 break;
14054 try_ = gimple_build_try (eval, cleanup,
14055 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
14056 ? GIMPLE_TRY_FINALLY
14057 : GIMPLE_TRY_CATCH);
14058 if (EXPR_HAS_LOCATION (save_expr))
14059 gimple_set_location (try_, EXPR_LOCATION (save_expr));
14060 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
14061 gimple_set_location (try_, saved_location);
14062 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
14063 gimple_try_set_catch_is_cleanup (try_,
14064 TRY_CATCH_IS_CLEANUP (*expr_p));
14065 gimplify_seq_add_stmt (pre_p, try_);
14066 ret = GS_ALL_DONE;
14067 break;
14070 case CLEANUP_POINT_EXPR:
14071 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
14072 break;
14074 case TARGET_EXPR:
14075 ret = gimplify_target_expr (expr_p, pre_p, post_p);
14076 break;
14078 case CATCH_EXPR:
14080 gimple *c;
14081 gimple_seq handler = NULL;
14082 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
14083 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
14084 gimplify_seq_add_stmt (pre_p, c);
14085 ret = GS_ALL_DONE;
14086 break;
14089 case EH_FILTER_EXPR:
14091 gimple *ehf;
14092 gimple_seq failure = NULL;
14094 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
14095 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
14096 gimple_set_no_warning (ehf, TREE_NO_WARNING (*expr_p));
14097 gimplify_seq_add_stmt (pre_p, ehf);
14098 ret = GS_ALL_DONE;
14099 break;
14102 case OBJ_TYPE_REF:
14104 enum gimplify_status r0, r1;
14105 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
14106 post_p, is_gimple_val, fb_rvalue);
14107 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
14108 post_p, is_gimple_val, fb_rvalue);
14109 TREE_SIDE_EFFECTS (*expr_p) = 0;
14110 ret = MIN (r0, r1);
14112 break;
14114 case LABEL_DECL:
14115 /* We get here when taking the address of a label. We mark
14116 the label as "forced"; meaning it can never be removed and
14117 it is a potential target for any computed goto. */
14118 FORCED_LABEL (*expr_p) = 1;
14119 ret = GS_ALL_DONE;
14120 break;
14122 case STATEMENT_LIST:
14123 ret = gimplify_statement_list (expr_p, pre_p);
14124 break;
14126 case WITH_SIZE_EXPR:
14128 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14129 post_p == &internal_post ? NULL : post_p,
14130 gimple_test_f, fallback);
14131 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
14132 is_gimple_val, fb_rvalue);
14133 ret = GS_ALL_DONE;
14135 break;
14137 case VAR_DECL:
14138 case PARM_DECL:
14139 ret = gimplify_var_or_parm_decl (expr_p);
14140 break;
14142 case RESULT_DECL:
14143 /* When within an OMP context, notice uses of variables. */
14144 if (gimplify_omp_ctxp)
14145 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
14146 ret = GS_ALL_DONE;
14147 break;
14149 case DEBUG_EXPR_DECL:
14150 gcc_unreachable ();
14152 case DEBUG_BEGIN_STMT:
14153 gimplify_seq_add_stmt (pre_p,
14154 gimple_build_debug_begin_stmt
14155 (TREE_BLOCK (*expr_p),
14156 EXPR_LOCATION (*expr_p)));
14157 ret = GS_ALL_DONE;
14158 *expr_p = NULL;
14159 break;
14161 case SSA_NAME:
14162 /* Allow callbacks into the gimplifier during optimization. */
14163 ret = GS_ALL_DONE;
14164 break;
14166 case OMP_PARALLEL:
14167 gimplify_omp_parallel (expr_p, pre_p);
14168 ret = GS_ALL_DONE;
14169 break;
14171 case OMP_TASK:
14172 gimplify_omp_task (expr_p, pre_p);
14173 ret = GS_ALL_DONE;
14174 break;
14176 case OMP_FOR:
14177 case OMP_SIMD:
14178 case OMP_DISTRIBUTE:
14179 case OMP_TASKLOOP:
14180 case OACC_LOOP:
14181 ret = gimplify_omp_for (expr_p, pre_p);
14182 break;
14184 case OMP_LOOP:
14185 ret = gimplify_omp_loop (expr_p, pre_p);
14186 break;
14188 case OACC_CACHE:
14189 gimplify_oacc_cache (expr_p, pre_p);
14190 ret = GS_ALL_DONE;
14191 break;
14193 case OACC_DECLARE:
14194 gimplify_oacc_declare (expr_p, pre_p);
14195 ret = GS_ALL_DONE;
14196 break;
14198 case OACC_HOST_DATA:
14199 case OACC_DATA:
14200 case OACC_KERNELS:
14201 case OACC_PARALLEL:
14202 case OACC_SERIAL:
14203 case OMP_SECTIONS:
14204 case OMP_SINGLE:
14205 case OMP_TARGET:
14206 case OMP_TARGET_DATA:
14207 case OMP_TEAMS:
14208 gimplify_omp_workshare (expr_p, pre_p);
14209 ret = GS_ALL_DONE;
14210 break;
14212 case OACC_ENTER_DATA:
14213 case OACC_EXIT_DATA:
14214 case OACC_UPDATE:
14215 case OMP_TARGET_UPDATE:
14216 case OMP_TARGET_ENTER_DATA:
14217 case OMP_TARGET_EXIT_DATA:
14218 gimplify_omp_target_update (expr_p, pre_p);
14219 ret = GS_ALL_DONE;
14220 break;
14222 case OMP_SECTION:
14223 case OMP_MASTER:
14224 case OMP_ORDERED:
14225 case OMP_CRITICAL:
14226 case OMP_SCAN:
14228 gimple_seq body = NULL;
14229 gimple *g;
14230 bool saved_in_omp_construct = in_omp_construct;
14232 in_omp_construct = true;
14233 gimplify_and_add (OMP_BODY (*expr_p), &body);
14234 in_omp_construct = saved_in_omp_construct;
14235 switch (TREE_CODE (*expr_p))
14237 case OMP_SECTION:
14238 g = gimple_build_omp_section (body);
14239 break;
14240 case OMP_MASTER:
14241 g = gimple_build_omp_master (body);
14242 break;
14243 case OMP_ORDERED:
14244 g = gimplify_omp_ordered (*expr_p, body);
14245 break;
14246 case OMP_CRITICAL:
14247 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
14248 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
14249 gimplify_adjust_omp_clauses (pre_p, body,
14250 &OMP_CRITICAL_CLAUSES (*expr_p),
14251 OMP_CRITICAL);
14252 g = gimple_build_omp_critical (body,
14253 OMP_CRITICAL_NAME (*expr_p),
14254 OMP_CRITICAL_CLAUSES (*expr_p));
14255 break;
14256 case OMP_SCAN:
14257 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
14258 pre_p, ORT_WORKSHARE, OMP_SCAN);
14259 gimplify_adjust_omp_clauses (pre_p, body,
14260 &OMP_SCAN_CLAUSES (*expr_p),
14261 OMP_SCAN);
14262 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
14263 break;
14264 default:
14265 gcc_unreachable ();
14267 gimplify_seq_add_stmt (pre_p, g);
14268 ret = GS_ALL_DONE;
14269 break;
14272 case OMP_TASKGROUP:
14274 gimple_seq body = NULL;
14276 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
14277 bool saved_in_omp_construct = in_omp_construct;
14278 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
14279 OMP_TASKGROUP);
14280 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
14282 in_omp_construct = true;
14283 gimplify_and_add (OMP_BODY (*expr_p), &body);
14284 in_omp_construct = saved_in_omp_construct;
14285 gimple_seq cleanup = NULL;
14286 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
14287 gimple *g = gimple_build_call (fn, 0);
14288 gimple_seq_add_stmt (&cleanup, g);
14289 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
14290 body = NULL;
14291 gimple_seq_add_stmt (&body, g);
14292 g = gimple_build_omp_taskgroup (body, *pclauses);
14293 gimplify_seq_add_stmt (pre_p, g);
14294 ret = GS_ALL_DONE;
14295 break;
14298 case OMP_ATOMIC:
14299 case OMP_ATOMIC_READ:
14300 case OMP_ATOMIC_CAPTURE_OLD:
14301 case OMP_ATOMIC_CAPTURE_NEW:
14302 ret = gimplify_omp_atomic (expr_p, pre_p);
14303 break;
14305 case TRANSACTION_EXPR:
14306 ret = gimplify_transaction (expr_p, pre_p);
14307 break;
14309 case TRUTH_AND_EXPR:
14310 case TRUTH_OR_EXPR:
14311 case TRUTH_XOR_EXPR:
14313 tree orig_type = TREE_TYPE (*expr_p);
14314 tree new_type, xop0, xop1;
14315 *expr_p = gimple_boolify (*expr_p);
14316 new_type = TREE_TYPE (*expr_p);
14317 if (!useless_type_conversion_p (orig_type, new_type))
14319 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
14320 ret = GS_OK;
14321 break;
14324 /* Boolified binary truth expressions are semantically equivalent
14325 to bitwise binary expressions. Canonicalize them to the
14326 bitwise variant. */
14327 switch (TREE_CODE (*expr_p))
14329 case TRUTH_AND_EXPR:
14330 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
14331 break;
14332 case TRUTH_OR_EXPR:
14333 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
14334 break;
14335 case TRUTH_XOR_EXPR:
14336 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
14337 break;
14338 default:
14339 break;
14341 /* Now make sure that operands have compatible type to
14342 expression's new_type. */
14343 xop0 = TREE_OPERAND (*expr_p, 0);
14344 xop1 = TREE_OPERAND (*expr_p, 1);
14345 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
14346 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
14347 new_type,
14348 xop0);
14349 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
14350 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
14351 new_type,
14352 xop1);
14353 /* Continue classified as tcc_binary. */
14354 goto expr_2;
14357 case VEC_COND_EXPR:
14358 goto expr_3;
14360 case VEC_PERM_EXPR:
14361 /* Classified as tcc_expression. */
14362 goto expr_3;
14364 case BIT_INSERT_EXPR:
14365 /* Argument 3 is a constant. */
14366 goto expr_2;
14368 case POINTER_PLUS_EXPR:
14370 enum gimplify_status r0, r1;
14371 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14372 post_p, is_gimple_val, fb_rvalue);
14373 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
14374 post_p, is_gimple_val, fb_rvalue);
14375 recalculate_side_effects (*expr_p);
14376 ret = MIN (r0, r1);
14377 break;
14380 default:
14381 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
14383 case tcc_comparison:
14384 /* Handle comparison of objects of non scalar mode aggregates
14385 with a call to memcmp. It would be nice to only have to do
14386 this for variable-sized objects, but then we'd have to allow
14387 the same nest of reference nodes we allow for MODIFY_EXPR and
14388 that's too complex.
14390 Compare scalar mode aggregates as scalar mode values. Using
14391 memcmp for them would be very inefficient at best, and is
14392 plain wrong if bitfields are involved. */
14394 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
14396 /* Vector comparisons need no boolification. */
14397 if (TREE_CODE (type) == VECTOR_TYPE)
14398 goto expr_2;
14399 else if (!AGGREGATE_TYPE_P (type))
14401 tree org_type = TREE_TYPE (*expr_p);
14402 *expr_p = gimple_boolify (*expr_p);
14403 if (!useless_type_conversion_p (org_type,
14404 TREE_TYPE (*expr_p)))
14406 *expr_p = fold_convert_loc (input_location,
14407 org_type, *expr_p);
14408 ret = GS_OK;
14410 else
14411 goto expr_2;
14413 else if (TYPE_MODE (type) != BLKmode)
14414 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
14415 else
14416 ret = gimplify_variable_sized_compare (expr_p);
14418 break;
14421 /* If *EXPR_P does not need to be special-cased, handle it
14422 according to its class. */
14423 case tcc_unary:
14424 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14425 post_p, is_gimple_val, fb_rvalue);
14426 break;
14428 case tcc_binary:
14429 expr_2:
14431 enum gimplify_status r0, r1;
14433 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14434 post_p, is_gimple_val, fb_rvalue);
14435 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
14436 post_p, is_gimple_val, fb_rvalue);
14438 ret = MIN (r0, r1);
14439 break;
14442 expr_3:
14444 enum gimplify_status r0, r1, r2;
14446 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14447 post_p, is_gimple_val, fb_rvalue);
14448 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
14449 post_p, is_gimple_val, fb_rvalue);
14450 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
14451 post_p, is_gimple_val, fb_rvalue);
14453 ret = MIN (MIN (r0, r1), r2);
14454 break;
14457 case tcc_declaration:
14458 case tcc_constant:
14459 ret = GS_ALL_DONE;
14460 goto dont_recalculate;
14462 default:
14463 gcc_unreachable ();
14466 recalculate_side_effects (*expr_p);
14468 dont_recalculate:
14469 break;
14472 gcc_assert (*expr_p || ret != GS_OK);
14474 while (ret == GS_OK);
14476 /* If we encountered an error_mark somewhere nested inside, either
14477 stub out the statement or propagate the error back out. */
14478 if (ret == GS_ERROR)
14480 if (is_statement)
14481 *expr_p = NULL;
14482 goto out;
14485 /* This was only valid as a return value from the langhook, which
14486 we handled. Make sure it doesn't escape from any other context. */
14487 gcc_assert (ret != GS_UNHANDLED);
14489 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
14491 /* We aren't looking for a value, and we don't have a valid
14492 statement. If it doesn't have side-effects, throw it away.
14493 We can also get here with code such as "*&&L;", where L is
14494 a LABEL_DECL that is marked as FORCED_LABEL. */
14495 if (TREE_CODE (*expr_p) == LABEL_DECL
14496 || !TREE_SIDE_EFFECTS (*expr_p))
14497 *expr_p = NULL;
14498 else if (!TREE_THIS_VOLATILE (*expr_p))
14500 /* This is probably a _REF that contains something nested that
14501 has side effects. Recurse through the operands to find it. */
14502 enum tree_code code = TREE_CODE (*expr_p);
14504 switch (code)
14506 case COMPONENT_REF:
14507 case REALPART_EXPR:
14508 case IMAGPART_EXPR:
14509 case VIEW_CONVERT_EXPR:
14510 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14511 gimple_test_f, fallback);
14512 break;
14514 case ARRAY_REF:
14515 case ARRAY_RANGE_REF:
14516 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14517 gimple_test_f, fallback);
14518 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
14519 gimple_test_f, fallback);
14520 break;
14522 default:
14523 /* Anything else with side-effects must be converted to
14524 a valid statement before we get here. */
14525 gcc_unreachable ();
14528 *expr_p = NULL;
14530 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
14531 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode)
14533 /* Historically, the compiler has treated a bare reference
14534 to a non-BLKmode volatile lvalue as forcing a load. */
14535 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
14537 /* Normally, we do not want to create a temporary for a
14538 TREE_ADDRESSABLE type because such a type should not be
14539 copied by bitwise-assignment. However, we make an
14540 exception here, as all we are doing here is ensuring that
14541 we read the bytes that make up the type. We use
14542 create_tmp_var_raw because create_tmp_var will abort when
14543 given a TREE_ADDRESSABLE type. */
14544 tree tmp = create_tmp_var_raw (type, "vol");
14545 gimple_add_tmp_var (tmp);
14546 gimplify_assign (tmp, *expr_p, pre_p);
14547 *expr_p = NULL;
14549 else
14550 /* We can't do anything useful with a volatile reference to
14551 an incomplete type, so just throw it away. Likewise for
14552 a BLKmode type, since any implicit inner load should
14553 already have been turned into an explicit one by the
14554 gimplification process. */
14555 *expr_p = NULL;
14558 /* If we are gimplifying at the statement level, we're done. Tack
14559 everything together and return. */
14560 if (fallback == fb_none || is_statement)
14562 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
14563 it out for GC to reclaim it. */
14564 *expr_p = NULL_TREE;
14566 if (!gimple_seq_empty_p (internal_pre)
14567 || !gimple_seq_empty_p (internal_post))
14569 gimplify_seq_add_seq (&internal_pre, internal_post);
14570 gimplify_seq_add_seq (pre_p, internal_pre);
14573 /* The result of gimplifying *EXPR_P is going to be the last few
14574 statements in *PRE_P and *POST_P. Add location information
14575 to all the statements that were added by the gimplification
14576 helpers. */
14577 if (!gimple_seq_empty_p (*pre_p))
14578 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
14580 if (!gimple_seq_empty_p (*post_p))
14581 annotate_all_with_location_after (*post_p, post_last_gsi,
14582 input_location);
14584 goto out;
14587 #ifdef ENABLE_GIMPLE_CHECKING
14588 if (*expr_p)
14590 enum tree_code code = TREE_CODE (*expr_p);
14591 /* These expressions should already be in gimple IR form. */
14592 gcc_assert (code != MODIFY_EXPR
14593 && code != ASM_EXPR
14594 && code != BIND_EXPR
14595 && code != CATCH_EXPR
14596 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
14597 && code != EH_FILTER_EXPR
14598 && code != GOTO_EXPR
14599 && code != LABEL_EXPR
14600 && code != LOOP_EXPR
14601 && code != SWITCH_EXPR
14602 && code != TRY_FINALLY_EXPR
14603 && code != EH_ELSE_EXPR
14604 && code != OACC_PARALLEL
14605 && code != OACC_KERNELS
14606 && code != OACC_SERIAL
14607 && code != OACC_DATA
14608 && code != OACC_HOST_DATA
14609 && code != OACC_DECLARE
14610 && code != OACC_UPDATE
14611 && code != OACC_ENTER_DATA
14612 && code != OACC_EXIT_DATA
14613 && code != OACC_CACHE
14614 && code != OMP_CRITICAL
14615 && code != OMP_FOR
14616 && code != OACC_LOOP
14617 && code != OMP_MASTER
14618 && code != OMP_TASKGROUP
14619 && code != OMP_ORDERED
14620 && code != OMP_PARALLEL
14621 && code != OMP_SCAN
14622 && code != OMP_SECTIONS
14623 && code != OMP_SECTION
14624 && code != OMP_SINGLE);
14626 #endif
14628 /* Otherwise we're gimplifying a subexpression, so the resulting
14629 value is interesting. If it's a valid operand that matches
14630 GIMPLE_TEST_F, we're done. Unless we are handling some
14631 post-effects internally; if that's the case, we need to copy into
14632 a temporary before adding the post-effects to POST_P. */
14633 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
14634 goto out;
14636 /* Otherwise, we need to create a new temporary for the gimplified
14637 expression. */
14639 /* We can't return an lvalue if we have an internal postqueue. The
14640 object the lvalue refers to would (probably) be modified by the
14641 postqueue; we need to copy the value out first, which means an
14642 rvalue. */
14643 if ((fallback & fb_lvalue)
14644 && gimple_seq_empty_p (internal_post)
14645 && is_gimple_addressable (*expr_p))
14647 /* An lvalue will do. Take the address of the expression, store it
14648 in a temporary, and replace the expression with an INDIRECT_REF of
14649 that temporary. */
14650 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
14651 unsigned int ref_align = get_object_alignment (*expr_p);
14652 tree ref_type = TREE_TYPE (*expr_p);
14653 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
14654 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
14655 if (TYPE_ALIGN (ref_type) != ref_align)
14656 ref_type = build_aligned_type (ref_type, ref_align);
14657 *expr_p = build2 (MEM_REF, ref_type,
14658 tmp, build_zero_cst (ref_alias_type));
14660 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
14662 /* An rvalue will do. Assign the gimplified expression into a
14663 new temporary TMP and replace the original expression with
14664 TMP. First, make sure that the expression has a type so that
14665 it can be assigned into a temporary. */
14666 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
14667 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
14669 else
14671 #ifdef ENABLE_GIMPLE_CHECKING
14672 if (!(fallback & fb_mayfail))
14674 fprintf (stderr, "gimplification failed:\n");
14675 print_generic_expr (stderr, *expr_p);
14676 debug_tree (*expr_p);
14677 internal_error ("gimplification failed");
14679 #endif
14680 gcc_assert (fallback & fb_mayfail);
14682 /* If this is an asm statement, and the user asked for the
14683 impossible, don't die. Fail and let gimplify_asm_expr
14684 issue an error. */
14685 ret = GS_ERROR;
14686 goto out;
14689 /* Make sure the temporary matches our predicate. */
14690 gcc_assert ((*gimple_test_f) (*expr_p));
14692 if (!gimple_seq_empty_p (internal_post))
14694 annotate_all_with_location (internal_post, input_location);
14695 gimplify_seq_add_seq (pre_p, internal_post);
14698 out:
14699 input_location = saved_location;
14700 return ret;
14703 /* Like gimplify_expr but make sure the gimplified result is not itself
14704 a SSA name (but a decl if it were). Temporaries required by
14705 evaluating *EXPR_P may be still SSA names. */
14707 static enum gimplify_status
14708 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
14709 bool (*gimple_test_f) (tree), fallback_t fallback,
14710 bool allow_ssa)
14712 bool was_ssa_name_p = TREE_CODE (*expr_p) == SSA_NAME;
14713 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
14714 gimple_test_f, fallback);
14715 if (! allow_ssa
14716 && TREE_CODE (*expr_p) == SSA_NAME)
14718 tree name = *expr_p;
14719 if (was_ssa_name_p)
14720 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
14721 else
14723 /* Avoid the extra copy if possible. */
14724 *expr_p = create_tmp_reg (TREE_TYPE (name));
14725 if (!gimple_nop_p (SSA_NAME_DEF_STMT (name)))
14726 gimple_set_lhs (SSA_NAME_DEF_STMT (name), *expr_p);
14727 release_ssa_name (name);
14730 return ret;
14733 /* Look through TYPE for variable-sized objects and gimplify each such
14734 size that we find. Add to LIST_P any statements generated. */
14736 void
14737 gimplify_type_sizes (tree type, gimple_seq *list_p)
14739 tree field, t;
14741 if (type == NULL || type == error_mark_node)
14742 return;
14744 /* We first do the main variant, then copy into any other variants. */
14745 type = TYPE_MAIN_VARIANT (type);
14747 /* Avoid infinite recursion. */
14748 if (TYPE_SIZES_GIMPLIFIED (type))
14749 return;
14751 TYPE_SIZES_GIMPLIFIED (type) = 1;
14753 switch (TREE_CODE (type))
14755 case INTEGER_TYPE:
14756 case ENUMERAL_TYPE:
14757 case BOOLEAN_TYPE:
14758 case REAL_TYPE:
14759 case FIXED_POINT_TYPE:
14760 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
14761 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
14763 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
14765 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
14766 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
14768 break;
14770 case ARRAY_TYPE:
14771 /* These types may not have declarations, so handle them here. */
14772 gimplify_type_sizes (TREE_TYPE (type), list_p);
14773 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
14774 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
14775 with assigned stack slots, for -O1+ -g they should be tracked
14776 by VTA. */
14777 if (!(TYPE_NAME (type)
14778 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
14779 && DECL_IGNORED_P (TYPE_NAME (type)))
14780 && TYPE_DOMAIN (type)
14781 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
14783 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
14784 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
14785 DECL_IGNORED_P (t) = 0;
14786 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
14787 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
14788 DECL_IGNORED_P (t) = 0;
14790 break;
14792 case RECORD_TYPE:
14793 case UNION_TYPE:
14794 case QUAL_UNION_TYPE:
14795 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
14796 if (TREE_CODE (field) == FIELD_DECL)
14798 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
14799 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
14800 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
14801 gimplify_type_sizes (TREE_TYPE (field), list_p);
14803 break;
14805 case POINTER_TYPE:
14806 case REFERENCE_TYPE:
14807 /* We used to recurse on the pointed-to type here, which turned out to
14808 be incorrect because its definition might refer to variables not
14809 yet initialized at this point if a forward declaration is involved.
14811 It was actually useful for anonymous pointed-to types to ensure
14812 that the sizes evaluation dominates every possible later use of the
14813 values. Restricting to such types here would be safe since there
14814 is no possible forward declaration around, but would introduce an
14815 undesirable middle-end semantic to anonymity. We then defer to
14816 front-ends the responsibility of ensuring that the sizes are
14817 evaluated both early and late enough, e.g. by attaching artificial
14818 type declarations to the tree. */
14819 break;
14821 default:
14822 break;
14825 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
14826 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
14828 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
14830 TYPE_SIZE (t) = TYPE_SIZE (type);
14831 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
14832 TYPE_SIZES_GIMPLIFIED (t) = 1;
14836 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
14837 a size or position, has had all of its SAVE_EXPRs evaluated.
14838 We add any required statements to *STMT_P. */
14840 void
14841 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
14843 tree expr = *expr_p;
14845 /* We don't do anything if the value isn't there, is constant, or contains
14846 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
14847 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
14848 will want to replace it with a new variable, but that will cause problems
14849 if this type is from outside the function. It's OK to have that here. */
14850 if (expr == NULL_TREE
14851 || is_gimple_constant (expr)
14852 || TREE_CODE (expr) == VAR_DECL
14853 || CONTAINS_PLACEHOLDER_P (expr))
14854 return;
14856 *expr_p = unshare_expr (expr);
14858 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
14859 if the def vanishes. */
14860 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
14862 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
14863 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
14864 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
14865 if (is_gimple_constant (*expr_p))
14866 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
14869 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
14870 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
14871 is true, also gimplify the parameters. */
14873 gbind *
14874 gimplify_body (tree fndecl, bool do_parms)
14876 location_t saved_location = input_location;
14877 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
14878 gimple *outer_stmt;
14879 gbind *outer_bind;
14881 timevar_push (TV_TREE_GIMPLIFY);
14883 init_tree_ssa (cfun);
14885 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
14886 gimplification. */
14887 default_rtl_profile ();
14889 gcc_assert (gimplify_ctxp == NULL);
14890 push_gimplify_context (true);
14892 if (flag_openacc || flag_openmp)
14894 gcc_assert (gimplify_omp_ctxp == NULL);
14895 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
14896 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
14899 /* Unshare most shared trees in the body and in that of any nested functions.
14900 It would seem we don't have to do this for nested functions because
14901 they are supposed to be output and then the outer function gimplified
14902 first, but the g++ front end doesn't always do it that way. */
14903 unshare_body (fndecl);
14904 unvisit_body (fndecl);
14906 /* Make sure input_location isn't set to something weird. */
14907 input_location = DECL_SOURCE_LOCATION (fndecl);
14909 /* Resolve callee-copies. This has to be done before processing
14910 the body so that DECL_VALUE_EXPR gets processed correctly. */
14911 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
14913 /* Gimplify the function's body. */
14914 seq = NULL;
14915 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
14916 outer_stmt = gimple_seq_first_nondebug_stmt (seq);
14917 if (!outer_stmt)
14919 outer_stmt = gimple_build_nop ();
14920 gimplify_seq_add_stmt (&seq, outer_stmt);
14923 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
14924 not the case, wrap everything in a GIMPLE_BIND to make it so. */
14925 if (gimple_code (outer_stmt) == GIMPLE_BIND
14926 && (gimple_seq_first_nondebug_stmt (seq)
14927 == gimple_seq_last_nondebug_stmt (seq)))
14929 outer_bind = as_a <gbind *> (outer_stmt);
14930 if (gimple_seq_first_stmt (seq) != outer_stmt
14931 || gimple_seq_last_stmt (seq) != outer_stmt)
14933 /* If there are debug stmts before or after outer_stmt, move them
14934 inside of outer_bind body. */
14935 gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
14936 gimple_seq second_seq = NULL;
14937 if (gimple_seq_first_stmt (seq) != outer_stmt
14938 && gimple_seq_last_stmt (seq) != outer_stmt)
14940 second_seq = gsi_split_seq_after (gsi);
14941 gsi_remove (&gsi, false);
14943 else if (gimple_seq_first_stmt (seq) != outer_stmt)
14944 gsi_remove (&gsi, false);
14945 else
14947 gsi_remove (&gsi, false);
14948 second_seq = seq;
14949 seq = NULL;
14951 gimple_seq_add_seq_without_update (&seq,
14952 gimple_bind_body (outer_bind));
14953 gimple_seq_add_seq_without_update (&seq, second_seq);
14954 gimple_bind_set_body (outer_bind, seq);
14957 else
14958 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
14960 DECL_SAVED_TREE (fndecl) = NULL_TREE;
14962 /* If we had callee-copies statements, insert them at the beginning
14963 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
14964 if (!gimple_seq_empty_p (parm_stmts))
14966 tree parm;
14968 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
14969 if (parm_cleanup)
14971 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
14972 GIMPLE_TRY_FINALLY);
14973 parm_stmts = NULL;
14974 gimple_seq_add_stmt (&parm_stmts, g);
14976 gimple_bind_set_body (outer_bind, parm_stmts);
14978 for (parm = DECL_ARGUMENTS (current_function_decl);
14979 parm; parm = DECL_CHAIN (parm))
14980 if (DECL_HAS_VALUE_EXPR_P (parm))
14982 DECL_HAS_VALUE_EXPR_P (parm) = 0;
14983 DECL_IGNORED_P (parm) = 0;
14987 if ((flag_openacc || flag_openmp || flag_openmp_simd)
14988 && gimplify_omp_ctxp)
14990 delete_omp_context (gimplify_omp_ctxp);
14991 gimplify_omp_ctxp = NULL;
14994 pop_gimplify_context (outer_bind);
14995 gcc_assert (gimplify_ctxp == NULL);
14997 if (flag_checking && !seen_error ())
14998 verify_gimple_in_seq (gimple_bind_body (outer_bind));
15000 timevar_pop (TV_TREE_GIMPLIFY);
15001 input_location = saved_location;
15003 return outer_bind;
15006 typedef char *char_p; /* For DEF_VEC_P. */
15008 /* Return whether we should exclude FNDECL from instrumentation. */
15010 static bool
15011 flag_instrument_functions_exclude_p (tree fndecl)
15013 vec<char_p> *v;
15015 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
15016 if (v && v->length () > 0)
15018 const char *name;
15019 int i;
15020 char *s;
15022 name = lang_hooks.decl_printable_name (fndecl, 1);
15023 FOR_EACH_VEC_ELT (*v, i, s)
15024 if (strstr (name, s) != NULL)
15025 return true;
15028 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
15029 if (v && v->length () > 0)
15031 const char *name;
15032 int i;
15033 char *s;
15035 name = DECL_SOURCE_FILE (fndecl);
15036 FOR_EACH_VEC_ELT (*v, i, s)
15037 if (strstr (name, s) != NULL)
15038 return true;
15041 return false;
15044 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
15045 node for the function we want to gimplify.
15047 Return the sequence of GIMPLE statements corresponding to the body
15048 of FNDECL. */
15050 void
15051 gimplify_function_tree (tree fndecl)
15053 gimple_seq seq;
15054 gbind *bind;
15056 gcc_assert (!gimple_body (fndecl));
15058 if (DECL_STRUCT_FUNCTION (fndecl))
15059 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
15060 else
15061 push_struct_function (fndecl);
15063 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
15064 if necessary. */
15065 cfun->curr_properties |= PROP_gimple_lva;
15067 if (asan_sanitize_use_after_scope () && sanitize_flags_p (SANITIZE_ADDRESS))
15068 asan_poisoned_variables = new hash_set<tree> ();
15069 bind = gimplify_body (fndecl, true);
15070 if (asan_poisoned_variables)
15072 delete asan_poisoned_variables;
15073 asan_poisoned_variables = NULL;
15076 /* The tree body of the function is no longer needed, replace it
15077 with the new GIMPLE body. */
15078 seq = NULL;
15079 gimple_seq_add_stmt (&seq, bind);
15080 gimple_set_body (fndecl, seq);
15082 /* If we're instrumenting function entry/exit, then prepend the call to
15083 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
15084 catch the exit hook. */
15085 /* ??? Add some way to ignore exceptions for this TFE. */
15086 if (flag_instrument_function_entry_exit
15087 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
15088 /* Do not instrument extern inline functions. */
15089 && !(DECL_DECLARED_INLINE_P (fndecl)
15090 && DECL_EXTERNAL (fndecl)
15091 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
15092 && !flag_instrument_functions_exclude_p (fndecl))
15094 tree x;
15095 gbind *new_bind;
15096 gimple *tf;
15097 gimple_seq cleanup = NULL, body = NULL;
15098 tree tmp_var, this_fn_addr;
15099 gcall *call;
15101 /* The instrumentation hooks aren't going to call the instrumented
15102 function and the address they receive is expected to be matchable
15103 against symbol addresses. Make sure we don't create a trampoline,
15104 in case the current function is nested. */
15105 this_fn_addr = build_fold_addr_expr (current_function_decl);
15106 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
15108 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
15109 call = gimple_build_call (x, 1, integer_zero_node);
15110 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
15111 gimple_call_set_lhs (call, tmp_var);
15112 gimplify_seq_add_stmt (&cleanup, call);
15113 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
15114 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
15115 gimplify_seq_add_stmt (&cleanup, call);
15116 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
15118 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
15119 call = gimple_build_call (x, 1, integer_zero_node);
15120 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
15121 gimple_call_set_lhs (call, tmp_var);
15122 gimplify_seq_add_stmt (&body, call);
15123 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
15124 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
15125 gimplify_seq_add_stmt (&body, call);
15126 gimplify_seq_add_stmt (&body, tf);
15127 new_bind = gimple_build_bind (NULL, body, NULL);
15129 /* Replace the current function body with the body
15130 wrapped in the try/finally TF. */
15131 seq = NULL;
15132 gimple_seq_add_stmt (&seq, new_bind);
15133 gimple_set_body (fndecl, seq);
15134 bind = new_bind;
15137 if (sanitize_flags_p (SANITIZE_THREAD)
15138 && param_tsan_instrument_func_entry_exit)
15140 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
15141 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
15142 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
15143 /* Replace the current function body with the body
15144 wrapped in the try/finally TF. */
15145 seq = NULL;
15146 gimple_seq_add_stmt (&seq, new_bind);
15147 gimple_set_body (fndecl, seq);
15150 DECL_SAVED_TREE (fndecl) = NULL_TREE;
15151 cfun->curr_properties |= PROP_gimple_any;
15153 pop_cfun ();
15155 dump_function (TDI_gimple, fndecl);
15158 /* Return a dummy expression of type TYPE in order to keep going after an
15159 error. */
15161 static tree
15162 dummy_object (tree type)
15164 tree t = build_int_cst (build_pointer_type (type), 0);
15165 return build2 (MEM_REF, type, t, t);
15168 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
15169 builtin function, but a very special sort of operator. */
15171 enum gimplify_status
15172 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
15173 gimple_seq *post_p ATTRIBUTE_UNUSED)
15175 tree promoted_type, have_va_type;
15176 tree valist = TREE_OPERAND (*expr_p, 0);
15177 tree type = TREE_TYPE (*expr_p);
15178 tree t, tag, aptag;
15179 location_t loc = EXPR_LOCATION (*expr_p);
15181 /* Verify that valist is of the proper type. */
15182 have_va_type = TREE_TYPE (valist);
15183 if (have_va_type == error_mark_node)
15184 return GS_ERROR;
15185 have_va_type = targetm.canonical_va_list_type (have_va_type);
15186 if (have_va_type == NULL_TREE
15187 && POINTER_TYPE_P (TREE_TYPE (valist)))
15188 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
15189 have_va_type
15190 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
15191 gcc_assert (have_va_type != NULL_TREE);
15193 /* Generate a diagnostic for requesting data of a type that cannot
15194 be passed through `...' due to type promotion at the call site. */
15195 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
15196 != type)
15198 static bool gave_help;
15199 bool warned;
15200 /* Use the expansion point to handle cases such as passing bool (defined
15201 in a system header) through `...'. */
15202 location_t xloc
15203 = expansion_point_location_if_in_system_header (loc);
15205 /* Unfortunately, this is merely undefined, rather than a constraint
15206 violation, so we cannot make this an error. If this call is never
15207 executed, the program is still strictly conforming. */
15208 auto_diagnostic_group d;
15209 warned = warning_at (xloc, 0,
15210 "%qT is promoted to %qT when passed through %<...%>",
15211 type, promoted_type);
15212 if (!gave_help && warned)
15214 gave_help = true;
15215 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
15216 promoted_type, type);
15219 /* We can, however, treat "undefined" any way we please.
15220 Call abort to encourage the user to fix the program. */
15221 if (warned)
15222 inform (xloc, "if this code is reached, the program will abort");
15223 /* Before the abort, allow the evaluation of the va_list
15224 expression to exit or longjmp. */
15225 gimplify_and_add (valist, pre_p);
15226 t = build_call_expr_loc (loc,
15227 builtin_decl_implicit (BUILT_IN_TRAP), 0);
15228 gimplify_and_add (t, pre_p);
15230 /* This is dead code, but go ahead and finish so that the
15231 mode of the result comes out right. */
15232 *expr_p = dummy_object (type);
15233 return GS_ALL_DONE;
15236 tag = build_int_cst (build_pointer_type (type), 0);
15237 aptag = build_int_cst (TREE_TYPE (valist), 0);
15239 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
15240 valist, tag, aptag);
15242 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
15243 needs to be expanded. */
15244 cfun->curr_properties &= ~PROP_gimple_lva;
15246 return GS_OK;
15249 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
15251 DST/SRC are the destination and source respectively. You can pass
15252 ungimplified trees in DST or SRC, in which case they will be
15253 converted to a gimple operand if necessary.
15255 This function returns the newly created GIMPLE_ASSIGN tuple. */
15257 gimple *
15258 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
15260 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
15261 gimplify_and_add (t, seq_p);
15262 ggc_free (t);
15263 return gimple_seq_last_stmt (*seq_p);
15266 inline hashval_t
15267 gimplify_hasher::hash (const elt_t *p)
15269 tree t = p->val;
15270 return iterative_hash_expr (t, 0);
15273 inline bool
15274 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
15276 tree t1 = p1->val;
15277 tree t2 = p2->val;
15278 enum tree_code code = TREE_CODE (t1);
15280 if (TREE_CODE (t2) != code
15281 || TREE_TYPE (t1) != TREE_TYPE (t2))
15282 return false;
15284 if (!operand_equal_p (t1, t2, 0))
15285 return false;
15287 /* Only allow them to compare equal if they also hash equal; otherwise
15288 results are nondeterminate, and we fail bootstrap comparison. */
15289 gcc_checking_assert (hash (p1) == hash (p2));
15291 return true;