1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2022 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
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
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/>. */
25 #include "coretypes.h"
33 #include "gimple-predict.h"
34 #include "tree-pass.h" /* FIXME: only for PROP_gimple_any */
37 #include "tree-pretty-print.h"
38 #include "diagnostic-core.h"
40 #include "fold-const.h"
45 #include "gimple-iterator.h"
46 #include "gimple-fold.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"
56 #include "tree-hash-traits.h"
57 #include "omp-general.h"
59 #include "gimple-low.h"
60 #include "gomp-constants.h"
61 #include "splay-tree.h"
62 #include "gimple-walk.h"
63 #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
65 #include "stringpool.h"
69 #include "omp-offload.h"
71 #include "tree-nested.h"
73 /* Hash set of poisoned variables in a bind expr. */
74 static hash_set<tree> *asan_poisoned_variables = NULL;
76 enum gimplify_omp_var_data
79 GOVD_EXPLICIT = 0x000002,
80 GOVD_SHARED = 0x000004,
81 GOVD_PRIVATE = 0x000008,
82 GOVD_FIRSTPRIVATE = 0x000010,
83 GOVD_LASTPRIVATE = 0x000020,
84 GOVD_REDUCTION = 0x000040,
87 GOVD_DEBUG_PRIVATE = 0x000200,
88 GOVD_PRIVATE_OUTER_REF = 0x000400,
89 GOVD_LINEAR = 0x000800,
90 GOVD_ALIGNED = 0x001000,
92 /* Flag for GOVD_MAP: don't copy back. */
93 GOVD_MAP_TO_ONLY = 0x002000,
95 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
96 GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 0x004000,
98 GOVD_MAP_0LEN_ARRAY = 0x008000,
100 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
101 GOVD_MAP_ALWAYS_TO = 0x010000,
103 /* Flag for shared vars that are or might be stored to in the region. */
104 GOVD_WRITTEN = 0x020000,
106 /* Flag for GOVD_MAP, if it is a forced mapping. */
107 GOVD_MAP_FORCE = 0x040000,
109 /* Flag for GOVD_MAP: must be present already. */
110 GOVD_MAP_FORCE_PRESENT = 0x080000,
112 /* Flag for GOVD_MAP: only allocate. */
113 GOVD_MAP_ALLOC_ONLY = 0x100000,
115 /* Flag for GOVD_MAP: only copy back. */
116 GOVD_MAP_FROM_ONLY = 0x200000,
118 GOVD_NONTEMPORAL = 0x400000,
120 /* Flag for GOVD_LASTPRIVATE: conditional modifier. */
121 GOVD_LASTPRIVATE_CONDITIONAL = 0x800000,
123 GOVD_CONDTEMP = 0x1000000,
125 /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause. */
126 GOVD_REDUCTION_INSCAN = 0x2000000,
128 /* Flag for GOVD_MAP: (struct) vars that have pointer attachments for
130 GOVD_MAP_HAS_ATTACHMENTS = 0x4000000,
132 /* Flag for GOVD_FIRSTPRIVATE: OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT. */
133 GOVD_FIRSTPRIVATE_IMPLICIT = 0x8000000,
135 GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
136 | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
143 ORT_WORKSHARE = 0x00,
144 ORT_TASKGROUP = 0x01,
148 ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1,
151 ORT_UNTIED_TASK = ORT_TASK | 1,
152 ORT_TASKLOOP = ORT_TASK | 2,
153 ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2,
156 ORT_COMBINED_TEAMS = ORT_TEAMS | 1,
157 ORT_HOST_TEAMS = ORT_TEAMS | 2,
158 ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2,
161 ORT_TARGET_DATA = 0x40,
163 /* Data region with offloading. */
165 ORT_COMBINED_TARGET = ORT_TARGET | 1,
166 ORT_IMPLICIT_TARGET = ORT_TARGET | 2,
168 /* OpenACC variants. */
169 ORT_ACC = 0x100, /* A generic OpenACC region. */
170 ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */
171 ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */
172 ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 2, /* Kernels construct. */
173 ORT_ACC_SERIAL = ORT_ACC | ORT_TARGET | 4, /* Serial construct. */
174 ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2, /* Host data. */
176 /* Dummy OpenMP region, used to disable expansion of
177 DECL_VALUE_EXPRs in taskloop pre body. */
181 /* Gimplify hashtable helper. */
183 struct gimplify_hasher : free_ptr_hash <elt_t>
185 static inline hashval_t hash (const elt_t *);
186 static inline bool equal (const elt_t *, const elt_t *);
191 struct gimplify_ctx *prev_context;
193 vec<gbind *> bind_expr_stack;
195 gimple_seq conditional_cleanups;
199 vec<tree> case_labels;
200 hash_set<tree> *live_switch_vars;
201 /* The formal temporary table. Should this be persistent? */
202 hash_table<gimplify_hasher> *temp_htab;
205 unsigned into_ssa : 1;
206 unsigned allow_rhs_cond_expr : 1;
207 unsigned in_cleanup_point_expr : 1;
208 unsigned keep_stack : 1;
209 unsigned save_stack : 1;
210 unsigned in_switch_expr : 1;
213 enum gimplify_defaultmap_kind
216 GDMK_SCALAR_TARGET, /* w/ Fortran's target attr, implicit mapping, only. */
222 struct gimplify_omp_ctx
224 struct gimplify_omp_ctx *outer_context;
225 splay_tree variables;
226 hash_set<tree> *privatized_types;
228 /* Iteration variables in an OMP_FOR. */
229 vec<tree> loop_iter_var;
231 enum omp_clause_default_kind default_kind;
232 enum omp_region_type region_type;
236 bool target_firstprivatize_array_bases;
238 bool order_concurrent;
244 static struct gimplify_ctx *gimplify_ctxp;
245 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
246 static bool in_omp_construct;
248 /* Forward declaration. */
249 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
250 static hash_map<tree, tree> *oacc_declare_returns;
251 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
252 bool (*) (tree), fallback_t, bool);
253 static void prepare_gimple_addressable (tree *, gimple_seq *);
255 /* Shorter alias name for the above function for use in gimplify.cc
259 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
261 gimple_seq_add_stmt_without_update (seq_p, gs);
264 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
265 NULL, a new sequence is allocated. This function is
266 similar to gimple_seq_add_seq, but does not scan the operands.
267 During gimplification, we need to manipulate statement sequences
268 before the def/use vectors have been constructed. */
271 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
273 gimple_stmt_iterator si;
278 si = gsi_last (*dst_p);
279 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
283 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
284 and popping gimplify contexts. */
286 static struct gimplify_ctx *ctx_pool = NULL;
288 /* Return a gimplify context struct from the pool. */
290 static inline struct gimplify_ctx *
293 struct gimplify_ctx * c = ctx_pool;
296 ctx_pool = c->prev_context;
298 c = XNEW (struct gimplify_ctx);
300 memset (c, '\0', sizeof (*c));
304 /* Put gimplify context C back into the pool. */
307 ctx_free (struct gimplify_ctx *c)
309 c->prev_context = ctx_pool;
313 /* Free allocated ctx stack memory. */
316 free_gimplify_stack (void)
318 struct gimplify_ctx *c;
320 while ((c = ctx_pool))
322 ctx_pool = c->prev_context;
328 /* Set up a context for the gimplifier. */
331 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
333 struct gimplify_ctx *c = ctx_alloc ();
335 c->prev_context = gimplify_ctxp;
337 gimplify_ctxp->into_ssa = in_ssa;
338 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
341 /* Tear down a context for the gimplifier. If BODY is non-null, then
342 put the temporaries into the outer BIND_EXPR. Otherwise, put them
345 BODY is not a sequence, but the first tuple in a sequence. */
348 pop_gimplify_context (gimple *body)
350 struct gimplify_ctx *c = gimplify_ctxp;
353 && (!c->bind_expr_stack.exists ()
354 || c->bind_expr_stack.is_empty ()));
355 c->bind_expr_stack.release ();
356 gimplify_ctxp = c->prev_context;
359 declare_vars (c->temps, body, false);
361 record_vars (c->temps);
368 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
371 gimple_push_bind_expr (gbind *bind_stmt)
373 gimplify_ctxp->bind_expr_stack.reserve (8);
374 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
377 /* Pop the first element off the stack of bindings. */
380 gimple_pop_bind_expr (void)
382 gimplify_ctxp->bind_expr_stack.pop ();
385 /* Return the first element of the stack of bindings. */
388 gimple_current_bind_expr (void)
390 return gimplify_ctxp->bind_expr_stack.last ();
393 /* Return the stack of bindings created during gimplification. */
396 gimple_bind_expr_stack (void)
398 return gimplify_ctxp->bind_expr_stack;
401 /* Return true iff there is a COND_EXPR between us and the innermost
402 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
405 gimple_conditional_context (void)
407 return gimplify_ctxp->conditions > 0;
410 /* Note that we've entered a COND_EXPR. */
413 gimple_push_condition (void)
415 #ifdef ENABLE_GIMPLE_CHECKING
416 if (gimplify_ctxp->conditions == 0)
417 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
419 ++(gimplify_ctxp->conditions);
422 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
423 now, add any conditional cleanups we've seen to the prequeue. */
426 gimple_pop_condition (gimple_seq *pre_p)
428 int conds = --(gimplify_ctxp->conditions);
430 gcc_assert (conds >= 0);
433 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
434 gimplify_ctxp->conditional_cleanups = NULL;
438 /* A stable comparison routine for use with splay trees and DECLs. */
441 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
446 return DECL_UID (a) - DECL_UID (b);
449 /* Create a new omp construct that deals with variable remapping. */
451 static struct gimplify_omp_ctx *
452 new_omp_context (enum omp_region_type region_type)
454 struct gimplify_omp_ctx *c;
456 c = XCNEW (struct gimplify_omp_ctx);
457 c->outer_context = gimplify_omp_ctxp;
458 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
459 c->privatized_types = new hash_set<tree>;
460 c->location = input_location;
461 c->region_type = region_type;
462 if ((region_type & ORT_TASK) == 0)
463 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
465 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
466 c->defaultmap[GDMK_SCALAR] = GOVD_MAP;
467 c->defaultmap[GDMK_SCALAR_TARGET] = GOVD_MAP;
468 c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
469 c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
470 c->defaultmap[GDMK_POINTER] = GOVD_MAP;
475 /* Destroy an omp construct that deals with variable remapping. */
478 delete_omp_context (struct gimplify_omp_ctx *c)
480 splay_tree_delete (c->variables);
481 delete c->privatized_types;
482 c->loop_iter_var.release ();
486 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
487 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
489 /* Both gimplify the statement T and append it to *SEQ_P. This function
490 behaves exactly as gimplify_stmt, but you don't have to pass T as a
494 gimplify_and_add (tree t, gimple_seq *seq_p)
496 gimplify_stmt (&t, seq_p);
499 /* Gimplify statement T into sequence *SEQ_P, and return the first
500 tuple in the sequence of generated tuples for this statement.
501 Return NULL if gimplifying T produced no tuples. */
504 gimplify_and_return_first (tree t, gimple_seq *seq_p)
506 gimple_stmt_iterator last = gsi_last (*seq_p);
508 gimplify_and_add (t, seq_p);
510 if (!gsi_end_p (last))
513 return gsi_stmt (last);
516 return gimple_seq_first_stmt (*seq_p);
519 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
520 LHS, or for a call argument. */
523 is_gimple_mem_rhs (tree t)
525 /* If we're dealing with a renamable type, either source or dest must be
526 a renamed variable. */
527 if (is_gimple_reg_type (TREE_TYPE (t)))
528 return is_gimple_val (t);
530 return is_gimple_val (t) || is_gimple_lvalue (t);
533 /* Return true if T is a CALL_EXPR or an expression that can be
534 assigned to a temporary. Note that this predicate should only be
535 used during gimplification. See the rationale for this in
536 gimplify_modify_expr. */
539 is_gimple_reg_rhs_or_call (tree t)
541 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
542 || TREE_CODE (t) == CALL_EXPR);
545 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
546 this predicate should only be used during gimplification. See the
547 rationale for this in gimplify_modify_expr. */
550 is_gimple_mem_rhs_or_call (tree t)
552 /* If we're dealing with a renamable type, either source or dest must be
553 a renamed variable. */
554 if (is_gimple_reg_type (TREE_TYPE (t)))
555 return is_gimple_val (t);
557 return (is_gimple_val (t)
558 || is_gimple_lvalue (t)
559 || TREE_CLOBBER_P (t)
560 || TREE_CODE (t) == CALL_EXPR);
563 /* Create a temporary with a name derived from VAL. Subroutine of
564 lookup_tmp_var; nobody else should call this function. */
567 create_tmp_from_val (tree val)
569 /* Drop all qualifiers and address-space information from the value type. */
570 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
571 tree var = create_tmp_var (type, get_name (val));
575 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
576 an existing expression temporary. If NOT_GIMPLE_REG, mark it as such. */
579 lookup_tmp_var (tree val, bool is_formal, bool not_gimple_reg)
583 /* We cannot mark a formal temporary with DECL_NOT_GIMPLE_REG_P. */
584 gcc_assert (!is_formal || !not_gimple_reg);
586 /* If not optimizing, never really reuse a temporary. local-alloc
587 won't allocate any variable that is used in more than one basic
588 block, which means it will go into memory, causing much extra
589 work in reload and final and poorer code generation, outweighing
590 the extra memory allocation here. */
591 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
593 ret = create_tmp_from_val (val);
594 DECL_NOT_GIMPLE_REG_P (ret) = not_gimple_reg;
602 if (!gimplify_ctxp->temp_htab)
603 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
604 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
607 elt_p = XNEW (elt_t);
609 elt_p->temp = ret = create_tmp_from_val (val);
622 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
625 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
626 bool is_formal, bool allow_ssa, bool not_gimple_reg)
630 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
631 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
632 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
636 && gimplify_ctxp->into_ssa
637 && is_gimple_reg_type (TREE_TYPE (val)))
639 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
640 if (! gimple_in_ssa_p (cfun))
642 const char *name = get_name (val);
644 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
648 t = lookup_tmp_var (val, is_formal, not_gimple_reg);
650 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
652 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
654 /* gimplify_modify_expr might want to reduce this further. */
655 gimplify_and_add (mod, pre_p);
661 /* Return a formal temporary variable initialized with VAL. PRE_P is as
662 in gimplify_expr. Only use this function if:
664 1) The value of the unfactored expression represented by VAL will not
665 change between the initialization and use of the temporary, and
666 2) The temporary will not be otherwise modified.
668 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
669 and #2 means it is inappropriate for && temps.
671 For other cases, use get_initialized_tmp_var instead. */
674 get_formal_tmp_var (tree val, gimple_seq *pre_p)
676 return internal_get_tmp_var (val, pre_p, NULL, true, true, false);
679 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
680 are as in gimplify_expr. */
683 get_initialized_tmp_var (tree val, gimple_seq *pre_p,
684 gimple_seq *post_p /* = NULL */,
685 bool allow_ssa /* = true */)
687 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa, false);
690 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
691 generate debug info for them; otherwise don't. */
694 declare_vars (tree vars, gimple *gs, bool debug_info)
701 gbind *scope = as_a <gbind *> (gs);
703 temps = nreverse (last);
705 block = gimple_bind_block (scope);
706 gcc_assert (!block || TREE_CODE (block) == BLOCK);
707 if (!block || !debug_info)
709 DECL_CHAIN (last) = gimple_bind_vars (scope);
710 gimple_bind_set_vars (scope, temps);
714 /* We need to attach the nodes both to the BIND_EXPR and to its
715 associated BLOCK for debugging purposes. The key point here
716 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
717 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
718 if (BLOCK_VARS (block))
719 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
722 gimple_bind_set_vars (scope,
723 chainon (gimple_bind_vars (scope), temps));
724 BLOCK_VARS (block) = temps;
730 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
731 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
732 no such upper bound can be obtained. */
735 force_constant_size (tree var)
737 /* The only attempt we make is by querying the maximum size of objects
738 of the variable's type. */
740 HOST_WIDE_INT max_size;
742 gcc_assert (VAR_P (var));
744 max_size = max_int_size_in_bytes (TREE_TYPE (var));
746 gcc_assert (max_size >= 0);
749 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
751 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
754 /* Push the temporary variable TMP into the current binding. */
757 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
759 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
761 /* Later processing assumes that the object size is constant, which might
762 not be true at this point. Force the use of a constant upper bound in
764 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
765 force_constant_size (tmp);
767 DECL_CONTEXT (tmp) = fn->decl;
768 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
770 record_vars_into (tmp, fn->decl);
773 /* Push the temporary variable TMP into the current binding. */
776 gimple_add_tmp_var (tree tmp)
778 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
780 /* Later processing assumes that the object size is constant, which might
781 not be true at this point. Force the use of a constant upper bound in
783 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
784 force_constant_size (tmp);
786 DECL_CONTEXT (tmp) = current_function_decl;
787 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
791 DECL_CHAIN (tmp) = gimplify_ctxp->temps;
792 gimplify_ctxp->temps = tmp;
794 /* Mark temporaries local within the nearest enclosing parallel. */
795 if (gimplify_omp_ctxp)
797 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
798 int flag = GOVD_LOCAL | GOVD_SEEN;
800 && (ctx->region_type == ORT_WORKSHARE
801 || ctx->region_type == ORT_TASKGROUP
802 || ctx->region_type == ORT_SIMD
803 || ctx->region_type == ORT_ACC))
805 if (ctx->region_type == ORT_SIMD
806 && TREE_ADDRESSABLE (tmp)
807 && !TREE_STATIC (tmp))
809 if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
810 ctx->add_safelen1 = true;
811 else if (ctx->in_for_exprs)
814 flag = GOVD_PRIVATE | GOVD_SEEN;
817 ctx = ctx->outer_context;
820 omp_add_variable (ctx, tmp, flag);
829 /* This case is for nested functions. We need to expose the locals
831 body_seq = gimple_body (current_function_decl);
832 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
838 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
839 nodes that are referenced more than once in GENERIC functions. This is
840 necessary because gimplification (translation into GIMPLE) is performed
841 by modifying tree nodes in-place, so gimplication of a shared node in a
842 first context could generate an invalid GIMPLE form in a second context.
844 This is achieved with a simple mark/copy/unmark algorithm that walks the
845 GENERIC representation top-down, marks nodes with TREE_VISITED the first
846 time it encounters them, duplicates them if they already have TREE_VISITED
847 set, and finally removes the TREE_VISITED marks it has set.
849 The algorithm works only at the function level, i.e. it generates a GENERIC
850 representation of a function with no nodes shared within the function when
851 passed a GENERIC function (except for nodes that are allowed to be shared).
853 At the global level, it is also necessary to unshare tree nodes that are
854 referenced in more than one function, for the same aforementioned reason.
855 This requires some cooperation from the front-end. There are 2 strategies:
857 1. Manual unsharing. The front-end needs to call unshare_expr on every
858 expression that might end up being shared across functions.
860 2. Deep unsharing. This is an extension of regular unsharing. Instead
861 of calling unshare_expr on expressions that might be shared across
862 functions, the front-end pre-marks them with TREE_VISITED. This will
863 ensure that they are unshared on the first reference within functions
864 when the regular unsharing algorithm runs. The counterpart is that
865 this algorithm must look deeper than for manual unsharing, which is
866 specified by LANG_HOOKS_DEEP_UNSHARING.
868 If there are only few specific cases of node sharing across functions, it is
869 probably easier for a front-end to unshare the expressions manually. On the
870 contrary, if the expressions generated at the global level are as widespread
871 as expressions generated within functions, deep unsharing is very likely the
874 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
875 These nodes model computations that must be done once. If we were to
876 unshare something like SAVE_EXPR(i++), the gimplification process would
877 create wrong code. However, if DATA is non-null, it must hold a pointer
878 set that is used to unshare the subtrees of these nodes. */
881 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
884 enum tree_code code = TREE_CODE (t);
886 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
887 copy their subtrees if we can make sure to do it only once. */
888 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
890 if (data && !((hash_set<tree> *)data)->add (t))
896 /* Stop at types, decls, constants like copy_tree_r. */
897 else if (TREE_CODE_CLASS (code) == tcc_type
898 || TREE_CODE_CLASS (code) == tcc_declaration
899 || TREE_CODE_CLASS (code) == tcc_constant)
902 /* Cope with the statement expression extension. */
903 else if (code == STATEMENT_LIST)
906 /* Leave the bulk of the work to copy_tree_r itself. */
908 copy_tree_r (tp, walk_subtrees, NULL);
913 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
914 If *TP has been visited already, then *TP is deeply copied by calling
915 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
918 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
921 enum tree_code code = TREE_CODE (t);
923 /* Skip types, decls, and constants. But we do want to look at their
924 types and the bounds of types. Mark them as visited so we properly
925 unmark their subtrees on the unmark pass. If we've already seen them,
926 don't look down further. */
927 if (TREE_CODE_CLASS (code) == tcc_type
928 || TREE_CODE_CLASS (code) == tcc_declaration
929 || TREE_CODE_CLASS (code) == tcc_constant)
931 if (TREE_VISITED (t))
934 TREE_VISITED (t) = 1;
937 /* If this node has been visited already, unshare it and don't look
939 else if (TREE_VISITED (t))
941 walk_tree (tp, mostly_copy_tree_r, data, NULL);
945 /* Otherwise, mark the node as visited and keep looking. */
947 TREE_VISITED (t) = 1;
952 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
953 copy_if_shared_r callback unmodified. */
956 copy_if_shared (tree *tp, void *data)
958 walk_tree (tp, copy_if_shared_r, data, NULL);
961 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
962 any nested functions. */
965 unshare_body (tree fndecl)
967 struct cgraph_node *cgn = cgraph_node::get (fndecl);
968 /* If the language requires deep unsharing, we need a pointer set to make
969 sure we don't repeatedly unshare subtrees of unshareable nodes. */
970 hash_set<tree> *visited
971 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
973 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
974 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
975 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
980 for (cgn = first_nested_function (cgn); cgn;
981 cgn = next_nested_function (cgn))
982 unshare_body (cgn->decl);
985 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
986 Subtrees are walked until the first unvisited node is encountered. */
989 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
993 /* If this node has been visited, unmark it and keep looking. */
994 if (TREE_VISITED (t))
995 TREE_VISITED (t) = 0;
997 /* Otherwise, don't look any deeper. */
1004 /* Unmark the visited trees rooted at *TP. */
1007 unmark_visited (tree *tp)
1009 walk_tree (tp, unmark_visited_r, NULL, NULL);
1012 /* Likewise, but mark all trees as not visited. */
1015 unvisit_body (tree fndecl)
1017 struct cgraph_node *cgn = cgraph_node::get (fndecl);
1019 unmark_visited (&DECL_SAVED_TREE (fndecl));
1020 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
1021 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
1024 for (cgn = first_nested_function (cgn);
1025 cgn; cgn = next_nested_function (cgn))
1026 unvisit_body (cgn->decl);
1029 /* Unconditionally make an unshared copy of EXPR. This is used when using
1030 stored expressions which span multiple functions, such as BINFO_VTABLE,
1031 as the normal unsharing process can't tell that they're shared. */
1034 unshare_expr (tree expr)
1036 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1040 /* Worker for unshare_expr_without_location. */
1043 prune_expr_location (tree *tp, int *walk_subtrees, void *)
1046 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
1052 /* Similar to unshare_expr but also prune all expression locations
1056 unshare_expr_without_location (tree expr)
1058 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1060 walk_tree (&expr, prune_expr_location, NULL, NULL);
1064 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1065 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1066 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1067 EXPR is the location of the EXPR. */
1070 rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION)
1075 if (EXPR_HAS_LOCATION (expr))
1076 return EXPR_LOCATION (expr);
1078 if (TREE_CODE (expr) != STATEMENT_LIST)
1081 tree_stmt_iterator i = tsi_start (expr);
1084 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
1090 if (!found || !tsi_one_before_end_p (i))
1093 return rexpr_location (tsi_stmt (i), or_else);
1096 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1097 rexpr_location for the potential recursion. */
1100 rexpr_has_location (tree expr)
1102 return rexpr_location (expr) != UNKNOWN_LOCATION;
1106 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1107 contain statements and have a value. Assign its value to a temporary
1108 and give it void_type_node. Return the temporary, or NULL_TREE if
1109 WRAPPER was already void. */
1112 voidify_wrapper_expr (tree wrapper, tree temp)
1114 tree type = TREE_TYPE (wrapper);
1115 if (type && !VOID_TYPE_P (type))
1119 /* Set p to point to the body of the wrapper. Loop until we find
1120 something that isn't a wrapper. */
1121 for (p = &wrapper; p && *p; )
1123 switch (TREE_CODE (*p))
1126 TREE_SIDE_EFFECTS (*p) = 1;
1127 TREE_TYPE (*p) = void_type_node;
1128 /* For a BIND_EXPR, the body is operand 1. */
1129 p = &BIND_EXPR_BODY (*p);
1132 case CLEANUP_POINT_EXPR:
1133 case TRY_FINALLY_EXPR:
1134 case TRY_CATCH_EXPR:
1135 TREE_SIDE_EFFECTS (*p) = 1;
1136 TREE_TYPE (*p) = void_type_node;
1137 p = &TREE_OPERAND (*p, 0);
1140 case STATEMENT_LIST:
1142 tree_stmt_iterator i = tsi_last (*p);
1143 TREE_SIDE_EFFECTS (*p) = 1;
1144 TREE_TYPE (*p) = void_type_node;
1145 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1150 /* Advance to the last statement. Set all container types to
1152 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1154 TREE_SIDE_EFFECTS (*p) = 1;
1155 TREE_TYPE (*p) = void_type_node;
1159 case TRANSACTION_EXPR:
1160 TREE_SIDE_EFFECTS (*p) = 1;
1161 TREE_TYPE (*p) = void_type_node;
1162 p = &TRANSACTION_EXPR_BODY (*p);
1166 /* Assume that any tree upon which voidify_wrapper_expr is
1167 directly called is a wrapper, and that its body is op0. */
1170 TREE_SIDE_EFFECTS (*p) = 1;
1171 TREE_TYPE (*p) = void_type_node;
1172 p = &TREE_OPERAND (*p, 0);
1180 if (p == NULL || IS_EMPTY_STMT (*p))
1184 /* The wrapper is on the RHS of an assignment that we're pushing
1186 gcc_assert (TREE_CODE (temp) == INIT_EXPR
1187 || TREE_CODE (temp) == MODIFY_EXPR);
1188 TREE_OPERAND (temp, 1) = *p;
1193 temp = create_tmp_var (type, "retval");
1194 *p = build2 (INIT_EXPR, type, temp, *p);
1203 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1204 a temporary through which they communicate. */
1207 build_stack_save_restore (gcall **save, gcall **restore)
1211 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1212 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1213 gimple_call_set_lhs (*save, tmp_var);
1216 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1220 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1223 build_asan_poison_call_expr (tree decl)
1225 /* Do not poison variables that have size equal to zero. */
1226 tree unit_size = DECL_SIZE_UNIT (decl);
1227 if (zerop (unit_size))
1230 tree base = build_fold_addr_expr (decl);
1232 return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
1234 build_int_cst (integer_type_node,
1239 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1240 on POISON flag, shadow memory of a DECL variable. The call will be
1241 put on location identified by IT iterator, where BEFORE flag drives
1242 position where the stmt will be put. */
1245 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
1248 tree unit_size = DECL_SIZE_UNIT (decl);
1249 tree base = build_fold_addr_expr (decl);
1251 /* Do not poison variables that have size equal to zero. */
1252 if (zerop (unit_size))
1255 /* It's necessary to have all stack variables aligned to ASAN granularity
1257 gcc_assert (!hwasan_sanitize_p () || hwasan_sanitize_stack_p ());
1258 unsigned shadow_granularity
1259 = hwasan_sanitize_p () ? HWASAN_TAG_GRANULE_SIZE : ASAN_SHADOW_GRANULARITY;
1260 if (DECL_ALIGN_UNIT (decl) <= shadow_granularity)
1261 SET_DECL_ALIGN (decl, BITS_PER_UNIT * shadow_granularity);
1263 HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
1266 = gimple_build_call_internal (IFN_ASAN_MARK, 3,
1267 build_int_cst (integer_type_node, flags),
1271 gsi_insert_before (it, g, GSI_NEW_STMT);
1273 gsi_insert_after (it, g, GSI_NEW_STMT);
1276 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1277 either poisons or unpoisons a DECL. Created statement is appended
1278 to SEQ_P gimple sequence. */
1281 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
1283 gimple_stmt_iterator it = gsi_last (*seq_p);
1284 bool before = false;
1289 asan_poison_variable (decl, poison, &it, before);
1292 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1295 sort_by_decl_uid (const void *a, const void *b)
1297 const tree *t1 = (const tree *)a;
1298 const tree *t2 = (const tree *)b;
1300 int uid1 = DECL_UID (*t1);
1301 int uid2 = DECL_UID (*t2);
1305 else if (uid1 > uid2)
1311 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1312 depending on POISON flag. Created statement is appended
1313 to SEQ_P gimple sequence. */
1316 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
1318 unsigned c = variables->elements ();
1322 auto_vec<tree> sorted_variables (c);
1324 for (hash_set<tree>::iterator it = variables->begin ();
1325 it != variables->end (); ++it)
1326 sorted_variables.safe_push (*it);
1328 sorted_variables.qsort (sort_by_decl_uid);
1332 FOR_EACH_VEC_ELT (sorted_variables, i, var)
1334 asan_poison_variable (var, poison, seq_p);
1336 /* Add use_after_scope_memory attribute for the variable in order
1337 to prevent re-written into SSA. */
1338 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
1339 DECL_ATTRIBUTES (var)))
1340 DECL_ATTRIBUTES (var)
1341 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
1343 DECL_ATTRIBUTES (var));
1347 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1349 static enum gimplify_status
1350 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1352 tree bind_expr = *expr_p;
1353 bool old_keep_stack = gimplify_ctxp->keep_stack;
1354 bool old_save_stack = gimplify_ctxp->save_stack;
1357 gimple_seq body, cleanup;
1359 location_t start_locus = 0, end_locus = 0;
1360 tree ret_clauses = NULL;
1362 tree temp = voidify_wrapper_expr (bind_expr, NULL);
1364 /* Mark variables seen in this bind expr. */
1365 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1369 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1371 /* Mark variable as local. */
1372 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t))
1374 if (! DECL_SEEN_IN_BIND_EXPR_P (t)
1375 || splay_tree_lookup (ctx->variables,
1376 (splay_tree_key) t) == NULL)
1378 int flag = GOVD_LOCAL;
1379 if (ctx->region_type == ORT_SIMD
1380 && TREE_ADDRESSABLE (t)
1381 && !TREE_STATIC (t))
1383 if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST)
1384 ctx->add_safelen1 = true;
1386 flag = GOVD_PRIVATE;
1388 omp_add_variable (ctx, t, flag | GOVD_SEEN);
1390 /* Static locals inside of target construct or offloaded
1391 routines need to be "omp declare target". */
1392 if (TREE_STATIC (t))
1393 for (; ctx; ctx = ctx->outer_context)
1394 if ((ctx->region_type & ORT_TARGET) != 0)
1396 if (!lookup_attribute ("omp declare target",
1397 DECL_ATTRIBUTES (t)))
1399 tree id = get_identifier ("omp declare target");
1401 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
1402 varpool_node *node = varpool_node::get (t);
1405 node->offloadable = 1;
1406 if (ENABLE_OFFLOADING && !DECL_EXTERNAL (t))
1408 g->have_offload = true;
1410 vec_safe_push (offload_vars, t);
1418 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1420 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1421 cfun->has_local_explicit_reg_vars = true;
1425 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1426 BIND_EXPR_BLOCK (bind_expr));
1427 gimple_push_bind_expr (bind_stmt);
1429 gimplify_ctxp->keep_stack = false;
1430 gimplify_ctxp->save_stack = false;
1432 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1434 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1435 gimple_bind_set_body (bind_stmt, body);
1437 /* Source location wise, the cleanup code (stack_restore and clobbers)
1438 belongs to the end of the block, so propagate what we have. The
1439 stack_save operation belongs to the beginning of block, which we can
1440 infer from the bind_expr directly if the block has no explicit
1442 if (BIND_EXPR_BLOCK (bind_expr))
1444 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1445 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1447 if (start_locus == 0)
1448 start_locus = EXPR_LOCATION (bind_expr);
1453 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1454 the stack space allocated to the VLAs. */
1455 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1457 gcall *stack_restore;
1459 /* Save stack on entry and restore it on exit. Add a try_finally
1460 block to achieve this. */
1461 build_stack_save_restore (&stack_save, &stack_restore);
1463 gimple_set_location (stack_save, start_locus);
1464 gimple_set_location (stack_restore, end_locus);
1466 gimplify_seq_add_stmt (&cleanup, stack_restore);
1469 /* Add clobbers for all variables that go out of scope. */
1470 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1473 && !is_global_var (t)
1474 && DECL_CONTEXT (t) == current_function_decl)
1476 if (!DECL_HARD_REGISTER (t)
1477 && !TREE_THIS_VOLATILE (t)
1478 && !DECL_HAS_VALUE_EXPR_P (t)
1479 /* Only care for variables that have to be in memory. Others
1480 will be rewritten into SSA names, hence moved to the
1482 && !is_gimple_reg (t)
1483 && flag_stack_reuse != SR_NONE)
1485 tree clobber = build_clobber (TREE_TYPE (t), CLOBBER_EOL);
1486 gimple *clobber_stmt;
1487 clobber_stmt = gimple_build_assign (t, clobber);
1488 gimple_set_location (clobber_stmt, end_locus);
1489 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1492 if (flag_openacc && oacc_declare_returns != NULL)
1495 if (DECL_HAS_VALUE_EXPR_P (key))
1497 key = DECL_VALUE_EXPR (key);
1498 if (TREE_CODE (key) == INDIRECT_REF)
1499 key = TREE_OPERAND (key, 0);
1501 tree *c = oacc_declare_returns->get (key);
1505 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1507 ret_clauses = unshare_expr (*c);
1509 oacc_declare_returns->remove (key);
1511 if (oacc_declare_returns->is_empty ())
1513 delete oacc_declare_returns;
1514 oacc_declare_returns = NULL;
1520 if (asan_poisoned_variables != NULL
1521 && asan_poisoned_variables->contains (t))
1523 asan_poisoned_variables->remove (t);
1524 asan_poison_variable (t, true, &cleanup);
1527 if (gimplify_ctxp->live_switch_vars != NULL
1528 && gimplify_ctxp->live_switch_vars->contains (t))
1529 gimplify_ctxp->live_switch_vars->remove (t);
1535 gimple_stmt_iterator si = gsi_start (cleanup);
1537 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1539 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1545 gimple_seq new_body;
1548 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1549 GIMPLE_TRY_FINALLY);
1552 gimplify_seq_add_stmt (&new_body, stack_save);
1553 gimplify_seq_add_stmt (&new_body, gs);
1554 gimple_bind_set_body (bind_stmt, new_body);
1557 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1558 if (!gimplify_ctxp->keep_stack)
1559 gimplify_ctxp->keep_stack = old_keep_stack;
1560 gimplify_ctxp->save_stack = old_save_stack;
1562 gimple_pop_bind_expr ();
1564 gimplify_seq_add_stmt (pre_p, bind_stmt);
1572 *expr_p = NULL_TREE;
1576 /* Maybe add early return predict statement to PRE_P sequence. */
1579 maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
1581 /* If we are not in a conditional context, add PREDICT statement. */
1582 if (gimple_conditional_context ())
1584 gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
1586 gimplify_seq_add_stmt (pre_p, predict);
1590 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1591 GIMPLE value, it is assigned to a new temporary and the statement is
1592 re-written to return the temporary.
1594 PRE_P points to the sequence where side effects that must happen before
1595 STMT should be stored. */
1597 static enum gimplify_status
1598 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1601 tree ret_expr = TREE_OPERAND (stmt, 0);
1602 tree result_decl, result;
1604 if (ret_expr == error_mark_node)
1608 || TREE_CODE (ret_expr) == RESULT_DECL)
1610 maybe_add_early_return_predict_stmt (pre_p);
1611 greturn *ret = gimple_build_return (ret_expr);
1612 copy_warning (ret, stmt);
1613 gimplify_seq_add_stmt (pre_p, ret);
1617 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1618 result_decl = NULL_TREE;
1619 else if (TREE_CODE (ret_expr) == COMPOUND_EXPR)
1621 /* Used in C++ for handling EH cleanup of the return value if a local
1622 cleanup throws. Assume the front-end knows what it's doing. */
1623 result_decl = DECL_RESULT (current_function_decl);
1624 /* But crash if we end up trying to modify ret_expr below. */
1625 ret_expr = NULL_TREE;
1629 result_decl = TREE_OPERAND (ret_expr, 0);
1631 /* See through a return by reference. */
1632 if (TREE_CODE (result_decl) == INDIRECT_REF)
1633 result_decl = TREE_OPERAND (result_decl, 0);
1635 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1636 || TREE_CODE (ret_expr) == INIT_EXPR)
1637 && TREE_CODE (result_decl) == RESULT_DECL);
1640 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1641 Recall that aggregate_value_p is FALSE for any aggregate type that is
1642 returned in registers. If we're returning values in registers, then
1643 we don't want to extend the lifetime of the RESULT_DECL, particularly
1644 across another call. In addition, for those aggregates for which
1645 hard_function_value generates a PARALLEL, we'll die during normal
1646 expansion of structure assignments; there's special code in expand_return
1647 to handle this case that does not exist in expand_expr. */
1650 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1652 if (!poly_int_tree_p (DECL_SIZE (result_decl)))
1654 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1655 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1656 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1657 should be effectively allocated by the caller, i.e. all calls to
1658 this function must be subject to the Return Slot Optimization. */
1659 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1660 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1662 result = result_decl;
1664 else if (gimplify_ctxp->return_temp)
1665 result = gimplify_ctxp->return_temp;
1668 result = create_tmp_reg (TREE_TYPE (result_decl));
1670 /* ??? With complex control flow (usually involving abnormal edges),
1671 we can wind up warning about an uninitialized value for this. Due
1672 to how this variable is constructed and initialized, this is never
1673 true. Give up and never warn. */
1674 suppress_warning (result, OPT_Wuninitialized);
1676 gimplify_ctxp->return_temp = result;
1679 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1680 Then gimplify the whole thing. */
1681 if (result != result_decl)
1682 TREE_OPERAND (ret_expr, 0) = result;
1684 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1686 maybe_add_early_return_predict_stmt (pre_p);
1687 ret = gimple_build_return (result);
1688 copy_warning (ret, stmt);
1689 gimplify_seq_add_stmt (pre_p, ret);
1694 /* Gimplify a variable-length array DECL. */
1697 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1699 /* This is a variable-sized decl. Simplify its size and mark it
1700 for deferred expansion. */
1701 tree t, addr, ptr_type;
1703 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1704 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1706 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1707 if (DECL_HAS_VALUE_EXPR_P (decl))
1710 /* All occurrences of this decl in final gimplified code will be
1711 replaced by indirection. Setting DECL_VALUE_EXPR does two
1712 things: First, it lets the rest of the gimplifier know what
1713 replacement to use. Second, it lets the debug info know
1714 where to find the value. */
1715 ptr_type = build_pointer_type (TREE_TYPE (decl));
1716 addr = create_tmp_var (ptr_type, get_name (decl));
1717 DECL_IGNORED_P (addr) = 0;
1718 t = build_fold_indirect_ref (addr);
1719 TREE_THIS_NOTRAP (t) = 1;
1720 SET_DECL_VALUE_EXPR (decl, t);
1721 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1723 t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
1724 max_int_size_in_bytes (TREE_TYPE (decl)));
1725 /* The call has been built for a variable-sized object. */
1726 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1727 t = fold_convert (ptr_type, t);
1728 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1730 gimplify_and_add (t, seq_p);
1732 /* Record the dynamic allocation associated with DECL if requested. */
1733 if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)
1734 record_dynamic_alloc (decl);
1737 /* A helper function to be called via walk_tree. Mark all labels under *TP
1738 as being forced. To be called for DECL_INITIAL of static variables. */
1741 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1745 if (TREE_CODE (*tp) == LABEL_DECL)
1747 FORCED_LABEL (*tp) = 1;
1748 cfun->has_forced_label_in_static = 1;
1754 /* Generate an initialization to automatic variable DECL based on INIT_TYPE.
1755 Build a call to internal const function DEFERRED_INIT:
1756 1st argument: SIZE of the DECL;
1757 2nd argument: INIT_TYPE;
1758 3rd argument: NAME of the DECL;
1760 as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, NAME of the DECL). */
1763 gimple_add_init_for_auto_var (tree decl,
1764 enum auto_init_type init_type,
1767 gcc_assert (auto_var_p (decl));
1768 gcc_assert (init_type > AUTO_INIT_UNINITIALIZED);
1769 location_t loc = EXPR_LOCATION (decl);
1770 tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl));
1773 = build_int_cst (integer_type_node, (int) init_type);
1775 tree decl_name = NULL_TREE;
1776 if (DECL_NAME (decl))
1778 decl_name = build_string_literal (IDENTIFIER_LENGTH (DECL_NAME (decl)) + 1,
1779 IDENTIFIER_POINTER (DECL_NAME (decl)));
1783 char *decl_name_anonymous = xasprintf ("D.%u", DECL_UID (decl));
1784 decl_name = build_string_literal (strlen (decl_name_anonymous) + 1,
1785 decl_name_anonymous);
1786 free (decl_name_anonymous);
1789 tree call = build_call_expr_internal_loc (loc, IFN_DEFERRED_INIT,
1790 TREE_TYPE (decl), 3,
1791 decl_size, init_type_node,
1794 gimplify_assign (decl, call, seq_p);
1797 /* Generate padding initialization for automatic vairable DECL.
1798 C guarantees that brace-init with fewer initializers than members
1799 aggregate will initialize the rest of the aggregate as-if it were
1800 static initialization. In turn static initialization guarantees
1801 that padding is initialized to zero. So, we always initialize paddings
1802 to zeroes regardless INIT_TYPE.
1803 To do the padding initialization, we insert a call to
1804 __builtin_clear_padding (&decl, 0, for_auto_init = true).
1805 Note, we add an additional dummy argument for __builtin_clear_padding,
1806 'for_auto_init' to distinguish whether this call is for automatic
1807 variable initialization or not.
1810 gimple_add_padding_init_for_auto_var (tree decl, bool is_vla,
1813 tree addr_of_decl = NULL_TREE;
1814 tree fn = builtin_decl_explicit (BUILT_IN_CLEAR_PADDING);
1818 /* The temporary address variable for this vla should be
1819 created in gimplify_vla_decl. */
1820 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
1821 gcc_assert (TREE_CODE (DECL_VALUE_EXPR (decl)) == INDIRECT_REF);
1822 addr_of_decl = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
1826 mark_addressable (decl);
1827 addr_of_decl = build_fold_addr_expr (decl);
1830 gimple *call = gimple_build_call (fn, 2, addr_of_decl,
1831 build_one_cst (TREE_TYPE (addr_of_decl)));
1832 gimplify_seq_add_stmt (seq_p, call);
1835 /* Return true if the DECL need to be automaticly initialized by the
1838 is_var_need_auto_init (tree decl)
1840 if (auto_var_p (decl)
1841 && (TREE_CODE (decl) != VAR_DECL
1842 || !DECL_HARD_REGISTER (decl))
1843 && (flag_auto_var_init > AUTO_INIT_UNINITIALIZED)
1844 && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl)))
1845 && !OPAQUE_TYPE_P (TREE_TYPE (decl))
1846 && !is_empty_type (TREE_TYPE (decl)))
1851 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1852 and initialization explicit. */
1854 static enum gimplify_status
1855 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1857 tree stmt = *stmt_p;
1858 tree decl = DECL_EXPR_DECL (stmt);
1860 *stmt_p = NULL_TREE;
1862 if (TREE_TYPE (decl) == error_mark_node)
1865 if ((TREE_CODE (decl) == TYPE_DECL
1867 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1869 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1870 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1871 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1874 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1875 in case its size expressions contain problematic nodes like CALL_EXPR. */
1876 if (TREE_CODE (decl) == TYPE_DECL
1877 && DECL_ORIGINAL_TYPE (decl)
1878 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1880 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1881 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1882 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1885 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1887 tree init = DECL_INITIAL (decl);
1888 bool is_vla = false;
1889 /* Check whether a decl has FE created VALUE_EXPR here BEFORE
1890 gimplify_vla_decl creates VALUE_EXPR for a vla decl.
1891 If the decl has VALUE_EXPR that was created by FE (usually
1892 C++FE), it's a proxy varaible, and FE already initialized
1893 the VALUE_EXPR of it, we should not initialize it anymore. */
1894 bool decl_had_value_expr_p = DECL_HAS_VALUE_EXPR_P (decl);
1897 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
1898 || (!TREE_STATIC (decl)
1899 && flag_stack_check == GENERIC_STACK_CHECK
1901 (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
1903 gimplify_vla_decl (decl, seq_p);
1907 if (asan_poisoned_variables
1909 && TREE_ADDRESSABLE (decl)
1910 && !TREE_STATIC (decl)
1911 && !DECL_HAS_VALUE_EXPR_P (decl)
1912 && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
1913 && dbg_cnt (asan_use_after_scope)
1914 && !gimplify_omp_ctxp
1915 /* GNAT introduces temporaries to hold return values of calls in
1916 initializers of variables defined in other units, so the
1917 declaration of the variable is discarded completely. We do not
1918 want to issue poison calls for such dropped variables. */
1919 && (DECL_SEEN_IN_BIND_EXPR_P (decl)
1920 || (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)))
1922 asan_poisoned_variables->add (decl);
1923 asan_poison_variable (decl, false, seq_p);
1924 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
1925 gimplify_ctxp->live_switch_vars->add (decl);
1928 /* Some front ends do not explicitly declare all anonymous
1929 artificial variables. We compensate here by declaring the
1930 variables, though it would be better if the front ends would
1931 explicitly declare them. */
1932 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1933 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1934 gimple_add_tmp_var (decl);
1936 if (init && init != error_mark_node)
1938 if (!TREE_STATIC (decl))
1940 DECL_INITIAL (decl) = NULL_TREE;
1941 init = build2 (INIT_EXPR, void_type_node, decl, init);
1942 gimplify_and_add (init, seq_p);
1944 /* Clear TREE_READONLY if we really have an initialization. */
1945 if (!DECL_INITIAL (decl)
1946 && !omp_privatize_by_reference (decl))
1947 TREE_READONLY (decl) = 0;
1950 /* We must still examine initializers for static variables
1951 as they may contain a label address. */
1952 walk_tree (&init, force_labels_r, NULL, NULL);
1954 /* When there is no explicit initializer, if the user requested,
1955 We should insert an artifical initializer for this automatic
1957 else if (is_var_need_auto_init (decl)
1958 && !decl_had_value_expr_p)
1960 gimple_add_init_for_auto_var (decl,
1963 /* The expanding of a call to the above .DEFERRED_INIT will apply
1964 block initialization to the whole space covered by this variable.
1965 As a result, all the paddings will be initialized to zeroes
1966 for zero initialization and 0xFE byte-repeatable patterns for
1967 pattern initialization.
1968 In order to make the paddings as zeroes for pattern init, We
1969 should add a call to __builtin_clear_padding to clear the
1970 paddings to zero in compatiple with CLANG.
1971 We cannot insert this call if the variable is a gimple register
1972 since __builtin_clear_padding will take the address of the
1973 variable. As a result, if a long double/_Complex long double
1974 variable will spilled into stack later, its padding is 0XFE. */
1975 if (flag_auto_var_init == AUTO_INIT_PATTERN
1976 && !is_gimple_reg (decl)
1977 && clear_padding_type_may_have_padding_p (TREE_TYPE (decl)))
1978 gimple_add_padding_init_for_auto_var (decl, is_vla, seq_p);
1985 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1986 and replacing the LOOP_EXPR with goto, but if the loop contains an
1987 EXIT_EXPR, we need to append a label for it to jump to. */
1989 static enum gimplify_status
1990 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1992 tree saved_label = gimplify_ctxp->exit_label;
1993 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1995 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1997 gimplify_ctxp->exit_label = NULL_TREE;
1999 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
2001 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
2003 if (gimplify_ctxp->exit_label)
2004 gimplify_seq_add_stmt (pre_p,
2005 gimple_build_label (gimplify_ctxp->exit_label));
2007 gimplify_ctxp->exit_label = saved_label;
2013 /* Gimplify a statement list onto a sequence. These may be created either
2014 by an enlightened front-end, or by shortcut_cond_expr. */
2016 static enum gimplify_status
2017 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
2019 tree temp = voidify_wrapper_expr (*expr_p, NULL);
2021 tree_stmt_iterator i = tsi_start (*expr_p);
2023 while (!tsi_end_p (i))
2025 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
2039 /* Emit warning for the unreachable statment STMT if needed.
2040 Return the gimple itself when the warning is emitted, otherwise
2043 emit_warn_switch_unreachable (gimple *stmt)
2045 if (gimple_code (stmt) == GIMPLE_GOTO
2046 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
2047 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
2048 /* Don't warn for compiler-generated gotos. These occur
2049 in Duff's devices, for example. */
2051 else if ((flag_auto_var_init > AUTO_INIT_UNINITIALIZED)
2052 && ((gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
2053 || (gimple_call_builtin_p (stmt, BUILT_IN_CLEAR_PADDING)
2054 && (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 1)))
2055 || (is_gimple_assign (stmt)
2056 && gimple_assign_single_p (stmt)
2057 && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
2058 && gimple_call_internal_p (
2059 SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt)),
2060 IFN_DEFERRED_INIT))))
2061 /* Don't warn for compiler-generated initializations for
2062 -ftrivial-auto-var-init.
2064 case 1: a call to .DEFERRED_INIT;
2065 case 2: a call to __builtin_clear_padding with the 2nd argument is
2066 present and non-zero;
2067 case 3: a gimple assign store right after the call to .DEFERRED_INIT
2068 that has the LHS of .DEFERRED_INIT as the RHS as following:
2069 _1 = .DEFERRED_INIT (4, 2, &"i1"[0]);
2073 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
2074 "statement will never be executed");
2078 /* Callback for walk_gimple_seq. */
2081 warn_switch_unreachable_and_auto_init_r (gimple_stmt_iterator *gsi_p,
2082 bool *handled_ops_p,
2083 struct walk_stmt_info *wi)
2085 gimple *stmt = gsi_stmt (*gsi_p);
2086 bool unreachable_issued = wi->info != NULL;
2088 *handled_ops_p = true;
2089 switch (gimple_code (stmt))
2092 /* A compiler-generated cleanup or a user-written try block.
2093 If it's empty, don't dive into it--that would result in
2094 worse location info. */
2095 if (gimple_try_eval (stmt) == NULL)
2097 if (warn_switch_unreachable && !unreachable_issued)
2098 wi->info = emit_warn_switch_unreachable (stmt);
2100 /* Stop when auto var init warning is not on. */
2101 if (!warn_trivial_auto_var_init)
2102 return integer_zero_node;
2107 case GIMPLE_EH_FILTER:
2108 case GIMPLE_TRANSACTION:
2109 /* Walk the sub-statements. */
2110 *handled_ops_p = false;
2114 /* Ignore these. We may generate them before declarations that
2115 are never executed. If there's something to warn about,
2116 there will be non-debug stmts too, and we'll catch those. */
2120 /* Stop till the first Label. */
2121 return integer_zero_node;
2123 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2125 *handled_ops_p = false;
2128 if (warn_trivial_auto_var_init
2129 && flag_auto_var_init > AUTO_INIT_UNINITIALIZED
2130 && gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
2132 /* Get the variable name from the 3rd argument of call. */
2133 tree var_name = gimple_call_arg (stmt, 2);
2134 var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0);
2135 const char *var_name_str = TREE_STRING_POINTER (var_name);
2137 warning_at (gimple_location (stmt), OPT_Wtrivial_auto_var_init,
2138 "%qs cannot be initialized with"
2139 "%<-ftrivial-auto-var_init%>",
2146 /* check the first "real" statement (not a decl/lexical scope/...), issue
2147 warning if needed. */
2148 if (warn_switch_unreachable && !unreachable_issued)
2149 wi->info = emit_warn_switch_unreachable (stmt);
2150 /* Stop when auto var init warning is not on. */
2151 if (!warn_trivial_auto_var_init)
2152 return integer_zero_node;
2159 /* Possibly warn about unreachable statements between switch's controlling
2160 expression and the first case. Also warn about -ftrivial-auto-var-init
2161 cannot initialize the auto variable under such situation.
2162 SEQ is the body of a switch expression. */
2165 maybe_warn_switch_unreachable_and_auto_init (gimple_seq seq)
2167 if ((!warn_switch_unreachable && !warn_trivial_auto_var_init)
2168 /* This warning doesn't play well with Fortran when optimizations
2170 || lang_GNU_Fortran ()
2174 struct walk_stmt_info wi;
2176 memset (&wi, 0, sizeof (wi));
2177 walk_gimple_seq (seq, warn_switch_unreachable_and_auto_init_r, NULL, &wi);
2181 /* A label entry that pairs label and a location. */
2188 /* Find LABEL in vector of label entries VEC. */
2190 static struct label_entry *
2191 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
2194 struct label_entry *l;
2196 FOR_EACH_VEC_ELT (*vec, i, l)
2197 if (l->label == label)
2202 /* Return true if LABEL, a LABEL_DECL, represents a case label
2203 in a vector of labels CASES. */
2206 case_label_p (const vec<tree> *cases, tree label)
2211 FOR_EACH_VEC_ELT (*cases, i, l)
2212 if (CASE_LABEL (l) == label)
2217 /* Find the last nondebug statement in a scope STMT. */
2220 last_stmt_in_scope (gimple *stmt)
2225 switch (gimple_code (stmt))
2229 gbind *bind = as_a <gbind *> (stmt);
2230 stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
2231 return last_stmt_in_scope (stmt);
2236 gtry *try_stmt = as_a <gtry *> (stmt);
2237 stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
2238 gimple *last_eval = last_stmt_in_scope (stmt);
2239 if (gimple_stmt_may_fallthru (last_eval)
2240 && (last_eval == NULL
2241 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
2242 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
2244 stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
2245 return last_stmt_in_scope (stmt);
2259 /* Collect labels that may fall through into LABELS and return the statement
2260 preceding another case label, or a user-defined label. Store a location
2261 useful to give warnings at *PREVLOC (usually the location of the returned
2262 statement or of its surrounding scope). */
2265 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
2266 auto_vec <struct label_entry> *labels,
2267 location_t *prevloc)
2269 gimple *prev = NULL;
2271 *prevloc = UNKNOWN_LOCATION;
2274 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
2276 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2277 which starts on a GIMPLE_SWITCH and ends with a break label.
2278 Handle that as a single statement that can fall through. */
2279 gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
2280 gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
2281 gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
2283 && gimple_code (first) == GIMPLE_SWITCH
2284 && gimple_code (last) == GIMPLE_LABEL)
2286 tree label = gimple_label_label (as_a <glabel *> (last));
2287 if (SWITCH_BREAK_LABEL_P (label))
2295 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
2296 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
2298 /* Nested scope. Only look at the last statement of
2299 the innermost scope. */
2300 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
2301 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
2305 /* It might be a label without a location. Use the
2306 location of the scope then. */
2307 if (!gimple_has_location (prev))
2308 *prevloc = bind_loc;
2314 /* Ifs are tricky. */
2315 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
2317 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
2318 tree false_lab = gimple_cond_false_label (cond_stmt);
2319 location_t if_loc = gimple_location (cond_stmt);
2322 if (i > 1) goto <D.2259>; else goto D;
2323 we can't do much with the else-branch. */
2324 if (!DECL_ARTIFICIAL (false_lab))
2327 /* Go on until the false label, then one step back. */
2328 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
2330 gimple *stmt = gsi_stmt (*gsi_p);
2331 if (gimple_code (stmt) == GIMPLE_LABEL
2332 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
2336 /* Not found? Oops. */
2337 if (gsi_end_p (*gsi_p))
2340 /* A dead label can't fall through. */
2341 if (!UNUSED_LABEL_P (false_lab))
2343 struct label_entry l = { false_lab, if_loc };
2344 labels->safe_push (l);
2347 /* Go to the last statement of the then branch. */
2350 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2356 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2357 && !gimple_has_location (gsi_stmt (*gsi_p)))
2359 /* Look at the statement before, it might be
2360 attribute fallthrough, in which case don't warn. */
2362 bool fallthru_before_dest
2363 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2365 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2366 if (!fallthru_before_dest)
2368 struct label_entry l = { goto_dest, if_loc };
2369 labels->safe_push (l);
2372 /* This case is about
2373 if (1 != 0) goto <D.2022>; else goto <D.2023>;
2378 where #2 is UNUSED_LABEL_P and we want to warn about #1 falling
2379 through to #3. So set PREV to #1. */
2380 else if (UNUSED_LABEL_P (false_lab))
2381 prev = gsi_stmt (*gsi_p);
2383 /* And move back. */
2387 /* Remember the last statement. Skip labels that are of no interest
2389 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2391 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2392 if (find_label_entry (labels, label))
2393 prev = gsi_stmt (*gsi_p);
2395 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2397 else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
2399 else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2400 prev = gsi_stmt (*gsi_p);
2403 while (!gsi_end_p (*gsi_p)
2404 /* Stop if we find a case or a user-defined label. */
2405 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2406 || !gimple_has_location (gsi_stmt (*gsi_p))));
2408 if (prev && gimple_has_location (prev))
2409 *prevloc = gimple_location (prev);
2413 /* Return true if the switch fallthough warning should occur. LABEL is
2414 the label statement that we're falling through to. */
2417 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2419 gimple_stmt_iterator gsi = *gsi_p;
2421 /* Don't warn if the label is marked with a "falls through" comment. */
2422 if (FALLTHROUGH_LABEL_P (label))
2425 /* Don't warn for non-case labels followed by a statement:
2430 as these are likely intentional. */
2431 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2434 while (!gsi_end_p (gsi)
2435 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2436 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2437 && !case_label_p (&gimplify_ctxp->case_labels, l))
2438 gsi_next_nondebug (&gsi);
2439 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2443 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2444 immediately breaks. */
2447 /* Skip all immediately following labels. */
2448 while (!gsi_end_p (gsi)
2449 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2450 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2451 gsi_next_nondebug (&gsi);
2453 /* { ... something; default:; } */
2455 /* { ... something; default: break; } or
2456 { ... something; default: goto L; } */
2457 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2458 /* { ... something; default: return; } */
2459 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2465 /* Callback for walk_gimple_seq. */
2468 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2469 struct walk_stmt_info *)
2471 gimple *stmt = gsi_stmt (*gsi_p);
2473 *handled_ops_p = true;
2474 switch (gimple_code (stmt))
2479 case GIMPLE_EH_FILTER:
2480 case GIMPLE_TRANSACTION:
2481 /* Walk the sub-statements. */
2482 *handled_ops_p = false;
2485 /* Find a sequence of form:
2492 and possibly warn. */
2495 /* Found a label. Skip all immediately following labels. */
2496 while (!gsi_end_p (*gsi_p)
2497 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2498 gsi_next_nondebug (gsi_p);
2500 /* There might be no more statements. */
2501 if (gsi_end_p (*gsi_p))
2502 return integer_zero_node;
2504 /* Vector of labels that fall through. */
2505 auto_vec <struct label_entry> labels;
2507 gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
2509 /* There might be no more statements. */
2510 if (gsi_end_p (*gsi_p))
2511 return integer_zero_node;
2513 gimple *next = gsi_stmt (*gsi_p);
2515 /* If what follows is a label, then we may have a fallthrough. */
2516 if (gimple_code (next) == GIMPLE_LABEL
2517 && gimple_has_location (next)
2518 && (label = gimple_label_label (as_a <glabel *> (next)))
2521 struct label_entry *l;
2522 bool warned_p = false;
2523 auto_diagnostic_group d;
2524 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2526 else if (gimple_code (prev) == GIMPLE_LABEL
2527 && (label = gimple_label_label (as_a <glabel *> (prev)))
2528 && (l = find_label_entry (&labels, label)))
2529 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2530 "this statement may fall through");
2531 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2532 /* Try to be clever and don't warn when the statement
2533 can't actually fall through. */
2534 && gimple_stmt_may_fallthru (prev)
2535 && prevloc != UNKNOWN_LOCATION)
2536 warned_p = warning_at (prevloc,
2537 OPT_Wimplicit_fallthrough_,
2538 "this statement may fall through");
2540 inform (gimple_location (next), "here");
2542 /* Mark this label as processed so as to prevent multiple
2543 warnings in nested switches. */
2544 FALLTHROUGH_LABEL_P (label) = true;
2546 /* So that next warn_implicit_fallthrough_r will start looking for
2547 a new sequence starting with this label. */
2558 /* Warn when a switch case falls through. */
2561 maybe_warn_implicit_fallthrough (gimple_seq seq)
2563 if (!warn_implicit_fallthrough)
2566 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2569 || lang_GNU_OBJC ()))
2572 struct walk_stmt_info wi;
2573 memset (&wi, 0, sizeof (wi));
2574 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2577 /* Callback for walk_gimple_seq. */
2580 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2581 struct walk_stmt_info *wi)
2583 gimple *stmt = gsi_stmt (*gsi_p);
2585 *handled_ops_p = true;
2586 switch (gimple_code (stmt))
2591 case GIMPLE_EH_FILTER:
2592 case GIMPLE_TRANSACTION:
2593 /* Walk the sub-statements. */
2594 *handled_ops_p = false;
2597 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2599 gsi_remove (gsi_p, true);
2600 if (gsi_end_p (*gsi_p))
2602 *static_cast<location_t *>(wi->info) = gimple_location (stmt);
2603 return integer_zero_node;
2607 location_t loc = gimple_location (stmt);
2609 gimple_stmt_iterator gsi2 = *gsi_p;
2610 stmt = gsi_stmt (gsi2);
2611 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2613 /* Go on until the artificial label. */
2614 tree goto_dest = gimple_goto_dest (stmt);
2615 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2617 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2618 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2623 /* Not found? Stop. */
2624 if (gsi_end_p (gsi2))
2627 /* Look one past it. */
2631 /* We're looking for a case label or default label here. */
2632 while (!gsi_end_p (gsi2))
2634 stmt = gsi_stmt (gsi2);
2635 if (gimple_code (stmt) == GIMPLE_LABEL)
2637 tree label = gimple_label_label (as_a <glabel *> (stmt));
2638 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2644 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2646 else if (!is_gimple_debug (stmt))
2647 /* Anything else is not expected. */
2652 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2653 "a case label or default label");
2662 /* Expand all FALLTHROUGH () calls in SEQ. */
2665 expand_FALLTHROUGH (gimple_seq *seq_p)
2667 struct walk_stmt_info wi;
2669 memset (&wi, 0, sizeof (wi));
2670 wi.info = (void *) &loc;
2671 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2672 if (wi.callback_result == integer_zero_node)
2673 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2674 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2675 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2676 "a case label or default label");
2680 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2683 static enum gimplify_status
2684 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2686 tree switch_expr = *expr_p;
2687 gimple_seq switch_body_seq = NULL;
2688 enum gimplify_status ret;
2689 tree index_type = TREE_TYPE (switch_expr);
2690 if (index_type == NULL_TREE)
2691 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2693 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2695 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2698 if (SWITCH_BODY (switch_expr))
2701 vec<tree> saved_labels;
2702 hash_set<tree> *saved_live_switch_vars = NULL;
2703 tree default_case = NULL_TREE;
2704 gswitch *switch_stmt;
2706 /* Save old labels, get new ones from body, then restore the old
2707 labels. Save all the things from the switch body to append after. */
2708 saved_labels = gimplify_ctxp->case_labels;
2709 gimplify_ctxp->case_labels.create (8);
2711 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2712 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2713 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2714 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2715 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2717 gimplify_ctxp->live_switch_vars = NULL;
2719 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2720 gimplify_ctxp->in_switch_expr = true;
2722 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2724 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2725 maybe_warn_switch_unreachable_and_auto_init (switch_body_seq);
2726 maybe_warn_implicit_fallthrough (switch_body_seq);
2727 /* Only do this for the outermost GIMPLE_SWITCH. */
2728 if (!gimplify_ctxp->in_switch_expr)
2729 expand_FALLTHROUGH (&switch_body_seq);
2731 labels = gimplify_ctxp->case_labels;
2732 gimplify_ctxp->case_labels = saved_labels;
2734 if (gimplify_ctxp->live_switch_vars)
2736 gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
2737 delete gimplify_ctxp->live_switch_vars;
2739 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2741 preprocess_case_label_vec_for_gimple (labels, index_type,
2744 bool add_bind = false;
2747 glabel *new_default;
2750 = build_case_label (NULL_TREE, NULL_TREE,
2751 create_artificial_label (UNKNOWN_LOCATION));
2752 if (old_in_switch_expr)
2754 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2757 new_default = gimple_build_label (CASE_LABEL (default_case));
2758 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2760 else if (old_in_switch_expr)
2762 gimple *last = gimple_seq_last_stmt (switch_body_seq);
2763 if (last && gimple_code (last) == GIMPLE_LABEL)
2765 tree label = gimple_label_label (as_a <glabel *> (last));
2766 if (SWITCH_BREAK_LABEL_P (label))
2771 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2772 default_case, labels);
2773 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2774 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2775 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2776 so that we can easily find the start and end of the switch
2780 gimple_seq bind_body = NULL;
2781 gimplify_seq_add_stmt (&bind_body, switch_stmt);
2782 gimple_seq_add_seq (&bind_body, switch_body_seq);
2783 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
2784 gimple_set_location (bind, EXPR_LOCATION (switch_expr));
2785 gimplify_seq_add_stmt (pre_p, bind);
2789 gimplify_seq_add_stmt (pre_p, switch_stmt);
2790 gimplify_seq_add_seq (pre_p, switch_body_seq);
2800 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2802 static enum gimplify_status
2803 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2805 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2806 == current_function_decl);
2808 tree label = LABEL_EXPR_LABEL (*expr_p);
2809 glabel *label_stmt = gimple_build_label (label);
2810 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2811 gimplify_seq_add_stmt (pre_p, label_stmt);
2813 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2814 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2816 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2817 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2823 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2825 static enum gimplify_status
2826 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2828 struct gimplify_ctx *ctxp;
2831 /* Invalid programs can play Duff's Device type games with, for example,
2832 #pragma omp parallel. At least in the C front end, we don't
2833 detect such invalid branches until after gimplification, in the
2834 diagnose_omp_blocks pass. */
2835 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2836 if (ctxp->case_labels.exists ())
2839 tree label = CASE_LABEL (*expr_p);
2840 label_stmt = gimple_build_label (label);
2841 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2842 ctxp->case_labels.safe_push (*expr_p);
2843 gimplify_seq_add_stmt (pre_p, label_stmt);
2845 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2846 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2848 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2849 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2855 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2859 build_and_jump (tree *label_p)
2861 if (label_p == NULL)
2862 /* If there's nowhere to jump, just fall through. */
2865 if (*label_p == NULL_TREE)
2867 tree label = create_artificial_label (UNKNOWN_LOCATION);
2871 return build1 (GOTO_EXPR, void_type_node, *label_p);
2874 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2875 This also involves building a label to jump to and communicating it to
2876 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2878 static enum gimplify_status
2879 gimplify_exit_expr (tree *expr_p)
2881 tree cond = TREE_OPERAND (*expr_p, 0);
2884 expr = build_and_jump (&gimplify_ctxp->exit_label);
2885 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2891 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2892 different from its canonical type, wrap the whole thing inside a
2893 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2896 The canonical type of a COMPONENT_REF is the type of the field being
2897 referenced--unless the field is a bit-field which can be read directly
2898 in a smaller mode, in which case the canonical type is the
2899 sign-appropriate type corresponding to that mode. */
2902 canonicalize_component_ref (tree *expr_p)
2904 tree expr = *expr_p;
2907 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2909 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2910 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2912 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2914 /* One could argue that all the stuff below is not necessary for
2915 the non-bitfield case and declare it a FE error if type
2916 adjustment would be needed. */
2917 if (TREE_TYPE (expr) != type)
2919 #ifdef ENABLE_TYPES_CHECKING
2920 tree old_type = TREE_TYPE (expr);
2924 /* We need to preserve qualifiers and propagate them from
2926 type_quals = TYPE_QUALS (type)
2927 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2928 if (TYPE_QUALS (type) != type_quals)
2929 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2931 /* Set the type of the COMPONENT_REF to the underlying type. */
2932 TREE_TYPE (expr) = type;
2934 #ifdef ENABLE_TYPES_CHECKING
2935 /* It is now a FE error, if the conversion from the canonical
2936 type to the original expression type is not useless. */
2937 gcc_assert (useless_type_conversion_p (old_type, type));
2942 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2943 to foo, embed that change in the ADDR_EXPR by converting
2948 where L is the lower bound. For simplicity, only do this for constant
2950 The constraint is that the type of &array[L] is trivially convertible
2954 canonicalize_addr_expr (tree *expr_p)
2956 tree expr = *expr_p;
2957 tree addr_expr = TREE_OPERAND (expr, 0);
2958 tree datype, ddatype, pddatype;
2960 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2961 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2962 || TREE_CODE (addr_expr) != ADDR_EXPR)
2965 /* The addr_expr type should be a pointer to an array. */
2966 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2967 if (TREE_CODE (datype) != ARRAY_TYPE)
2970 /* The pointer to element type shall be trivially convertible to
2971 the expression pointer type. */
2972 ddatype = TREE_TYPE (datype);
2973 pddatype = build_pointer_type (ddatype);
2974 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2978 /* The lower bound and element sizes must be constant. */
2979 if (!TYPE_SIZE_UNIT (ddatype)
2980 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2981 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2982 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2985 /* All checks succeeded. Build a new node to merge the cast. */
2986 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2987 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2988 NULL_TREE, NULL_TREE);
2989 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2991 /* We can have stripped a required restrict qualifier above. */
2992 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2993 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2996 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2997 underneath as appropriate. */
2999 static enum gimplify_status
3000 gimplify_conversion (tree *expr_p)
3002 location_t loc = EXPR_LOCATION (*expr_p);
3003 gcc_assert (CONVERT_EXPR_P (*expr_p));
3005 /* Then strip away all but the outermost conversion. */
3006 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
3008 /* And remove the outermost conversion if it's useless. */
3009 if (tree_ssa_useless_type_conversion (*expr_p))
3010 *expr_p = TREE_OPERAND (*expr_p, 0);
3012 /* If we still have a conversion at the toplevel,
3013 then canonicalize some constructs. */
3014 if (CONVERT_EXPR_P (*expr_p))
3016 tree sub = TREE_OPERAND (*expr_p, 0);
3018 /* If a NOP conversion is changing the type of a COMPONENT_REF
3019 expression, then canonicalize its type now in order to expose more
3020 redundant conversions. */
3021 if (TREE_CODE (sub) == COMPONENT_REF)
3022 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
3024 /* If a NOP conversion is changing a pointer to array of foo
3025 to a pointer to foo, embed that change in the ADDR_EXPR. */
3026 else if (TREE_CODE (sub) == ADDR_EXPR)
3027 canonicalize_addr_expr (expr_p);
3030 /* If we have a conversion to a non-register type force the
3031 use of a VIEW_CONVERT_EXPR instead. */
3032 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
3033 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
3034 TREE_OPERAND (*expr_p, 0));
3036 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
3037 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
3038 TREE_SET_CODE (*expr_p, NOP_EXPR);
3043 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
3044 DECL_VALUE_EXPR, and it's worth re-examining things. */
3046 static enum gimplify_status
3047 gimplify_var_or_parm_decl (tree *expr_p)
3049 tree decl = *expr_p;
3051 /* ??? If this is a local variable, and it has not been seen in any
3052 outer BIND_EXPR, then it's probably the result of a duplicate
3053 declaration, for which we've already issued an error. It would
3054 be really nice if the front end wouldn't leak these at all.
3055 Currently the only known culprit is C++ destructors, as seen
3056 in g++.old-deja/g++.jason/binding.C.
3057 Another possible culpit are size expressions for variably modified
3058 types which are lost in the FE or not gimplified correctly. */
3060 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
3061 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
3062 && decl_function_context (decl) == current_function_decl)
3064 gcc_assert (seen_error ());
3068 /* When within an OMP context, notice uses of variables. */
3069 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
3072 /* If the decl is an alias for another expression, substitute it now. */
3073 if (DECL_HAS_VALUE_EXPR_P (decl))
3075 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
3082 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
3085 recalculate_side_effects (tree t)
3087 enum tree_code code = TREE_CODE (t);
3088 int len = TREE_OPERAND_LENGTH (t);
3091 switch (TREE_CODE_CLASS (code))
3093 case tcc_expression:
3099 case PREDECREMENT_EXPR:
3100 case PREINCREMENT_EXPR:
3101 case POSTDECREMENT_EXPR:
3102 case POSTINCREMENT_EXPR:
3103 /* All of these have side-effects, no matter what their
3112 case tcc_comparison: /* a comparison expression */
3113 case tcc_unary: /* a unary arithmetic expression */
3114 case tcc_binary: /* a binary arithmetic expression */
3115 case tcc_reference: /* a reference */
3116 case tcc_vl_exp: /* a function call */
3117 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
3118 for (i = 0; i < len; ++i)
3120 tree op = TREE_OPERAND (t, i);
3121 if (op && TREE_SIDE_EFFECTS (op))
3122 TREE_SIDE_EFFECTS (t) = 1;
3127 /* No side-effects. */
3135 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
3139 : min_lval '[' val ']'
3141 | compound_lval '[' val ']'
3142 | compound_lval '.' ID
3144 This is not part of the original SIMPLE definition, which separates
3145 array and member references, but it seems reasonable to handle them
3146 together. Also, this way we don't run into problems with union
3147 aliasing; gcc requires that for accesses through a union to alias, the
3148 union reference must be explicit, which was not always the case when we
3149 were splitting up array and member refs.
3151 PRE_P points to the sequence where side effects that must happen before
3152 *EXPR_P should be stored.
3154 POST_P points to the sequence where side effects that must happen after
3155 *EXPR_P should be stored. */
3157 static enum gimplify_status
3158 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3159 fallback_t fallback)
3162 enum gimplify_status ret = GS_ALL_DONE, tret;
3164 location_t loc = EXPR_LOCATION (*expr_p);
3165 tree expr = *expr_p;
3167 /* Create a stack of the subexpressions so later we can walk them in
3168 order from inner to outer. */
3169 auto_vec<tree, 10> expr_stack;
3171 /* We can handle anything that get_inner_reference can deal with. */
3172 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
3175 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
3176 if (TREE_CODE (*p) == INDIRECT_REF)
3177 *p = fold_indirect_ref_loc (loc, *p);
3179 if (handled_component_p (*p))
3181 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
3182 additional COMPONENT_REFs. */
3183 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
3184 && gimplify_var_or_parm_decl (p) == GS_OK)
3189 expr_stack.safe_push (*p);
3192 gcc_assert (expr_stack.length ());
3194 /* Now EXPR_STACK is a stack of pointers to all the refs we've
3195 walked through and P points to the innermost expression.
3197 Java requires that we elaborated nodes in source order. That
3198 means we must gimplify the inner expression followed by each of
3199 the indices, in order. But we can't gimplify the inner
3200 expression until we deal with any variable bounds, sizes, or
3201 positions in order to deal with PLACEHOLDER_EXPRs.
3203 The base expression may contain a statement expression that
3204 has declarations used in size expressions, so has to be
3205 gimplified before gimplifying the size expressions.
3207 So we do this in three steps. First we deal with variable
3208 bounds, sizes, and positions, then we gimplify the base and
3209 ensure it is memory if needed, then we deal with the annotations
3210 for any variables in the components and any indices, from left
3213 bool need_non_reg = false;
3214 for (i = expr_stack.length () - 1; i >= 0; i--)
3216 tree t = expr_stack[i];
3218 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3220 /* Deal with the low bound and element type size and put them into
3221 the ARRAY_REF. If these values are set, they have already been
3223 if (TREE_OPERAND (t, 2) == NULL_TREE)
3225 tree low = unshare_expr (array_ref_low_bound (t));
3226 if (!is_gimple_min_invariant (low))
3228 TREE_OPERAND (t, 2) = low;
3232 if (TREE_OPERAND (t, 3) == NULL_TREE)
3234 tree elmt_size = array_ref_element_size (t);
3235 if (!is_gimple_min_invariant (elmt_size))
3237 elmt_size = unshare_expr (elmt_size);
3238 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
3239 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
3241 /* Divide the element size by the alignment of the element
3243 elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR,
3246 TREE_OPERAND (t, 3) = elmt_size;
3249 need_non_reg = true;
3251 else if (TREE_CODE (t) == COMPONENT_REF)
3253 /* Set the field offset into T and gimplify it. */
3254 if (TREE_OPERAND (t, 2) == NULL_TREE)
3256 tree offset = component_ref_field_offset (t);
3257 if (!is_gimple_min_invariant (offset))
3259 offset = unshare_expr (offset);
3260 tree field = TREE_OPERAND (t, 1);
3262 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
3264 /* Divide the offset by its alignment. */
3265 offset = size_binop_loc (loc, EXACT_DIV_EXPR,
3268 TREE_OPERAND (t, 2) = offset;
3271 need_non_reg = true;
3275 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3276 so as to match the min_lval predicate. Failure to do so may result
3277 in the creation of large aggregate temporaries. */
3278 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
3279 fallback | fb_lvalue);
3280 ret = MIN (ret, tret);
3282 /* Step 2a: if we have component references we do not support on
3283 registers then make sure the base isn't a register. Of course
3284 we can only do so if an rvalue is OK. */
3285 if (need_non_reg && (fallback & fb_rvalue))
3286 prepare_gimple_addressable (p, pre_p);
3288 /* Step 3: gimplify size expressions and the indices and operands of
3289 ARRAY_REF. During this loop we also remove any useless conversions. */
3291 for (; expr_stack.length () > 0; )
3293 tree t = expr_stack.pop ();
3295 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3297 /* Gimplify the low bound and element type size. */
3298 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3299 is_gimple_reg, fb_rvalue);
3300 ret = MIN (ret, tret);
3302 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
3303 is_gimple_reg, fb_rvalue);
3304 ret = MIN (ret, tret);
3306 /* Gimplify the dimension. */
3307 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
3308 is_gimple_val, fb_rvalue);
3309 ret = MIN (ret, tret);
3311 else if (TREE_CODE (t) == COMPONENT_REF)
3313 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3314 is_gimple_reg, fb_rvalue);
3315 ret = MIN (ret, tret);
3318 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
3320 /* The innermost expression P may have originally had
3321 TREE_SIDE_EFFECTS set which would have caused all the outer
3322 expressions in *EXPR_P leading to P to also have had
3323 TREE_SIDE_EFFECTS set. */
3324 recalculate_side_effects (t);
3327 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3328 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
3330 canonicalize_component_ref (expr_p);
3333 expr_stack.release ();
3335 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
3340 /* Gimplify the self modifying expression pointed to by EXPR_P
3343 PRE_P points to the list where side effects that must happen before
3344 *EXPR_P should be stored.
3346 POST_P points to the list where side effects that must happen after
3347 *EXPR_P should be stored.
3349 WANT_VALUE is nonzero iff we want to use the value of this expression
3350 in another expression.
3352 ARITH_TYPE is the type the computation should be performed in. */
3354 enum gimplify_status
3355 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3356 bool want_value, tree arith_type)
3358 enum tree_code code;
3359 tree lhs, lvalue, rhs, t1;
3360 gimple_seq post = NULL, *orig_post_p = post_p;
3362 enum tree_code arith_code;
3363 enum gimplify_status ret;
3364 location_t loc = EXPR_LOCATION (*expr_p);
3366 code = TREE_CODE (*expr_p);
3368 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3369 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3371 /* Prefix or postfix? */
3372 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3373 /* Faster to treat as prefix if result is not used. */
3374 postfix = want_value;
3378 /* For postfix, make sure the inner expression's post side effects
3379 are executed after side effects from this expression. */
3383 /* Add or subtract? */
3384 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3385 arith_code = PLUS_EXPR;
3387 arith_code = MINUS_EXPR;
3389 /* Gimplify the LHS into a GIMPLE lvalue. */
3390 lvalue = TREE_OPERAND (*expr_p, 0);
3391 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3392 if (ret == GS_ERROR)
3395 /* Extract the operands to the arithmetic operation. */
3397 rhs = TREE_OPERAND (*expr_p, 1);
3399 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3400 that as the result value and in the postqueue operation. */
3403 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3404 if (ret == GS_ERROR)
3407 lhs = get_initialized_tmp_var (lhs, pre_p);
3410 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3411 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3413 rhs = convert_to_ptrofftype_loc (loc, rhs);
3414 if (arith_code == MINUS_EXPR)
3415 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3416 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3419 t1 = fold_convert (TREE_TYPE (*expr_p),
3420 fold_build2 (arith_code, arith_type,
3421 fold_convert (arith_type, lhs),
3422 fold_convert (arith_type, rhs)));
3426 gimplify_assign (lvalue, t1, pre_p);
3427 gimplify_seq_add_seq (orig_post_p, post);
3433 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3438 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3441 maybe_with_size_expr (tree *expr_p)
3443 tree expr = *expr_p;
3444 tree type = TREE_TYPE (expr);
3447 /* If we've already wrapped this or the type is error_mark_node, we can't do
3449 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3450 || type == error_mark_node)
3453 /* If the size isn't known or is a constant, we have nothing to do. */
3454 size = TYPE_SIZE_UNIT (type);
3455 if (!size || poly_int_tree_p (size))
3458 /* Otherwise, make a WITH_SIZE_EXPR. */
3459 size = unshare_expr (size);
3460 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3461 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3464 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3465 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3466 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3467 gimplified to an SSA name. */
3469 enum gimplify_status
3470 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3473 bool (*test) (tree);
3476 /* In general, we allow lvalues for function arguments to avoid
3477 extra overhead of copying large aggregates out of even larger
3478 aggregates into temporaries only to copy the temporaries to
3479 the argument list. Make optimizers happy by pulling out to
3480 temporaries those types that fit in registers. */
3481 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3482 test = is_gimple_val, fb = fb_rvalue;
3485 test = is_gimple_lvalue, fb = fb_either;
3486 /* Also strip a TARGET_EXPR that would force an extra copy. */
3487 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3489 tree init = TARGET_EXPR_INITIAL (*arg_p);
3491 && !VOID_TYPE_P (TREE_TYPE (init)))
3496 /* If this is a variable sized type, we must remember the size. */
3497 maybe_with_size_expr (arg_p);
3499 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3500 /* Make sure arguments have the same location as the function call
3502 protected_set_expr_location (*arg_p, call_location);
3504 /* There is a sequence point before a function call. Side effects in
3505 the argument list must occur before the actual call. So, when
3506 gimplifying arguments, force gimplify_expr to use an internal
3507 post queue which is then appended to the end of PRE_P. */
3508 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3511 /* Don't fold inside offloading or taskreg regions: it can break code by
3512 adding decl references that weren't in the source. We'll do it during
3513 omplower pass instead. */
3516 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3518 struct gimplify_omp_ctx *ctx;
3519 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3520 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3522 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3524 /* Delay folding of builtins until the IL is in consistent state
3525 so the diagnostic machinery can do a better job. */
3526 if (gimple_call_builtin_p (gsi_stmt (*gsi)))
3528 return fold_stmt (gsi);
3531 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3532 WANT_VALUE is true if the result of the call is desired. */
3534 static enum gimplify_status
3535 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3537 tree fndecl, parms, p, fnptrtype;
3538 enum gimplify_status ret;
3541 bool builtin_va_start_p = false;
3542 location_t loc = EXPR_LOCATION (*expr_p);
3544 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3546 /* For reliable diagnostics during inlining, it is necessary that
3547 every call_expr be annotated with file and line. */
3548 if (! EXPR_HAS_LOCATION (*expr_p))
3549 SET_EXPR_LOCATION (*expr_p, input_location);
3551 /* Gimplify internal functions created in the FEs. */
3552 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3557 nargs = call_expr_nargs (*expr_p);
3558 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3559 auto_vec<tree> vargs (nargs);
3561 for (i = 0; i < nargs; i++)
3563 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3564 EXPR_LOCATION (*expr_p));
3565 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3568 gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3569 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3570 gimplify_seq_add_stmt (pre_p, call);
3574 /* This may be a call to a builtin function.
3576 Builtin function calls may be transformed into different
3577 (and more efficient) builtin function calls under certain
3578 circumstances. Unfortunately, gimplification can muck things
3579 up enough that the builtin expanders are not aware that certain
3580 transformations are still valid.
3582 So we attempt transformation/gimplification of the call before
3583 we gimplify the CALL_EXPR. At this time we do not manage to
3584 transform all calls in the same manner as the expanders do, but
3585 we do transform most of them. */
3586 fndecl = get_callee_fndecl (*expr_p);
3587 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3588 switch (DECL_FUNCTION_CODE (fndecl))
3590 CASE_BUILT_IN_ALLOCA:
3591 /* If the call has been built for a variable-sized object, then we
3592 want to restore the stack level when the enclosing BIND_EXPR is
3593 exited to reclaim the allocated space; otherwise, we precisely
3594 need to do the opposite and preserve the latest stack level. */
3595 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3596 gimplify_ctxp->save_stack = true;
3598 gimplify_ctxp->keep_stack = true;
3601 case BUILT_IN_VA_START:
3603 builtin_va_start_p = TRUE;
3604 if (call_expr_nargs (*expr_p) < 2)
3606 error ("too few arguments to function %<va_start%>");
3607 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3611 if (fold_builtin_next_arg (*expr_p, true))
3613 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3619 case BUILT_IN_EH_RETURN:
3620 cfun->calls_eh_return = true;
3623 case BUILT_IN_CLEAR_PADDING:
3624 if (call_expr_nargs (*expr_p) == 1)
3626 /* Remember the original type of the argument in an internal
3627 dummy second argument, as in GIMPLE pointer conversions are
3628 useless. Also mark this call as not for automatic
3629 initialization in the internal dummy third argument. */
3630 p = CALL_EXPR_ARG (*expr_p, 0);
3632 = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p,
3633 build_zero_cst (TREE_TYPE (p)));
3641 if (fndecl && fndecl_built_in_p (fndecl))
3643 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3644 if (new_tree && new_tree != *expr_p)
3646 /* There was a transformation of this call which computes the
3647 same value, but in a more efficient way. Return and try
3654 /* Remember the original function pointer type. */
3655 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3660 && (cfun->curr_properties & PROP_gimple_any) == 0)
3662 tree variant = omp_resolve_declare_variant (fndecl);
3663 if (variant != fndecl)
3664 CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
3667 /* There is a sequence point before the call, so any side effects in
3668 the calling expression must occur before the actual call. Force
3669 gimplify_expr to use an internal post queue. */
3670 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3671 is_gimple_call_addr, fb_rvalue);
3673 nargs = call_expr_nargs (*expr_p);
3675 /* Get argument types for verification. */
3676 fndecl = get_callee_fndecl (*expr_p);
3679 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3681 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3683 if (fndecl && DECL_ARGUMENTS (fndecl))
3684 p = DECL_ARGUMENTS (fndecl);
3689 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3692 /* If the last argument is __builtin_va_arg_pack () and it is not
3693 passed as a named argument, decrease the number of CALL_EXPR
3694 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3697 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3699 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3700 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3703 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3705 tree call = *expr_p;
3708 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3709 CALL_EXPR_FN (call),
3710 nargs, CALL_EXPR_ARGP (call));
3712 /* Copy all CALL_EXPR flags, location and block, except
3713 CALL_EXPR_VA_ARG_PACK flag. */
3714 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3715 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3716 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3717 = CALL_EXPR_RETURN_SLOT_OPT (call);
3718 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3719 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3721 /* Set CALL_EXPR_VA_ARG_PACK. */
3722 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3726 /* If the call returns twice then after building the CFG the call
3727 argument computations will no longer dominate the call because
3728 we add an abnormal incoming edge to the call. So do not use SSA
3730 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3732 /* Gimplify the function arguments. */
3735 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3736 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3737 PUSH_ARGS_REVERSED ? i-- : i++)
3739 enum gimplify_status t;
3741 /* Avoid gimplifying the second argument to va_start, which needs to
3742 be the plain PARM_DECL. */
3743 if ((i != 1) || !builtin_va_start_p)
3745 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3746 EXPR_LOCATION (*expr_p), ! returns_twice);
3754 /* Gimplify the static chain. */
3755 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3757 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3758 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3761 enum gimplify_status t;
3762 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3763 EXPR_LOCATION (*expr_p), ! returns_twice);
3769 /* Verify the function result. */
3770 if (want_value && fndecl
3771 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3773 error_at (loc, "using result of function returning %<void%>");
3777 /* Try this again in case gimplification exposed something. */
3778 if (ret != GS_ERROR)
3780 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3782 if (new_tree && new_tree != *expr_p)
3784 /* There was a transformation of this call which computes the
3785 same value, but in a more efficient way. Return and try
3793 *expr_p = error_mark_node;
3797 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3798 decl. This allows us to eliminate redundant or useless
3799 calls to "const" functions. */
3800 if (TREE_CODE (*expr_p) == CALL_EXPR)
3802 int flags = call_expr_flags (*expr_p);
3803 if (flags & (ECF_CONST | ECF_PURE)
3804 /* An infinite loop is considered a side effect. */
3805 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3806 TREE_SIDE_EFFECTS (*expr_p) = 0;
3809 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3810 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3811 form and delegate the creation of a GIMPLE_CALL to
3812 gimplify_modify_expr. This is always possible because when
3813 WANT_VALUE is true, the caller wants the result of this call into
3814 a temporary, which means that we will emit an INIT_EXPR in
3815 internal_get_tmp_var which will then be handled by
3816 gimplify_modify_expr. */
3819 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3820 have to do is replicate it as a GIMPLE_CALL tuple. */
3821 gimple_stmt_iterator gsi;
3822 call = gimple_build_call_from_tree (*expr_p, fnptrtype);
3823 notice_special_calls (call);
3824 gimplify_seq_add_stmt (pre_p, call);
3825 gsi = gsi_last (*pre_p);
3826 maybe_fold_stmt (&gsi);
3827 *expr_p = NULL_TREE;
3830 /* Remember the original function type. */
3831 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3832 CALL_EXPR_FN (*expr_p));
3837 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3838 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3840 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3841 condition is true or false, respectively. If null, we should generate
3842 our own to skip over the evaluation of this specific expression.
3844 LOCUS is the source location of the COND_EXPR.
3846 This function is the tree equivalent of do_jump.
3848 shortcut_cond_r should only be called by shortcut_cond_expr. */
3851 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3854 tree local_label = NULL_TREE;
3855 tree t, expr = NULL;
3857 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3858 retain the shortcut semantics. Just insert the gotos here;
3859 shortcut_cond_expr will append the real blocks later. */
3860 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3862 location_t new_locus;
3864 /* Turn if (a && b) into
3866 if (a); else goto no;
3867 if (b) goto yes; else goto no;
3870 if (false_label_p == NULL)
3871 false_label_p = &local_label;
3873 /* Keep the original source location on the first 'if'. */
3874 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3875 append_to_statement_list (t, &expr);
3877 /* Set the source location of the && on the second 'if'. */
3878 new_locus = rexpr_location (pred, locus);
3879 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3881 append_to_statement_list (t, &expr);
3883 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3885 location_t new_locus;
3887 /* Turn if (a || b) into
3890 if (b) goto yes; else goto no;
3893 if (true_label_p == NULL)
3894 true_label_p = &local_label;
3896 /* Keep the original source location on the first 'if'. */
3897 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3898 append_to_statement_list (t, &expr);
3900 /* Set the source location of the || on the second 'if'. */
3901 new_locus = rexpr_location (pred, locus);
3902 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3904 append_to_statement_list (t, &expr);
3906 else if (TREE_CODE (pred) == COND_EXPR
3907 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3908 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3910 location_t new_locus;
3912 /* As long as we're messing with gotos, turn if (a ? b : c) into
3914 if (b) goto yes; else goto no;
3916 if (c) goto yes; else goto no;
3918 Don't do this if one of the arms has void type, which can happen
3919 in C++ when the arm is throw. */
3921 /* Keep the original source location on the first 'if'. Set the source
3922 location of the ? on the second 'if'. */
3923 new_locus = rexpr_location (pred, locus);
3924 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3925 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3926 false_label_p, locus),
3927 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3928 false_label_p, new_locus));
3932 expr = build3 (COND_EXPR, void_type_node, pred,
3933 build_and_jump (true_label_p),
3934 build_and_jump (false_label_p));
3935 SET_EXPR_LOCATION (expr, locus);
3940 t = build1 (LABEL_EXPR, void_type_node, local_label);
3941 append_to_statement_list (t, &expr);
3947 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3948 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3949 statement, if it is the last one. Otherwise, return NULL. */
3952 find_goto (tree expr)
3957 if (TREE_CODE (expr) == GOTO_EXPR)
3960 if (TREE_CODE (expr) != STATEMENT_LIST)
3963 tree_stmt_iterator i = tsi_start (expr);
3965 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
3968 if (!tsi_one_before_end_p (i))
3971 return find_goto (tsi_stmt (i));
3974 /* Same as find_goto, except that it returns NULL if the destination
3975 is not a LABEL_DECL. */
3978 find_goto_label (tree expr)
3980 tree dest = find_goto (expr);
3981 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
3986 /* Given a conditional expression EXPR with short-circuit boolean
3987 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3988 predicate apart into the equivalent sequence of conditionals. */
3991 shortcut_cond_expr (tree expr)
3993 tree pred = TREE_OPERAND (expr, 0);
3994 tree then_ = TREE_OPERAND (expr, 1);
3995 tree else_ = TREE_OPERAND (expr, 2);
3996 tree true_label, false_label, end_label, t;
3998 tree *false_label_p;
3999 bool emit_end, emit_false, jump_over_else;
4000 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
4001 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
4003 /* First do simple transformations. */
4006 /* If there is no 'else', turn
4009 if (a) if (b) then c. */
4010 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
4012 /* Keep the original source location on the first 'if'. */
4013 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
4014 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
4015 /* Set the source location of the && on the second 'if'. */
4016 if (rexpr_has_location (pred))
4017 SET_EXPR_LOCATION (expr, rexpr_location (pred));
4018 then_ = shortcut_cond_expr (expr);
4019 then_se = then_ && TREE_SIDE_EFFECTS (then_);
4020 pred = TREE_OPERAND (pred, 0);
4021 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
4022 SET_EXPR_LOCATION (expr, locus);
4028 /* If there is no 'then', turn
4031 if (a); else if (b); else d. */
4032 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
4034 /* Keep the original source location on the first 'if'. */
4035 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
4036 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
4037 /* Set the source location of the || on the second 'if'. */
4038 if (rexpr_has_location (pred))
4039 SET_EXPR_LOCATION (expr, rexpr_location (pred));
4040 else_ = shortcut_cond_expr (expr);
4041 else_se = else_ && TREE_SIDE_EFFECTS (else_);
4042 pred = TREE_OPERAND (pred, 0);
4043 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
4044 SET_EXPR_LOCATION (expr, locus);
4048 /* If we're done, great. */
4049 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
4050 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
4053 /* Otherwise we need to mess with gotos. Change
4056 if (a); else goto no;
4059 and recursively gimplify the condition. */
4061 true_label = false_label = end_label = NULL_TREE;
4063 /* If our arms just jump somewhere, hijack those labels so we don't
4064 generate jumps to jumps. */
4066 if (tree then_goto = find_goto_label (then_))
4068 true_label = GOTO_DESTINATION (then_goto);
4073 if (tree else_goto = find_goto_label (else_))
4075 false_label = GOTO_DESTINATION (else_goto);
4080 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
4082 true_label_p = &true_label;
4084 true_label_p = NULL;
4086 /* The 'else' branch also needs a label if it contains interesting code. */
4087 if (false_label || else_se)
4088 false_label_p = &false_label;
4090 false_label_p = NULL;
4092 /* If there was nothing else in our arms, just forward the label(s). */
4093 if (!then_se && !else_se)
4094 return shortcut_cond_r (pred, true_label_p, false_label_p,
4095 EXPR_LOC_OR_LOC (expr, input_location));
4097 /* If our last subexpression already has a terminal label, reuse it. */
4099 t = expr_last (else_);
4101 t = expr_last (then_);
4104 if (t && TREE_CODE (t) == LABEL_EXPR)
4105 end_label = LABEL_EXPR_LABEL (t);
4107 /* If we don't care about jumping to the 'else' branch, jump to the end
4108 if the condition is false. */
4110 false_label_p = &end_label;
4112 /* We only want to emit these labels if we aren't hijacking them. */
4113 emit_end = (end_label == NULL_TREE);
4114 emit_false = (false_label == NULL_TREE);
4116 /* We only emit the jump over the else clause if we have to--if the
4117 then clause may fall through. Otherwise we can wind up with a
4118 useless jump and a useless label at the end of gimplified code,
4119 which will cause us to think that this conditional as a whole
4120 falls through even if it doesn't. If we then inline a function
4121 which ends with such a condition, that can cause us to issue an
4122 inappropriate warning about control reaching the end of a
4123 non-void function. */
4124 jump_over_else = block_may_fallthru (then_);
4126 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
4127 EXPR_LOC_OR_LOC (expr, input_location));
4130 append_to_statement_list (pred, &expr);
4132 append_to_statement_list (then_, &expr);
4137 tree last = expr_last (expr);
4138 t = build_and_jump (&end_label);
4139 if (rexpr_has_location (last))
4140 SET_EXPR_LOCATION (t, rexpr_location (last));
4141 append_to_statement_list (t, &expr);
4145 t = build1 (LABEL_EXPR, void_type_node, false_label);
4146 append_to_statement_list (t, &expr);
4148 append_to_statement_list (else_, &expr);
4150 if (emit_end && end_label)
4152 t = build1 (LABEL_EXPR, void_type_node, end_label);
4153 append_to_statement_list (t, &expr);
4159 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
4162 gimple_boolify (tree expr)
4164 tree type = TREE_TYPE (expr);
4165 location_t loc = EXPR_LOCATION (expr);
4167 if (TREE_CODE (expr) == NE_EXPR
4168 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
4169 && integer_zerop (TREE_OPERAND (expr, 1)))
4171 tree call = TREE_OPERAND (expr, 0);
4172 tree fn = get_callee_fndecl (call);
4174 /* For __builtin_expect ((long) (x), y) recurse into x as well
4175 if x is truth_value_p. */
4177 && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
4178 && call_expr_nargs (call) == 2)
4180 tree arg = CALL_EXPR_ARG (call, 0);
4183 if (TREE_CODE (arg) == NOP_EXPR
4184 && TREE_TYPE (arg) == TREE_TYPE (call))
4185 arg = TREE_OPERAND (arg, 0);
4186 if (truth_value_p (TREE_CODE (arg)))
4188 arg = gimple_boolify (arg);
4189 CALL_EXPR_ARG (call, 0)
4190 = fold_convert_loc (loc, TREE_TYPE (call), arg);
4196 switch (TREE_CODE (expr))
4198 case TRUTH_AND_EXPR:
4200 case TRUTH_XOR_EXPR:
4201 case TRUTH_ANDIF_EXPR:
4202 case TRUTH_ORIF_EXPR:
4203 /* Also boolify the arguments of truth exprs. */
4204 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
4207 case TRUTH_NOT_EXPR:
4208 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4210 /* These expressions always produce boolean results. */
4211 if (TREE_CODE (type) != BOOLEAN_TYPE)
4212 TREE_TYPE (expr) = boolean_type_node;
4216 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
4218 case annot_expr_ivdep_kind:
4219 case annot_expr_unroll_kind:
4220 case annot_expr_no_vector_kind:
4221 case annot_expr_vector_kind:
4222 case annot_expr_parallel_kind:
4223 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4224 if (TREE_CODE (type) != BOOLEAN_TYPE)
4225 TREE_TYPE (expr) = boolean_type_node;
4232 if (COMPARISON_CLASS_P (expr))
4234 /* There expressions always prduce boolean results. */
4235 if (TREE_CODE (type) != BOOLEAN_TYPE)
4236 TREE_TYPE (expr) = boolean_type_node;
4239 /* Other expressions that get here must have boolean values, but
4240 might need to be converted to the appropriate mode. */
4241 if (TREE_CODE (type) == BOOLEAN_TYPE)
4243 return fold_convert_loc (loc, boolean_type_node, expr);
4247 /* Given a conditional expression *EXPR_P without side effects, gimplify
4248 its operands. New statements are inserted to PRE_P. */
4250 static enum gimplify_status
4251 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
4253 tree expr = *expr_p, cond;
4254 enum gimplify_status ret, tret;
4255 enum tree_code code;
4257 cond = gimple_boolify (COND_EXPR_COND (expr));
4259 /* We need to handle && and || specially, as their gimplification
4260 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4261 code = TREE_CODE (cond);
4262 if (code == TRUTH_ANDIF_EXPR)
4263 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
4264 else if (code == TRUTH_ORIF_EXPR)
4265 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
4266 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_val, fb_rvalue);
4267 COND_EXPR_COND (*expr_p) = cond;
4269 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
4270 is_gimple_val, fb_rvalue);
4271 ret = MIN (ret, tret);
4272 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
4273 is_gimple_val, fb_rvalue);
4275 return MIN (ret, tret);
4278 /* Return true if evaluating EXPR could trap.
4279 EXPR is GENERIC, while tree_could_trap_p can be called
4283 generic_expr_could_trap_p (tree expr)
4287 if (!expr || is_gimple_val (expr))
4290 if (!EXPR_P (expr) || tree_could_trap_p (expr))
4293 n = TREE_OPERAND_LENGTH (expr);
4294 for (i = 0; i < n; i++)
4295 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
4301 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4310 The second form is used when *EXPR_P is of type void.
4312 PRE_P points to the list where side effects that must happen before
4313 *EXPR_P should be stored. */
4315 static enum gimplify_status
4316 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
4318 tree expr = *expr_p;
4319 tree type = TREE_TYPE (expr);
4320 location_t loc = EXPR_LOCATION (expr);
4321 tree tmp, arm1, arm2;
4322 enum gimplify_status ret;
4323 tree label_true, label_false, label_cont;
4324 bool have_then_clause_p, have_else_clause_p;
4326 enum tree_code pred_code;
4327 gimple_seq seq = NULL;
4329 /* If this COND_EXPR has a value, copy the values into a temporary within
4331 if (!VOID_TYPE_P (type))
4333 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
4336 /* If either an rvalue is ok or we do not require an lvalue, create the
4337 temporary. But we cannot do that if the type is addressable. */
4338 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
4339 && !TREE_ADDRESSABLE (type))
4341 if (gimplify_ctxp->allow_rhs_cond_expr
4342 /* If either branch has side effects or could trap, it can't be
4343 evaluated unconditionally. */
4344 && !TREE_SIDE_EFFECTS (then_)
4345 && !generic_expr_could_trap_p (then_)
4346 && !TREE_SIDE_EFFECTS (else_)
4347 && !generic_expr_could_trap_p (else_))
4348 return gimplify_pure_cond_expr (expr_p, pre_p);
4350 tmp = create_tmp_var (type, "iftmp");
4354 /* Otherwise, only create and copy references to the values. */
4357 type = build_pointer_type (type);
4359 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4360 then_ = build_fold_addr_expr_loc (loc, then_);
4362 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4363 else_ = build_fold_addr_expr_loc (loc, else_);
4366 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
4368 tmp = create_tmp_var (type, "iftmp");
4369 result = build_simple_mem_ref_loc (loc, tmp);
4372 /* Build the new then clause, `tmp = then_;'. But don't build the
4373 assignment if the value is void; in C++ it can be if it's a throw. */
4374 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4375 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
4377 /* Similarly, build the new else clause, `tmp = else_;'. */
4378 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4379 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
4381 TREE_TYPE (expr) = void_type_node;
4382 recalculate_side_effects (expr);
4384 /* Move the COND_EXPR to the prequeue. */
4385 gimplify_stmt (&expr, pre_p);
4391 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4392 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4393 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4394 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4396 /* Make sure the condition has BOOLEAN_TYPE. */
4397 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4399 /* Break apart && and || conditions. */
4400 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4401 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4403 expr = shortcut_cond_expr (expr);
4405 if (expr != *expr_p)
4409 /* We can't rely on gimplify_expr to re-gimplify the expanded
4410 form properly, as cleanups might cause the target labels to be
4411 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4412 set up a conditional context. */
4413 gimple_push_condition ();
4414 gimplify_stmt (expr_p, &seq);
4415 gimple_pop_condition (pre_p);
4416 gimple_seq_add_seq (pre_p, seq);
4422 /* Now do the normal gimplification. */
4424 /* Gimplify condition. */
4425 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
4426 is_gimple_condexpr_for_cond, fb_rvalue);
4427 if (ret == GS_ERROR)
4429 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4431 gimple_push_condition ();
4433 have_then_clause_p = have_else_clause_p = false;
4434 label_true = find_goto_label (TREE_OPERAND (expr, 1));
4436 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4437 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4438 have different locations, otherwise we end up with incorrect
4439 location information on the branches. */
4441 || !EXPR_HAS_LOCATION (expr)
4442 || !rexpr_has_location (label_true)
4443 || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4445 have_then_clause_p = true;
4446 label_true = GOTO_DESTINATION (label_true);
4449 label_true = create_artificial_label (UNKNOWN_LOCATION);
4450 label_false = find_goto_label (TREE_OPERAND (expr, 2));
4452 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4453 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4454 have different locations, otherwise we end up with incorrect
4455 location information on the branches. */
4457 || !EXPR_HAS_LOCATION (expr)
4458 || !rexpr_has_location (label_false)
4459 || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4461 have_else_clause_p = true;
4462 label_false = GOTO_DESTINATION (label_false);
4465 label_false = create_artificial_label (UNKNOWN_LOCATION);
4467 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4469 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4471 gimple_set_location (cond_stmt, EXPR_LOCATION (expr));
4472 copy_warning (cond_stmt, COND_EXPR_COND (expr));
4473 gimplify_seq_add_stmt (&seq, cond_stmt);
4474 gimple_stmt_iterator gsi = gsi_last (seq);
4475 maybe_fold_stmt (&gsi);
4477 label_cont = NULL_TREE;
4478 if (!have_then_clause_p)
4480 /* For if (...) {} else { code; } put label_true after
4482 if (TREE_OPERAND (expr, 1) == NULL_TREE
4483 && !have_else_clause_p
4484 && TREE_OPERAND (expr, 2) != NULL_TREE)
4486 /* For if (0) {} else { code; } tell -Wimplicit-fallthrough
4487 handling that label_cont == label_true can be only reached
4488 through fallthrough from { code; }. */
4489 if (integer_zerop (COND_EXPR_COND (expr)))
4490 UNUSED_LABEL_P (label_true) = 1;
4491 label_cont = label_true;
4495 bool then_side_effects
4496 = (TREE_OPERAND (expr, 1)
4497 && TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)));
4498 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4499 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4500 /* For if (...) { code; } else {} or
4501 if (...) { code; } else goto label; or
4502 if (...) { code; return; } else { ... }
4503 label_cont isn't needed. */
4504 if (!have_else_clause_p
4505 && TREE_OPERAND (expr, 2) != NULL_TREE
4506 && gimple_seq_may_fallthru (seq))
4509 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4511 /* For if (0) { non-side-effect-code } else { code }
4512 tell -Wimplicit-fallthrough handling that label_cont can
4513 be only reached through fallthrough from { code }. */
4514 if (integer_zerop (COND_EXPR_COND (expr)))
4516 UNUSED_LABEL_P (label_true) = 1;
4517 if (!then_side_effects)
4518 UNUSED_LABEL_P (label_cont) = 1;
4521 g = gimple_build_goto (label_cont);
4523 /* GIMPLE_COND's are very low level; they have embedded
4524 gotos. This particular embedded goto should not be marked
4525 with the location of the original COND_EXPR, as it would
4526 correspond to the COND_EXPR's condition, not the ELSE or the
4527 THEN arms. To avoid marking it with the wrong location, flag
4528 it as "no location". */
4529 gimple_set_do_not_emit_location (g);
4531 gimplify_seq_add_stmt (&seq, g);
4535 if (!have_else_clause_p)
4537 /* For if (1) { code } or if (1) { code } else { non-side-effect-code }
4538 tell -Wimplicit-fallthrough handling that label_false can be only
4539 reached through fallthrough from { code }. */
4540 if (integer_nonzerop (COND_EXPR_COND (expr))
4541 && (TREE_OPERAND (expr, 2) == NULL_TREE
4542 || !TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2))))
4543 UNUSED_LABEL_P (label_false) = 1;
4544 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4545 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4548 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4550 gimple_pop_condition (pre_p);
4551 gimple_seq_add_seq (pre_p, seq);
4553 if (ret == GS_ERROR)
4555 else if (have_then_clause_p || have_else_clause_p)
4559 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4560 expr = TREE_OPERAND (expr, 0);
4561 gimplify_stmt (&expr, pre_p);
4568 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4569 to be marked addressable.
4571 We cannot rely on such an expression being directly markable if a temporary
4572 has been created by the gimplification. In this case, we create another
4573 temporary and initialize it with a copy, which will become a store after we
4574 mark it addressable. This can happen if the front-end passed us something
4575 that it could not mark addressable yet, like a Fortran pass-by-reference
4576 parameter (int) floatvar. */
4579 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4581 while (handled_component_p (*expr_p))
4582 expr_p = &TREE_OPERAND (*expr_p, 0);
4584 /* Do not allow an SSA name as the temporary. */
4585 if (is_gimple_reg (*expr_p))
4586 *expr_p = internal_get_tmp_var (*expr_p, seq_p, NULL, false, false, true);
4589 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4590 a call to __builtin_memcpy. */
4592 static enum gimplify_status
4593 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4596 tree t, to, to_ptr, from, from_ptr;
4598 location_t loc = EXPR_LOCATION (*expr_p);
4600 to = TREE_OPERAND (*expr_p, 0);
4601 from = TREE_OPERAND (*expr_p, 1);
4603 /* Mark the RHS addressable. Beware that it may not be possible to do so
4604 directly if a temporary has been created by the gimplification. */
4605 prepare_gimple_addressable (&from, seq_p);
4607 mark_addressable (from);
4608 from_ptr = build_fold_addr_expr_loc (loc, from);
4609 gimplify_arg (&from_ptr, seq_p, loc);
4611 mark_addressable (to);
4612 to_ptr = build_fold_addr_expr_loc (loc, to);
4613 gimplify_arg (&to_ptr, seq_p, loc);
4615 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4617 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4618 gimple_call_set_alloca_for_var (gs, true);
4622 /* tmp = memcpy() */
4623 t = create_tmp_var (TREE_TYPE (to_ptr));
4624 gimple_call_set_lhs (gs, t);
4625 gimplify_seq_add_stmt (seq_p, gs);
4627 *expr_p = build_simple_mem_ref (t);
4631 gimplify_seq_add_stmt (seq_p, gs);
4636 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4637 a call to __builtin_memset. In this case we know that the RHS is
4638 a CONSTRUCTOR with an empty element list. */
4640 static enum gimplify_status
4641 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4644 tree t, from, to, to_ptr;
4646 location_t loc = EXPR_LOCATION (*expr_p);
4648 /* Assert our assumptions, to abort instead of producing wrong code
4649 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4650 not be immediately exposed. */
4651 from = TREE_OPERAND (*expr_p, 1);
4652 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4653 from = TREE_OPERAND (from, 0);
4655 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4656 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4659 to = TREE_OPERAND (*expr_p, 0);
4661 to_ptr = build_fold_addr_expr_loc (loc, to);
4662 gimplify_arg (&to_ptr, seq_p, loc);
4663 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4665 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4669 /* tmp = memset() */
4670 t = create_tmp_var (TREE_TYPE (to_ptr));
4671 gimple_call_set_lhs (gs, t);
4672 gimplify_seq_add_stmt (seq_p, gs);
4674 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4678 gimplify_seq_add_stmt (seq_p, gs);
4683 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4684 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4685 assignment. Return non-null if we detect a potential overlap. */
4687 struct gimplify_init_ctor_preeval_data
4689 /* The base decl of the lhs object. May be NULL, in which case we
4690 have to assume the lhs is indirect. */
4693 /* The alias set of the lhs object. */
4694 alias_set_type lhs_alias_set;
4698 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4700 struct gimplify_init_ctor_preeval_data *data
4701 = (struct gimplify_init_ctor_preeval_data *) xdata;
4704 /* If we find the base object, obviously we have overlap. */
4705 if (data->lhs_base_decl == t)
4708 /* If the constructor component is indirect, determine if we have a
4709 potential overlap with the lhs. The only bits of information we
4710 have to go on at this point are addressability and alias sets. */
4711 if ((INDIRECT_REF_P (t)
4712 || TREE_CODE (t) == MEM_REF)
4713 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4714 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4717 /* If the constructor component is a call, determine if it can hide a
4718 potential overlap with the lhs through an INDIRECT_REF like above.
4719 ??? Ugh - this is completely broken. In fact this whole analysis
4720 doesn't look conservative. */
4721 if (TREE_CODE (t) == CALL_EXPR)
4723 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4725 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4726 if (POINTER_TYPE_P (TREE_VALUE (type))
4727 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4728 && alias_sets_conflict_p (data->lhs_alias_set,
4730 (TREE_TYPE (TREE_VALUE (type)))))
4734 if (IS_TYPE_OR_DECL_P (t))
4739 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4740 force values that overlap with the lhs (as described by *DATA)
4741 into temporaries. */
4744 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4745 struct gimplify_init_ctor_preeval_data *data)
4747 enum gimplify_status one;
4749 /* If the value is constant, then there's nothing to pre-evaluate. */
4750 if (TREE_CONSTANT (*expr_p))
4752 /* Ensure it does not have side effects, it might contain a reference to
4753 the object we're initializing. */
4754 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4758 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4759 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4762 /* Recurse for nested constructors. */
4763 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4765 unsigned HOST_WIDE_INT ix;
4766 constructor_elt *ce;
4767 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4769 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4770 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4775 /* If this is a variable sized type, we must remember the size. */
4776 maybe_with_size_expr (expr_p);
4778 /* Gimplify the constructor element to something appropriate for the rhs
4779 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4780 the gimplifier will consider this a store to memory. Doing this
4781 gimplification now means that we won't have to deal with complicated
4782 language-specific trees, nor trees like SAVE_EXPR that can induce
4783 exponential search behavior. */
4784 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4785 if (one == GS_ERROR)
4791 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4792 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4793 always be true for all scalars, since is_gimple_mem_rhs insists on a
4794 temporary variable for them. */
4795 if (DECL_P (*expr_p))
4798 /* If this is of variable size, we have no choice but to assume it doesn't
4799 overlap since we can't make a temporary for it. */
4800 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4803 /* Otherwise, we must search for overlap ... */
4804 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4807 /* ... and if found, force the value into a temporary. */
4808 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4811 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4812 a RANGE_EXPR in a CONSTRUCTOR for an array.
4816 object[var] = value;
4823 We increment var _after_ the loop exit check because we might otherwise
4824 fail if upper == TYPE_MAX_VALUE (type for upper).
4826 Note that we never have to deal with SAVE_EXPRs here, because this has
4827 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4829 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4830 gimple_seq *, bool);
4833 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4834 tree value, tree array_elt_type,
4835 gimple_seq *pre_p, bool cleared)
4837 tree loop_entry_label, loop_exit_label, fall_thru_label;
4838 tree var, var_type, cref, tmp;
4840 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4841 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4842 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4844 /* Create and initialize the index variable. */
4845 var_type = TREE_TYPE (upper);
4846 var = create_tmp_var (var_type);
4847 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4849 /* Add the loop entry label. */
4850 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4852 /* Build the reference. */
4853 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4854 var, NULL_TREE, NULL_TREE);
4856 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4857 the store. Otherwise just assign value to the reference. */
4859 if (TREE_CODE (value) == CONSTRUCTOR)
4860 /* NB we might have to call ourself recursively through
4861 gimplify_init_ctor_eval if the value is a constructor. */
4862 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4866 if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue)
4868 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4871 /* We exit the loop when the index var is equal to the upper bound. */
4872 gimplify_seq_add_stmt (pre_p,
4873 gimple_build_cond (EQ_EXPR, var, upper,
4874 loop_exit_label, fall_thru_label));
4876 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4878 /* Otherwise, increment the index var... */
4879 tmp = build2 (PLUS_EXPR, var_type, var,
4880 fold_convert (var_type, integer_one_node));
4881 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4883 /* ...and jump back to the loop entry. */
4884 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4886 /* Add the loop exit label. */
4887 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4890 /* A subroutine of gimplify_init_constructor. Generate individual
4891 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4892 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4893 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4897 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4898 gimple_seq *pre_p, bool cleared)
4900 tree array_elt_type = NULL;
4901 unsigned HOST_WIDE_INT ix;
4902 tree purpose, value;
4904 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4905 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4907 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4911 /* NULL values are created above for gimplification errors. */
4915 if (cleared && initializer_zerop (value))
4918 /* ??? Here's to hoping the front end fills in all of the indices,
4919 so we don't have to figure out what's missing ourselves. */
4920 gcc_assert (purpose);
4922 /* Skip zero-sized fields, unless value has side-effects. This can
4923 happen with calls to functions returning a empty type, which
4924 we shouldn't discard. As a number of downstream passes don't
4925 expect sets of empty type fields, we rely on the gimplification of
4926 the MODIFY_EXPR we make below to drop the assignment statement. */
4927 if (!TREE_SIDE_EFFECTS (value)
4928 && TREE_CODE (purpose) == FIELD_DECL
4929 && is_empty_type (TREE_TYPE (purpose)))
4932 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4934 if (TREE_CODE (purpose) == RANGE_EXPR)
4936 tree lower = TREE_OPERAND (purpose, 0);
4937 tree upper = TREE_OPERAND (purpose, 1);
4939 /* If the lower bound is equal to upper, just treat it as if
4940 upper was the index. */
4941 if (simple_cst_equal (lower, upper))
4945 gimplify_init_ctor_eval_range (object, lower, upper, value,
4946 array_elt_type, pre_p, cleared);
4953 /* Do not use bitsizetype for ARRAY_REF indices. */
4954 if (TYPE_DOMAIN (TREE_TYPE (object)))
4956 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4958 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4959 purpose, NULL_TREE, NULL_TREE);
4963 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4964 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4965 unshare_expr (object), purpose, NULL_TREE);
4968 if (TREE_CODE (value) == CONSTRUCTOR
4969 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4970 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4974 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4975 gimplify_and_add (init, pre_p);
4981 /* Return the appropriate RHS predicate for this LHS. */
4984 rhs_predicate_for (tree lhs)
4986 if (is_gimple_reg (lhs))
4987 return is_gimple_reg_rhs_or_call;
4989 return is_gimple_mem_rhs_or_call;
4992 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4993 before the LHS has been gimplified. */
4995 static gimple_predicate
4996 initial_rhs_predicate_for (tree lhs)
4998 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4999 return is_gimple_reg_rhs_or_call;
5001 return is_gimple_mem_rhs_or_call;
5004 /* Gimplify a C99 compound literal expression. This just means adding
5005 the DECL_EXPR before the current statement and using its anonymous
5008 static enum gimplify_status
5009 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
5010 bool (*gimple_test_f) (tree),
5011 fallback_t fallback)
5013 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
5014 tree decl = DECL_EXPR_DECL (decl_s);
5015 tree init = DECL_INITIAL (decl);
5016 /* Mark the decl as addressable if the compound literal
5017 expression is addressable now, otherwise it is marked too late
5018 after we gimplify the initialization expression. */
5019 if (TREE_ADDRESSABLE (*expr_p))
5020 TREE_ADDRESSABLE (decl) = 1;
5021 /* Otherwise, if we don't need an lvalue and have a literal directly
5022 substitute it. Check if it matches the gimple predicate, as
5023 otherwise we'd generate a new temporary, and we can as well just
5024 use the decl we already have. */
5025 else if (!TREE_ADDRESSABLE (decl)
5026 && !TREE_THIS_VOLATILE (decl)
5028 && (fallback & fb_lvalue) == 0
5029 && gimple_test_f (init))
5035 /* If the decl is not addressable, then it is being used in some
5036 expression or on the right hand side of a statement, and it can
5037 be put into a readonly data section. */
5038 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
5039 TREE_READONLY (decl) = 1;
5041 /* This decl isn't mentioned in the enclosing block, so add it to the
5042 list of temps. FIXME it seems a bit of a kludge to say that
5043 anonymous artificial vars aren't pushed, but everything else is. */
5044 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
5045 gimple_add_tmp_var (decl);
5047 gimplify_and_add (decl_s, pre_p);
5052 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
5053 return a new CONSTRUCTOR if something changed. */
5056 optimize_compound_literals_in_ctor (tree orig_ctor)
5058 tree ctor = orig_ctor;
5059 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
5060 unsigned int idx, num = vec_safe_length (elts);
5062 for (idx = 0; idx < num; idx++)
5064 tree value = (*elts)[idx].value;
5065 tree newval = value;
5066 if (TREE_CODE (value) == CONSTRUCTOR)
5067 newval = optimize_compound_literals_in_ctor (value);
5068 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
5070 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
5071 tree decl = DECL_EXPR_DECL (decl_s);
5072 tree init = DECL_INITIAL (decl);
5074 if (!TREE_ADDRESSABLE (value)
5075 && !TREE_ADDRESSABLE (decl)
5077 && TREE_CODE (init) == CONSTRUCTOR)
5078 newval = optimize_compound_literals_in_ctor (init);
5080 if (newval == value)
5083 if (ctor == orig_ctor)
5085 ctor = copy_node (orig_ctor);
5086 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
5087 elts = CONSTRUCTOR_ELTS (ctor);
5089 (*elts)[idx].value = newval;
5094 /* A subroutine of gimplify_modify_expr. Break out elements of a
5095 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
5097 Note that we still need to clear any elements that don't have explicit
5098 initializers, so if not all elements are initialized we keep the
5099 original MODIFY_EXPR, we just remove all of the constructor elements.
5101 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
5102 GS_ERROR if we would have to create a temporary when gimplifying
5103 this constructor. Otherwise, return GS_OK.
5105 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
5107 static enum gimplify_status
5108 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5109 bool want_value, bool notify_temp_creation)
5111 tree object, ctor, type;
5112 enum gimplify_status ret;
5113 vec<constructor_elt, va_gc> *elts;
5114 bool cleared = false;
5115 bool is_empty_ctor = false;
5116 bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR);
5118 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
5120 if (!notify_temp_creation)
5122 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5123 is_gimple_lvalue, fb_lvalue);
5124 if (ret == GS_ERROR)
5128 object = TREE_OPERAND (*expr_p, 0);
5129 ctor = TREE_OPERAND (*expr_p, 1)
5130 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
5131 type = TREE_TYPE (ctor);
5132 elts = CONSTRUCTOR_ELTS (ctor);
5135 switch (TREE_CODE (type))
5139 case QUAL_UNION_TYPE:
5142 /* Use readonly data for initializers of this or smaller size
5143 regardless of the num_nonzero_elements / num_unique_nonzero_elements
5145 const HOST_WIDE_INT min_unique_size = 64;
5146 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
5147 is smaller than this, use readonly data. */
5148 const int unique_nonzero_ratio = 8;
5149 /* True if a single access of the object must be ensured. This is the
5150 case if the target is volatile, the type is non-addressable and more
5151 than one field need to be assigned. */
5152 const bool ensure_single_access
5153 = TREE_THIS_VOLATILE (object)
5154 && !TREE_ADDRESSABLE (type)
5155 && vec_safe_length (elts) > 1;
5156 struct gimplify_init_ctor_preeval_data preeval_data;
5157 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
5158 HOST_WIDE_INT num_unique_nonzero_elements;
5159 bool complete_p, valid_const_initializer;
5161 /* Aggregate types must lower constructors to initialization of
5162 individual elements. The exception is that a CONSTRUCTOR node
5163 with no elements indicates zero-initialization of the whole. */
5164 if (vec_safe_is_empty (elts))
5166 if (notify_temp_creation)
5169 /* The var will be initialized and so appear on lhs of
5170 assignment, it can't be TREE_READONLY anymore. */
5172 TREE_READONLY (object) = 0;
5174 is_empty_ctor = true;
5178 /* Fetch information about the constructor to direct later processing.
5179 We might want to make static versions of it in various cases, and
5180 can only do so if it known to be a valid constant initializer. */
5181 valid_const_initializer
5182 = categorize_ctor_elements (ctor, &num_nonzero_elements,
5183 &num_unique_nonzero_elements,
5184 &num_ctor_elements, &complete_p);
5186 /* If a const aggregate variable is being initialized, then it
5187 should never be a lose to promote the variable to be static. */
5188 if (valid_const_initializer
5189 && num_nonzero_elements > 1
5190 && TREE_READONLY (object)
5192 && !DECL_REGISTER (object)
5193 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))
5194 /* For ctors that have many repeated nonzero elements
5195 represented through RANGE_EXPRs, prefer initializing
5196 those through runtime loops over copies of large amounts
5197 of data from readonly data section. */
5198 && (num_unique_nonzero_elements
5199 > num_nonzero_elements / unique_nonzero_ratio
5200 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
5201 <= (unsigned HOST_WIDE_INT) min_unique_size)))
5203 if (notify_temp_creation)
5206 DECL_INITIAL (object) = ctor;
5207 TREE_STATIC (object) = 1;
5208 if (!DECL_NAME (object))
5209 DECL_NAME (object) = create_tmp_var_name ("C");
5210 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
5212 /* ??? C++ doesn't automatically append a .<number> to the
5213 assembler name, and even when it does, it looks at FE private
5214 data structures to figure out what that number should be,
5215 which are not set for this variable. I suppose this is
5216 important for local statics for inline functions, which aren't
5217 "local" in the object file sense. So in order to get a unique
5218 TU-local symbol, we must invoke the lhd version now. */
5219 lhd_set_decl_assembler_name (object);
5221 *expr_p = NULL_TREE;
5225 /* The var will be initialized and so appear on lhs of
5226 assignment, it can't be TREE_READONLY anymore. */
5227 if (VAR_P (object) && !notify_temp_creation)
5228 TREE_READONLY (object) = 0;
5230 /* If there are "lots" of initialized elements, even discounting
5231 those that are not address constants (and thus *must* be
5232 computed at runtime), then partition the constructor into
5233 constant and non-constant parts. Block copy the constant
5234 parts in, then generate code for the non-constant parts. */
5235 /* TODO. There's code in cp/typeck.cc to do this. */
5237 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
5238 /* store_constructor will ignore the clearing of variable-sized
5239 objects. Initializers for such objects must explicitly set
5240 every field that needs to be set. */
5242 else if (!complete_p)
5243 /* If the constructor isn't complete, clear the whole object
5244 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
5246 ??? This ought not to be needed. For any element not present
5247 in the initializer, we should simply set them to zero. Except
5248 we'd need to *find* the elements that are not present, and that
5249 requires trickery to avoid quadratic compile-time behavior in
5250 large cases or excessive memory use in small cases. */
5251 cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
5252 else if (num_ctor_elements - num_nonzero_elements
5253 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
5254 && num_nonzero_elements < num_ctor_elements / 4)
5255 /* If there are "lots" of zeros, it's more efficient to clear
5256 the memory and then set the nonzero elements. */
5258 else if (ensure_single_access && num_nonzero_elements == 0)
5259 /* If a single access to the target must be ensured and all elements
5260 are zero, then it's optimal to clear whatever their number. */
5265 /* If there are "lots" of initialized elements, and all of them
5266 are valid address constants, then the entire initializer can
5267 be dropped to memory, and then memcpy'd out. Don't do this
5268 for sparse arrays, though, as it's more efficient to follow
5269 the standard CONSTRUCTOR behavior of memset followed by
5270 individual element initialization. Also don't do this for small
5271 all-zero initializers (which aren't big enough to merit
5272 clearing), and don't try to make bitwise copies of
5273 TREE_ADDRESSABLE types. */
5274 if (valid_const_initializer
5276 && !(cleared || num_nonzero_elements == 0)
5277 && !TREE_ADDRESSABLE (type))
5279 HOST_WIDE_INT size = int_size_in_bytes (type);
5282 /* ??? We can still get unbounded array types, at least
5283 from the C++ front end. This seems wrong, but attempt
5284 to work around it for now. */
5287 size = int_size_in_bytes (TREE_TYPE (object));
5289 TREE_TYPE (ctor) = type = TREE_TYPE (object);
5292 /* Find the maximum alignment we can assume for the object. */
5293 /* ??? Make use of DECL_OFFSET_ALIGN. */
5294 if (DECL_P (object))
5295 align = DECL_ALIGN (object);
5297 align = TYPE_ALIGN (type);
5299 /* Do a block move either if the size is so small as to make
5300 each individual move a sub-unit move on average, or if it
5301 is so large as to make individual moves inefficient. */
5303 && num_nonzero_elements > 1
5304 /* For ctors that have many repeated nonzero elements
5305 represented through RANGE_EXPRs, prefer initializing
5306 those through runtime loops over copies of large amounts
5307 of data from readonly data section. */
5308 && (num_unique_nonzero_elements
5309 > num_nonzero_elements / unique_nonzero_ratio
5310 || size <= min_unique_size)
5311 && (size < num_nonzero_elements
5312 || !can_move_by_pieces (size, align)))
5314 if (notify_temp_creation)
5317 walk_tree (&ctor, force_labels_r, NULL, NULL);
5318 ctor = tree_output_constant_def (ctor);
5319 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
5320 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
5321 TREE_OPERAND (*expr_p, 1) = ctor;
5323 /* This is no longer an assignment of a CONSTRUCTOR, but
5324 we still may have processing to do on the LHS. So
5325 pretend we didn't do anything here to let that happen. */
5326 return GS_UNHANDLED;
5330 /* If a single access to the target must be ensured and there are
5331 nonzero elements or the zero elements are not assigned en masse,
5332 initialize the target from a temporary. */
5333 if (ensure_single_access && (num_nonzero_elements > 0 || !cleared))
5335 if (notify_temp_creation)
5338 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
5339 TREE_OPERAND (*expr_p, 0) = temp;
5340 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
5342 build2 (MODIFY_EXPR, void_type_node,
5347 if (notify_temp_creation)
5350 /* If there are nonzero elements and if needed, pre-evaluate to capture
5351 elements overlapping with the lhs into temporaries. We must do this
5352 before clearing to fetch the values before they are zeroed-out. */
5353 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
5355 preeval_data.lhs_base_decl = get_base_address (object);
5356 if (!DECL_P (preeval_data.lhs_base_decl))
5357 preeval_data.lhs_base_decl = NULL;
5358 preeval_data.lhs_alias_set = get_alias_set (object);
5360 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
5361 pre_p, post_p, &preeval_data);
5364 bool ctor_has_side_effects_p
5365 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
5369 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5370 Note that we still have to gimplify, in order to handle the
5371 case of variable sized types. Avoid shared tree structures. */
5372 CONSTRUCTOR_ELTS (ctor) = NULL;
5373 TREE_SIDE_EFFECTS (ctor) = 0;
5374 object = unshare_expr (object);
5375 gimplify_stmt (expr_p, pre_p);
5378 /* If we have not block cleared the object, or if there are nonzero
5379 elements in the constructor, or if the constructor has side effects,
5380 add assignments to the individual scalar fields of the object. */
5382 || num_nonzero_elements > 0
5383 || ctor_has_side_effects_p)
5384 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
5386 *expr_p = NULL_TREE;
5394 if (notify_temp_creation)
5397 /* Extract the real and imaginary parts out of the ctor. */
5398 gcc_assert (elts->length () == 2);
5399 r = (*elts)[0].value;
5400 i = (*elts)[1].value;
5401 if (r == NULL || i == NULL)
5403 tree zero = build_zero_cst (TREE_TYPE (type));
5410 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5411 represent creation of a complex value. */
5412 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
5414 ctor = build_complex (type, r, i);
5415 TREE_OPERAND (*expr_p, 1) = ctor;
5419 ctor = build2 (COMPLEX_EXPR, type, r, i);
5420 TREE_OPERAND (*expr_p, 1) = ctor;
5421 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
5424 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
5432 unsigned HOST_WIDE_INT ix;
5433 constructor_elt *ce;
5435 if (notify_temp_creation)
5438 /* Vector types use CONSTRUCTOR all the way through gimple
5439 compilation as a general initializer. */
5440 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5442 enum gimplify_status tret;
5443 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5445 if (tret == GS_ERROR)
5447 else if (TREE_STATIC (ctor)
5448 && !initializer_constant_valid_p (ce->value,
5449 TREE_TYPE (ce->value)))
5450 TREE_STATIC (ctor) = 0;
5452 recompute_constructor_flags (ctor);
5454 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5455 if (TREE_CONSTANT (ctor))
5457 bool constant_p = true;
5460 /* Even when ctor is constant, it might contain non-*_CST
5461 elements, such as addresses or trapping values like
5462 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5463 in VECTOR_CST nodes. */
5464 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5465 if (!CONSTANT_CLASS_P (value))
5473 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5478 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5479 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5484 /* So how did we get a CONSTRUCTOR for a scalar type? */
5488 if (ret == GS_ERROR)
5490 /* If we have gimplified both sides of the initializer but have
5491 not emitted an assignment, do so now. */
5493 /* If the type is an empty type, we don't need to emit the
5495 && !is_empty_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
5497 tree lhs = TREE_OPERAND (*expr_p, 0);
5498 tree rhs = TREE_OPERAND (*expr_p, 1);
5499 if (want_value && object == lhs)
5500 lhs = unshare_expr (lhs);
5501 gassign *init = gimple_build_assign (lhs, rhs);
5502 gimplify_seq_add_stmt (pre_p, init);
5515 /* If the user requests to initialize automatic variables, we
5516 should initialize paddings inside the variable. Add a call to
5517 __builtin_clear_pading (&object, 0, for_auto_init = true) to
5518 initialize paddings of object always to zero regardless of
5519 INIT_TYPE. Note, we will not insert this call if the aggregate
5520 variable has be completely cleared already or it's initialized
5521 with an empty constructor. We cannot insert this call if the
5522 variable is a gimple register since __builtin_clear_padding will take
5523 the address of the variable. As a result, if a long double/_Complex long
5524 double variable will be spilled into stack later, its padding cannot
5525 be cleared with __builtin_clear_padding. We should clear its padding
5526 when it is spilled into memory. */
5528 && !is_gimple_reg (object)
5529 && clear_padding_type_may_have_padding_p (type)
5530 && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor)
5531 || !AGGREGATE_TYPE_P (type))
5532 && is_var_need_auto_init (object))
5533 gimple_add_padding_init_for_auto_var (object, false, pre_p);
5538 /* Given a pointer value OP0, return a simplified version of an
5539 indirection through OP0, or NULL_TREE if no simplification is
5540 possible. This may only be applied to a rhs of an expression.
5541 Note that the resulting type may be different from the type pointed
5542 to in the sense that it is still compatible from the langhooks
5546 gimple_fold_indirect_ref_rhs (tree t)
5548 return gimple_fold_indirect_ref (t);
5551 /* Subroutine of gimplify_modify_expr to do simplifications of
5552 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5553 something changes. */
5555 static enum gimplify_status
5556 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5557 gimple_seq *pre_p, gimple_seq *post_p,
5560 enum gimplify_status ret = GS_UNHANDLED;
5566 switch (TREE_CODE (*from_p))
5569 /* If we're assigning from a read-only variable initialized with
5570 a constructor and not volatile, do the direct assignment from
5571 the constructor, but only if the target is not volatile either
5572 since this latter assignment might end up being done on a per
5573 field basis. However, if the target is volatile and the type
5574 is aggregate and non-addressable, gimplify_init_constructor
5575 knows that it needs to ensure a single access to the target
5576 and it will return GS_OK only in this case. */
5577 if (TREE_READONLY (*from_p)
5578 && DECL_INITIAL (*from_p)
5579 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR
5580 && !TREE_THIS_VOLATILE (*from_p)
5581 && (!TREE_THIS_VOLATILE (*to_p)
5582 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p))
5583 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p)))))
5585 tree old_from = *from_p;
5586 enum gimplify_status subret;
5588 /* Move the constructor into the RHS. */
5589 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5591 /* Let's see if gimplify_init_constructor will need to put
5593 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5595 if (subret == GS_ERROR)
5597 /* If so, revert the change. */
5609 /* If we have code like
5613 where the type of "x" is a (possibly cv-qualified variant
5614 of "A"), treat the entire expression as identical to "x".
5615 This kind of code arises in C++ when an object is bound
5616 to a const reference, and if "x" is a TARGET_EXPR we want
5617 to take advantage of the optimization below. */
5618 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5619 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5622 if (TREE_THIS_VOLATILE (t) != volatile_p)
5625 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5626 build_fold_addr_expr (t));
5627 if (REFERENCE_CLASS_P (t))
5628 TREE_THIS_VOLATILE (t) = volatile_p;
5639 /* If we are initializing something from a TARGET_EXPR, strip the
5640 TARGET_EXPR and initialize it directly, if possible. This can't
5641 be done if the initializer is void, since that implies that the
5642 temporary is set in some non-trivial way.
5644 ??? What about code that pulls out the temp and uses it
5645 elsewhere? I think that such code never uses the TARGET_EXPR as
5646 an initializer. If I'm wrong, we'll die because the temp won't
5647 have any RTL. In that case, I guess we'll need to replace
5648 references somehow. */
5649 tree init = TARGET_EXPR_INITIAL (*from_p);
5652 && (TREE_CODE (*expr_p) != MODIFY_EXPR
5653 || !TARGET_EXPR_NO_ELIDE (*from_p))
5654 && !VOID_TYPE_P (TREE_TYPE (init)))
5664 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5666 gimplify_compound_expr (from_p, pre_p, true);
5672 /* If we already made some changes, let the front end have a
5673 crack at this before we break it down. */
5674 if (ret != GS_UNHANDLED)
5677 /* If we're initializing from a CONSTRUCTOR, break this into
5678 individual MODIFY_EXPRs. */
5679 ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5684 /* If we're assigning to a non-register type, push the assignment
5685 down into the branches. This is mandatory for ADDRESSABLE types,
5686 since we cannot generate temporaries for such, but it saves a
5687 copy in other cases as well. */
5688 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5690 /* This code should mirror the code in gimplify_cond_expr. */
5691 enum tree_code code = TREE_CODE (*expr_p);
5692 tree cond = *from_p;
5693 tree result = *to_p;
5695 ret = gimplify_expr (&result, pre_p, post_p,
5696 is_gimple_lvalue, fb_lvalue);
5697 if (ret != GS_ERROR)
5700 /* If we are going to write RESULT more than once, clear
5701 TREE_READONLY flag, otherwise we might incorrectly promote
5702 the variable to static const and initialize it at compile
5703 time in one of the branches. */
5705 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5706 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5707 TREE_READONLY (result) = 0;
5708 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5709 TREE_OPERAND (cond, 1)
5710 = build2 (code, void_type_node, result,
5711 TREE_OPERAND (cond, 1));
5712 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5713 TREE_OPERAND (cond, 2)
5714 = build2 (code, void_type_node, unshare_expr (result),
5715 TREE_OPERAND (cond, 2));
5717 TREE_TYPE (cond) = void_type_node;
5718 recalculate_side_effects (cond);
5722 gimplify_and_add (cond, pre_p);
5723 *expr_p = unshare_expr (result);
5732 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5733 return slot so that we don't generate a temporary. */
5734 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5735 && aggregate_value_p (*from_p, *from_p))
5739 if (!(rhs_predicate_for (*to_p))(*from_p))
5740 /* If we need a temporary, *to_p isn't accurate. */
5742 /* It's OK to use the return slot directly unless it's an NRV. */
5743 else if (TREE_CODE (*to_p) == RESULT_DECL
5744 && DECL_NAME (*to_p) == NULL_TREE
5745 && needs_to_live_in_memory (*to_p))
5747 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5748 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5749 /* Don't force regs into memory. */
5751 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5752 /* It's OK to use the target directly if it's being
5755 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5757 /* Always use the target and thus RSO for variable-sized types.
5758 GIMPLE cannot deal with a variable-sized assignment
5759 embedded in a call statement. */
5761 else if (TREE_CODE (*to_p) != SSA_NAME
5762 && (!is_gimple_variable (*to_p)
5763 || needs_to_live_in_memory (*to_p)))
5764 /* Don't use the original target if it's already addressable;
5765 if its address escapes, and the called function uses the
5766 NRV optimization, a conforming program could see *to_p
5767 change before the called function returns; see c++/19317.
5768 When optimizing, the return_slot pass marks more functions
5769 as safe after we have escape info. */
5776 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5777 mark_addressable (*to_p);
5782 case WITH_SIZE_EXPR:
5783 /* Likewise for calls that return an aggregate of non-constant size,
5784 since we would not be able to generate a temporary at all. */
5785 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5787 *from_p = TREE_OPERAND (*from_p, 0);
5788 /* We don't change ret in this case because the
5789 WITH_SIZE_EXPR might have been added in
5790 gimplify_modify_expr, so returning GS_OK would lead to an
5796 /* If we're initializing from a container, push the initialization
5798 case CLEANUP_POINT_EXPR:
5800 case STATEMENT_LIST:
5802 tree wrap = *from_p;
5805 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5807 if (ret != GS_ERROR)
5810 t = voidify_wrapper_expr (wrap, *expr_p);
5811 gcc_assert (t == *expr_p);
5815 gimplify_and_add (wrap, pre_p);
5816 *expr_p = unshare_expr (*to_p);
5824 /* Pull out compound literal expressions from a NOP_EXPR.
5825 Those are created in the C FE to drop qualifiers during
5826 lvalue conversion. */
5827 if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
5828 && tree_ssa_useless_type_conversion (*from_p))
5830 *from_p = TREE_OPERAND (*from_p, 0);
5836 case COMPOUND_LITERAL_EXPR:
5838 tree complit = TREE_OPERAND (*expr_p, 1);
5839 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5840 tree decl = DECL_EXPR_DECL (decl_s);
5841 tree init = DECL_INITIAL (decl);
5843 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5844 into struct T x = { 0, 1, 2 } if the address of the
5845 compound literal has never been taken. */
5846 if (!TREE_ADDRESSABLE (complit)
5847 && !TREE_ADDRESSABLE (decl)
5850 *expr_p = copy_node (*expr_p);
5851 TREE_OPERAND (*expr_p, 1) = init;
5866 /* Return true if T looks like a valid GIMPLE statement. */
5869 is_gimple_stmt (tree t)
5871 const enum tree_code code = TREE_CODE (t);
5876 /* The only valid NOP_EXPR is the empty statement. */
5877 return IS_EMPTY_STMT (t);
5881 /* These are only valid if they're void. */
5882 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5888 case CASE_LABEL_EXPR:
5889 case TRY_CATCH_EXPR:
5890 case TRY_FINALLY_EXPR:
5891 case EH_FILTER_EXPR:
5894 case STATEMENT_LIST:
5899 case OACC_HOST_DATA:
5902 case OACC_ENTER_DATA:
5903 case OACC_EXIT_DATA:
5908 case OMP_DISTRIBUTE:
5923 case OMP_TARGET_DATA:
5924 case OMP_TARGET_UPDATE:
5925 case OMP_TARGET_ENTER_DATA:
5926 case OMP_TARGET_EXIT_DATA:
5929 /* These are always void. */
5935 /* These are valid regardless of their type. */
5944 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5945 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
5947 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5948 other, unmodified part of the complex object just before the total store.
5949 As a consequence, if the object is still uninitialized, an undefined value
5950 will be loaded into a register, which may result in a spurious exception
5951 if the register is floating-point and the value happens to be a signaling
5952 NaN for example. Then the fully-fledged complex operations lowering pass
5953 followed by a DCE pass are necessary in order to fix things up. */
5955 static enum gimplify_status
5956 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5959 enum tree_code code, ocode;
5960 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5962 lhs = TREE_OPERAND (*expr_p, 0);
5963 rhs = TREE_OPERAND (*expr_p, 1);
5964 code = TREE_CODE (lhs);
5965 lhs = TREE_OPERAND (lhs, 0);
5967 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5968 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5969 suppress_warning (other);
5970 other = get_formal_tmp_var (other, pre_p);
5972 realpart = code == REALPART_EXPR ? rhs : other;
5973 imagpart = code == REALPART_EXPR ? other : rhs;
5975 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5976 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5978 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5980 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5981 *expr_p = (want_value) ? rhs : NULL_TREE;
5986 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5992 PRE_P points to the list where side effects that must happen before
5993 *EXPR_P should be stored.
5995 POST_P points to the list where side effects that must happen after
5996 *EXPR_P should be stored.
5998 WANT_VALUE is nonzero iff we want to use the value of this expression
5999 in another expression. */
6001 static enum gimplify_status
6002 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
6005 tree *from_p = &TREE_OPERAND (*expr_p, 1);
6006 tree *to_p = &TREE_OPERAND (*expr_p, 0);
6007 enum gimplify_status ret = GS_UNHANDLED;
6009 location_t loc = EXPR_LOCATION (*expr_p);
6010 gimple_stmt_iterator gsi;
6012 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
6013 || TREE_CODE (*expr_p) == INIT_EXPR);
6015 /* Trying to simplify a clobber using normal logic doesn't work,
6016 so handle it here. */
6017 if (TREE_CLOBBER_P (*from_p))
6019 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
6020 if (ret == GS_ERROR)
6022 gcc_assert (!want_value);
6023 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
6025 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
6027 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
6029 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
6034 /* Insert pointer conversions required by the middle-end that are not
6035 required by the frontend. This fixes middle-end type checking for
6036 for example gcc.dg/redecl-6.c. */
6037 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
6039 STRIP_USELESS_TYPE_CONVERSION (*from_p);
6040 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
6041 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
6044 /* See if any simplifications can be done based on what the RHS is. */
6045 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
6047 if (ret != GS_UNHANDLED)
6050 /* For empty types only gimplify the left hand side and right hand
6051 side as statements and throw away the assignment. Do this after
6052 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
6054 if (is_empty_type (TREE_TYPE (*from_p))
6056 /* Don't do this for calls that return addressable types, expand_call
6057 relies on those having a lhs. */
6058 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
6059 && TREE_CODE (*from_p) == CALL_EXPR))
6061 gimplify_stmt (from_p, pre_p);
6062 gimplify_stmt (to_p, pre_p);
6063 *expr_p = NULL_TREE;
6067 /* If the value being copied is of variable width, compute the length
6068 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
6069 before gimplifying any of the operands so that we can resolve any
6070 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
6071 the size of the expression to be copied, not of the destination, so
6072 that is what we must do here. */
6073 maybe_with_size_expr (from_p);
6075 /* As a special case, we have to temporarily allow for assignments
6076 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
6077 a toplevel statement, when gimplifying the GENERIC expression
6078 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
6079 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
6081 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
6082 prevent gimplify_expr from trying to create a new temporary for
6083 foo's LHS, we tell it that it should only gimplify until it
6084 reaches the CALL_EXPR. On return from gimplify_expr, the newly
6085 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
6086 and all we need to do here is set 'a' to be its LHS. */
6088 /* Gimplify the RHS first for C++17 and bug 71104. */
6089 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
6090 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
6091 if (ret == GS_ERROR)
6094 /* Then gimplify the LHS. */
6095 /* If we gimplified the RHS to a CALL_EXPR and that call may return
6096 twice we have to make sure to gimplify into non-SSA as otherwise
6097 the abnormal edge added later will make those defs not dominate
6099 ??? Technically this applies only to the registers used in the
6100 resulting non-register *TO_P. */
6101 bool saved_into_ssa = gimplify_ctxp->into_ssa;
6103 && TREE_CODE (*from_p) == CALL_EXPR
6104 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
6105 gimplify_ctxp->into_ssa = false;
6106 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
6107 gimplify_ctxp->into_ssa = saved_into_ssa;
6108 if (ret == GS_ERROR)
6111 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
6112 guess for the predicate was wrong. */
6113 gimple_predicate final_pred = rhs_predicate_for (*to_p);
6114 if (final_pred != initial_pred)
6116 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
6117 if (ret == GS_ERROR)
6121 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
6122 size as argument to the call. */
6123 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
6125 tree call = TREE_OPERAND (*from_p, 0);
6126 tree vlasize = TREE_OPERAND (*from_p, 1);
6128 if (TREE_CODE (call) == CALL_EXPR
6129 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
6131 int nargs = call_expr_nargs (call);
6132 tree type = TREE_TYPE (call);
6133 tree ap = CALL_EXPR_ARG (call, 0);
6134 tree tag = CALL_EXPR_ARG (call, 1);
6135 tree aptag = CALL_EXPR_ARG (call, 2);
6136 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
6140 TREE_OPERAND (*from_p, 0) = newcall;
6144 /* Now see if the above changed *from_p to something we handle specially. */
6145 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
6147 if (ret != GS_UNHANDLED)
6150 /* If we've got a variable sized assignment between two lvalues (i.e. does
6151 not involve a call), then we can make things a bit more straightforward
6152 by converting the assignment to memcpy or memset. */
6153 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
6155 tree from = TREE_OPERAND (*from_p, 0);
6156 tree size = TREE_OPERAND (*from_p, 1);
6158 if (TREE_CODE (from) == CONSTRUCTOR)
6159 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
6161 if (is_gimple_addressable (from))
6164 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
6169 /* Transform partial stores to non-addressable complex variables into
6170 total stores. This allows us to use real instead of virtual operands
6171 for these variables, which improves optimization. */
6172 if ((TREE_CODE (*to_p) == REALPART_EXPR
6173 || TREE_CODE (*to_p) == IMAGPART_EXPR)
6174 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
6175 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
6177 /* Try to alleviate the effects of the gimplification creating artificial
6178 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
6179 make sure not to create DECL_DEBUG_EXPR links across functions. */
6180 if (!gimplify_ctxp->into_ssa
6182 && DECL_IGNORED_P (*from_p)
6184 && !DECL_IGNORED_P (*to_p)
6185 && decl_function_context (*to_p) == current_function_decl
6186 && decl_function_context (*from_p) == current_function_decl)
6188 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
6190 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
6191 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
6192 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
6195 if (want_value && TREE_THIS_VOLATILE (*to_p))
6196 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
6198 if (TREE_CODE (*from_p) == CALL_EXPR)
6200 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
6201 instead of a GIMPLE_ASSIGN. */
6203 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
6205 /* Gimplify internal functions created in the FEs. */
6206 int nargs = call_expr_nargs (*from_p), i;
6207 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
6208 auto_vec<tree> vargs (nargs);
6210 for (i = 0; i < nargs; i++)
6212 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
6213 EXPR_LOCATION (*from_p));
6214 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
6216 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
6217 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
6218 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
6222 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
6223 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
6224 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
6225 tree fndecl = get_callee_fndecl (*from_p);
6227 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
6228 && call_expr_nargs (*from_p) == 3)
6229 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
6230 CALL_EXPR_ARG (*from_p, 0),
6231 CALL_EXPR_ARG (*from_p, 1),
6232 CALL_EXPR_ARG (*from_p, 2));
6235 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
6238 notice_special_calls (call_stmt);
6239 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
6240 gimple_call_set_lhs (call_stmt, *to_p);
6241 else if (TREE_CODE (*to_p) == SSA_NAME)
6242 /* The above is somewhat premature, avoid ICEing later for a
6243 SSA name w/o a definition. We may have uses in the GIMPLE IL.
6244 ??? This doesn't make it a default-def. */
6245 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
6251 assign = gimple_build_assign (*to_p, *from_p);
6252 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
6253 if (COMPARISON_CLASS_P (*from_p))
6254 copy_warning (assign, *from_p);
6257 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
6259 /* We should have got an SSA name from the start. */
6260 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
6261 || ! gimple_in_ssa_p (cfun));
6264 gimplify_seq_add_stmt (pre_p, assign);
6265 gsi = gsi_last (*pre_p);
6266 maybe_fold_stmt (&gsi);
6270 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
6279 /* Gimplify a comparison between two variable-sized objects. Do this
6280 with a call to BUILT_IN_MEMCMP. */
6282 static enum gimplify_status
6283 gimplify_variable_sized_compare (tree *expr_p)
6285 location_t loc = EXPR_LOCATION (*expr_p);
6286 tree op0 = TREE_OPERAND (*expr_p, 0);
6287 tree op1 = TREE_OPERAND (*expr_p, 1);
6288 tree t, arg, dest, src, expr;
6290 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
6291 arg = unshare_expr (arg);
6292 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
6293 src = build_fold_addr_expr_loc (loc, op1);
6294 dest = build_fold_addr_expr_loc (loc, op0);
6295 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
6296 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
6299 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
6300 SET_EXPR_LOCATION (expr, loc);
6306 /* Gimplify a comparison between two aggregate objects of integral scalar
6307 mode as a comparison between the bitwise equivalent scalar values. */
6309 static enum gimplify_status
6310 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
6312 location_t loc = EXPR_LOCATION (*expr_p);
6313 tree op0 = TREE_OPERAND (*expr_p, 0);
6314 tree op1 = TREE_OPERAND (*expr_p, 1);
6316 tree type = TREE_TYPE (op0);
6317 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
6319 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
6320 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
6323 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
6328 /* Gimplify an expression sequence. This function gimplifies each
6329 expression and rewrites the original expression with the last
6330 expression of the sequence in GIMPLE form.
6332 PRE_P points to the list where the side effects for all the
6333 expressions in the sequence will be emitted.
6335 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6337 static enum gimplify_status
6338 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
6344 tree *sub_p = &TREE_OPERAND (t, 0);
6346 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
6347 gimplify_compound_expr (sub_p, pre_p, false);
6349 gimplify_stmt (sub_p, pre_p);
6351 t = TREE_OPERAND (t, 1);
6353 while (TREE_CODE (t) == COMPOUND_EXPR);
6360 gimplify_stmt (expr_p, pre_p);
6365 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6366 gimplify. After gimplification, EXPR_P will point to a new temporary
6367 that holds the original value of the SAVE_EXPR node.
6369 PRE_P points to the list where side effects that must happen before
6370 *EXPR_P should be stored. */
6372 static enum gimplify_status
6373 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6375 enum gimplify_status ret = GS_ALL_DONE;
6378 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
6379 val = TREE_OPERAND (*expr_p, 0);
6381 if (TREE_TYPE (val) == error_mark_node)
6384 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6385 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
6387 /* The operand may be a void-valued expression. It is
6388 being executed only for its side-effects. */
6389 if (TREE_TYPE (val) == void_type_node)
6391 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
6392 is_gimple_stmt, fb_none);
6396 /* The temporary may not be an SSA name as later abnormal and EH
6397 control flow may invalidate use/def domination. When in SSA
6398 form then assume there are no such issues and SAVE_EXPRs only
6399 appear via GENERIC foldings. */
6400 val = get_initialized_tmp_var (val, pre_p, post_p,
6401 gimple_in_ssa_p (cfun));
6403 TREE_OPERAND (*expr_p, 0) = val;
6404 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
6412 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6419 PRE_P points to the list where side effects that must happen before
6420 *EXPR_P should be stored.
6422 POST_P points to the list where side effects that must happen after
6423 *EXPR_P should be stored. */
6425 static enum gimplify_status
6426 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6428 tree expr = *expr_p;
6429 tree op0 = TREE_OPERAND (expr, 0);
6430 enum gimplify_status ret;
6431 location_t loc = EXPR_LOCATION (*expr_p);
6433 switch (TREE_CODE (op0))
6437 /* Check if we are dealing with an expression of the form '&*ptr'.
6438 While the front end folds away '&*ptr' into 'ptr', these
6439 expressions may be generated internally by the compiler (e.g.,
6440 builtins like __builtin_va_end). */
6441 /* Caution: the silent array decomposition semantics we allow for
6442 ADDR_EXPR means we can't always discard the pair. */
6443 /* Gimplification of the ADDR_EXPR operand may drop
6444 cv-qualification conversions, so make sure we add them if
6447 tree op00 = TREE_OPERAND (op0, 0);
6448 tree t_expr = TREE_TYPE (expr);
6449 tree t_op00 = TREE_TYPE (op00);
6451 if (!useless_type_conversion_p (t_expr, t_op00))
6452 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
6458 case VIEW_CONVERT_EXPR:
6459 /* Take the address of our operand and then convert it to the type of
6462 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6463 all clear. The impact of this transformation is even less clear. */
6465 /* If the operand is a useless conversion, look through it. Doing so
6466 guarantees that the ADDR_EXPR and its operand will remain of the
6468 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
6469 op0 = TREE_OPERAND (op0, 0);
6471 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
6472 build_fold_addr_expr_loc (loc,
6473 TREE_OPERAND (op0, 0)));
6478 if (integer_zerop (TREE_OPERAND (op0, 1)))
6479 goto do_indirect_ref;
6484 /* If we see a call to a declared builtin or see its address
6485 being taken (we can unify those cases here) then we can mark
6486 the builtin for implicit generation by GCC. */
6487 if (TREE_CODE (op0) == FUNCTION_DECL
6488 && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6489 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6490 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6492 /* We use fb_either here because the C frontend sometimes takes
6493 the address of a call that returns a struct; see
6494 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6495 the implied temporary explicit. */
6497 /* Make the operand addressable. */
6498 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6499 is_gimple_addressable, fb_either);
6500 if (ret == GS_ERROR)
6503 /* Then mark it. Beware that it may not be possible to do so directly
6504 if a temporary has been created by the gimplification. */
6505 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6507 op0 = TREE_OPERAND (expr, 0);
6509 /* For various reasons, the gimplification of the expression
6510 may have made a new INDIRECT_REF. */
6511 if (TREE_CODE (op0) == INDIRECT_REF
6512 || (TREE_CODE (op0) == MEM_REF
6513 && integer_zerop (TREE_OPERAND (op0, 1))))
6514 goto do_indirect_ref;
6516 mark_addressable (TREE_OPERAND (expr, 0));
6518 /* The FEs may end up building ADDR_EXPRs early on a decl with
6519 an incomplete type. Re-build ADDR_EXPRs in canonical form
6521 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6522 *expr_p = build_fold_addr_expr (op0);
6524 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6525 recompute_tree_invariant_for_addr_expr (*expr_p);
6527 /* If we re-built the ADDR_EXPR add a conversion to the original type
6529 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6530 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6538 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6539 value; output operands should be a gimple lvalue. */
6541 static enum gimplify_status
6542 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6546 const char **oconstraints;
6549 const char *constraint;
6550 bool allows_mem, allows_reg, is_inout;
6551 enum gimplify_status ret, tret;
6553 vec<tree, va_gc> *inputs;
6554 vec<tree, va_gc> *outputs;
6555 vec<tree, va_gc> *clobbers;
6556 vec<tree, va_gc> *labels;
6560 noutputs = list_length (ASM_OUTPUTS (expr));
6561 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6569 link_next = NULL_TREE;
6570 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6573 size_t constraint_len;
6575 link_next = TREE_CHAIN (link);
6579 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6580 constraint_len = strlen (constraint);
6581 if (constraint_len == 0)
6584 ok = parse_output_constraint (&constraint, i, 0, 0,
6585 &allows_mem, &allows_reg, &is_inout);
6592 /* If we can't make copies, we can only accept memory.
6593 Similarly for VLAs. */
6594 tree outtype = TREE_TYPE (TREE_VALUE (link));
6595 if (outtype != error_mark_node
6596 && (TREE_ADDRESSABLE (outtype)
6597 || !COMPLETE_TYPE_P (outtype)
6598 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
6604 error ("impossible constraint in %<asm%>");
6605 error ("non-memory output %d must stay in memory", i);
6610 if (!allows_reg && allows_mem)
6611 mark_addressable (TREE_VALUE (link));
6613 tree orig = TREE_VALUE (link);
6614 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6615 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6616 fb_lvalue | fb_mayfail);
6617 if (tret == GS_ERROR)
6619 if (orig != error_mark_node)
6620 error ("invalid lvalue in %<asm%> output %d", i);
6624 /* If the constraint does not allow memory make sure we gimplify
6625 it to a register if it is not already but its base is. This
6626 happens for complex and vector components. */
6629 tree op = TREE_VALUE (link);
6630 if (! is_gimple_val (op)
6631 && is_gimple_reg_type (TREE_TYPE (op))
6632 && is_gimple_reg (get_base_address (op)))
6634 tree tem = create_tmp_reg (TREE_TYPE (op));
6638 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6639 tem, unshare_expr (op));
6640 gimplify_and_add (ass, pre_p);
6642 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6643 gimplify_and_add (ass, post_p);
6645 TREE_VALUE (link) = tem;
6650 vec_safe_push (outputs, link);
6651 TREE_CHAIN (link) = NULL_TREE;
6655 /* An input/output operand. To give the optimizers more
6656 flexibility, split it into separate input and output
6659 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6662 /* Turn the in/out constraint into an output constraint. */
6663 char *p = xstrdup (constraint);
6665 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6667 /* And add a matching input constraint. */
6670 sprintf (buf, "%u", i);
6672 /* If there are multiple alternatives in the constraint,
6673 handle each of them individually. Those that allow register
6674 will be replaced with operand number, the others will stay
6676 if (strchr (p, ',') != NULL)
6678 size_t len = 0, buflen = strlen (buf);
6679 char *beg, *end, *str, *dst;
6683 end = strchr (beg, ',');
6685 end = strchr (beg, '\0');
6686 if ((size_t) (end - beg) < buflen)
6689 len += end - beg + 1;
6696 str = (char *) alloca (len);
6697 for (beg = p + 1, dst = str;;)
6700 bool mem_p, reg_p, inout_p;
6702 end = strchr (beg, ',');
6707 parse_output_constraint (&tem, i, 0, 0,
6708 &mem_p, ®_p, &inout_p);
6713 memcpy (dst, buf, buflen);
6722 memcpy (dst, beg, len);
6731 input = build_string (dst - str, str);
6734 input = build_string (strlen (buf), buf);
6737 input = build_string (constraint_len - 1, constraint + 1);
6741 input = build_tree_list (build_tree_list (NULL_TREE, input),
6742 unshare_expr (TREE_VALUE (link)));
6743 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6747 link_next = NULL_TREE;
6748 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6750 link_next = TREE_CHAIN (link);
6751 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6752 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6753 oconstraints, &allows_mem, &allows_reg);
6755 /* If we can't make copies, we can only accept memory. */
6756 tree intype = TREE_TYPE (TREE_VALUE (link));
6757 if (intype != error_mark_node
6758 && (TREE_ADDRESSABLE (intype)
6759 || !COMPLETE_TYPE_P (intype)
6760 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
6766 error ("impossible constraint in %<asm%>");
6767 error ("non-memory input %d must stay in memory", i);
6772 /* If the operand is a memory input, it should be an lvalue. */
6773 if (!allows_reg && allows_mem)
6775 tree inputv = TREE_VALUE (link);
6776 STRIP_NOPS (inputv);
6777 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6778 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6779 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6780 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6781 || TREE_CODE (inputv) == MODIFY_EXPR)
6782 TREE_VALUE (link) = error_mark_node;
6783 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6784 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6785 if (tret != GS_ERROR)
6787 /* Unlike output operands, memory inputs are not guaranteed
6788 to be lvalues by the FE, and while the expressions are
6789 marked addressable there, if it is e.g. a statement
6790 expression, temporaries in it might not end up being
6791 addressable. They might be already used in the IL and thus
6792 it is too late to make them addressable now though. */
6793 tree x = TREE_VALUE (link);
6794 while (handled_component_p (x))
6795 x = TREE_OPERAND (x, 0);
6796 if (TREE_CODE (x) == MEM_REF
6797 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6798 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6800 || TREE_CODE (x) == PARM_DECL
6801 || TREE_CODE (x) == RESULT_DECL)
6802 && !TREE_ADDRESSABLE (x)
6803 && is_gimple_reg (x))
6805 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6807 "memory input %d is not directly addressable",
6809 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6812 mark_addressable (TREE_VALUE (link));
6813 if (tret == GS_ERROR)
6815 if (inputv != error_mark_node)
6816 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6817 "memory input %d is not directly addressable", i);
6823 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6824 is_gimple_asm_val, fb_rvalue);
6825 if (tret == GS_ERROR)
6829 TREE_CHAIN (link) = NULL_TREE;
6830 vec_safe_push (inputs, link);
6833 link_next = NULL_TREE;
6834 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6836 link_next = TREE_CHAIN (link);
6837 TREE_CHAIN (link) = NULL_TREE;
6838 vec_safe_push (clobbers, link);
6841 link_next = NULL_TREE;
6842 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6844 link_next = TREE_CHAIN (link);
6845 TREE_CHAIN (link) = NULL_TREE;
6846 vec_safe_push (labels, link);
6849 /* Do not add ASMs with errors to the gimple IL stream. */
6850 if (ret != GS_ERROR)
6852 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6853 inputs, outputs, clobbers, labels);
6855 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
6856 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6857 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
6859 gimplify_seq_add_stmt (pre_p, stmt);
6865 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6866 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6867 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6868 return to this function.
6870 FIXME should we complexify the prequeue handling instead? Or use flags
6871 for all the cleanups and let the optimizer tighten them up? The current
6872 code seems pretty fragile; it will break on a cleanup within any
6873 non-conditional nesting. But any such nesting would be broken, anyway;
6874 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6875 and continues out of it. We can do that at the RTL level, though, so
6876 having an optimizer to tighten up try/finally regions would be a Good
6879 static enum gimplify_status
6880 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6882 gimple_stmt_iterator iter;
6883 gimple_seq body_sequence = NULL;
6885 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6887 /* We only care about the number of conditions between the innermost
6888 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6889 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6890 int old_conds = gimplify_ctxp->conditions;
6891 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6892 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6893 gimplify_ctxp->conditions = 0;
6894 gimplify_ctxp->conditional_cleanups = NULL;
6895 gimplify_ctxp->in_cleanup_point_expr = true;
6897 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6899 gimplify_ctxp->conditions = old_conds;
6900 gimplify_ctxp->conditional_cleanups = old_cleanups;
6901 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6903 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6905 gimple *wce = gsi_stmt (iter);
6907 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6909 if (gsi_one_before_end_p (iter))
6911 /* Note that gsi_insert_seq_before and gsi_remove do not
6912 scan operands, unlike some other sequence mutators. */
6913 if (!gimple_wce_cleanup_eh_only (wce))
6914 gsi_insert_seq_before_without_update (&iter,
6915 gimple_wce_cleanup (wce),
6917 gsi_remove (&iter, true);
6924 enum gimple_try_flags kind;
6926 if (gimple_wce_cleanup_eh_only (wce))
6927 kind = GIMPLE_TRY_CATCH;
6929 kind = GIMPLE_TRY_FINALLY;
6930 seq = gsi_split_seq_after (iter);
6932 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6933 /* Do not use gsi_replace here, as it may scan operands.
6934 We want to do a simple structural modification only. */
6935 gsi_set_stmt (&iter, gtry);
6936 iter = gsi_start (gtry->eval);
6943 gimplify_seq_add_seq (pre_p, body_sequence);
6956 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6957 is the cleanup action required. EH_ONLY is true if the cleanup should
6958 only be executed if an exception is thrown, not on normal exit.
6959 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6960 only valid for clobbers. */
6963 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6964 bool force_uncond = false)
6967 gimple_seq cleanup_stmts = NULL;
6969 /* Errors can result in improperly nested cleanups. Which results in
6970 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6974 if (gimple_conditional_context ())
6976 /* If we're in a conditional context, this is more complex. We only
6977 want to run the cleanup if we actually ran the initialization that
6978 necessitates it, but we want to run it after the end of the
6979 conditional context. So we wrap the try/finally around the
6980 condition and use a flag to determine whether or not to actually
6981 run the destructor. Thus
6985 becomes (approximately)
6989 if (test) { A::A(temp); flag = 1; val = f(temp); }
6992 if (flag) A::~A(temp);
6998 gimplify_stmt (&cleanup, &cleanup_stmts);
6999 wce = gimple_build_wce (cleanup_stmts);
7000 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
7004 tree flag = create_tmp_var (boolean_type_node, "cleanup");
7005 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
7006 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
7008 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
7009 gimplify_stmt (&cleanup, &cleanup_stmts);
7010 wce = gimple_build_wce (cleanup_stmts);
7011 gimple_wce_set_cleanup_eh_only (wce, eh_only);
7013 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
7014 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
7015 gimplify_seq_add_stmt (pre_p, ftrue);
7017 /* Because of this manipulation, and the EH edges that jump
7018 threading cannot redirect, the temporary (VAR) will appear
7019 to be used uninitialized. Don't warn. */
7020 suppress_warning (var, OPT_Wuninitialized);
7025 gimplify_stmt (&cleanup, &cleanup_stmts);
7026 wce = gimple_build_wce (cleanup_stmts);
7027 gimple_wce_set_cleanup_eh_only (wce, eh_only);
7028 gimplify_seq_add_stmt (pre_p, wce);
7032 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
7034 static enum gimplify_status
7035 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
7037 tree targ = *expr_p;
7038 tree temp = TARGET_EXPR_SLOT (targ);
7039 tree init = TARGET_EXPR_INITIAL (targ);
7040 enum gimplify_status ret;
7042 bool unpoison_empty_seq = false;
7043 gimple_stmt_iterator unpoison_it;
7047 gimple_seq init_pre_p = NULL;
7049 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
7050 to the temps list. Handle also variable length TARGET_EXPRs. */
7051 if (!poly_int_tree_p (DECL_SIZE (temp)))
7053 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
7054 gimplify_type_sizes (TREE_TYPE (temp), &init_pre_p);
7055 /* FIXME: this is correct only when the size of the type does
7056 not depend on expressions evaluated in init. */
7057 gimplify_vla_decl (temp, &init_pre_p);
7061 /* Save location where we need to place unpoisoning. It's possible
7062 that a variable will be converted to needs_to_live_in_memory. */
7063 unpoison_it = gsi_last (*pre_p);
7064 unpoison_empty_seq = gsi_end_p (unpoison_it);
7066 gimple_add_tmp_var (temp);
7069 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
7070 expression is supposed to initialize the slot. */
7071 if (VOID_TYPE_P (TREE_TYPE (init)))
7072 ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
7076 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
7078 ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
7081 ggc_free (init_expr);
7083 if (ret == GS_ERROR)
7085 /* PR c++/28266 Make sure this is expanded only once. */
7086 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
7091 gimplify_and_add (init, &init_pre_p);
7093 /* Add a clobber for the temporary going out of scope, like
7094 gimplify_bind_expr. */
7095 if (gimplify_ctxp->in_cleanup_point_expr
7096 && needs_to_live_in_memory (temp))
7098 if (flag_stack_reuse == SR_ALL)
7100 tree clobber = build_clobber (TREE_TYPE (temp), CLOBBER_EOL);
7101 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
7102 gimple_push_cleanup (temp, clobber, false, pre_p, true);
7104 if (asan_poisoned_variables
7105 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
7106 && !TREE_STATIC (temp)
7107 && dbg_cnt (asan_use_after_scope)
7108 && !gimplify_omp_ctxp)
7110 tree asan_cleanup = build_asan_poison_call_expr (temp);
7113 if (unpoison_empty_seq)
7114 unpoison_it = gsi_start (*pre_p);
7116 asan_poison_variable (temp, false, &unpoison_it,
7117 unpoison_empty_seq);
7118 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
7123 gimple_seq_add_seq (pre_p, init_pre_p);
7125 /* If needed, push the cleanup for the temp. */
7126 if (TARGET_EXPR_CLEANUP (targ))
7127 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
7128 CLEANUP_EH_ONLY (targ), pre_p);
7130 /* Only expand this once. */
7131 TREE_OPERAND (targ, 3) = init;
7132 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
7135 /* We should have expanded this before. */
7136 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
7142 /* Gimplification of expression trees. */
7144 /* Gimplify an expression which appears at statement context. The
7145 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
7146 NULL, a new sequence is allocated.
7148 Return true if we actually added a statement to the queue. */
7151 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
7153 gimple_seq_node last;
7155 last = gimple_seq_last (*seq_p);
7156 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
7157 return last != gimple_seq_last (*seq_p);
7160 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
7161 to CTX. If entries already exist, force them to be some flavor of private.
7162 If there is no enclosing parallel, do nothing. */
7165 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
7169 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
7174 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7177 if (n->value & GOVD_SHARED)
7178 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
7179 else if (n->value & GOVD_MAP)
7180 n->value |= GOVD_MAP_TO_ONLY;
7184 else if ((ctx->region_type & ORT_TARGET) != 0)
7186 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
7187 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7189 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
7191 else if (ctx->region_type != ORT_WORKSHARE
7192 && ctx->region_type != ORT_TASKGROUP
7193 && ctx->region_type != ORT_SIMD
7194 && ctx->region_type != ORT_ACC
7195 && !(ctx->region_type & ORT_TARGET_DATA))
7196 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7198 ctx = ctx->outer_context;
7203 /* Similarly for each of the type sizes of TYPE. */
7206 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
7208 if (type == NULL || type == error_mark_node)
7210 type = TYPE_MAIN_VARIANT (type);
7212 if (ctx->privatized_types->add (type))
7215 switch (TREE_CODE (type))
7221 case FIXED_POINT_TYPE:
7222 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
7223 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
7227 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7228 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
7233 case QUAL_UNION_TYPE:
7236 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
7237 if (TREE_CODE (field) == FIELD_DECL)
7239 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
7240 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
7246 case REFERENCE_TYPE:
7247 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7254 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
7255 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
7256 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
7259 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
7262 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
7265 unsigned int nflags;
7268 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
7271 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
7272 there are constructors involved somewhere. Exception is a shared clause,
7273 there is nothing privatized in that case. */
7274 if ((flags & GOVD_SHARED) == 0
7275 && (TREE_ADDRESSABLE (TREE_TYPE (decl))
7276 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
7279 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7280 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7282 /* We shouldn't be re-adding the decl with the same data
7284 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
7285 nflags = n->value | flags;
7286 /* The only combination of data sharing classes we should see is
7287 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
7288 reduction variables to be used in data sharing clauses. */
7289 gcc_assert ((ctx->region_type & ORT_ACC) != 0
7290 || ((nflags & GOVD_DATA_SHARE_CLASS)
7291 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
7292 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
7297 /* When adding a variable-sized variable, we have to handle all sorts
7298 of additional bits of data: the pointer replacement variable, and
7299 the parameters of the type. */
7300 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7302 /* Add the pointer replacement variable as PRIVATE if the variable
7303 replacement is private, else FIRSTPRIVATE since we'll need the
7304 address of the original variable either for SHARED, or for the
7305 copy into or out of the context. */
7306 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
7308 if (flags & GOVD_MAP)
7309 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
7310 else if (flags & GOVD_PRIVATE)
7311 nflags = GOVD_PRIVATE;
7312 else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7313 && (flags & GOVD_FIRSTPRIVATE))
7314 || (ctx->region_type == ORT_TARGET_DATA
7315 && (flags & GOVD_DATA_SHARE_CLASS) == 0))
7316 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
7318 nflags = GOVD_FIRSTPRIVATE;
7319 nflags |= flags & GOVD_SEEN;
7320 t = DECL_VALUE_EXPR (decl);
7321 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7322 t = TREE_OPERAND (t, 0);
7323 gcc_assert (DECL_P (t));
7324 omp_add_variable (ctx, t, nflags);
7327 /* Add all of the variable and type parameters (which should have
7328 been gimplified to a formal temporary) as FIRSTPRIVATE. */
7329 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
7330 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
7331 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7333 /* The variable-sized variable itself is never SHARED, only some form
7334 of PRIVATE. The sharing would take place via the pointer variable
7335 which we remapped above. */
7336 if (flags & GOVD_SHARED)
7337 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
7338 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
7340 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7341 alloca statement we generate for the variable, so make sure it
7342 is available. This isn't automatically needed for the SHARED
7343 case, since we won't be allocating local storage then.
7344 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7345 in this case omp_notice_variable will be called later
7346 on when it is gimplified. */
7347 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
7348 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
7349 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
7351 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
7352 && omp_privatize_by_reference (decl))
7354 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7356 /* Similar to the direct variable sized case above, we'll need the
7357 size of references being privatized. */
7358 if ((flags & GOVD_SHARED) == 0)
7360 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7361 if (t && DECL_P (t))
7362 omp_notice_variable (ctx, t, true);
7369 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
7371 /* For reductions clauses in OpenACC loop directives, by default create a
7372 copy clause on the enclosing parallel construct for carrying back the
7374 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
7376 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
7379 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
7382 /* Ignore local variables and explicitly declared clauses. */
7383 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
7385 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
7387 /* According to the OpenACC spec, such a reduction variable
7388 should already have a copy map on a kernels construct,
7389 verify that here. */
7390 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
7391 && (n->value & GOVD_MAP));
7393 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7395 /* Remove firstprivate and make it a copy map. */
7396 n->value &= ~GOVD_FIRSTPRIVATE;
7397 n->value |= GOVD_MAP;
7400 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7402 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
7403 GOVD_MAP | GOVD_SEEN);
7406 outer_ctx = outer_ctx->outer_context;
7411 /* Notice a threadprivate variable DECL used in OMP context CTX.
7412 This just prints out diagnostics about threadprivate variable uses
7413 in untied tasks. If DECL2 is non-NULL, prevent this warning
7414 on that variable. */
7417 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
7421 struct gimplify_omp_ctx *octx;
7423 for (octx = ctx; octx; octx = octx->outer_context)
7424 if ((octx->region_type & ORT_TARGET) != 0
7425 || octx->order_concurrent)
7427 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
7430 if (octx->order_concurrent)
7432 error ("threadprivate variable %qE used in a region with"
7433 " %<order(concurrent)%> clause", DECL_NAME (decl));
7434 inform (octx->location, "enclosing region");
7438 error ("threadprivate variable %qE used in target region",
7440 inform (octx->location, "enclosing target region");
7442 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
7445 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
7448 if (ctx->region_type != ORT_UNTIED_TASK)
7450 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7453 error ("threadprivate variable %qE used in untied task",
7455 inform (ctx->location, "enclosing task");
7456 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
7459 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
7463 /* Return true if global var DECL is device resident. */
7466 device_resident_p (tree decl)
7468 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
7473 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
7475 tree c = TREE_VALUE (t);
7476 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
7483 /* Return true if DECL has an ACC DECLARE attribute. */
7486 is_oacc_declared (tree decl)
7488 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
7489 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
7490 return declared != NULL_TREE;
7493 /* Determine outer default flags for DECL mentioned in an OMP region
7494 but not declared in an enclosing clause.
7496 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7497 remapped firstprivate instead of shared. To some extent this is
7498 addressed in omp_firstprivatize_type_sizes, but not
7502 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
7503 bool in_code, unsigned flags)
7505 enum omp_clause_default_kind default_kind = ctx->default_kind;
7506 enum omp_clause_default_kind kind;
7508 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
7509 if (ctx->region_type & ORT_TASK)
7511 tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH);
7513 /* The event-handle specified by a detach clause should always be firstprivate,
7514 regardless of the current default. */
7515 if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl)
7516 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
7518 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7519 default_kind = kind;
7520 else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
7521 default_kind = OMP_CLAUSE_DEFAULT_SHARED;
7522 /* For C/C++ default({,first}private), variables with static storage duration
7523 declared in a namespace or global scope and referenced in construct
7524 must be explicitly specified, i.e. acts as default(none). */
7525 else if ((default_kind == OMP_CLAUSE_DEFAULT_PRIVATE
7526 || default_kind == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
7528 && is_global_var (decl)
7529 && (DECL_FILE_SCOPE_P (decl)
7530 || (DECL_CONTEXT (decl)
7531 && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
7532 && !lang_GNU_Fortran ())
7533 default_kind = OMP_CLAUSE_DEFAULT_NONE;
7535 switch (default_kind)
7537 case OMP_CLAUSE_DEFAULT_NONE:
7541 if (ctx->region_type & ORT_PARALLEL)
7543 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
7545 else if (ctx->region_type & ORT_TASK)
7547 else if (ctx->region_type & ORT_TEAMS)
7552 error ("%qE not specified in enclosing %qs",
7553 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7554 inform (ctx->location, "enclosing %qs", rtype);
7557 case OMP_CLAUSE_DEFAULT_SHARED:
7558 flags |= GOVD_SHARED;
7560 case OMP_CLAUSE_DEFAULT_PRIVATE:
7561 flags |= GOVD_PRIVATE;
7563 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7564 flags |= GOVD_FIRSTPRIVATE;
7566 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7567 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7568 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7569 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7571 omp_notice_variable (octx, decl, in_code);
7572 for (; octx; octx = octx->outer_context)
7576 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7577 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7578 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7580 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7582 flags |= GOVD_FIRSTPRIVATE;
7585 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7587 flags |= GOVD_SHARED;
7593 if (TREE_CODE (decl) == PARM_DECL
7594 || (!is_global_var (decl)
7595 && DECL_CONTEXT (decl) == current_function_decl))
7596 flags |= GOVD_FIRSTPRIVATE;
7598 flags |= GOVD_SHARED;
7610 /* Determine outer default flags for DECL mentioned in an OACC region
7611 but not declared in an enclosing clause. */
7614 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7617 bool on_device = false;
7618 bool is_private = false;
7619 bool declared = is_oacc_declared (decl);
7620 tree type = TREE_TYPE (decl);
7622 if (omp_privatize_by_reference (decl))
7623 type = TREE_TYPE (type);
7625 /* For Fortran COMMON blocks, only used variables in those blocks are
7626 transfered and remapped. The block itself will have a private clause to
7627 avoid transfering the data twice.
7628 The hook evaluates to false by default. For a variable in Fortran's COMMON
7629 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7630 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7631 the whole block. For C++ and Fortran, it can also be true under certain
7632 other conditions, if DECL_HAS_VALUE_EXPR. */
7633 if (RECORD_OR_UNION_TYPE_P (type))
7634 is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
7636 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7637 && is_global_var (decl)
7638 && device_resident_p (decl)
7642 flags |= GOVD_MAP_TO_ONLY;
7645 switch (ctx->region_type)
7647 case ORT_ACC_KERNELS:
7651 flags |= GOVD_FIRSTPRIVATE;
7652 else if (AGGREGATE_TYPE_P (type))
7654 /* Aggregates default to 'present_or_copy', or 'present'. */
7655 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7658 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7661 /* Scalars default to 'copy'. */
7662 flags |= GOVD_MAP | GOVD_MAP_FORCE;
7666 case ORT_ACC_PARALLEL:
7667 case ORT_ACC_SERIAL:
7668 rkind = ctx->region_type == ORT_ACC_PARALLEL ? "parallel" : "serial";
7671 flags |= GOVD_FIRSTPRIVATE;
7672 else if (on_device || declared)
7674 else if (AGGREGATE_TYPE_P (type))
7676 /* Aggregates default to 'present_or_copy', or 'present'. */
7677 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7680 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7683 /* Scalars default to 'firstprivate'. */
7684 flags |= GOVD_FIRSTPRIVATE;
7692 if (DECL_ARTIFICIAL (decl))
7693 ; /* We can get compiler-generated decls, and should not complain
7695 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7697 error ("%qE not specified in enclosing OpenACC %qs construct",
7698 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
7699 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
7701 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7702 ; /* Handled above. */
7704 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7709 /* Record the fact that DECL was used within the OMP context CTX.
7710 IN_CODE is true when real code uses DECL, and false when we should
7711 merely emit default(none) errors. Return true if DECL is going to
7712 be remapped and thus DECL shouldn't be gimplified into its
7713 DECL_VALUE_EXPR (if any). */
7716 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7719 unsigned flags = in_code ? GOVD_SEEN : 0;
7720 bool ret = false, shared;
7722 if (error_operand_p (decl))
7725 if (ctx->region_type == ORT_NONE)
7726 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7728 if (is_global_var (decl))
7730 /* Threadprivate variables are predetermined. */
7731 if (DECL_THREAD_LOCAL_P (decl))
7732 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7734 if (DECL_HAS_VALUE_EXPR_P (decl))
7736 if (ctx->region_type & ORT_ACC)
7737 /* For OpenACC, defer expansion of value to avoid transfering
7738 privatized common block data instead of im-/explicitly transfered
7739 variables which are in common blocks. */
7743 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7745 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7746 return omp_notice_threadprivate_variable (ctx, decl, value);
7750 if (gimplify_omp_ctxp->outer_context == NULL
7752 && oacc_get_fn_attrib (current_function_decl))
7754 location_t loc = DECL_SOURCE_LOCATION (decl);
7756 if (lookup_attribute ("omp declare target link",
7757 DECL_ATTRIBUTES (decl)))
7760 "%qE with %<link%> clause used in %<routine%> function",
7764 else if (!lookup_attribute ("omp declare target",
7765 DECL_ATTRIBUTES (decl)))
7768 "%qE requires a %<declare%> directive for use "
7769 "in a %<routine%> function", DECL_NAME (decl));
7775 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7776 if ((ctx->region_type & ORT_TARGET) != 0)
7778 if (ctx->region_type & ORT_ACC)
7779 /* For OpenACC, as remarked above, defer expansion. */
7784 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7787 unsigned nflags = flags;
7788 if ((ctx->region_type & ORT_ACC) == 0)
7790 bool is_declare_target = false;
7791 if (is_global_var (decl)
7792 && varpool_node::get_create (decl)->offloadable)
7794 struct gimplify_omp_ctx *octx;
7795 for (octx = ctx->outer_context;
7796 octx; octx = octx->outer_context)
7798 n = splay_tree_lookup (octx->variables,
7799 (splay_tree_key)decl);
7801 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7802 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7805 is_declare_target = octx == NULL;
7807 if (!is_declare_target)
7810 enum omp_clause_defaultmap_kind kind;
7811 if (lang_hooks.decls.omp_allocatable_p (decl))
7812 gdmk = GDMK_ALLOCATABLE;
7813 else if (lang_hooks.decls.omp_scalar_target_p (decl))
7814 gdmk = GDMK_SCALAR_TARGET;
7815 else if (lang_hooks.decls.omp_scalar_p (decl, false))
7817 else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7818 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7819 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7821 gdmk = GDMK_POINTER;
7823 gdmk = GDMK_AGGREGATE;
7824 kind = lang_hooks.decls.omp_predetermined_mapping (decl);
7825 if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
7827 if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
7828 nflags |= GOVD_FIRSTPRIVATE;
7829 else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
7830 nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
7834 else if (ctx->defaultmap[gdmk] == 0)
7836 tree d = lang_hooks.decls.omp_report_decl (decl);
7837 error ("%qE not specified in enclosing %<target%>",
7839 inform (ctx->location, "enclosing %<target%>");
7841 else if (ctx->defaultmap[gdmk]
7842 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
7843 nflags |= ctx->defaultmap[gdmk];
7846 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
7847 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
7852 struct gimplify_omp_ctx *octx = ctx->outer_context;
7853 if ((ctx->region_type & ORT_ACC) && octx)
7855 /* Look in outer OpenACC contexts, to see if there's a
7856 data attribute for this variable. */
7857 omp_notice_variable (octx, decl, in_code);
7859 for (; octx; octx = octx->outer_context)
7861 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7864 = splay_tree_lookup (octx->variables,
7865 (splay_tree_key) decl);
7868 if (octx->region_type == ORT_ACC_HOST_DATA)
7869 error ("variable %qE declared in enclosing "
7870 "%<host_data%> region", DECL_NAME (decl));
7872 if (octx->region_type == ORT_ACC_DATA
7873 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7874 nflags |= GOVD_MAP_0LEN_ARRAY;
7880 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
7881 | GOVD_MAP_ALLOC_ONLY)) == flags)
7883 tree type = TREE_TYPE (decl);
7885 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
7886 && omp_privatize_by_reference (decl))
7887 type = TREE_TYPE (type);
7888 if (!omp_mappable_type (type))
7890 error ("%qD referenced in target region does not have "
7891 "a mappable type", decl);
7892 nflags |= GOVD_MAP | GOVD_EXPLICIT;
7896 if ((ctx->region_type & ORT_ACC) != 0)
7897 nflags = oacc_default_clause (ctx, decl, flags);
7903 omp_add_variable (ctx, decl, nflags);
7907 /* If nothing changed, there's nothing left to do. */
7908 if ((n->value & flags) == flags)
7918 if (ctx->region_type == ORT_WORKSHARE
7919 || ctx->region_type == ORT_TASKGROUP
7920 || ctx->region_type == ORT_SIMD
7921 || ctx->region_type == ORT_ACC
7922 || (ctx->region_type & ORT_TARGET_DATA) != 0)
7925 flags = omp_default_clause (ctx, decl, in_code, flags);
7927 if ((flags & GOVD_PRIVATE)
7928 && lang_hooks.decls.omp_private_outer_ref (decl))
7929 flags |= GOVD_PRIVATE_OUTER_REF;
7931 omp_add_variable (ctx, decl, flags);
7933 shared = (flags & GOVD_SHARED) != 0;
7934 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7938 /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
7939 lb, b or incr expressions, those shouldn't be turned into simd arrays. */
7940 if (ctx->region_type == ORT_SIMD
7941 && ctx->in_for_exprs
7942 && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
7944 flags &= ~GOVD_SEEN;
7946 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7947 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7948 && DECL_SIZE (decl))
7950 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7953 tree t = DECL_VALUE_EXPR (decl);
7954 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7955 t = TREE_OPERAND (t, 0);
7956 gcc_assert (DECL_P (t));
7957 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7958 n2->value |= GOVD_SEEN;
7960 else if (omp_privatize_by_reference (decl)
7961 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7962 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7966 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7967 gcc_assert (DECL_P (t));
7968 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7970 omp_notice_variable (ctx, t, true);
7974 if (ctx->region_type & ORT_ACC)
7975 /* For OpenACC, as remarked above, defer expansion. */
7978 shared = ((flags | n->value) & GOVD_SHARED) != 0;
7979 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7981 /* If nothing changed, there's nothing left to do. */
7982 if ((n->value & flags) == flags)
7988 /* If the variable is private in the current context, then we don't
7989 need to propagate anything to an outer context. */
7990 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7992 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7993 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7995 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7996 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7997 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7999 if (ctx->outer_context
8000 && omp_notice_variable (ctx->outer_context, decl, in_code))
8005 /* Verify that DECL is private within CTX. If there's specific information
8006 to the contrary in the innermost scope, generate an error. */
8009 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
8013 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
8016 if (n->value & GOVD_SHARED)
8018 if (ctx == gimplify_omp_ctxp)
8021 error ("iteration variable %qE is predetermined linear",
8024 error ("iteration variable %qE should be private",
8026 n->value = GOVD_PRIVATE;
8032 else if ((n->value & GOVD_EXPLICIT) != 0
8033 && (ctx == gimplify_omp_ctxp
8034 || (ctx->region_type == ORT_COMBINED_PARALLEL
8035 && gimplify_omp_ctxp->outer_context == ctx)))
8037 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
8038 error ("iteration variable %qE should not be firstprivate",
8040 else if ((n->value & GOVD_REDUCTION) != 0)
8041 error ("iteration variable %qE should not be reduction",
8043 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
8044 error ("iteration variable %qE should not be linear",
8047 return (ctx == gimplify_omp_ctxp
8048 || (ctx->region_type == ORT_COMBINED_PARALLEL
8049 && gimplify_omp_ctxp->outer_context == ctx));
8052 if (ctx->region_type != ORT_WORKSHARE
8053 && ctx->region_type != ORT_TASKGROUP
8054 && ctx->region_type != ORT_SIMD
8055 && ctx->region_type != ORT_ACC)
8057 else if (ctx->outer_context)
8058 return omp_is_private (ctx->outer_context, decl, simd);
8062 /* Return true if DECL is private within a parallel region
8063 that binds to the current construct's context or in parallel
8064 region's REDUCTION clause. */
8067 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
8073 ctx = ctx->outer_context;
8076 if (is_global_var (decl))
8079 /* References might be private, but might be shared too,
8080 when checking for copyprivate, assume they might be
8081 private, otherwise assume they might be shared. */
8085 if (omp_privatize_by_reference (decl))
8088 /* Treat C++ privatized non-static data members outside
8089 of the privatization the same. */
8090 if (omp_member_access_dummy_var (decl))
8096 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8098 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
8099 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
8101 if ((ctx->region_type & ORT_TARGET_DATA) != 0
8103 || (n->value & GOVD_MAP) == 0)
8110 if ((n->value & GOVD_LOCAL) != 0
8111 && omp_member_access_dummy_var (decl))
8113 return (n->value & GOVD_SHARED) == 0;
8116 if (ctx->region_type == ORT_WORKSHARE
8117 || ctx->region_type == ORT_TASKGROUP
8118 || ctx->region_type == ORT_SIMD
8119 || ctx->region_type == ORT_ACC)
8128 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
8131 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
8135 /* If this node has been visited, unmark it and keep looking. */
8136 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
8139 if (IS_TYPE_OR_DECL_P (t))
8145 /* Gimplify the affinity clause but effectively ignore it.
8148 if ((step > 1) ? var <= end : var > end)
8149 locatator_var_expr; */
8152 gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p)
8154 tree last_iter = NULL_TREE;
8155 tree last_bind = NULL_TREE;
8156 tree label = NULL_TREE;
8157 tree *last_body = NULL;
8158 for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8159 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
8161 tree t = OMP_CLAUSE_DECL (c);
8162 if (TREE_CODE (t) == TREE_LIST
8164 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8166 if (TREE_VALUE (t) == null_pointer_node)
8168 if (TREE_PURPOSE (t) != last_iter)
8172 append_to_statement_list (label, last_body);
8173 gimplify_and_add (last_bind, pre_p);
8174 last_bind = NULL_TREE;
8176 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8178 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8179 is_gimple_val, fb_rvalue) == GS_ERROR
8180 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8181 is_gimple_val, fb_rvalue) == GS_ERROR
8182 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8183 is_gimple_val, fb_rvalue) == GS_ERROR
8184 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8185 is_gimple_val, fb_rvalue)
8189 last_iter = TREE_PURPOSE (t);
8190 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8191 last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
8193 last_body = &BIND_EXPR_BODY (last_bind);
8194 tree cond = NULL_TREE;
8195 location_t loc = OMP_CLAUSE_LOCATION (c);
8196 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8198 tree var = TREE_VEC_ELT (it, 0);
8199 tree begin = TREE_VEC_ELT (it, 1);
8200 tree end = TREE_VEC_ELT (it, 2);
8201 tree step = TREE_VEC_ELT (it, 3);
8202 loc = DECL_SOURCE_LOCATION (var);
8203 tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8205 append_to_statement_list_force (tem, last_body);
8207 tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8208 step, build_zero_cst (TREE_TYPE (step)));
8209 tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node,
8211 tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8213 cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node,
8214 cond1, cond2, cond3);
8216 cond = fold_build2_loc (loc, TRUTH_AND_EXPR,
8217 boolean_type_node, cond, cond1);
8221 tree cont_label = create_artificial_label (loc);
8222 label = build1 (LABEL_EXPR, void_type_node, cont_label);
8223 tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
8225 build_and_jump (&cont_label));
8226 append_to_statement_list_force (tem, last_body);
8228 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8230 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0),
8232 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8234 if (error_operand_p (TREE_VALUE (t)))
8236 append_to_statement_list_force (TREE_VALUE (t), last_body);
8237 TREE_VALUE (t) = null_pointer_node;
8243 append_to_statement_list (label, last_body);
8244 gimplify_and_add (last_bind, pre_p);
8245 last_bind = NULL_TREE;
8247 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8249 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8250 NULL, is_gimple_val, fb_rvalue);
8251 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8253 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8255 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8256 is_gimple_lvalue, fb_lvalue) == GS_ERROR)
8258 gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p);
8263 append_to_statement_list (label, last_body);
8264 gimplify_and_add (last_bind, pre_p);
8269 /* If *LIST_P contains any OpenMP depend clauses with iterators,
8270 lower all the depend clauses by populating corresponding depend
8271 array. Returns 0 if there are no such depend clauses, or
8272 2 if all depend clauses should be removed, 1 otherwise. */
8275 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
8279 size_t n[5] = { 0, 0, 0, 0, 0 };
8281 tree counts[5] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
8282 tree last_iter = NULL_TREE, last_count = NULL_TREE;
8284 location_t first_loc = UNKNOWN_LOCATION;
8286 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8287 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8289 switch (OMP_CLAUSE_DEPEND_KIND (c))
8291 case OMP_CLAUSE_DEPEND_IN:
8294 case OMP_CLAUSE_DEPEND_OUT:
8295 case OMP_CLAUSE_DEPEND_INOUT:
8298 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8301 case OMP_CLAUSE_DEPEND_DEPOBJ:
8304 case OMP_CLAUSE_DEPEND_INOUTSET:
8307 case OMP_CLAUSE_DEPEND_SOURCE:
8308 case OMP_CLAUSE_DEPEND_SINK:
8313 tree t = OMP_CLAUSE_DECL (c);
8314 if (first_loc == UNKNOWN_LOCATION)
8315 first_loc = OMP_CLAUSE_LOCATION (c);
8316 if (TREE_CODE (t) == TREE_LIST
8318 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8320 if (TREE_PURPOSE (t) != last_iter)
8322 tree tcnt = size_one_node;
8323 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8325 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8326 is_gimple_val, fb_rvalue) == GS_ERROR
8327 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8328 is_gimple_val, fb_rvalue) == GS_ERROR
8329 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8330 is_gimple_val, fb_rvalue) == GS_ERROR
8331 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8332 is_gimple_val, fb_rvalue)
8335 tree var = TREE_VEC_ELT (it, 0);
8336 tree begin = TREE_VEC_ELT (it, 1);
8337 tree end = TREE_VEC_ELT (it, 2);
8338 tree step = TREE_VEC_ELT (it, 3);
8339 tree orig_step = TREE_VEC_ELT (it, 4);
8340 tree type = TREE_TYPE (var);
8341 tree stype = TREE_TYPE (step);
8342 location_t loc = DECL_SOURCE_LOCATION (var);
8344 /* Compute count for this iterator as
8346 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
8347 : (begin > end ? (end - begin + (step + 1)) / step : 0)
8348 and compute product of those for the entire depend
8350 if (POINTER_TYPE_P (type))
8351 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
8354 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
8356 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
8358 build_int_cst (stype, 1));
8359 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
8360 build_int_cst (stype, 1));
8361 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
8362 unshare_expr (endmbegin),
8364 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8366 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
8368 if (TYPE_UNSIGNED (stype))
8370 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
8371 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
8373 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8376 tree cond = fold_build2_loc (loc, LT_EXPR,
8379 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
8380 build_int_cst (stype, 0));
8381 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
8383 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
8384 build_int_cst (stype, 0));
8385 tree osteptype = TREE_TYPE (orig_step);
8386 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8388 build_int_cst (osteptype, 0));
8389 tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
8391 cnt = fold_convert_loc (loc, sizetype, cnt);
8392 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
8393 fb_rvalue) == GS_ERROR)
8395 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
8397 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
8398 fb_rvalue) == GS_ERROR)
8400 last_iter = TREE_PURPOSE (t);
8403 if (counts[i] == NULL_TREE)
8404 counts[i] = last_count;
8406 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
8407 PLUS_EXPR, counts[i], last_count);
8412 for (i = 0; i < 5; i++)
8418 tree total = size_zero_node;
8419 for (i = 0; i < 5; i++)
8421 unused[i] = counts[i] == NULL_TREE && n[i] == 0;
8422 if (counts[i] == NULL_TREE)
8423 counts[i] = size_zero_node;
8425 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
8426 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
8427 fb_rvalue) == GS_ERROR)
8429 total = size_binop (PLUS_EXPR, total, counts[i]);
8432 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
8435 bool is_old = unused[1] && unused[3] && unused[4];
8436 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
8437 size_int (is_old ? 1 : 4));
8439 totalpx = size_binop (PLUS_EXPR, totalpx,
8440 size_binop (MULT_EXPR, counts[4], size_int (2)));
8441 tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
8442 tree array = create_tmp_var_raw (type);
8443 TREE_ADDRESSABLE (array) = 1;
8444 if (!poly_int_tree_p (totalpx))
8446 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
8447 gimplify_type_sizes (TREE_TYPE (array), pre_p);
8448 if (gimplify_omp_ctxp)
8450 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8452 && (ctx->region_type == ORT_WORKSHARE
8453 || ctx->region_type == ORT_TASKGROUP
8454 || ctx->region_type == ORT_SIMD
8455 || ctx->region_type == ORT_ACC))
8456 ctx = ctx->outer_context;
8458 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
8460 gimplify_vla_decl (array, pre_p);
8463 gimple_add_tmp_var (array);
8464 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
8469 tem = build2 (MODIFY_EXPR, void_type_node, r,
8470 build_int_cst (ptr_type_node, 0));
8471 gimplify_and_add (tem, pre_p);
8472 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
8475 tem = build2 (MODIFY_EXPR, void_type_node, r,
8476 fold_convert (ptr_type_node, total));
8477 gimplify_and_add (tem, pre_p);
8478 for (i = 1; i < (is_old ? 2 : 4); i++)
8480 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
8481 NULL_TREE, NULL_TREE);
8482 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
8483 gimplify_and_add (tem, pre_p);
8490 for (i = 0; i < 5; i++)
8492 if (i && (i >= j || unused[i - 1]))
8494 cnts[i] = cnts[i - 1];
8497 cnts[i] = create_tmp_var (sizetype);
8499 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
8504 t = size_binop (PLUS_EXPR, counts[0], size_int (2));
8506 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
8507 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
8510 g = gimple_build_assign (cnts[i], t);
8512 gimple_seq_add_stmt (pre_p, g);
8515 cnts[5] = NULL_TREE;
8518 tree t = size_binop (PLUS_EXPR, total, size_int (5));
8519 cnts[5] = create_tmp_var (sizetype);
8520 g = gimple_build_assign (cnts[i], t);
8521 gimple_seq_add_stmt (pre_p, g);
8524 last_iter = NULL_TREE;
8525 tree last_bind = NULL_TREE;
8526 tree *last_body = NULL;
8527 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8528 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8530 switch (OMP_CLAUSE_DEPEND_KIND (c))
8532 case OMP_CLAUSE_DEPEND_IN:
8535 case OMP_CLAUSE_DEPEND_OUT:
8536 case OMP_CLAUSE_DEPEND_INOUT:
8539 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8542 case OMP_CLAUSE_DEPEND_DEPOBJ:
8545 case OMP_CLAUSE_DEPEND_INOUTSET:
8548 case OMP_CLAUSE_DEPEND_SOURCE:
8549 case OMP_CLAUSE_DEPEND_SINK:
8554 tree t = OMP_CLAUSE_DECL (c);
8555 if (TREE_CODE (t) == TREE_LIST
8557 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8559 if (TREE_PURPOSE (t) != last_iter)
8562 gimplify_and_add (last_bind, pre_p);
8563 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8564 last_bind = build3 (BIND_EXPR, void_type_node,
8565 BLOCK_VARS (block), NULL, block);
8566 TREE_SIDE_EFFECTS (last_bind) = 1;
8567 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
8568 tree *p = &BIND_EXPR_BODY (last_bind);
8569 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8571 tree var = TREE_VEC_ELT (it, 0);
8572 tree begin = TREE_VEC_ELT (it, 1);
8573 tree end = TREE_VEC_ELT (it, 2);
8574 tree step = TREE_VEC_ELT (it, 3);
8575 tree orig_step = TREE_VEC_ELT (it, 4);
8576 tree type = TREE_TYPE (var);
8577 location_t loc = DECL_SOURCE_LOCATION (var);
8585 if (orig_step > 0) {
8586 if (var < end) goto beg_label;
8588 if (var > end) goto beg_label;
8590 for each iterator, with inner iterators added to
8592 tree beg_label = create_artificial_label (loc);
8593 tree cond_label = NULL_TREE;
8594 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8596 append_to_statement_list_force (tem, p);
8597 tem = build_and_jump (&cond_label);
8598 append_to_statement_list_force (tem, p);
8599 tem = build1 (LABEL_EXPR, void_type_node, beg_label);
8600 append_to_statement_list (tem, p);
8601 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
8602 NULL_TREE, NULL_TREE);
8603 TREE_SIDE_EFFECTS (bind) = 1;
8604 SET_EXPR_LOCATION (bind, loc);
8605 append_to_statement_list_force (bind, p);
8606 if (POINTER_TYPE_P (type))
8607 tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
8608 var, fold_convert_loc (loc, sizetype,
8611 tem = build2_loc (loc, PLUS_EXPR, type, var, step);
8612 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8614 append_to_statement_list_force (tem, p);
8615 tem = build1 (LABEL_EXPR, void_type_node, cond_label);
8616 append_to_statement_list (tem, p);
8617 tree cond = fold_build2_loc (loc, LT_EXPR,
8621 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8622 cond, build_and_jump (&beg_label),
8624 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8627 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8628 cond, build_and_jump (&beg_label),
8630 tree osteptype = TREE_TYPE (orig_step);
8631 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8633 build_int_cst (osteptype, 0));
8634 tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
8636 append_to_statement_list_force (tem, p);
8637 p = &BIND_EXPR_BODY (bind);
8641 last_iter = TREE_PURPOSE (t);
8642 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8644 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
8646 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8648 if (error_operand_p (TREE_VALUE (t)))
8650 if (TREE_VALUE (t) != null_pointer_node)
8651 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
8654 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8655 NULL_TREE, NULL_TREE);
8656 tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5],
8657 NULL_TREE, NULL_TREE);
8658 r2 = build_fold_addr_expr_with_type (r2, ptr_type_node);
8659 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8660 void_type_node, r, r2);
8661 append_to_statement_list_force (tem, last_body);
8662 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8663 void_type_node, cnts[i],
8664 size_binop (PLUS_EXPR, cnts[i],
8666 append_to_statement_list_force (tem, last_body);
8669 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8670 NULL_TREE, NULL_TREE);
8671 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8672 void_type_node, r, TREE_VALUE (t));
8673 append_to_statement_list_force (tem, last_body);
8676 r = build4 (ARRAY_REF, ptr_type_node, array,
8677 size_binop (PLUS_EXPR, cnts[i], size_int (1)),
8678 NULL_TREE, NULL_TREE);
8679 tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
8680 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8681 void_type_node, r, tem);
8682 append_to_statement_list_force (tem, last_body);
8684 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8685 void_type_node, cnts[i],
8686 size_binop (PLUS_EXPR, cnts[i],
8687 size_int (1 + (i == 5))));
8688 append_to_statement_list_force (tem, last_body);
8689 TREE_VALUE (t) = null_pointer_node;
8695 gimplify_and_add (last_bind, pre_p);
8696 last_bind = NULL_TREE;
8698 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8700 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8701 NULL, is_gimple_val, fb_rvalue);
8702 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8704 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8706 if (OMP_CLAUSE_DECL (c) != null_pointer_node)
8707 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8708 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8709 is_gimple_val, fb_rvalue) == GS_ERROR)
8713 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8714 NULL_TREE, NULL_TREE);
8715 tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5],
8716 NULL_TREE, NULL_TREE);
8717 r2 = build_fold_addr_expr_with_type (r2, ptr_type_node);
8718 tem = build2 (MODIFY_EXPR, void_type_node, r, r2);
8719 gimplify_and_add (tem, pre_p);
8720 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR,
8723 gimple_seq_add_stmt (pre_p, g);
8726 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8727 NULL_TREE, NULL_TREE);
8728 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
8729 gimplify_and_add (tem, pre_p);
8732 r = build4 (ARRAY_REF, ptr_type_node, array,
8733 size_binop (PLUS_EXPR, cnts[i], size_int (1)),
8734 NULL_TREE, NULL_TREE);
8735 tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
8736 tem = build2 (MODIFY_EXPR, void_type_node, r, tem);
8737 append_to_statement_list_force (tem, last_body);
8738 gimplify_and_add (tem, pre_p);
8740 g = gimple_build_assign (cnts[i],
8741 size_binop (PLUS_EXPR, cnts[i],
8742 size_int (1 + (i == 5))));
8743 gimple_seq_add_stmt (pre_p, g);
8747 gimplify_and_add (last_bind, pre_p);
8748 tree cond = boolean_false_node;
8752 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
8753 size_binop_loc (first_loc, PLUS_EXPR, counts[0],
8756 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8757 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8759 size_binop_loc (first_loc, PLUS_EXPR,
8765 tree prev = size_int (5);
8766 for (i = 0; i < 5; i++)
8770 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
8771 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8772 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8773 cnts[i], unshare_expr (prev)));
8776 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
8777 build_call_expr_loc (first_loc,
8778 builtin_decl_explicit (BUILT_IN_TRAP),
8780 gimplify_and_add (tem, pre_p);
8781 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
8782 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
8783 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
8784 OMP_CLAUSE_CHAIN (c) = *list_p;
8789 /* Insert a GOMP_MAP_ALLOC or GOMP_MAP_RELEASE node following a
8790 GOMP_MAP_STRUCT mapping. C is an always_pointer mapping. STRUCT_NODE is
8791 the struct node to insert the new mapping after (when the struct node is
8792 initially created). PREV_NODE is the first of two or three mappings for a
8793 pointer, and is either:
8794 - the node before C, when a pair of mappings is used, e.g. for a C/C++
8796 - not the node before C. This is true when we have a reference-to-pointer
8797 type (with a mapping for the reference and for the pointer), or for
8798 Fortran derived-type mappings with a GOMP_MAP_TO_PSET.
8799 If SCP is non-null, the new node is inserted before *SCP.
8800 if SCP is null, the new node is inserted before PREV_NODE.
8802 - PREV_NODE, if SCP is non-null.
8803 - The newly-created ALLOC or RELEASE node, if SCP is null.
8804 - The second newly-created ALLOC or RELEASE node, if we are mapping a
8805 reference to a pointer. */
8808 insert_struct_comp_map (enum tree_code code, tree c, tree struct_node,
8809 tree prev_node, tree *scp)
8811 enum gomp_map_kind mkind
8812 = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
8813 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8815 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8816 tree cl = scp ? prev_node : c2;
8817 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8818 OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (c));
8819 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : prev_node;
8820 if (OMP_CLAUSE_CHAIN (prev_node) != c
8821 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8822 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8823 == GOMP_MAP_TO_PSET))
8824 OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (OMP_CLAUSE_CHAIN (prev_node));
8826 OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
8828 OMP_CLAUSE_CHAIN (struct_node) = c2;
8830 /* We might need to create an additional mapping if we have a reference to a
8831 pointer (in C++). Don't do this if we have something other than a
8832 GOMP_MAP_ALWAYS_POINTER though, i.e. a GOMP_MAP_TO_PSET. */
8833 if (OMP_CLAUSE_CHAIN (prev_node) != c
8834 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8835 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8836 == GOMP_MAP_ALWAYS_POINTER)
8837 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8838 == GOMP_MAP_ATTACH_DETACH)))
8840 tree c4 = OMP_CLAUSE_CHAIN (prev_node);
8841 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8842 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8843 OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (c4));
8844 OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
8845 OMP_CLAUSE_CHAIN (c3) = prev_node;
8847 OMP_CLAUSE_CHAIN (c2) = c3;
8858 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
8859 and set *BITPOSP and *POFFSETP to the bit offset of the access.
8860 If BASE_REF is non-NULL and the containing object is a reference, set
8861 *BASE_REF to that reference before dereferencing the object.
8862 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
8863 has array type, else return NULL. */
8866 extract_base_bit_offset (tree base, tree *base_ref, poly_int64 *bitposp,
8867 poly_offset_int *poffsetp, tree *offsetp)
8870 poly_int64 bitsize, bitpos;
8872 int unsignedp, reversep, volatilep = 0;
8873 poly_offset_int poffset;
8877 *base_ref = NULL_TREE;
8879 while (TREE_CODE (base) == ARRAY_REF)
8880 base = TREE_OPERAND (base, 0);
8882 if (TREE_CODE (base) == INDIRECT_REF)
8883 base = TREE_OPERAND (base, 0);
8887 if (TREE_CODE (base) == ARRAY_REF)
8889 while (TREE_CODE (base) == ARRAY_REF)
8890 base = TREE_OPERAND (base, 0);
8891 if (TREE_CODE (base) != COMPONENT_REF
8892 || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
8895 else if (TREE_CODE (base) == INDIRECT_REF
8896 && TREE_CODE (TREE_OPERAND (base, 0)) == COMPONENT_REF
8897 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
8899 base = TREE_OPERAND (base, 0);
8902 base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
8903 &unsignedp, &reversep, &volatilep);
8905 tree orig_base = base;
8907 if ((TREE_CODE (base) == INDIRECT_REF
8908 || (TREE_CODE (base) == MEM_REF
8909 && integer_zerop (TREE_OPERAND (base, 1))))
8910 && DECL_P (TREE_OPERAND (base, 0))
8911 && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == REFERENCE_TYPE)
8912 base = TREE_OPERAND (base, 0);
8914 if (offset && poly_int_tree_p (offset))
8916 poffset = wi::to_poly_offset (offset);
8922 if (maybe_ne (bitpos, 0))
8923 poffset += bits_to_bytes_round_down (bitpos);
8926 *poffsetp = poffset;
8929 /* Set *BASE_REF if BASE was a dereferenced reference variable. */
8930 if (base_ref && orig_base != base)
8931 *base_ref = orig_base;
8936 /* Returns true if EXPR is or contains (as a sub-component) BASE_PTR. */
8939 is_or_contains_p (tree expr, tree base_ptr)
8941 if ((TREE_CODE (expr) == INDIRECT_REF && TREE_CODE (base_ptr) == MEM_REF)
8942 || (TREE_CODE (expr) == MEM_REF && TREE_CODE (base_ptr) == INDIRECT_REF))
8943 return operand_equal_p (TREE_OPERAND (expr, 0),
8944 TREE_OPERAND (base_ptr, 0));
8945 while (!operand_equal_p (expr, base_ptr))
8947 if (TREE_CODE (base_ptr) == COMPOUND_EXPR)
8948 base_ptr = TREE_OPERAND (base_ptr, 1);
8949 if (TREE_CODE (base_ptr) == COMPONENT_REF
8950 || TREE_CODE (base_ptr) == POINTER_PLUS_EXPR
8951 || TREE_CODE (base_ptr) == SAVE_EXPR)
8952 base_ptr = TREE_OPERAND (base_ptr, 0);
8956 return operand_equal_p (expr, base_ptr);
8959 /* Implement OpenMP 5.x map ordering rules for target directives. There are
8960 several rules, and with some level of ambiguity, hopefully we can at least
8961 collect the complexity here in one place. */
8964 omp_target_reorder_clauses (tree *list_p)
8966 /* Collect refs to alloc/release/delete maps. */
8967 auto_vec<tree, 32> ard;
8969 while (*cp != NULL_TREE)
8970 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8971 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALLOC
8972 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_RELEASE
8973 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_DELETE))
8975 /* Unlink cp and push to ard. */
8977 tree nc = OMP_CLAUSE_CHAIN (c);
8981 /* Any associated pointer type maps should also move along. */
8982 while (*cp != NULL_TREE
8983 && OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8984 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
8985 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_POINTER
8986 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH
8987 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_POINTER
8988 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALWAYS_POINTER
8989 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_TO_PSET))
8992 nc = OMP_CLAUSE_CHAIN (c);
8998 cp = &OMP_CLAUSE_CHAIN (*cp);
9000 /* Link alloc/release/delete maps to the end of list. */
9001 for (unsigned int i = 0; i < ard.length (); i++)
9004 cp = &OMP_CLAUSE_CHAIN (ard[i]);
9008 /* OpenMP 5.0 requires that pointer variables are mapped before
9009 its use as a base-pointer. */
9010 auto_vec<tree *, 32> atf;
9011 for (tree *cp = list_p; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
9012 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
9014 /* Collect alloc, to, from, to/from clause tree pointers. */
9015 gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
9016 if (k == GOMP_MAP_ALLOC
9018 || k == GOMP_MAP_FROM
9019 || k == GOMP_MAP_TOFROM
9020 || k == GOMP_MAP_ALWAYS_TO
9021 || k == GOMP_MAP_ALWAYS_FROM
9022 || k == GOMP_MAP_ALWAYS_TOFROM)
9026 for (unsigned int i = 0; i < atf.length (); i++)
9030 tree decl = OMP_CLAUSE_DECL (*cp);
9031 if (TREE_CODE (decl) == INDIRECT_REF || TREE_CODE (decl) == MEM_REF)
9033 tree base_ptr = TREE_OPERAND (decl, 0);
9034 STRIP_TYPE_NOPS (base_ptr);
9035 for (unsigned int j = i + 1; j < atf.length (); j++)
9039 tree decl2 = OMP_CLAUSE_DECL (*cp2);
9041 decl2 = OMP_CLAUSE_DECL (*cp2);
9042 if (is_or_contains_p (decl2, base_ptr))
9044 /* Move *cp2 to before *cp. */
9046 *cp2 = OMP_CLAUSE_CHAIN (c);
9047 OMP_CLAUSE_CHAIN (c) = *cp;
9050 if (*cp2 != NULL_TREE
9051 && OMP_CLAUSE_CODE (*cp2) == OMP_CLAUSE_MAP
9052 && OMP_CLAUSE_MAP_KIND (*cp2) == GOMP_MAP_ALWAYS_POINTER)
9055 *cp2 = OMP_CLAUSE_CHAIN (c2);
9056 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
9057 OMP_CLAUSE_CHAIN (c) = c2;
9066 /* For attach_detach map clauses, if there is another map that maps the
9067 attached/detached pointer, make sure that map is ordered before the
9070 for (tree *cp = list_p; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
9071 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
9073 /* Collect alloc, to, from, to/from clauses, and
9074 always_pointer/attach_detach clauses. */
9075 gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
9076 if (k == GOMP_MAP_ALLOC
9078 || k == GOMP_MAP_FROM
9079 || k == GOMP_MAP_TOFROM
9080 || k == GOMP_MAP_ALWAYS_TO
9081 || k == GOMP_MAP_ALWAYS_FROM
9082 || k == GOMP_MAP_ALWAYS_TOFROM
9083 || k == GOMP_MAP_ATTACH_DETACH
9084 || k == GOMP_MAP_ALWAYS_POINTER)
9088 for (unsigned int i = 0; i < atf.length (); i++)
9092 tree ptr = OMP_CLAUSE_DECL (*cp);
9093 STRIP_TYPE_NOPS (ptr);
9094 if (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH)
9095 for (unsigned int j = i + 1; j < atf.length (); j++)
9098 tree decl2 = OMP_CLAUSE_DECL (*cp2);
9099 if (OMP_CLAUSE_MAP_KIND (*cp2) != GOMP_MAP_ATTACH_DETACH
9100 && OMP_CLAUSE_MAP_KIND (*cp2) != GOMP_MAP_ALWAYS_POINTER
9101 && is_or_contains_p (decl2, ptr))
9103 /* Move *cp2 to before *cp. */
9105 *cp2 = OMP_CLAUSE_CHAIN (c);
9106 OMP_CLAUSE_CHAIN (c) = *cp;
9110 /* If decl2 is of the form '*decl2_opnd0', and followed by an
9111 ALWAYS_POINTER or ATTACH_DETACH of 'decl2_opnd0', move the
9112 pointer operation along with *cp2. This can happen for C++
9113 reference sequences. */
9114 if (j + 1 < atf.length ()
9115 && (TREE_CODE (decl2) == INDIRECT_REF
9116 || TREE_CODE (decl2) == MEM_REF))
9118 tree *cp3 = atf[j + 1];
9119 tree decl3 = OMP_CLAUSE_DECL (*cp3);
9120 tree decl2_opnd0 = TREE_OPERAND (decl2, 0);
9121 if ((OMP_CLAUSE_MAP_KIND (*cp3) == GOMP_MAP_ALWAYS_POINTER
9122 || OMP_CLAUSE_MAP_KIND (*cp3) == GOMP_MAP_ATTACH_DETACH)
9123 && operand_equal_p (decl3, decl2_opnd0))
9125 /* Also move *cp3 to before *cp. */
9127 *cp2 = OMP_CLAUSE_CHAIN (c);
9128 OMP_CLAUSE_CHAIN (c) = *cp;
9139 /* DECL is supposed to have lastprivate semantics in the outer contexts
9140 of combined/composite constructs, starting with OCTX.
9141 Add needed lastprivate, shared or map clause if no data sharing or
9142 mapping clause are present. IMPLICIT_P is true if it is an implicit
9143 clause (IV on simd), in which case the lastprivate will not be
9144 copied to some constructs. */
9147 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx,
9148 tree decl, bool implicit_p)
9150 struct gimplify_omp_ctx *orig_octx = octx;
9151 for (; octx; octx = octx->outer_context)
9153 if ((octx->region_type == ORT_COMBINED_PARALLEL
9154 || (octx->region_type & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS)
9155 && splay_tree_lookup (octx->variables,
9156 (splay_tree_key) decl) == NULL)
9158 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
9161 if ((octx->region_type & ORT_TASK) != 0
9162 && octx->combined_loop
9163 && splay_tree_lookup (octx->variables,
9164 (splay_tree_key) decl) == NULL)
9166 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
9170 && octx->region_type == ORT_WORKSHARE
9171 && octx->combined_loop
9172 && splay_tree_lookup (octx->variables,
9173 (splay_tree_key) decl) == NULL
9174 && octx->outer_context
9175 && octx->outer_context->region_type == ORT_COMBINED_PARALLEL
9176 && splay_tree_lookup (octx->outer_context->variables,
9177 (splay_tree_key) decl) == NULL)
9179 octx = octx->outer_context;
9180 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
9183 if ((octx->region_type == ORT_WORKSHARE || octx->region_type == ORT_ACC)
9184 && octx->combined_loop
9185 && splay_tree_lookup (octx->variables,
9186 (splay_tree_key) decl) == NULL
9187 && !omp_check_private (octx, decl, false))
9189 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
9192 if (octx->region_type == ORT_COMBINED_TARGET)
9194 splay_tree_node n = splay_tree_lookup (octx->variables,
9195 (splay_tree_key) decl);
9198 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
9199 octx = octx->outer_context;
9201 else if (!implicit_p
9202 && (n->value & GOVD_FIRSTPRIVATE_IMPLICIT))
9204 n->value &= ~(GOVD_FIRSTPRIVATE
9205 | GOVD_FIRSTPRIVATE_IMPLICIT
9207 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
9208 octx = octx->outer_context;
9213 if (octx && (implicit_p || octx != orig_octx))
9214 omp_notice_variable (octx, decl, true);
9217 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
9218 and previous omp contexts. */
9221 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
9222 enum omp_region_type region_type,
9223 enum tree_code code)
9225 struct gimplify_omp_ctx *ctx, *outer_ctx;
9227 hash_map<tree_operand_hash, tree> *struct_map_to_clause = NULL;
9228 hash_map<tree_operand_hash, tree *> *struct_seen_clause = NULL;
9229 hash_set<tree> *struct_deref_set = NULL;
9230 tree *prev_list_p = NULL, *orig_list_p = list_p;
9231 int handled_depend_iterators = -1;
9234 ctx = new_omp_context (region_type);
9236 outer_ctx = ctx->outer_context;
9237 if (code == OMP_TARGET)
9239 if (!lang_GNU_Fortran ())
9240 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
9241 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
9242 ctx->defaultmap[GDMK_SCALAR_TARGET] = (lang_GNU_Fortran ()
9243 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
9245 if (!lang_GNU_Fortran ())
9249 case OMP_TARGET_DATA:
9250 case OMP_TARGET_ENTER_DATA:
9251 case OMP_TARGET_EXIT_DATA:
9253 case OACC_HOST_DATA:
9256 ctx->target_firstprivatize_array_bases = true;
9261 if (code == OMP_TARGET
9262 || code == OMP_TARGET_DATA
9263 || code == OMP_TARGET_ENTER_DATA
9264 || code == OMP_TARGET_EXIT_DATA)
9265 omp_target_reorder_clauses (list_p);
9267 while ((c = *list_p) != NULL)
9269 bool remove = false;
9270 bool notice_outer = true;
9271 const char *check_non_private = NULL;
9275 switch (OMP_CLAUSE_CODE (c))
9277 case OMP_CLAUSE_PRIVATE:
9278 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
9279 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
9281 flags |= GOVD_PRIVATE_OUTER_REF;
9282 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
9285 notice_outer = false;
9287 case OMP_CLAUSE_SHARED:
9288 flags = GOVD_SHARED | GOVD_EXPLICIT;
9290 case OMP_CLAUSE_FIRSTPRIVATE:
9291 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
9292 check_non_private = "firstprivate";
9293 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
9295 gcc_assert (code == OMP_TARGET);
9296 flags |= GOVD_FIRSTPRIVATE_IMPLICIT;
9299 case OMP_CLAUSE_LASTPRIVATE:
9300 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
9303 case OMP_DISTRIBUTE:
9304 error_at (OMP_CLAUSE_LOCATION (c),
9305 "conditional %<lastprivate%> clause on "
9306 "%qs construct", "distribute");
9307 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9310 error_at (OMP_CLAUSE_LOCATION (c),
9311 "conditional %<lastprivate%> clause on "
9312 "%qs construct", "taskloop");
9313 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9318 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
9319 if (code != OMP_LOOP)
9320 check_non_private = "lastprivate";
9321 decl = OMP_CLAUSE_DECL (c);
9322 if (error_operand_p (decl))
9324 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
9325 && !lang_hooks.decls.omp_scalar_p (decl, true))
9327 error_at (OMP_CLAUSE_LOCATION (c),
9328 "non-scalar variable %qD in conditional "
9329 "%<lastprivate%> clause", decl);
9330 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9332 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
9333 flags |= GOVD_LASTPRIVATE_CONDITIONAL;
9334 omp_lastprivate_for_combined_outer_constructs (outer_ctx, decl,
9337 case OMP_CLAUSE_REDUCTION:
9338 if (OMP_CLAUSE_REDUCTION_TASK (c))
9340 if (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
9343 nowait = omp_find_clause (*list_p,
9344 OMP_CLAUSE_NOWAIT) != NULL_TREE;
9346 && (outer_ctx == NULL
9347 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
9349 error_at (OMP_CLAUSE_LOCATION (c),
9350 "%<task%> reduction modifier on a construct "
9351 "with a %<nowait%> clause");
9352 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
9355 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
9357 error_at (OMP_CLAUSE_LOCATION (c),
9358 "invalid %<task%> reduction modifier on construct "
9359 "other than %<parallel%>, %qs, %<sections%> or "
9360 "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
9361 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
9364 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
9368 error_at (OMP_CLAUSE_LOCATION (c),
9369 "%<inscan%> %<reduction%> clause on "
9370 "%qs construct", "sections");
9371 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9374 error_at (OMP_CLAUSE_LOCATION (c),
9375 "%<inscan%> %<reduction%> clause on "
9376 "%qs construct", "parallel");
9377 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9380 error_at (OMP_CLAUSE_LOCATION (c),
9381 "%<inscan%> %<reduction%> clause on "
9382 "%qs construct", "teams");
9383 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9386 error_at (OMP_CLAUSE_LOCATION (c),
9387 "%<inscan%> %<reduction%> clause on "
9388 "%qs construct", "taskloop");
9389 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9392 error_at (OMP_CLAUSE_LOCATION (c),
9393 "%<inscan%> %<reduction%> clause on "
9394 "%qs construct", "scope");
9395 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9401 case OMP_CLAUSE_IN_REDUCTION:
9402 case OMP_CLAUSE_TASK_REDUCTION:
9403 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
9404 /* OpenACC permits reductions on private variables. */
9405 if (!(region_type & ORT_ACC)
9406 /* taskgroup is actually not a worksharing region. */
9407 && code != OMP_TASKGROUP)
9408 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
9409 decl = OMP_CLAUSE_DECL (c);
9410 if (TREE_CODE (decl) == MEM_REF)
9412 tree type = TREE_TYPE (decl);
9413 bool saved_into_ssa = gimplify_ctxp->into_ssa;
9414 gimplify_ctxp->into_ssa = false;
9415 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
9416 NULL, is_gimple_val, fb_rvalue, false)
9419 gimplify_ctxp->into_ssa = saved_into_ssa;
9423 gimplify_ctxp->into_ssa = saved_into_ssa;
9424 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
9427 omp_firstprivatize_variable (ctx, v);
9428 omp_notice_variable (ctx, v, true);
9430 decl = TREE_OPERAND (decl, 0);
9431 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
9433 gimplify_ctxp->into_ssa = false;
9434 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
9435 NULL, is_gimple_val, fb_rvalue, false)
9438 gimplify_ctxp->into_ssa = saved_into_ssa;
9442 gimplify_ctxp->into_ssa = saved_into_ssa;
9443 v = TREE_OPERAND (decl, 1);
9446 omp_firstprivatize_variable (ctx, v);
9447 omp_notice_variable (ctx, v, true);
9449 decl = TREE_OPERAND (decl, 0);
9451 if (TREE_CODE (decl) == ADDR_EXPR
9452 || TREE_CODE (decl) == INDIRECT_REF)
9453 decl = TREE_OPERAND (decl, 0);
9456 case OMP_CLAUSE_LINEAR:
9457 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
9458 is_gimple_val, fb_rvalue) == GS_ERROR)
9465 if (code == OMP_SIMD
9466 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9468 struct gimplify_omp_ctx *octx = outer_ctx;
9470 && octx->region_type == ORT_WORKSHARE
9471 && octx->combined_loop
9472 && !octx->distribute)
9474 if (octx->outer_context
9475 && (octx->outer_context->region_type
9476 == ORT_COMBINED_PARALLEL))
9477 octx = octx->outer_context->outer_context;
9479 octx = octx->outer_context;
9482 && octx->region_type == ORT_WORKSHARE
9483 && octx->combined_loop
9484 && octx->distribute)
9486 error_at (OMP_CLAUSE_LOCATION (c),
9487 "%<linear%> clause for variable other than "
9488 "loop iterator specified on construct "
9489 "combined with %<distribute%>");
9494 /* For combined #pragma omp parallel for simd, need to put
9495 lastprivate and perhaps firstprivate too on the
9496 parallel. Similarly for #pragma omp for simd. */
9497 struct gimplify_omp_ctx *octx = outer_ctx;
9498 bool taskloop_seen = false;
9502 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9503 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9505 decl = OMP_CLAUSE_DECL (c);
9506 if (error_operand_p (decl))
9512 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9513 flags |= GOVD_FIRSTPRIVATE;
9514 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9515 flags |= GOVD_LASTPRIVATE;
9517 && octx->region_type == ORT_WORKSHARE
9518 && octx->combined_loop)
9520 if (octx->outer_context
9521 && (octx->outer_context->region_type
9522 == ORT_COMBINED_PARALLEL))
9523 octx = octx->outer_context;
9524 else if (omp_check_private (octx, decl, false))
9528 && (octx->region_type & ORT_TASK) != 0
9529 && octx->combined_loop)
9530 taskloop_seen = true;
9532 && octx->region_type == ORT_COMBINED_PARALLEL
9533 && ((ctx->region_type == ORT_WORKSHARE
9534 && octx == outer_ctx)
9536 flags = GOVD_SEEN | GOVD_SHARED;
9538 && ((octx->region_type & ORT_COMBINED_TEAMS)
9539 == ORT_COMBINED_TEAMS))
9540 flags = GOVD_SEEN | GOVD_SHARED;
9542 && octx->region_type == ORT_COMBINED_TARGET)
9544 if (flags & GOVD_LASTPRIVATE)
9545 flags = GOVD_SEEN | GOVD_MAP;
9550 = splay_tree_lookup (octx->variables,
9551 (splay_tree_key) decl);
9552 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
9557 omp_add_variable (octx, decl, flags);
9558 if (octx->outer_context == NULL)
9560 octx = octx->outer_context;
9565 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9566 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
9567 omp_notice_variable (octx, decl, true);
9569 flags = GOVD_LINEAR | GOVD_EXPLICIT;
9570 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9571 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9573 notice_outer = false;
9574 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9578 case OMP_CLAUSE_MAP:
9579 decl = OMP_CLAUSE_DECL (c);
9580 if (error_operand_p (decl))
9587 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
9590 case OMP_TARGET_DATA:
9591 case OMP_TARGET_ENTER_DATA:
9592 case OMP_TARGET_EXIT_DATA:
9593 case OACC_ENTER_DATA:
9594 case OACC_EXIT_DATA:
9595 case OACC_HOST_DATA:
9596 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9597 || (OMP_CLAUSE_MAP_KIND (c)
9598 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9599 /* For target {,enter ,exit }data only the array slice is
9600 mapped, but not the pointer to it. */
9606 /* For Fortran, not only the pointer to the data is mapped but also
9607 the address of the pointer, the array descriptor etc.; for
9608 'exit data' - and in particular for 'delete:' - having an 'alloc:'
9609 does not make sense. Likewise, for 'update' only transferring the
9610 data itself is needed as the rest has been handled in previous
9611 directives. However, for 'exit data', the array descriptor needs
9612 to be delete; hence, we turn the MAP_TO_PSET into a MAP_DELETE.
9614 NOTE: Generally, it is not safe to perform "enter data" operations
9615 on arrays where the data *or the descriptor* may go out of scope
9616 before a corresponding "exit data" operation -- and such a
9617 descriptor may be synthesized temporarily, e.g. to pass an
9618 explicit-shape array to a function expecting an assumed-shape
9619 argument. Performing "enter data" inside the called function
9620 would thus be problematic. */
9621 if (code == OMP_TARGET_EXIT_DATA
9622 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
9623 OMP_CLAUSE_SET_MAP_KIND (c, OMP_CLAUSE_MAP_KIND (*prev_list_p)
9625 ? GOMP_MAP_DELETE : GOMP_MAP_RELEASE);
9626 else if ((code == OMP_TARGET_EXIT_DATA || code == OMP_TARGET_UPDATE)
9627 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9628 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET))
9633 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
9635 struct gimplify_omp_ctx *octx;
9636 for (octx = outer_ctx; octx; octx = octx->outer_context)
9638 if (octx->region_type != ORT_ACC_HOST_DATA)
9641 = splay_tree_lookup (octx->variables,
9642 (splay_tree_key) decl);
9644 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
9645 "declared in enclosing %<host_data%> region",
9649 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9650 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
9651 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
9652 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
9653 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
9658 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9659 || (OMP_CLAUSE_MAP_KIND (c)
9660 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9661 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9662 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
9665 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
9667 if ((region_type & ORT_TARGET) != 0)
9668 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
9669 GOVD_FIRSTPRIVATE | GOVD_SEEN);
9672 if (TREE_CODE (decl) == TARGET_EXPR)
9674 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
9675 is_gimple_lvalue, fb_lvalue)
9679 else if (!DECL_P (decl))
9682 if (TREE_CODE (d) == ARRAY_REF)
9684 while (TREE_CODE (d) == ARRAY_REF)
9685 d = TREE_OPERAND (d, 0);
9686 if (TREE_CODE (d) == COMPONENT_REF
9687 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
9690 pd = &OMP_CLAUSE_DECL (c);
9692 && TREE_CODE (decl) == INDIRECT_REF
9693 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
9694 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9696 && (OMP_CLAUSE_MAP_KIND (c)
9697 != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
9699 pd = &TREE_OPERAND (decl, 0);
9700 decl = TREE_OPERAND (decl, 0);
9702 bool indir_p = false;
9703 bool component_ref_p = false;
9704 tree indir_base = NULL_TREE;
9705 tree orig_decl = decl;
9706 tree decl_ref = NULL_TREE;
9707 if ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA)) != 0
9708 && TREE_CODE (*pd) == COMPONENT_REF
9709 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
9710 && code != OACC_UPDATE)
9712 while (TREE_CODE (decl) == COMPONENT_REF)
9714 decl = TREE_OPERAND (decl, 0);
9715 component_ref_p = true;
9716 if (((TREE_CODE (decl) == MEM_REF
9717 && integer_zerop (TREE_OPERAND (decl, 1)))
9718 || INDIRECT_REF_P (decl))
9719 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9724 decl = TREE_OPERAND (decl, 0);
9727 if (TREE_CODE (decl) == INDIRECT_REF
9728 && DECL_P (TREE_OPERAND (decl, 0))
9729 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9733 decl = TREE_OPERAND (decl, 0);
9737 else if (TREE_CODE (decl) == COMPONENT_REF
9738 && (OMP_CLAUSE_MAP_KIND (c)
9739 != GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION))
9741 component_ref_p = true;
9742 while (TREE_CODE (decl) == COMPONENT_REF)
9743 decl = TREE_OPERAND (decl, 0);
9744 if (TREE_CODE (decl) == INDIRECT_REF
9745 && DECL_P (TREE_OPERAND (decl, 0))
9746 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9748 decl = TREE_OPERAND (decl, 0);
9750 if (decl != orig_decl && DECL_P (decl) && indir_p
9751 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
9753 && TREE_CODE (TREE_TYPE (decl_ref)) == POINTER_TYPE)))
9756 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9757 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9758 /* We have a dereference of a struct member. Make this an
9759 attach/detach operation, and ensure the base pointer is
9760 mapped as a FIRSTPRIVATE_POINTER. */
9761 OMP_CLAUSE_SET_MAP_KIND (c, k);
9762 flags = GOVD_MAP | GOVD_SEEN | GOVD_EXPLICIT;
9763 tree next_clause = OMP_CLAUSE_CHAIN (c);
9764 if (k == GOMP_MAP_ATTACH
9765 && code != OACC_ENTER_DATA
9766 && code != OMP_TARGET_ENTER_DATA
9768 || (OMP_CLAUSE_CODE (next_clause) != OMP_CLAUSE_MAP)
9769 || (OMP_CLAUSE_MAP_KIND (next_clause)
9770 != GOMP_MAP_POINTER)
9771 || OMP_CLAUSE_DECL (next_clause) != decl)
9772 && (!struct_deref_set
9773 || !struct_deref_set->contains (decl))
9774 && (!struct_map_to_clause
9775 || !struct_map_to_clause->get (indir_base)))
9777 if (!struct_deref_set)
9778 struct_deref_set = new hash_set<tree> ();
9779 /* As well as the attach, we also need a
9780 FIRSTPRIVATE_POINTER clause to properly map the
9781 pointer to the struct base. */
9782 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9784 OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALLOC);
9785 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c2)
9788 = build_int_cst (build_pointer_type (char_type_node),
9790 OMP_CLAUSE_DECL (c2)
9791 = build2 (MEM_REF, char_type_node,
9792 decl_ref ? decl_ref : decl, charptr_zero);
9793 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9794 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9796 OMP_CLAUSE_SET_MAP_KIND (c3,
9797 GOMP_MAP_FIRSTPRIVATE_POINTER);
9798 OMP_CLAUSE_DECL (c3) = decl;
9799 OMP_CLAUSE_SIZE (c3) = size_zero_node;
9800 tree mapgrp = *prev_list_p;
9802 OMP_CLAUSE_CHAIN (c3) = mapgrp;
9803 OMP_CLAUSE_CHAIN (c2) = c3;
9805 struct_deref_set->add (decl);
9809 /* An "attach/detach" operation on an update directive should
9810 behave as a GOMP_MAP_ALWAYS_POINTER. Beware that
9811 unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
9812 depends on the previous mapping. */
9813 if (code == OACC_UPDATE
9814 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9815 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
9818 && (INDIRECT_REF_P (decl)
9819 || TREE_CODE (decl) == MEM_REF
9820 || TREE_CODE (decl) == ARRAY_REF)))
9821 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
9822 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
9823 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
9824 && code != OACC_UPDATE
9825 && code != OMP_TARGET_UPDATE)
9827 if (error_operand_p (decl))
9833 tree stype = TREE_TYPE (decl);
9834 if (TREE_CODE (stype) == REFERENCE_TYPE)
9835 stype = TREE_TYPE (stype);
9836 if (TYPE_SIZE_UNIT (stype) == NULL
9837 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
9839 error_at (OMP_CLAUSE_LOCATION (c),
9840 "mapping field %qE of variable length "
9841 "structure", OMP_CLAUSE_DECL (c));
9846 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
9847 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9849 /* Error recovery. */
9850 if (prev_list_p == NULL)
9856 /* The below prev_list_p based error recovery code is
9857 currently no longer valid for OpenMP. */
9858 if (code != OMP_TARGET
9859 && code != OMP_TARGET_DATA
9860 && code != OMP_TARGET_UPDATE
9861 && code != OMP_TARGET_ENTER_DATA
9862 && code != OMP_TARGET_EXIT_DATA
9863 && OMP_CLAUSE_CHAIN (*prev_list_p) != c)
9865 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
9866 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
9874 poly_offset_int offset1;
9880 = extract_base_bit_offset (OMP_CLAUSE_DECL (c), &base_ref,
9884 bool do_map_struct = (base == decl && !tree_offset1);
9888 ? splay_tree_lookup (ctx->variables,
9889 (splay_tree_key) decl)
9891 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
9892 == GOMP_MAP_ALWAYS_POINTER);
9893 bool attach_detach = (OMP_CLAUSE_MAP_KIND (c)
9894 == GOMP_MAP_ATTACH_DETACH);
9895 bool attach = OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9896 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH;
9897 bool has_attachments = false;
9898 /* For OpenACC, pointers in structs should trigger an
9901 && ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA))
9902 || code == OMP_TARGET_ENTER_DATA
9903 || code == OMP_TARGET_EXIT_DATA))
9906 /* Turn a GOMP_MAP_ATTACH_DETACH clause into a
9907 GOMP_MAP_ATTACH or GOMP_MAP_DETACH clause after we
9908 have detected a case that needs a GOMP_MAP_STRUCT
9911 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9912 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9913 OMP_CLAUSE_SET_MAP_KIND (c, k);
9914 has_attachments = true;
9917 /* We currently don't handle non-constant offset accesses wrt to
9918 GOMP_MAP_STRUCT elements. */
9920 goto skip_map_struct;
9922 /* Nor for attach_detach for OpenMP. */
9923 if ((code == OMP_TARGET
9924 || code == OMP_TARGET_DATA
9925 || code == OMP_TARGET_UPDATE
9926 || code == OMP_TARGET_ENTER_DATA
9927 || code == OMP_TARGET_EXIT_DATA)
9932 if (struct_seen_clause == NULL)
9934 = new hash_map<tree_operand_hash, tree *>;
9935 if (!struct_seen_clause->get (decl))
9936 struct_seen_clause->put (decl, list_p);
9939 goto skip_map_struct;
9943 && (n == NULL || (n->value & GOVD_MAP) == 0))
9945 && (!struct_map_to_clause
9946 || struct_map_to_clause->get (decl) == NULL)))
9948 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9950 gomp_map_kind k = attach ? GOMP_MAP_FORCE_PRESENT
9953 OMP_CLAUSE_SET_MAP_KIND (l, k);
9955 OMP_CLAUSE_DECL (l) = unshare_expr (base_ref);
9958 OMP_CLAUSE_DECL (l) = unshare_expr (decl);
9959 if (!DECL_P (OMP_CLAUSE_DECL (l))
9960 && (gimplify_expr (&OMP_CLAUSE_DECL (l),
9961 pre_p, NULL, is_gimple_lvalue,
9972 : DECL_P (OMP_CLAUSE_DECL (l))
9973 ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l))
9974 : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l))));
9975 if (struct_map_to_clause == NULL)
9976 struct_map_to_clause
9977 = new hash_map<tree_operand_hash, tree>;
9978 struct_map_to_clause->put (decl, l);
9979 if (ptr || attach_detach)
9981 tree **sc = (struct_seen_clause
9982 ? struct_seen_clause->get (decl)
9984 tree *insert_node_pos = sc ? *sc : prev_list_p;
9986 insert_struct_comp_map (code, c, l, *insert_node_pos,
9988 *insert_node_pos = l;
9993 OMP_CLAUSE_CHAIN (l) = c;
9995 list_p = &OMP_CLAUSE_CHAIN (l);
9997 if (base_ref && code == OMP_TARGET)
9999 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10001 enum gomp_map_kind mkind
10002 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
10003 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
10004 OMP_CLAUSE_DECL (c2) = decl;
10005 OMP_CLAUSE_SIZE (c2) = size_zero_node;
10006 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
10007 OMP_CLAUSE_CHAIN (l) = c2;
10009 flags = GOVD_MAP | GOVD_EXPLICIT;
10010 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
10013 flags |= GOVD_SEEN;
10014 if (has_attachments)
10015 flags |= GOVD_MAP_HAS_ATTACHMENTS;
10017 /* If this is a *pointer-to-struct expression, make sure a
10018 firstprivate map of the base-pointer exists. */
10019 if (component_ref_p
10020 && ((TREE_CODE (decl) == MEM_REF
10021 && integer_zerop (TREE_OPERAND (decl, 1)))
10022 || INDIRECT_REF_P (decl))
10023 && DECL_P (TREE_OPERAND (decl, 0))
10024 && !splay_tree_lookup (ctx->variables,
10026 TREE_OPERAND (decl, 0))))
10028 decl = TREE_OPERAND (decl, 0);
10029 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10031 enum gomp_map_kind mkind
10032 = GOMP_MAP_FIRSTPRIVATE_POINTER;
10033 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
10034 OMP_CLAUSE_DECL (c2) = decl;
10035 OMP_CLAUSE_SIZE (c2) = size_zero_node;
10036 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
10037 OMP_CLAUSE_CHAIN (c) = c2;
10043 else if (struct_map_to_clause)
10045 tree *osc = struct_map_to_clause->get (decl);
10046 tree *sc = NULL, *scp = NULL;
10048 && (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
10051 n->value |= GOVD_SEEN;
10052 sc = &OMP_CLAUSE_CHAIN (*osc);
10054 && (OMP_CLAUSE_MAP_KIND (*sc)
10055 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
10056 sc = &OMP_CLAUSE_CHAIN (*sc);
10057 /* Here "prev_list_p" is the end of the inserted
10058 alloc/release nodes after the struct node, OSC. */
10059 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
10060 if ((ptr || attach_detach) && sc == prev_list_p)
10062 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
10064 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
10066 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
10071 tree sc_decl = OMP_CLAUSE_DECL (*sc);
10072 poly_offset_int offsetn;
10073 poly_int64 bitposn;
10076 = extract_base_bit_offset (sc_decl, NULL,
10077 &bitposn, &offsetn,
10083 if ((region_type & ORT_ACC) != 0)
10085 /* This duplicate checking code is currently only
10086 enabled for OpenACC. */
10087 tree d1 = OMP_CLAUSE_DECL (*sc);
10088 tree d2 = OMP_CLAUSE_DECL (c);
10089 while (TREE_CODE (d1) == ARRAY_REF)
10090 d1 = TREE_OPERAND (d1, 0);
10091 while (TREE_CODE (d2) == ARRAY_REF)
10092 d2 = TREE_OPERAND (d2, 0);
10093 if (TREE_CODE (d1) == INDIRECT_REF)
10094 d1 = TREE_OPERAND (d1, 0);
10095 if (TREE_CODE (d2) == INDIRECT_REF)
10096 d2 = TREE_OPERAND (d2, 0);
10097 while (TREE_CODE (d1) == COMPONENT_REF)
10098 if (TREE_CODE (d2) == COMPONENT_REF
10099 && TREE_OPERAND (d1, 1)
10100 == TREE_OPERAND (d2, 1))
10102 d1 = TREE_OPERAND (d1, 0);
10103 d2 = TREE_OPERAND (d2, 0);
10109 error_at (OMP_CLAUSE_LOCATION (c),
10110 "%qE appears more than once in map "
10111 "clauses", OMP_CLAUSE_DECL (c));
10116 if (maybe_lt (offset1, offsetn)
10117 || (known_eq (offset1, offsetn)
10118 && maybe_lt (bitpos1, bitposn)))
10120 if (ptr || attach_detach)
10129 OMP_CLAUSE_SIZE (*osc)
10130 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
10132 if (ptr || attach_detach)
10134 tree cl = insert_struct_comp_map (code, c, NULL,
10135 *prev_list_p, scp);
10136 if (sc == prev_list_p)
10139 prev_list_p = NULL;
10143 *prev_list_p = OMP_CLAUSE_CHAIN (c);
10144 list_p = prev_list_p;
10145 prev_list_p = NULL;
10146 OMP_CLAUSE_CHAIN (c) = *sc;
10153 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
10160 *list_p = OMP_CLAUSE_CHAIN (c);
10161 OMP_CLAUSE_CHAIN (c) = *sc;
10169 else if ((code == OACC_ENTER_DATA
10170 || code == OACC_EXIT_DATA
10171 || code == OACC_DATA
10172 || code == OACC_PARALLEL
10173 || code == OACC_KERNELS
10174 || code == OACC_SERIAL
10175 || code == OMP_TARGET_ENTER_DATA
10176 || code == OMP_TARGET_EXIT_DATA)
10177 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
10179 gomp_map_kind k = ((code == OACC_EXIT_DATA
10180 || code == OMP_TARGET_EXIT_DATA)
10181 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
10182 OMP_CLAUSE_SET_MAP_KIND (c, k);
10185 if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
10187 /* Don't gimplify *pd fully at this point, as the base
10188 will need to be adjusted during omp lowering. */
10189 auto_vec<tree, 10> expr_stack;
10191 while (handled_component_p (*p)
10192 || TREE_CODE (*p) == INDIRECT_REF
10193 || TREE_CODE (*p) == ADDR_EXPR
10194 || TREE_CODE (*p) == MEM_REF
10195 || TREE_CODE (*p) == NON_LVALUE_EXPR)
10197 expr_stack.safe_push (*p);
10198 p = &TREE_OPERAND (*p, 0);
10200 for (int i = expr_stack.length () - 1; i >= 0; i--)
10202 tree t = expr_stack[i];
10203 if (TREE_CODE (t) == ARRAY_REF
10204 || TREE_CODE (t) == ARRAY_RANGE_REF)
10206 if (TREE_OPERAND (t, 2) == NULL_TREE)
10208 tree low = unshare_expr (array_ref_low_bound (t));
10209 if (!is_gimple_min_invariant (low))
10211 TREE_OPERAND (t, 2) = low;
10212 if (gimplify_expr (&TREE_OPERAND (t, 2),
10215 fb_rvalue) == GS_ERROR)
10219 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
10220 NULL, is_gimple_reg,
10221 fb_rvalue) == GS_ERROR)
10223 if (TREE_OPERAND (t, 3) == NULL_TREE)
10225 tree elmt_size = array_ref_element_size (t);
10226 if (!is_gimple_min_invariant (elmt_size))
10228 elmt_size = unshare_expr (elmt_size);
10230 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t,
10233 = size_int (TYPE_ALIGN_UNIT (elmt_type));
10235 = size_binop (EXACT_DIV_EXPR, elmt_size,
10237 TREE_OPERAND (t, 3) = elmt_size;
10238 if (gimplify_expr (&TREE_OPERAND (t, 3),
10241 fb_rvalue) == GS_ERROR)
10245 else if (gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
10246 NULL, is_gimple_reg,
10247 fb_rvalue) == GS_ERROR)
10250 else if (TREE_CODE (t) == COMPONENT_REF)
10252 if (TREE_OPERAND (t, 2) == NULL_TREE)
10254 tree offset = component_ref_field_offset (t);
10255 if (!is_gimple_min_invariant (offset))
10257 offset = unshare_expr (offset);
10258 tree field = TREE_OPERAND (t, 1);
10260 = size_int (DECL_OFFSET_ALIGN (field)
10262 offset = size_binop (EXACT_DIV_EXPR, offset,
10264 TREE_OPERAND (t, 2) = offset;
10265 if (gimplify_expr (&TREE_OPERAND (t, 2),
10268 fb_rvalue) == GS_ERROR)
10272 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
10273 NULL, is_gimple_reg,
10274 fb_rvalue) == GS_ERROR)
10278 for (; expr_stack.length () > 0; )
10280 tree t = expr_stack.pop ();
10282 if (TREE_CODE (t) == ARRAY_REF
10283 || TREE_CODE (t) == ARRAY_RANGE_REF)
10285 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))
10286 && gimplify_expr (&TREE_OPERAND (t, 1), pre_p,
10287 NULL, is_gimple_val,
10288 fb_rvalue) == GS_ERROR)
10293 else if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
10294 fb_lvalue) == GS_ERROR)
10300 /* If this was of the form map(*pointer_to_struct), then the
10301 'pointer_to_struct' DECL should be considered deref'ed. */
10302 if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALLOC
10303 || GOMP_MAP_COPY_TO_P (OMP_CLAUSE_MAP_KIND (c))
10304 || GOMP_MAP_COPY_FROM_P (OMP_CLAUSE_MAP_KIND (c)))
10305 && INDIRECT_REF_P (orig_decl)
10306 && DECL_P (TREE_OPERAND (orig_decl, 0))
10307 && TREE_CODE (TREE_TYPE (orig_decl)) == RECORD_TYPE)
10309 tree ptr = TREE_OPERAND (orig_decl, 0);
10310 if (!struct_deref_set || !struct_deref_set->contains (ptr))
10312 if (!struct_deref_set)
10313 struct_deref_set = new hash_set<tree> ();
10314 struct_deref_set->add (ptr);
10319 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
10320 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
10321 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
10322 && OMP_CLAUSE_CHAIN (c)
10323 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
10324 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10325 == GOMP_MAP_ALWAYS_POINTER)
10326 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10327 == GOMP_MAP_ATTACH_DETACH)
10328 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10329 == GOMP_MAP_TO_PSET)))
10330 prev_list_p = list_p;
10336 /* DECL_P (decl) == true */
10338 if (struct_map_to_clause
10339 && (sc = struct_map_to_clause->get (decl)) != NULL
10340 && OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_STRUCT
10341 && decl == OMP_CLAUSE_DECL (*sc))
10343 /* We have found a map of the whole structure after a
10344 leading GOMP_MAP_STRUCT has been created, so refill the
10345 leading clause into a map of the whole structure
10346 variable, and remove the current one.
10347 TODO: we should be able to remove some maps of the
10348 following structure element maps if they are of
10349 compatible TO/FROM/ALLOC type. */
10350 OMP_CLAUSE_SET_MAP_KIND (*sc, OMP_CLAUSE_MAP_KIND (c));
10351 OMP_CLAUSE_SIZE (*sc) = unshare_expr (OMP_CLAUSE_SIZE (c));
10356 flags = GOVD_MAP | GOVD_EXPLICIT;
10357 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
10358 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
10359 flags |= GOVD_MAP_ALWAYS_TO;
10361 if ((code == OMP_TARGET
10362 || code == OMP_TARGET_DATA
10363 || code == OMP_TARGET_ENTER_DATA
10364 || code == OMP_TARGET_EXIT_DATA)
10365 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
10367 for (struct gimplify_omp_ctx *octx = outer_ctx; octx;
10368 octx = octx->outer_context)
10371 = splay_tree_lookup (octx->variables,
10372 (splay_tree_key) OMP_CLAUSE_DECL (c));
10373 /* If this is contained in an outer OpenMP region as a
10374 firstprivate value, remove the attach/detach. */
10375 if (n && (n->value & GOVD_FIRSTPRIVATE))
10377 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FIRSTPRIVATE_POINTER);
10382 enum gomp_map_kind map_kind = (code == OMP_TARGET_EXIT_DATA
10384 : GOMP_MAP_ATTACH);
10385 OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
10390 case OMP_CLAUSE_AFFINITY:
10391 gimplify_omp_affinity (list_p, pre_p);
10394 case OMP_CLAUSE_DEPEND:
10395 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
10397 tree deps = OMP_CLAUSE_DECL (c);
10398 while (deps && TREE_CODE (deps) == TREE_LIST)
10400 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
10401 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
10402 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
10403 pre_p, NULL, is_gimple_val, fb_rvalue);
10404 deps = TREE_CHAIN (deps);
10408 else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
10410 if (handled_depend_iterators == -1)
10411 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
10412 if (handled_depend_iterators)
10414 if (handled_depend_iterators == 2)
10418 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
10420 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
10421 NULL, is_gimple_val, fb_rvalue);
10422 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
10424 if (error_operand_p (OMP_CLAUSE_DECL (c)))
10429 if (OMP_CLAUSE_DECL (c) != null_pointer_node)
10431 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
10432 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
10433 is_gimple_val, fb_rvalue) == GS_ERROR)
10439 if (code == OMP_TASK)
10440 ctx->has_depend = true;
10443 case OMP_CLAUSE_TO:
10444 case OMP_CLAUSE_FROM:
10445 case OMP_CLAUSE__CACHE_:
10446 decl = OMP_CLAUSE_DECL (c);
10447 if (error_operand_p (decl))
10452 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10453 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
10454 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
10455 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
10456 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
10461 if (!DECL_P (decl))
10463 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
10464 NULL, is_gimple_lvalue, fb_lvalue)
10474 case OMP_CLAUSE_USE_DEVICE_PTR:
10475 case OMP_CLAUSE_USE_DEVICE_ADDR:
10476 flags = GOVD_EXPLICIT;
10479 case OMP_CLAUSE_HAS_DEVICE_ADDR:
10480 decl = OMP_CLAUSE_DECL (c);
10481 while (TREE_CODE (decl) == INDIRECT_REF
10482 || TREE_CODE (decl) == ARRAY_REF)
10483 decl = TREE_OPERAND (decl, 0);
10484 flags = GOVD_EXPLICIT;
10487 case OMP_CLAUSE_IS_DEVICE_PTR:
10488 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
10492 decl = OMP_CLAUSE_DECL (c);
10494 if (error_operand_p (decl))
10499 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
10501 tree t = omp_member_access_dummy_var (decl);
10504 tree v = DECL_VALUE_EXPR (decl);
10505 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
10507 omp_notice_variable (outer_ctx, t, true);
10510 if (code == OACC_DATA
10511 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10512 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
10513 flags |= GOVD_MAP_0LEN_ARRAY;
10514 omp_add_variable (ctx, decl, flags);
10515 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10516 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
10517 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
10518 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
10520 struct gimplify_omp_ctx *pctx
10521 = code == OMP_TARGET ? outer_ctx : ctx;
10523 omp_add_variable (pctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
10524 GOVD_LOCAL | GOVD_SEEN);
10526 && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
10527 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
10529 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
10530 NULL) == NULL_TREE)
10531 omp_add_variable (pctx,
10532 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
10533 GOVD_LOCAL | GOVD_SEEN);
10534 gimplify_omp_ctxp = pctx;
10535 push_gimplify_context ();
10537 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
10538 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
10540 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
10541 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
10542 pop_gimplify_context
10543 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
10544 push_gimplify_context ();
10545 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
10546 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
10547 pop_gimplify_context
10548 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
10549 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
10550 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
10552 gimplify_omp_ctxp = outer_ctx;
10554 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10555 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
10557 gimplify_omp_ctxp = ctx;
10558 push_gimplify_context ();
10559 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
10561 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
10563 TREE_SIDE_EFFECTS (bind) = 1;
10564 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
10565 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
10567 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
10568 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
10569 pop_gimplify_context
10570 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
10571 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
10573 gimplify_omp_ctxp = outer_ctx;
10575 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10576 && OMP_CLAUSE_LINEAR_STMT (c))
10578 gimplify_omp_ctxp = ctx;
10579 push_gimplify_context ();
10580 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
10582 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
10584 TREE_SIDE_EFFECTS (bind) = 1;
10585 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
10586 OMP_CLAUSE_LINEAR_STMT (c) = bind;
10588 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
10589 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
10590 pop_gimplify_context
10591 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
10592 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
10594 gimplify_omp_ctxp = outer_ctx;
10600 case OMP_CLAUSE_COPYIN:
10601 case OMP_CLAUSE_COPYPRIVATE:
10602 decl = OMP_CLAUSE_DECL (c);
10603 if (error_operand_p (decl))
10608 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
10610 && !omp_check_private (ctx, decl, true))
10613 if (is_global_var (decl))
10615 if (DECL_THREAD_LOCAL_P (decl))
10617 else if (DECL_HAS_VALUE_EXPR_P (decl))
10619 tree value = get_base_address (DECL_VALUE_EXPR (decl));
10623 && DECL_THREAD_LOCAL_P (value))
10628 error_at (OMP_CLAUSE_LOCATION (c),
10629 "copyprivate variable %qE is not threadprivate"
10630 " or private in outer context", DECL_NAME (decl));
10633 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10634 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10635 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
10637 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
10638 || (region_type == ORT_WORKSHARE
10639 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10640 && (OMP_CLAUSE_REDUCTION_INSCAN (c)
10641 || code == OMP_LOOP)))
10642 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
10643 || (code == OMP_LOOP
10644 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10645 && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
10646 == ORT_COMBINED_TEAMS))))
10649 = splay_tree_lookup (outer_ctx->variables,
10650 (splay_tree_key)decl);
10651 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
10653 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10654 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10655 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
10656 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
10657 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
10658 == POINTER_TYPE))))
10659 omp_firstprivatize_variable (outer_ctx, decl);
10662 omp_add_variable (outer_ctx, decl,
10663 GOVD_SEEN | GOVD_SHARED);
10664 if (outer_ctx->outer_context)
10665 omp_notice_variable (outer_ctx->outer_context, decl,
10671 omp_notice_variable (outer_ctx, decl, true);
10672 if (check_non_private
10673 && (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
10674 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
10675 || decl == OMP_CLAUSE_DECL (c)
10676 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10677 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10679 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10680 == POINTER_PLUS_EXPR
10681 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
10682 (OMP_CLAUSE_DECL (c), 0), 0))
10684 && omp_check_private (ctx, decl, false))
10686 error ("%s variable %qE is private in outer context",
10687 check_non_private, DECL_NAME (decl));
10692 case OMP_CLAUSE_DETACH:
10693 flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
10696 case OMP_CLAUSE_IF:
10697 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
10698 && OMP_CLAUSE_IF_MODIFIER (c) != code)
10701 for (int i = 0; i < 2; i++)
10702 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
10704 case VOID_CST: p[i] = "cancel"; break;
10705 case OMP_PARALLEL: p[i] = "parallel"; break;
10706 case OMP_SIMD: p[i] = "simd"; break;
10707 case OMP_TASK: p[i] = "task"; break;
10708 case OMP_TASKLOOP: p[i] = "taskloop"; break;
10709 case OMP_TARGET_DATA: p[i] = "target data"; break;
10710 case OMP_TARGET: p[i] = "target"; break;
10711 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
10712 case OMP_TARGET_ENTER_DATA:
10713 p[i] = "target enter data"; break;
10714 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
10715 default: gcc_unreachable ();
10717 error_at (OMP_CLAUSE_LOCATION (c),
10718 "expected %qs %<if%> clause modifier rather than %qs",
10722 /* Fall through. */
10724 case OMP_CLAUSE_FINAL:
10725 OMP_CLAUSE_OPERAND (c, 0)
10726 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
10727 /* Fall through. */
10729 case OMP_CLAUSE_NUM_TEAMS:
10730 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
10731 && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
10732 && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
10734 if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
10739 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
10740 = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c),
10741 pre_p, NULL, true);
10743 /* Fall through. */
10745 case OMP_CLAUSE_SCHEDULE:
10746 case OMP_CLAUSE_NUM_THREADS:
10747 case OMP_CLAUSE_THREAD_LIMIT:
10748 case OMP_CLAUSE_DIST_SCHEDULE:
10749 case OMP_CLAUSE_DEVICE:
10750 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE
10751 && OMP_CLAUSE_DEVICE_ANCESTOR (c))
10753 if (code != OMP_TARGET)
10755 error_at (OMP_CLAUSE_LOCATION (c),
10756 "%<device%> clause with %<ancestor%> is only "
10757 "allowed on %<target%> construct");
10762 tree clauses = *orig_list_p;
10763 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
10764 if (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEVICE
10765 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_FIRSTPRIVATE
10766 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_PRIVATE
10767 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEFAULTMAP
10768 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_MAP
10771 error_at (OMP_CLAUSE_LOCATION (c),
10772 "with %<ancestor%>, only the %<device%>, "
10773 "%<firstprivate%>, %<private%>, %<defaultmap%>, "
10774 "and %<map%> clauses may appear on the "
10780 /* Fall through. */
10782 case OMP_CLAUSE_PRIORITY:
10783 case OMP_CLAUSE_GRAINSIZE:
10784 case OMP_CLAUSE_NUM_TASKS:
10785 case OMP_CLAUSE_FILTER:
10786 case OMP_CLAUSE_HINT:
10787 case OMP_CLAUSE_ASYNC:
10788 case OMP_CLAUSE_WAIT:
10789 case OMP_CLAUSE_NUM_GANGS:
10790 case OMP_CLAUSE_NUM_WORKERS:
10791 case OMP_CLAUSE_VECTOR_LENGTH:
10792 case OMP_CLAUSE_WORKER:
10793 case OMP_CLAUSE_VECTOR:
10794 if (OMP_CLAUSE_OPERAND (c, 0)
10795 && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0)))
10797 if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0)))
10802 /* All these clauses care about value, not a particular decl,
10803 so try to force it into a SSA_NAME or fresh temporary. */
10804 OMP_CLAUSE_OPERAND (c, 0)
10805 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0),
10806 pre_p, NULL, true);
10810 case OMP_CLAUSE_GANG:
10811 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
10812 is_gimple_val, fb_rvalue) == GS_ERROR)
10814 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
10815 is_gimple_val, fb_rvalue) == GS_ERROR)
10819 case OMP_CLAUSE_NOWAIT:
10823 case OMP_CLAUSE_ORDERED:
10824 case OMP_CLAUSE_UNTIED:
10825 case OMP_CLAUSE_COLLAPSE:
10826 case OMP_CLAUSE_TILE:
10827 case OMP_CLAUSE_AUTO:
10828 case OMP_CLAUSE_SEQ:
10829 case OMP_CLAUSE_INDEPENDENT:
10830 case OMP_CLAUSE_MERGEABLE:
10831 case OMP_CLAUSE_PROC_BIND:
10832 case OMP_CLAUSE_SAFELEN:
10833 case OMP_CLAUSE_SIMDLEN:
10834 case OMP_CLAUSE_NOGROUP:
10835 case OMP_CLAUSE_THREADS:
10836 case OMP_CLAUSE_SIMD:
10837 case OMP_CLAUSE_BIND:
10838 case OMP_CLAUSE_IF_PRESENT:
10839 case OMP_CLAUSE_FINALIZE:
10842 case OMP_CLAUSE_ORDER:
10843 ctx->order_concurrent = true;
10846 case OMP_CLAUSE_DEFAULTMAP:
10847 enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
10848 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
10850 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
10851 gdmkmin = GDMK_SCALAR;
10852 gdmkmax = GDMK_POINTER;
10854 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
10855 gdmkmin = GDMK_SCALAR;
10856 gdmkmax = GDMK_SCALAR_TARGET;
10858 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
10859 gdmkmin = gdmkmax = GDMK_AGGREGATE;
10861 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
10862 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
10864 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
10865 gdmkmin = gdmkmax = GDMK_POINTER;
10868 gcc_unreachable ();
10870 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
10871 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
10873 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
10874 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
10876 case OMP_CLAUSE_DEFAULTMAP_TO:
10877 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
10879 case OMP_CLAUSE_DEFAULTMAP_FROM:
10880 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
10882 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
10883 ctx->defaultmap[gdmk] = GOVD_MAP;
10885 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
10886 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10888 case OMP_CLAUSE_DEFAULTMAP_NONE:
10889 ctx->defaultmap[gdmk] = 0;
10891 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
10895 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10897 case GDMK_SCALAR_TARGET:
10898 ctx->defaultmap[gdmk] = (lang_GNU_Fortran ()
10899 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
10901 case GDMK_AGGREGATE:
10902 case GDMK_ALLOCATABLE:
10903 ctx->defaultmap[gdmk] = GOVD_MAP;
10906 ctx->defaultmap[gdmk] = GOVD_MAP;
10907 if (!lang_GNU_Fortran ())
10908 ctx->defaultmap[gdmk] |= GOVD_MAP_0LEN_ARRAY;
10911 gcc_unreachable ();
10915 gcc_unreachable ();
10919 case OMP_CLAUSE_ALIGNED:
10920 decl = OMP_CLAUSE_DECL (c);
10921 if (error_operand_p (decl))
10926 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
10927 is_gimple_val, fb_rvalue) == GS_ERROR)
10932 if (!is_global_var (decl)
10933 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
10934 omp_add_variable (ctx, decl, GOVD_ALIGNED);
10937 case OMP_CLAUSE_NONTEMPORAL:
10938 decl = OMP_CLAUSE_DECL (c);
10939 if (error_operand_p (decl))
10944 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
10947 case OMP_CLAUSE_ALLOCATE:
10948 decl = OMP_CLAUSE_DECL (c);
10949 if (error_operand_p (decl))
10954 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL,
10955 is_gimple_val, fb_rvalue) == GS_ERROR)
10960 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
10961 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
10964 else if (code == OMP_TASKLOOP
10965 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
10966 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
10967 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
10968 pre_p, NULL, false);
10971 case OMP_CLAUSE_DEFAULT:
10972 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
10975 case OMP_CLAUSE_INCLUSIVE:
10976 case OMP_CLAUSE_EXCLUSIVE:
10977 decl = OMP_CLAUSE_DECL (c);
10979 splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
10980 (splay_tree_key) decl);
10981 if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
10983 error_at (OMP_CLAUSE_LOCATION (c),
10984 "%qD specified in %qs clause but not in %<inscan%> "
10985 "%<reduction%> clause on the containing construct",
10986 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10991 n->value |= GOVD_REDUCTION_INSCAN;
10992 if (outer_ctx->region_type == ORT_SIMD
10993 && outer_ctx->outer_context
10994 && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
10996 n = splay_tree_lookup (outer_ctx->outer_context->variables,
10997 (splay_tree_key) decl);
10998 if (n && (n->value & GOVD_REDUCTION) != 0)
10999 n->value |= GOVD_REDUCTION_INSCAN;
11005 case OMP_CLAUSE_NOHOST:
11007 gcc_unreachable ();
11010 if (code == OACC_DATA
11011 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
11012 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
11013 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
11016 *list_p = OMP_CLAUSE_CHAIN (c);
11018 list_p = &OMP_CLAUSE_CHAIN (c);
11021 ctx->clauses = *orig_list_p;
11022 gimplify_omp_ctxp = ctx;
11023 if (struct_seen_clause)
11024 delete struct_seen_clause;
11025 if (struct_map_to_clause)
11026 delete struct_map_to_clause;
11027 if (struct_deref_set)
11028 delete struct_deref_set;
11031 /* Return true if DECL is a candidate for shared to firstprivate
11032 optimization. We only consider non-addressable scalars, not
11033 too big, and not references. */
11036 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
11038 if (TREE_ADDRESSABLE (decl))
11040 tree type = TREE_TYPE (decl);
11041 if (!is_gimple_reg_type (type)
11042 || TREE_CODE (type) == REFERENCE_TYPE
11043 || TREE_ADDRESSABLE (type))
11045 /* Don't optimize too large decls, as each thread/task will have
11047 HOST_WIDE_INT len = int_size_in_bytes (type);
11048 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
11050 if (omp_privatize_by_reference (decl))
11055 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
11056 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
11057 GOVD_WRITTEN in outer contexts. */
11060 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
11062 for (; ctx; ctx = ctx->outer_context)
11064 splay_tree_node n = splay_tree_lookup (ctx->variables,
11065 (splay_tree_key) decl);
11068 else if (n->value & GOVD_SHARED)
11070 n->value |= GOVD_WRITTEN;
11073 else if (n->value & GOVD_DATA_SHARE_CLASS)
11078 /* Helper callback for walk_gimple_seq to discover possible stores
11079 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
11080 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
11084 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
11086 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
11088 *walk_subtrees = 0;
11095 if (handled_component_p (op))
11096 op = TREE_OPERAND (op, 0);
11097 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
11098 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
11099 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
11104 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
11107 omp_mark_stores (gimplify_omp_ctxp, op);
11111 /* Helper callback for walk_gimple_seq to discover possible stores
11112 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
11113 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
11117 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
11118 bool *handled_ops_p,
11119 struct walk_stmt_info *wi)
11121 gimple *stmt = gsi_stmt (*gsi_p);
11122 switch (gimple_code (stmt))
11124 /* Don't recurse on OpenMP constructs for which
11125 gimplify_adjust_omp_clauses already handled the bodies,
11126 except handle gimple_omp_for_pre_body. */
11127 case GIMPLE_OMP_FOR:
11128 *handled_ops_p = true;
11129 if (gimple_omp_for_pre_body (stmt))
11130 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
11131 omp_find_stores_stmt, omp_find_stores_op, wi);
11133 case GIMPLE_OMP_PARALLEL:
11134 case GIMPLE_OMP_TASK:
11135 case GIMPLE_OMP_SECTIONS:
11136 case GIMPLE_OMP_SINGLE:
11137 case GIMPLE_OMP_SCOPE:
11138 case GIMPLE_OMP_TARGET:
11139 case GIMPLE_OMP_TEAMS:
11140 case GIMPLE_OMP_CRITICAL:
11141 *handled_ops_p = true;
11149 struct gimplify_adjust_omp_clauses_data
11155 /* For all variables that were not actually used within the context,
11156 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
11159 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
11161 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
11163 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
11164 tree decl = (tree) n->key;
11165 unsigned flags = n->value;
11166 enum omp_clause_code code;
11168 bool private_debug;
11170 if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
11171 && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
11172 flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
11173 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
11175 if ((flags & GOVD_SEEN) == 0)
11177 if ((flags & GOVD_MAP_HAS_ATTACHMENTS) != 0)
11179 if (flags & GOVD_DEBUG_PRIVATE)
11181 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
11182 private_debug = true;
11184 else if (flags & GOVD_MAP)
11185 private_debug = false;
11188 = lang_hooks.decls.omp_private_debug_clause (decl,
11189 !!(flags & GOVD_SHARED));
11191 code = OMP_CLAUSE_PRIVATE;
11192 else if (flags & GOVD_MAP)
11194 code = OMP_CLAUSE_MAP;
11195 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
11196 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
11198 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
11202 && DECL_IN_CONSTANT_POOL (decl)
11203 && !lookup_attribute ("omp declare target",
11204 DECL_ATTRIBUTES (decl)))
11206 tree id = get_identifier ("omp declare target");
11207 DECL_ATTRIBUTES (decl)
11208 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
11209 varpool_node *node = varpool_node::get (decl);
11212 node->offloadable = 1;
11213 if (ENABLE_OFFLOADING)
11214 g->have_offload = true;
11218 else if (flags & GOVD_SHARED)
11220 if (is_global_var (decl))
11222 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
11223 while (ctx != NULL)
11226 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11227 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
11228 | GOVD_PRIVATE | GOVD_REDUCTION
11229 | GOVD_LINEAR | GOVD_MAP)) != 0)
11231 ctx = ctx->outer_context;
11236 code = OMP_CLAUSE_SHARED;
11237 /* Don't optimize shared into firstprivate for read-only vars
11238 on tasks with depend clause, we shouldn't try to copy them
11239 until the dependencies are satisfied. */
11240 if (gimplify_omp_ctxp->has_depend)
11241 flags |= GOVD_WRITTEN;
11243 else if (flags & GOVD_PRIVATE)
11244 code = OMP_CLAUSE_PRIVATE;
11245 else if (flags & GOVD_FIRSTPRIVATE)
11247 code = OMP_CLAUSE_FIRSTPRIVATE;
11248 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
11249 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
11250 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
11252 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
11253 "%<target%> construct", decl);
11257 else if (flags & GOVD_LASTPRIVATE)
11258 code = OMP_CLAUSE_LASTPRIVATE;
11259 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
11261 else if (flags & GOVD_CONDTEMP)
11263 code = OMP_CLAUSE__CONDTEMP_;
11264 gimple_add_tmp_var (decl);
11267 gcc_unreachable ();
11269 if (((flags & GOVD_LASTPRIVATE)
11270 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
11271 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11272 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11274 tree chain = *list_p;
11275 clause = build_omp_clause (input_location, code);
11276 OMP_CLAUSE_DECL (clause) = decl;
11277 OMP_CLAUSE_CHAIN (clause) = chain;
11279 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
11280 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
11281 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
11282 else if (code == OMP_CLAUSE_SHARED
11283 && (flags & GOVD_WRITTEN) == 0
11284 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11285 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
11286 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
11287 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
11288 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
11290 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
11291 OMP_CLAUSE_DECL (nc) = decl;
11292 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
11293 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
11294 OMP_CLAUSE_DECL (clause)
11295 = build_simple_mem_ref_loc (input_location, decl);
11296 OMP_CLAUSE_DECL (clause)
11297 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
11298 build_int_cst (build_pointer_type (char_type_node), 0));
11299 OMP_CLAUSE_SIZE (clause) = size_zero_node;
11300 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11301 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
11302 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
11303 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
11304 OMP_CLAUSE_CHAIN (nc) = chain;
11305 OMP_CLAUSE_CHAIN (clause) = nc;
11306 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11307 gimplify_omp_ctxp = ctx->outer_context;
11308 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
11309 pre_p, NULL, is_gimple_val, fb_rvalue);
11310 gimplify_omp_ctxp = ctx;
11312 else if (code == OMP_CLAUSE_MAP)
11315 /* Not all combinations of these GOVD_MAP flags are actually valid. */
11316 switch (flags & (GOVD_MAP_TO_ONLY
11318 | GOVD_MAP_FORCE_PRESENT
11319 | GOVD_MAP_ALLOC_ONLY
11320 | GOVD_MAP_FROM_ONLY))
11323 kind = GOMP_MAP_TOFROM;
11325 case GOVD_MAP_FORCE:
11326 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
11328 case GOVD_MAP_TO_ONLY:
11329 kind = GOMP_MAP_TO;
11331 case GOVD_MAP_FROM_ONLY:
11332 kind = GOMP_MAP_FROM;
11334 case GOVD_MAP_ALLOC_ONLY:
11335 kind = GOMP_MAP_ALLOC;
11337 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
11338 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
11340 case GOVD_MAP_FORCE_PRESENT:
11341 kind = GOMP_MAP_FORCE_PRESENT;
11344 gcc_unreachable ();
11346 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
11347 /* Setting of the implicit flag for the runtime is currently disabled for
11349 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
11350 OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
11351 if (DECL_SIZE (decl)
11352 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
11354 tree decl2 = DECL_VALUE_EXPR (decl);
11355 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11356 decl2 = TREE_OPERAND (decl2, 0);
11357 gcc_assert (DECL_P (decl2));
11358 tree mem = build_simple_mem_ref (decl2);
11359 OMP_CLAUSE_DECL (clause) = mem;
11360 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11361 if (gimplify_omp_ctxp->outer_context)
11363 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
11364 omp_notice_variable (ctx, decl2, true);
11365 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
11367 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
11369 OMP_CLAUSE_DECL (nc) = decl;
11370 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11371 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
11372 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
11374 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
11375 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
11376 OMP_CLAUSE_CHAIN (clause) = nc;
11378 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
11379 && omp_privatize_by_reference (decl))
11381 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
11382 OMP_CLAUSE_SIZE (clause)
11383 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
11384 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11385 gimplify_omp_ctxp = ctx->outer_context;
11386 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
11387 pre_p, NULL, is_gimple_val, fb_rvalue);
11388 gimplify_omp_ctxp = ctx;
11389 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
11391 OMP_CLAUSE_DECL (nc) = decl;
11392 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11393 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
11394 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
11395 OMP_CLAUSE_CHAIN (clause) = nc;
11398 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
11400 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
11402 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
11403 OMP_CLAUSE_DECL (nc) = decl;
11404 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
11405 OMP_CLAUSE_CHAIN (nc) = chain;
11406 OMP_CLAUSE_CHAIN (clause) = nc;
11407 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11408 gimplify_omp_ctxp = ctx->outer_context;
11409 lang_hooks.decls.omp_finish_clause (nc, pre_p,
11410 (ctx->region_type & ORT_ACC) != 0);
11411 gimplify_omp_ctxp = ctx;
11414 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11415 gimplify_omp_ctxp = ctx->outer_context;
11416 /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
11417 in simd. Those are only added for the local vars inside of simd body
11418 and they don't need to be e.g. default constructible. */
11419 if (code != OMP_CLAUSE_PRIVATE || ctx->region_type != ORT_SIMD)
11420 lang_hooks.decls.omp_finish_clause (clause, pre_p,
11421 (ctx->region_type & ORT_ACC) != 0);
11422 if (gimplify_omp_ctxp)
11423 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
11424 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
11425 && DECL_P (OMP_CLAUSE_SIZE (clause)))
11426 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
11428 gimplify_omp_ctxp = ctx;
11433 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
11434 enum tree_code code)
11436 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11437 tree *orig_list_p = list_p;
11439 bool has_inscan_reductions = false;
11443 struct gimplify_omp_ctx *octx;
11444 for (octx = ctx; octx; octx = octx->outer_context)
11445 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
11449 struct walk_stmt_info wi;
11450 memset (&wi, 0, sizeof (wi));
11451 walk_gimple_seq (body, omp_find_stores_stmt,
11452 omp_find_stores_op, &wi);
11456 if (ctx->add_safelen1)
11458 /* If there are VLAs in the body of simd loop, prevent
11460 gcc_assert (ctx->region_type == ORT_SIMD);
11461 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
11462 OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
11463 OMP_CLAUSE_CHAIN (c) = *list_p;
11465 list_p = &OMP_CLAUSE_CHAIN (c);
11468 if (ctx->region_type == ORT_WORKSHARE
11469 && ctx->outer_context
11470 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
11472 for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
11473 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11474 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
11476 decl = OMP_CLAUSE_DECL (c);
11478 = splay_tree_lookup (ctx->outer_context->variables,
11479 (splay_tree_key) decl);
11480 gcc_checking_assert (!splay_tree_lookup (ctx->variables,
11481 (splay_tree_key) decl));
11482 omp_add_variable (ctx, decl, n->value);
11483 tree c2 = copy_node (c);
11484 OMP_CLAUSE_CHAIN (c2) = *list_p;
11486 if ((n->value & GOVD_FIRSTPRIVATE) == 0)
11488 c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11489 OMP_CLAUSE_FIRSTPRIVATE);
11490 OMP_CLAUSE_DECL (c2) = decl;
11491 OMP_CLAUSE_CHAIN (c2) = *list_p;
11495 while ((c = *list_p) != NULL)
11498 bool remove = false;
11500 switch (OMP_CLAUSE_CODE (c))
11502 case OMP_CLAUSE_FIRSTPRIVATE:
11503 if ((ctx->region_type & ORT_TARGET)
11504 && (ctx->region_type & ORT_ACC) == 0
11505 && TYPE_ATOMIC (strip_array_types
11506 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
11508 error_at (OMP_CLAUSE_LOCATION (c),
11509 "%<_Atomic%> %qD in %<firstprivate%> clause on "
11510 "%<target%> construct", OMP_CLAUSE_DECL (c));
11514 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
11516 decl = OMP_CLAUSE_DECL (c);
11517 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11518 if ((n->value & GOVD_MAP) != 0)
11523 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) = 0;
11524 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) = 0;
11527 case OMP_CLAUSE_PRIVATE:
11528 case OMP_CLAUSE_SHARED:
11529 case OMP_CLAUSE_LINEAR:
11530 decl = OMP_CLAUSE_DECL (c);
11531 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11532 remove = !(n->value & GOVD_SEEN);
11533 if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
11534 && code == OMP_PARALLEL
11535 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
11539 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
11540 if ((n->value & GOVD_DEBUG_PRIVATE)
11541 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
11543 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
11544 || ((n->value & GOVD_DATA_SHARE_CLASS)
11546 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
11547 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
11549 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11552 n->value |= GOVD_WRITTEN;
11553 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11554 && (n->value & GOVD_WRITTEN) == 0
11556 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11557 OMP_CLAUSE_SHARED_READONLY (c) = 1;
11558 else if (DECL_P (decl)
11559 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11560 && (n->value & GOVD_WRITTEN) != 0)
11561 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11562 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
11563 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11564 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11567 n->value &= ~GOVD_EXPLICIT;
11570 case OMP_CLAUSE_LASTPRIVATE:
11571 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
11572 accurately reflect the presence of a FIRSTPRIVATE clause. */
11573 decl = OMP_CLAUSE_DECL (c);
11574 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11575 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
11576 = (n->value & GOVD_FIRSTPRIVATE) != 0;
11577 if (code == OMP_DISTRIBUTE
11578 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
11581 error_at (OMP_CLAUSE_LOCATION (c),
11582 "same variable used in %<firstprivate%> and "
11583 "%<lastprivate%> clauses on %<distribute%> "
11587 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11589 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11590 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11591 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
11595 case OMP_CLAUSE_ALIGNED:
11596 decl = OMP_CLAUSE_DECL (c);
11597 if (!is_global_var (decl))
11599 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11600 remove = n == NULL || !(n->value & GOVD_SEEN);
11601 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
11603 struct gimplify_omp_ctx *octx;
11605 && (n->value & (GOVD_DATA_SHARE_CLASS
11606 & ~GOVD_FIRSTPRIVATE)))
11609 for (octx = ctx->outer_context; octx;
11610 octx = octx->outer_context)
11612 n = splay_tree_lookup (octx->variables,
11613 (splay_tree_key) decl);
11616 if (n->value & GOVD_LOCAL)
11618 /* We have to avoid assigning a shared variable
11619 to itself when trying to add
11620 __builtin_assume_aligned. */
11621 if (n->value & GOVD_SHARED)
11629 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
11631 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11632 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
11637 case OMP_CLAUSE_HAS_DEVICE_ADDR:
11638 decl = OMP_CLAUSE_DECL (c);
11639 while (TREE_CODE (decl) == INDIRECT_REF
11640 || TREE_CODE (decl) == ARRAY_REF)
11641 decl = TREE_OPERAND (decl, 0);
11642 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11643 remove = n == NULL || !(n->value & GOVD_SEEN);
11646 case OMP_CLAUSE_IS_DEVICE_PTR:
11647 case OMP_CLAUSE_NONTEMPORAL:
11648 decl = OMP_CLAUSE_DECL (c);
11649 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11650 remove = n == NULL || !(n->value & GOVD_SEEN);
11653 case OMP_CLAUSE_MAP:
11654 if (code == OMP_TARGET_EXIT_DATA
11655 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
11660 decl = OMP_CLAUSE_DECL (c);
11661 /* Data clauses associated with reductions must be
11662 compatible with present_or_copy. Warn and adjust the clause
11663 if that is not the case. */
11664 if (ctx->region_type == ORT_ACC_PARALLEL
11665 || ctx->region_type == ORT_ACC_SERIAL)
11667 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
11671 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
11673 if (n && (n->value & GOVD_REDUCTION))
11675 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
11677 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
11678 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
11679 && kind != GOMP_MAP_FORCE_PRESENT
11680 && kind != GOMP_MAP_POINTER)
11682 warning_at (OMP_CLAUSE_LOCATION (c), 0,
11683 "incompatible data clause with reduction "
11684 "on %qE; promoting to %<present_or_copy%>",
11686 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
11690 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
11691 && (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA))
11696 if (!DECL_P (decl))
11698 if ((ctx->region_type & ORT_TARGET) != 0
11699 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
11701 if (TREE_CODE (decl) == INDIRECT_REF
11702 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
11703 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
11704 == REFERENCE_TYPE))
11705 decl = TREE_OPERAND (decl, 0);
11706 if (TREE_CODE (decl) == COMPONENT_REF)
11708 while (TREE_CODE (decl) == COMPONENT_REF)
11709 decl = TREE_OPERAND (decl, 0);
11712 n = splay_tree_lookup (ctx->variables,
11713 (splay_tree_key) decl);
11714 if (!(n->value & GOVD_SEEN))
11721 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11722 if ((ctx->region_type & ORT_TARGET) != 0
11723 && !(n->value & GOVD_SEEN)
11724 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
11725 && (!is_global_var (decl)
11726 || !lookup_attribute ("omp declare target link",
11727 DECL_ATTRIBUTES (decl))))
11730 /* For struct element mapping, if struct is never referenced
11731 in target block and none of the mapping has always modifier,
11732 remove all the struct element mappings, which immediately
11733 follow the GOMP_MAP_STRUCT map clause. */
11734 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
11736 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
11738 OMP_CLAUSE_CHAIN (c)
11739 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
11742 else if (DECL_SIZE (decl)
11743 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
11744 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
11745 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
11746 && (OMP_CLAUSE_MAP_KIND (c)
11747 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
11749 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
11750 for these, TREE_CODE (DECL_SIZE (decl)) will always be
11752 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
11754 tree decl2 = DECL_VALUE_EXPR (decl);
11755 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11756 decl2 = TREE_OPERAND (decl2, 0);
11757 gcc_assert (DECL_P (decl2));
11758 tree mem = build_simple_mem_ref (decl2);
11759 OMP_CLAUSE_DECL (c) = mem;
11760 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11761 if (ctx->outer_context)
11763 omp_notice_variable (ctx->outer_context, decl2, true);
11764 omp_notice_variable (ctx->outer_context,
11765 OMP_CLAUSE_SIZE (c), true);
11767 if (((ctx->region_type & ORT_TARGET) != 0
11768 || !ctx->target_firstprivatize_array_bases)
11769 && ((n->value & GOVD_SEEN) == 0
11770 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
11772 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11774 OMP_CLAUSE_DECL (nc) = decl;
11775 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11776 if (ctx->target_firstprivatize_array_bases)
11777 OMP_CLAUSE_SET_MAP_KIND (nc,
11778 GOMP_MAP_FIRSTPRIVATE_POINTER);
11780 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
11781 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
11782 OMP_CLAUSE_CHAIN (c) = nc;
11788 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11789 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11790 gcc_assert ((n->value & GOVD_SEEN) == 0
11791 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11796 case OMP_CLAUSE_TO:
11797 case OMP_CLAUSE_FROM:
11798 case OMP_CLAUSE__CACHE_:
11799 decl = OMP_CLAUSE_DECL (c);
11800 if (!DECL_P (decl))
11802 if (DECL_SIZE (decl)
11803 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
11805 tree decl2 = DECL_VALUE_EXPR (decl);
11806 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11807 decl2 = TREE_OPERAND (decl2, 0);
11808 gcc_assert (DECL_P (decl2));
11809 tree mem = build_simple_mem_ref (decl2);
11810 OMP_CLAUSE_DECL (c) = mem;
11811 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11812 if (ctx->outer_context)
11814 omp_notice_variable (ctx->outer_context, decl2, true);
11815 omp_notice_variable (ctx->outer_context,
11816 OMP_CLAUSE_SIZE (c), true);
11819 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11820 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11823 case OMP_CLAUSE_REDUCTION:
11824 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
11826 decl = OMP_CLAUSE_DECL (c);
11827 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11828 if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
11831 error_at (OMP_CLAUSE_LOCATION (c),
11832 "%qD specified in %<inscan%> %<reduction%> clause "
11833 "but not in %<scan%> directive clause", decl);
11836 has_inscan_reductions = true;
11839 case OMP_CLAUSE_IN_REDUCTION:
11840 case OMP_CLAUSE_TASK_REDUCTION:
11841 decl = OMP_CLAUSE_DECL (c);
11842 /* OpenACC reductions need a present_or_copy data clause.
11843 Add one if necessary. Emit error when the reduction is private. */
11844 if (ctx->region_type == ORT_ACC_PARALLEL
11845 || ctx->region_type == ORT_ACC_SERIAL)
11847 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11848 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11851 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
11852 "reduction on %qE", DECL_NAME (decl));
11854 else if ((n->value & GOVD_MAP) == 0)
11856 tree next = OMP_CLAUSE_CHAIN (c);
11857 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
11858 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
11859 OMP_CLAUSE_DECL (nc) = decl;
11860 OMP_CLAUSE_CHAIN (c) = nc;
11861 lang_hooks.decls.omp_finish_clause (nc, pre_p,
11866 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
11867 if (OMP_CLAUSE_CHAIN (nc) == NULL)
11869 nc = OMP_CLAUSE_CHAIN (nc);
11871 OMP_CLAUSE_CHAIN (nc) = next;
11872 n->value |= GOVD_MAP;
11876 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11877 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11880 case OMP_CLAUSE_ALLOCATE:
11881 decl = OMP_CLAUSE_DECL (c);
11882 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11883 if (n != NULL && !(n->value & GOVD_SEEN))
11885 if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR))
11887 && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0)
11891 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
11892 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST
11893 && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0
11894 || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK
11895 || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS))
11897 tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
11898 n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator);
11901 enum omp_clause_default_kind default_kind
11902 = ctx->default_kind;
11903 ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
11904 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11906 ctx->default_kind = default_kind;
11909 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11914 case OMP_CLAUSE_COPYIN:
11915 case OMP_CLAUSE_COPYPRIVATE:
11916 case OMP_CLAUSE_IF:
11917 case OMP_CLAUSE_NUM_THREADS:
11918 case OMP_CLAUSE_NUM_TEAMS:
11919 case OMP_CLAUSE_THREAD_LIMIT:
11920 case OMP_CLAUSE_DIST_SCHEDULE:
11921 case OMP_CLAUSE_DEVICE:
11922 case OMP_CLAUSE_SCHEDULE:
11923 case OMP_CLAUSE_NOWAIT:
11924 case OMP_CLAUSE_ORDERED:
11925 case OMP_CLAUSE_DEFAULT:
11926 case OMP_CLAUSE_UNTIED:
11927 case OMP_CLAUSE_COLLAPSE:
11928 case OMP_CLAUSE_FINAL:
11929 case OMP_CLAUSE_MERGEABLE:
11930 case OMP_CLAUSE_PROC_BIND:
11931 case OMP_CLAUSE_SAFELEN:
11932 case OMP_CLAUSE_SIMDLEN:
11933 case OMP_CLAUSE_DEPEND:
11934 case OMP_CLAUSE_PRIORITY:
11935 case OMP_CLAUSE_GRAINSIZE:
11936 case OMP_CLAUSE_NUM_TASKS:
11937 case OMP_CLAUSE_NOGROUP:
11938 case OMP_CLAUSE_THREADS:
11939 case OMP_CLAUSE_SIMD:
11940 case OMP_CLAUSE_FILTER:
11941 case OMP_CLAUSE_HINT:
11942 case OMP_CLAUSE_DEFAULTMAP:
11943 case OMP_CLAUSE_ORDER:
11944 case OMP_CLAUSE_BIND:
11945 case OMP_CLAUSE_DETACH:
11946 case OMP_CLAUSE_USE_DEVICE_PTR:
11947 case OMP_CLAUSE_USE_DEVICE_ADDR:
11948 case OMP_CLAUSE_ASYNC:
11949 case OMP_CLAUSE_WAIT:
11950 case OMP_CLAUSE_INDEPENDENT:
11951 case OMP_CLAUSE_NUM_GANGS:
11952 case OMP_CLAUSE_NUM_WORKERS:
11953 case OMP_CLAUSE_VECTOR_LENGTH:
11954 case OMP_CLAUSE_GANG:
11955 case OMP_CLAUSE_WORKER:
11956 case OMP_CLAUSE_VECTOR:
11957 case OMP_CLAUSE_AUTO:
11958 case OMP_CLAUSE_SEQ:
11959 case OMP_CLAUSE_TILE:
11960 case OMP_CLAUSE_IF_PRESENT:
11961 case OMP_CLAUSE_FINALIZE:
11962 case OMP_CLAUSE_INCLUSIVE:
11963 case OMP_CLAUSE_EXCLUSIVE:
11966 case OMP_CLAUSE_NOHOST:
11968 gcc_unreachable ();
11972 *list_p = OMP_CLAUSE_CHAIN (c);
11974 list_p = &OMP_CLAUSE_CHAIN (c);
11977 /* Add in any implicit data sharing. */
11978 struct gimplify_adjust_omp_clauses_data data;
11979 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
11981 /* OpenMP. Implicit clauses are added at the start of the clause list,
11982 but after any non-map clauses. */
11983 tree *implicit_add_list_p = orig_list_p;
11984 while (*implicit_add_list_p
11985 && OMP_CLAUSE_CODE (*implicit_add_list_p) != OMP_CLAUSE_MAP)
11986 implicit_add_list_p = &OMP_CLAUSE_CHAIN (*implicit_add_list_p);
11987 data.list_p = implicit_add_list_p;
11991 data.list_p = list_p;
11992 data.pre_p = pre_p;
11993 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
11995 if (has_inscan_reductions)
11996 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
11997 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11998 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
12000 error_at (OMP_CLAUSE_LOCATION (c),
12001 "%<inscan%> %<reduction%> clause used together with "
12002 "%<linear%> clause for a variable other than loop "
12007 gimplify_omp_ctxp = ctx->outer_context;
12008 delete_omp_context (ctx);
12011 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
12012 -1 if unknown yet (simd is involved, won't be known until vectorization)
12013 and 1 if they do. If SCORES is non-NULL, it should point to an array
12014 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
12015 of the CONSTRUCTS (position -1 if it will never match) followed by
12016 number of constructs in the OpenMP context construct trait. If the
12017 score depends on whether it will be in a declare simd clone or not,
12018 the function returns 2 and there will be two sets of the scores, the first
12019 one for the case that it is not in a declare simd clone, the other
12020 that it is in a declare simd clone. */
12023 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
12026 int matched = 0, cnt = 0;
12027 bool simd_seen = false;
12028 bool target_seen = false;
12029 int declare_simd_cnt = -1;
12030 auto_vec<enum tree_code, 16> codes;
12031 for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
12033 if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
12034 || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
12035 == ORT_TARGET && ctx->code == OMP_TARGET)
12036 || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
12037 || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
12038 || (ctx->region_type == ORT_SIMD
12039 && ctx->code == OMP_SIMD
12040 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
12044 codes.safe_push (ctx->code);
12045 else if (matched < nconstructs && ctx->code == constructs[matched])
12047 if (ctx->code == OMP_SIMD)
12055 if (ctx->code == OMP_TARGET)
12057 if (scores == NULL)
12058 return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
12059 target_seen = true;
12063 else if (ctx->region_type == ORT_WORKSHARE
12064 && ctx->code == OMP_LOOP
12065 && ctx->outer_context
12066 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
12067 && ctx->outer_context->outer_context
12068 && ctx->outer_context->outer_context->code == OMP_LOOP
12069 && ctx->outer_context->outer_context->distribute)
12070 ctx = ctx->outer_context->outer_context;
12071 ctx = ctx->outer_context;
12074 && lookup_attribute ("omp declare simd",
12075 DECL_ATTRIBUTES (current_function_decl)))
12077 /* Declare simd is a maybe case, it is supposed to be added only to the
12078 omp-simd-clone.cc added clones and not to the base function. */
12079 declare_simd_cnt = cnt++;
12081 codes.safe_push (OMP_SIMD);
12083 && constructs[0] == OMP_SIMD)
12085 gcc_assert (matched == 0);
12087 if (++matched == nconstructs)
12091 if (tree attr = lookup_attribute ("omp declare variant variant",
12092 DECL_ATTRIBUTES (current_function_decl)))
12094 enum tree_code variant_constructs[5];
12095 int variant_nconstructs = 0;
12097 variant_nconstructs
12098 = omp_constructor_traits_to_codes (TREE_VALUE (attr),
12099 variant_constructs);
12100 for (int i = 0; i < variant_nconstructs; i++)
12104 codes.safe_push (variant_constructs[i]);
12105 else if (matched < nconstructs
12106 && variant_constructs[i] == constructs[matched])
12108 if (variant_constructs[i] == OMP_SIMD)
12119 && lookup_attribute ("omp declare target block",
12120 DECL_ATTRIBUTES (current_function_decl)))
12123 codes.safe_push (OMP_TARGET);
12124 else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
12129 for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
12131 int j = codes.length () - 1;
12132 for (int i = nconstructs - 1; i >= 0; i--)
12135 && (pass != 0 || declare_simd_cnt != j)
12136 && constructs[i] != codes[j])
12138 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
12143 *scores++ = ((pass == 0 && declare_simd_cnt != -1)
12144 ? codes.length () - 1 : codes.length ());
12146 return declare_simd_cnt == -1 ? 1 : 2;
12148 if (matched == nconstructs)
12149 return simd_seen ? -1 : 1;
12153 /* Gimplify OACC_CACHE. */
12156 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
12158 tree expr = *expr_p;
12160 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
12162 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
12165 /* TODO: Do something sensible with this information. */
12167 *expr_p = NULL_TREE;
12170 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
12171 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
12172 kind. The entry kind will replace the one in CLAUSE, while the exit
12173 kind will be used in a new omp_clause and returned to the caller. */
12176 gimplify_oacc_declare_1 (tree clause)
12178 HOST_WIDE_INT kind, new_op;
12182 kind = OMP_CLAUSE_MAP_KIND (clause);
12186 case GOMP_MAP_ALLOC:
12187 new_op = GOMP_MAP_RELEASE;
12191 case GOMP_MAP_FROM:
12192 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
12193 new_op = GOMP_MAP_FROM;
12197 case GOMP_MAP_TOFROM:
12198 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
12199 new_op = GOMP_MAP_FROM;
12203 case GOMP_MAP_DEVICE_RESIDENT:
12204 case GOMP_MAP_FORCE_DEVICEPTR:
12205 case GOMP_MAP_FORCE_PRESENT:
12206 case GOMP_MAP_LINK:
12207 case GOMP_MAP_POINTER:
12212 gcc_unreachable ();
12218 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
12219 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
12220 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
12226 /* Gimplify OACC_DECLARE. */
12229 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
12231 tree expr = *expr_p;
12233 tree clauses, t, decl;
12235 clauses = OACC_DECLARE_CLAUSES (expr);
12237 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
12238 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
12240 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
12242 decl = OMP_CLAUSE_DECL (t);
12244 if (TREE_CODE (decl) == MEM_REF)
12245 decl = TREE_OPERAND (decl, 0);
12247 if (VAR_P (decl) && !is_oacc_declared (decl))
12249 tree attr = get_identifier ("oacc declare target");
12250 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
12251 DECL_ATTRIBUTES (decl));
12255 && !is_global_var (decl)
12256 && DECL_CONTEXT (decl) == current_function_decl)
12258 tree c = gimplify_oacc_declare_1 (t);
12261 if (oacc_declare_returns == NULL)
12262 oacc_declare_returns = new hash_map<tree, tree>;
12264 oacc_declare_returns->put (decl, c);
12268 if (gimplify_omp_ctxp)
12269 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
12272 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
12275 gimplify_seq_add_stmt (pre_p, stmt);
12277 *expr_p = NULL_TREE;
12280 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
12281 gimplification of the body, as well as scanning the body for used
12282 variables. We need to do this scan now, because variable-sized
12283 decls will be decomposed during gimplification. */
12286 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
12288 tree expr = *expr_p;
12290 gimple_seq body = NULL;
12292 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
12293 OMP_PARALLEL_COMBINED (expr)
12294 ? ORT_COMBINED_PARALLEL
12295 : ORT_PARALLEL, OMP_PARALLEL);
12297 push_gimplify_context ();
12299 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
12300 if (gimple_code (g) == GIMPLE_BIND)
12301 pop_gimplify_context (g);
12303 pop_gimplify_context (NULL);
12305 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
12308 g = gimple_build_omp_parallel (body,
12309 OMP_PARALLEL_CLAUSES (expr),
12310 NULL_TREE, NULL_TREE);
12311 if (OMP_PARALLEL_COMBINED (expr))
12312 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
12313 gimplify_seq_add_stmt (pre_p, g);
12314 *expr_p = NULL_TREE;
12317 /* Gimplify the contents of an OMP_TASK statement. This involves
12318 gimplification of the body, as well as scanning the body for used
12319 variables. We need to do this scan now, because variable-sized
12320 decls will be decomposed during gimplification. */
12323 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
12325 tree expr = *expr_p;
12327 gimple_seq body = NULL;
12328 bool nowait = false;
12329 bool has_depend = false;
12331 if (OMP_TASK_BODY (expr) == NULL_TREE)
12333 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
12334 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
12337 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
12339 error_at (OMP_CLAUSE_LOCATION (c),
12340 "%<mutexinoutset%> kind in %<depend%> clause on a "
12341 "%<taskwait%> construct");
12345 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOWAIT)
12347 if (nowait && !has_depend)
12349 error_at (EXPR_LOCATION (expr),
12350 "%<taskwait%> construct with %<nowait%> clause but no "
12351 "%<depend%> clauses");
12352 *expr_p = NULL_TREE;
12357 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
12358 omp_find_clause (OMP_TASK_CLAUSES (expr),
12360 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
12362 if (OMP_TASK_BODY (expr))
12364 push_gimplify_context ();
12366 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
12367 if (gimple_code (g) == GIMPLE_BIND)
12368 pop_gimplify_context (g);
12370 pop_gimplify_context (NULL);
12373 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
12376 g = gimple_build_omp_task (body,
12377 OMP_TASK_CLAUSES (expr),
12378 NULL_TREE, NULL_TREE,
12379 NULL_TREE, NULL_TREE, NULL_TREE);
12380 if (OMP_TASK_BODY (expr) == NULL_TREE)
12381 gimple_omp_task_set_taskwait_p (g, true);
12382 gimplify_seq_add_stmt (pre_p, g);
12383 *expr_p = NULL_TREE;
12386 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
12387 force it into a temporary initialized in PRE_P and add firstprivate clause
12388 to ORIG_FOR_STMT. */
12391 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
12392 tree orig_for_stmt)
12394 if (*tp == NULL || is_gimple_constant (*tp))
12397 *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
12398 /* Reference to pointer conversion is considered useless,
12399 but is significant for firstprivate clause. Force it
12402 && TREE_CODE (type) == POINTER_TYPE
12403 && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
12405 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
12406 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
12407 gimplify_and_add (m, pre_p);
12411 tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
12412 OMP_CLAUSE_DECL (c) = *tp;
12413 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
12414 OMP_FOR_CLAUSES (orig_for_stmt) = c;
12417 /* Gimplify the gross structure of an OMP_FOR statement. */
12419 static enum gimplify_status
12420 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
12422 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
12423 enum gimplify_status ret = GS_ALL_DONE;
12424 enum gimplify_status tret;
12426 gimple_seq for_body, for_pre_body;
12428 bitmap has_decl_expr = NULL;
12429 enum omp_region_type ort = ORT_WORKSHARE;
12430 bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
12432 orig_for_stmt = for_stmt = *expr_p;
12434 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
12436 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
12438 tree *data[4] = { NULL, NULL, NULL, NULL };
12439 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
12440 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
12441 find_combined_omp_for, data, NULL);
12442 if (inner_for_stmt == NULL_TREE)
12444 gcc_assert (seen_error ());
12445 *expr_p = NULL_TREE;
12448 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
12450 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
12451 &OMP_FOR_PRE_BODY (for_stmt));
12452 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
12454 if (OMP_FOR_PRE_BODY (inner_for_stmt))
12456 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
12457 &OMP_FOR_PRE_BODY (for_stmt));
12458 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
12463 /* We have some statements or variable declarations in between
12464 the composite construct directives. Move them around the
12467 for (i = 0; i < 3; i++)
12471 if (i < 2 && data[i + 1] == &OMP_BODY (t))
12472 data[i + 1] = data[i];
12473 *data[i] = OMP_BODY (t);
12474 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
12475 NULL_TREE, make_node (BLOCK));
12476 OMP_BODY (t) = body;
12477 append_to_statement_list_force (inner_for_stmt,
12478 &BIND_EXPR_BODY (body));
12480 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
12481 gcc_assert (*data[3] == inner_for_stmt);
12486 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
12488 && OMP_FOR_ORIG_DECLS (inner_for_stmt)
12489 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12491 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12494 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
12495 /* Class iterators aren't allowed on OMP_SIMD, so the only
12496 case we need to solve is distribute parallel for. They are
12497 allowed on the loop construct, but that is already handled
12498 in gimplify_omp_loop. */
12499 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
12500 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
12502 tree orig_decl = TREE_PURPOSE (orig);
12503 tree last = TREE_VALUE (orig);
12505 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
12506 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
12507 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
12508 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
12509 && OMP_CLAUSE_DECL (*pc) == orig_decl)
12511 if (*pc == NULL_TREE)
12514 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
12515 *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
12516 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
12517 && OMP_CLAUSE_DECL (*spc) == orig_decl)
12522 *spc = OMP_CLAUSE_CHAIN (c);
12523 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
12527 if (*pc == NULL_TREE)
12529 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
12531 /* private clause will appear only on inner_for_stmt.
12532 Change it into firstprivate, and add private clause
12534 tree c = copy_node (*pc);
12535 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12536 OMP_FOR_CLAUSES (for_stmt) = c;
12537 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
12538 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12542 /* lastprivate clause will appear on both inner_for_stmt
12543 and for_stmt. Add firstprivate clause to
12545 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
12546 OMP_CLAUSE_FIRSTPRIVATE);
12547 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
12548 OMP_CLAUSE_CHAIN (c) = *pc;
12550 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12552 tree c = build_omp_clause (UNKNOWN_LOCATION,
12553 OMP_CLAUSE_FIRSTPRIVATE);
12554 OMP_CLAUSE_DECL (c) = last;
12555 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12556 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12557 c = build_omp_clause (UNKNOWN_LOCATION,
12558 *pc ? OMP_CLAUSE_SHARED
12559 : OMP_CLAUSE_FIRSTPRIVATE);
12560 OMP_CLAUSE_DECL (c) = orig_decl;
12561 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12562 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12564 /* Similarly, take care of C++ range for temporaries, those should
12565 be firstprivate on OMP_PARALLEL if any. */
12567 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
12568 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
12569 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12571 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12575 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
12576 tree v = TREE_CHAIN (orig);
12577 tree c = build_omp_clause (UNKNOWN_LOCATION,
12578 OMP_CLAUSE_FIRSTPRIVATE);
12579 /* First add firstprivate clause for the __for_end artificial
12581 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
12582 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12584 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12585 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12586 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12587 if (TREE_VEC_ELT (v, 0))
12589 /* And now the same for __for_range artificial decl if it
12591 c = build_omp_clause (UNKNOWN_LOCATION,
12592 OMP_CLAUSE_FIRSTPRIVATE);
12593 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
12594 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12596 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12597 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12598 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12603 switch (TREE_CODE (for_stmt))
12606 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
12608 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12609 OMP_CLAUSE_SCHEDULE))
12610 error_at (EXPR_LOCATION (for_stmt),
12611 "%qs clause may not appear on non-rectangular %qs",
12612 "schedule", lang_GNU_Fortran () ? "do" : "for");
12613 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
12614 error_at (EXPR_LOCATION (for_stmt),
12615 "%qs clause may not appear on non-rectangular %qs",
12616 "ordered", lang_GNU_Fortran () ? "do" : "for");
12619 case OMP_DISTRIBUTE:
12620 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
12621 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12622 OMP_CLAUSE_DIST_SCHEDULE))
12623 error_at (EXPR_LOCATION (for_stmt),
12624 "%qs clause may not appear on non-rectangular %qs",
12625 "dist_schedule", "distribute");
12631 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
12633 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12634 OMP_CLAUSE_GRAINSIZE))
12635 error_at (EXPR_LOCATION (for_stmt),
12636 "%qs clause may not appear on non-rectangular %qs",
12637 "grainsize", "taskloop");
12638 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12639 OMP_CLAUSE_NUM_TASKS))
12640 error_at (EXPR_LOCATION (for_stmt),
12641 "%qs clause may not appear on non-rectangular %qs",
12642 "num_tasks", "taskloop");
12644 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
12645 ort = ORT_UNTIED_TASKLOOP;
12647 ort = ORT_TASKLOOP;
12653 gcc_unreachable ();
12656 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
12657 clause for the IV. */
12658 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12660 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
12661 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12662 decl = TREE_OPERAND (t, 0);
12663 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
12664 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12665 && OMP_CLAUSE_DECL (c) == decl)
12667 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12672 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
12673 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
12674 loop_p && TREE_CODE (for_stmt) != OMP_SIMD
12675 ? OMP_LOOP : TREE_CODE (for_stmt));
12677 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
12678 gimplify_omp_ctxp->distribute = true;
12680 /* Handle OMP_FOR_INIT. */
12681 for_pre_body = NULL;
12682 if ((ort == ORT_SIMD
12683 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
12684 && OMP_FOR_PRE_BODY (for_stmt))
12686 has_decl_expr = BITMAP_ALLOC (NULL);
12687 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
12688 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
12691 t = OMP_FOR_PRE_BODY (for_stmt);
12692 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12694 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
12696 tree_stmt_iterator si;
12697 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
12701 if (TREE_CODE (t) == DECL_EXPR
12702 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
12703 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12707 if (OMP_FOR_PRE_BODY (for_stmt))
12709 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
12710 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12713 struct gimplify_omp_ctx ctx;
12714 memset (&ctx, 0, sizeof (ctx));
12715 ctx.region_type = ORT_NONE;
12716 gimplify_omp_ctxp = &ctx;
12717 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12718 gimplify_omp_ctxp = NULL;
12721 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
12723 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
12724 for_stmt = inner_for_stmt;
12726 /* For taskloop, need to gimplify the start, end and step before the
12727 taskloop, outside of the taskloop omp context. */
12728 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12730 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12732 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12733 gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
12734 ? pre_p : &for_pre_body);
12735 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
12736 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12738 tree v = TREE_OPERAND (t, 1);
12739 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12740 for_pre_p, orig_for_stmt);
12741 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12742 for_pre_p, orig_for_stmt);
12745 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12748 /* Handle OMP_FOR_COND. */
12749 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12750 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12752 tree v = TREE_OPERAND (t, 1);
12753 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12754 for_pre_p, orig_for_stmt);
12755 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12756 for_pre_p, orig_for_stmt);
12759 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12762 /* Handle OMP_FOR_INCR. */
12763 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12764 if (TREE_CODE (t) == MODIFY_EXPR)
12766 decl = TREE_OPERAND (t, 0);
12767 t = TREE_OPERAND (t, 1);
12768 tree *tp = &TREE_OPERAND (t, 1);
12769 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
12770 tp = &TREE_OPERAND (t, 0);
12772 gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
12777 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
12781 if (orig_for_stmt != for_stmt)
12782 gimplify_omp_ctxp->combined_loop = true;
12785 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12786 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
12787 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12788 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
12790 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
12791 bool is_doacross = false;
12792 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
12794 is_doacross = true;
12795 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
12796 (OMP_FOR_INIT (for_stmt))
12799 int collapse = 1, tile = 0;
12800 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
12802 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
12803 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
12805 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
12806 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
12807 hash_set<tree> *allocate_uids = NULL;
12810 allocate_uids = new hash_set<tree>;
12811 for (; c; c = OMP_CLAUSE_CHAIN (c))
12812 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
12813 allocate_uids->add (OMP_CLAUSE_DECL (c));
12815 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12817 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12818 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12819 decl = TREE_OPERAND (t, 0);
12820 gcc_assert (DECL_P (decl));
12821 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
12822 || POINTER_TYPE_P (TREE_TYPE (decl)));
12825 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
12827 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12828 if (TREE_CODE (orig_decl) == TREE_LIST)
12830 orig_decl = TREE_PURPOSE (orig_decl);
12834 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
12837 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12838 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12841 if (for_stmt == orig_for_stmt)
12843 tree orig_decl = decl;
12844 if (OMP_FOR_ORIG_DECLS (for_stmt))
12846 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12847 if (TREE_CODE (orig_decl) == TREE_LIST)
12849 orig_decl = TREE_PURPOSE (orig_decl);
12854 if (is_global_var (orig_decl) && DECL_THREAD_LOCAL_P (orig_decl))
12855 error_at (EXPR_LOCATION (for_stmt),
12856 "threadprivate iteration variable %qD", orig_decl);
12859 /* Make sure the iteration variable is private. */
12860 tree c = NULL_TREE;
12861 tree c2 = NULL_TREE;
12862 if (orig_for_stmt != for_stmt)
12864 /* Preserve this information until we gimplify the inner simd. */
12866 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12867 TREE_PRIVATE (t) = 1;
12869 else if (ort == ORT_SIMD)
12871 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12872 (splay_tree_key) decl);
12873 omp_is_private (gimplify_omp_ctxp, decl,
12874 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12876 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
12878 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12879 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
12880 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12881 OMP_CLAUSE_LASTPRIVATE);
12882 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12883 OMP_CLAUSE_LASTPRIVATE))
12884 if (OMP_CLAUSE_DECL (c3) == decl)
12886 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12887 "conditional %<lastprivate%> on loop "
12888 "iterator %qD ignored", decl);
12889 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12890 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12893 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
12895 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12896 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12897 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
12899 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12900 || TREE_PRIVATE (t))
12902 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12903 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12905 struct gimplify_omp_ctx *outer
12906 = gimplify_omp_ctxp->outer_context;
12907 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12909 if (outer->region_type == ORT_WORKSHARE
12910 && outer->combined_loop)
12912 n = splay_tree_lookup (outer->variables,
12913 (splay_tree_key)decl);
12914 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12916 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12917 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12921 struct gimplify_omp_ctx *octx = outer->outer_context;
12923 && octx->region_type == ORT_COMBINED_PARALLEL
12924 && octx->outer_context
12925 && (octx->outer_context->region_type
12927 && octx->outer_context->combined_loop)
12929 octx = octx->outer_context;
12930 n = splay_tree_lookup (octx->variables,
12931 (splay_tree_key)decl);
12932 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12934 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12935 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12942 OMP_CLAUSE_DECL (c) = decl;
12943 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12944 OMP_FOR_CLAUSES (for_stmt) = c;
12945 omp_add_variable (gimplify_omp_ctxp, decl, flags);
12946 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12947 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12954 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
12955 if (TREE_PRIVATE (t))
12956 lastprivate = false;
12957 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
12959 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12960 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
12961 lastprivate = false;
12964 struct gimplify_omp_ctx *outer
12965 = gimplify_omp_ctxp->outer_context;
12966 if (outer && lastprivate)
12967 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12970 c = build_omp_clause (input_location,
12971 lastprivate ? OMP_CLAUSE_LASTPRIVATE
12972 : OMP_CLAUSE_PRIVATE);
12973 OMP_CLAUSE_DECL (c) = decl;
12974 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12975 OMP_FOR_CLAUSES (for_stmt) = c;
12976 omp_add_variable (gimplify_omp_ctxp, decl,
12977 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
12978 | GOVD_EXPLICIT | GOVD_SEEN);
12982 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
12984 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12985 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12986 (splay_tree_key) decl);
12987 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
12988 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12989 OMP_CLAUSE_LASTPRIVATE);
12990 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12991 OMP_CLAUSE_LASTPRIVATE))
12992 if (OMP_CLAUSE_DECL (c3) == decl)
12994 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12995 "conditional %<lastprivate%> on loop "
12996 "iterator %qD ignored", decl);
12997 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12998 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
13002 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
13004 /* If DECL is not a gimple register, create a temporary variable to act
13005 as an iteration counter. This is valid, since DECL cannot be
13006 modified in the body of the loop. Similarly for any iteration vars
13007 in simd with collapse > 1 where the iterator vars must be
13008 lastprivate. And similarly for vars mentioned in allocate clauses. */
13009 if (orig_for_stmt != for_stmt)
13011 else if (!is_gimple_reg (decl)
13012 || (ort == ORT_SIMD
13013 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
13014 || (allocate_uids && allocate_uids->contains (decl)))
13016 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13017 /* Make sure omp_add_variable is not called on it prematurely.
13018 We call it ourselves a few lines later. */
13019 gimplify_omp_ctxp = NULL;
13020 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
13021 gimplify_omp_ctxp = ctx;
13022 TREE_OPERAND (t, 0) = var;
13024 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
13026 if (ort == ORT_SIMD
13027 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
13029 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
13030 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
13031 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
13032 OMP_CLAUSE_DECL (c2) = var;
13033 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
13034 OMP_FOR_CLAUSES (for_stmt) = c2;
13035 omp_add_variable (gimplify_omp_ctxp, var,
13036 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
13037 if (c == NULL_TREE)
13044 omp_add_variable (gimplify_omp_ctxp, var,
13045 GOVD_PRIVATE | GOVD_SEEN);
13050 gimplify_omp_ctxp->in_for_exprs = true;
13051 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
13053 tree lb = TREE_OPERAND (t, 1);
13054 tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
13055 is_gimple_val, fb_rvalue, false);
13056 ret = MIN (ret, tret);
13057 tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
13058 is_gimple_val, fb_rvalue, false);
13061 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
13062 is_gimple_val, fb_rvalue, false);
13063 gimplify_omp_ctxp->in_for_exprs = false;
13064 ret = MIN (ret, tret);
13065 if (ret == GS_ERROR)
13068 /* Handle OMP_FOR_COND. */
13069 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
13070 gcc_assert (COMPARISON_CLASS_P (t));
13071 gcc_assert (TREE_OPERAND (t, 0) == decl);
13073 gimplify_omp_ctxp->in_for_exprs = true;
13074 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
13076 tree ub = TREE_OPERAND (t, 1);
13077 tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
13078 is_gimple_val, fb_rvalue, false);
13079 ret = MIN (ret, tret);
13080 tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
13081 is_gimple_val, fb_rvalue, false);
13084 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
13085 is_gimple_val, fb_rvalue, false);
13086 gimplify_omp_ctxp->in_for_exprs = false;
13087 ret = MIN (ret, tret);
13089 /* Handle OMP_FOR_INCR. */
13090 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
13091 switch (TREE_CODE (t))
13093 case PREINCREMENT_EXPR:
13094 case POSTINCREMENT_EXPR:
13096 tree decl = TREE_OPERAND (t, 0);
13097 /* c_omp_for_incr_canonicalize_ptr() should have been
13098 called to massage things appropriately. */
13099 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
13101 if (orig_for_stmt != for_stmt)
13103 t = build_int_cst (TREE_TYPE (decl), 1);
13105 OMP_CLAUSE_LINEAR_STEP (c) = t;
13106 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
13107 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
13108 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
13112 case PREDECREMENT_EXPR:
13113 case POSTDECREMENT_EXPR:
13114 /* c_omp_for_incr_canonicalize_ptr() should have been
13115 called to massage things appropriately. */
13116 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
13117 if (orig_for_stmt != for_stmt)
13119 t = build_int_cst (TREE_TYPE (decl), -1);
13121 OMP_CLAUSE_LINEAR_STEP (c) = t;
13122 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
13123 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
13124 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
13128 gcc_assert (TREE_OPERAND (t, 0) == decl);
13129 TREE_OPERAND (t, 0) = var;
13131 t = TREE_OPERAND (t, 1);
13132 switch (TREE_CODE (t))
13135 if (TREE_OPERAND (t, 1) == decl)
13137 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
13138 TREE_OPERAND (t, 0) = var;
13144 case POINTER_PLUS_EXPR:
13145 gcc_assert (TREE_OPERAND (t, 0) == decl);
13146 TREE_OPERAND (t, 0) = var;
13149 gcc_unreachable ();
13152 gimplify_omp_ctxp->in_for_exprs = true;
13153 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
13154 is_gimple_val, fb_rvalue, false);
13155 ret = MIN (ret, tret);
13158 tree step = TREE_OPERAND (t, 1);
13159 tree stept = TREE_TYPE (decl);
13160 if (POINTER_TYPE_P (stept))
13162 step = fold_convert (stept, step);
13163 if (TREE_CODE (t) == MINUS_EXPR)
13164 step = fold_build1 (NEGATE_EXPR, stept, step);
13165 OMP_CLAUSE_LINEAR_STEP (c) = step;
13166 if (step != TREE_OPERAND (t, 1))
13168 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
13169 &for_pre_body, NULL,
13170 is_gimple_val, fb_rvalue, false);
13171 ret = MIN (ret, tret);
13174 gimplify_omp_ctxp->in_for_exprs = false;
13178 gcc_unreachable ();
13184 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
13187 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
13189 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
13190 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13191 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
13192 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
13193 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
13194 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
13195 && OMP_CLAUSE_DECL (c) == decl)
13197 if (is_doacross && (collapse == 1 || i >= collapse))
13201 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
13202 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13203 gcc_assert (TREE_OPERAND (t, 0) == var);
13204 t = TREE_OPERAND (t, 1);
13205 gcc_assert (TREE_CODE (t) == PLUS_EXPR
13206 || TREE_CODE (t) == MINUS_EXPR
13207 || TREE_CODE (t) == POINTER_PLUS_EXPR);
13208 gcc_assert (TREE_OPERAND (t, 0) == var);
13209 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
13210 is_doacross ? var : decl,
13211 TREE_OPERAND (t, 1));
13214 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
13215 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
13217 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
13218 push_gimplify_context ();
13219 gimplify_assign (decl, t, seq);
13220 gimple *bind = NULL;
13221 if (gimplify_ctxp->temps)
13223 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
13225 gimplify_seq_add_stmt (seq, bind);
13227 pop_gimplify_context (bind);
13230 if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
13231 for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
13233 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
13234 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13235 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13236 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13237 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13238 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
13239 gcc_assert (COMPARISON_CLASS_P (t));
13240 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13241 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13242 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13246 BITMAP_FREE (has_decl_expr);
13247 delete allocate_uids;
13249 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
13250 || (loop_p && orig_for_stmt == for_stmt))
13252 push_gimplify_context ();
13253 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
13255 OMP_FOR_BODY (orig_for_stmt)
13256 = build3 (BIND_EXPR, void_type_node, NULL,
13257 OMP_FOR_BODY (orig_for_stmt), NULL);
13258 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
13262 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
13265 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
13266 || (loop_p && orig_for_stmt == for_stmt))
13268 if (gimple_code (g) == GIMPLE_BIND)
13269 pop_gimplify_context (g);
13271 pop_gimplify_context (NULL);
13274 if (orig_for_stmt != for_stmt)
13275 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13277 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13278 decl = TREE_OPERAND (t, 0);
13279 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13280 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
13281 gimplify_omp_ctxp = ctx->outer_context;
13282 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
13283 gimplify_omp_ctxp = ctx;
13284 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
13285 TREE_OPERAND (t, 0) = var;
13286 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
13287 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13288 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
13289 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
13290 for (int j = i + 1;
13291 j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
13293 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
13294 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13295 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13296 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13298 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13299 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13301 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
13302 gcc_assert (COMPARISON_CLASS_P (t));
13303 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13304 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13306 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13307 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13312 gimplify_adjust_omp_clauses (pre_p, for_body,
13313 &OMP_FOR_CLAUSES (orig_for_stmt),
13314 TREE_CODE (orig_for_stmt));
13317 switch (TREE_CODE (orig_for_stmt))
13319 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
13320 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
13321 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
13322 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
13323 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
13325 gcc_unreachable ();
13327 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
13329 gimplify_seq_add_seq (pre_p, for_pre_body);
13330 for_pre_body = NULL;
13332 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
13333 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
13335 if (orig_for_stmt != for_stmt)
13336 gimple_omp_for_set_combined_p (gfor, true);
13337 if (gimplify_omp_ctxp
13338 && (gimplify_omp_ctxp->combined_loop
13339 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
13340 && gimplify_omp_ctxp->outer_context
13341 && gimplify_omp_ctxp->outer_context->combined_loop)))
13343 gimple_omp_for_set_combined_into_p (gfor, true);
13344 if (gimplify_omp_ctxp->combined_loop)
13345 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
13347 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
13350 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13352 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13353 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
13354 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
13355 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
13356 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
13357 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
13358 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
13359 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
13362 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
13363 constructs with GIMPLE_OMP_TASK sandwiched in between them.
13364 The outer taskloop stands for computing the number of iterations,
13365 counts for collapsed loops and holding taskloop specific clauses.
13366 The task construct stands for the effect of data sharing on the
13367 explicit task it creates and the inner taskloop stands for expansion
13368 of the static loop inside of the explicit task construct. */
13369 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
13371 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
13372 tree task_clauses = NULL_TREE;
13373 tree c = *gfor_clauses_ptr;
13374 tree *gtask_clauses_ptr = &task_clauses;
13375 tree outer_for_clauses = NULL_TREE;
13376 tree *gforo_clauses_ptr = &outer_for_clauses;
13377 bitmap lastprivate_uids = NULL;
13378 if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
13380 c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
13383 lastprivate_uids = BITMAP_ALLOC (NULL);
13384 for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
13385 OMP_CLAUSE_LASTPRIVATE))
13386 bitmap_set_bit (lastprivate_uids,
13387 DECL_UID (OMP_CLAUSE_DECL (c)));
13389 c = *gfor_clauses_ptr;
13391 for (; c; c = OMP_CLAUSE_CHAIN (c))
13392 switch (OMP_CLAUSE_CODE (c))
13394 /* These clauses are allowed on task, move them there. */
13395 case OMP_CLAUSE_SHARED:
13396 case OMP_CLAUSE_FIRSTPRIVATE:
13397 case OMP_CLAUSE_DEFAULT:
13398 case OMP_CLAUSE_IF:
13399 case OMP_CLAUSE_UNTIED:
13400 case OMP_CLAUSE_FINAL:
13401 case OMP_CLAUSE_MERGEABLE:
13402 case OMP_CLAUSE_PRIORITY:
13403 case OMP_CLAUSE_REDUCTION:
13404 case OMP_CLAUSE_IN_REDUCTION:
13405 *gtask_clauses_ptr = c;
13406 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13408 case OMP_CLAUSE_PRIVATE:
13409 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
13411 /* We want private on outer for and firstprivate
13414 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13415 OMP_CLAUSE_FIRSTPRIVATE);
13416 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13417 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
13419 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13420 *gforo_clauses_ptr = c;
13421 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13425 *gtask_clauses_ptr = c;
13426 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13429 /* These clauses go into outer taskloop clauses. */
13430 case OMP_CLAUSE_GRAINSIZE:
13431 case OMP_CLAUSE_NUM_TASKS:
13432 case OMP_CLAUSE_NOGROUP:
13433 *gforo_clauses_ptr = c;
13434 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13436 /* Collapse clause we duplicate on both taskloops. */
13437 case OMP_CLAUSE_COLLAPSE:
13438 *gfor_clauses_ptr = c;
13439 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13440 *gforo_clauses_ptr = copy_node (c);
13441 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
13443 /* For lastprivate, keep the clause on inner taskloop, and add
13444 a shared clause on task. If the same decl is also firstprivate,
13445 add also firstprivate clause on the inner taskloop. */
13446 case OMP_CLAUSE_LASTPRIVATE:
13447 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
13449 /* For taskloop C++ lastprivate IVs, we want:
13450 1) private on outer taskloop
13451 2) firstprivate and shared on task
13452 3) lastprivate on inner taskloop */
13454 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13455 OMP_CLAUSE_FIRSTPRIVATE);
13456 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13457 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
13459 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13460 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
13461 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13462 OMP_CLAUSE_PRIVATE);
13463 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
13464 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
13465 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
13466 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
13468 *gfor_clauses_ptr = c;
13469 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13471 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
13472 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13473 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
13474 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
13476 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13478 /* Allocate clause we duplicate on task and inner taskloop
13479 if the decl is lastprivate, otherwise just put on task. */
13480 case OMP_CLAUSE_ALLOCATE:
13481 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
13482 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
13484 /* Additionally, put firstprivate clause on task
13485 for the allocator if it is not constant. */
13487 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13488 OMP_CLAUSE_FIRSTPRIVATE);
13489 OMP_CLAUSE_DECL (*gtask_clauses_ptr)
13490 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
13491 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13493 if (lastprivate_uids
13494 && bitmap_bit_p (lastprivate_uids,
13495 DECL_UID (OMP_CLAUSE_DECL (c))))
13497 *gfor_clauses_ptr = c;
13498 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13499 *gtask_clauses_ptr = copy_node (c);
13500 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13504 *gtask_clauses_ptr = c;
13505 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13509 gcc_unreachable ();
13511 *gfor_clauses_ptr = NULL_TREE;
13512 *gtask_clauses_ptr = NULL_TREE;
13513 *gforo_clauses_ptr = NULL_TREE;
13514 BITMAP_FREE (lastprivate_uids);
13515 gimple_set_location (gfor, input_location);
13516 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
13517 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
13518 NULL_TREE, NULL_TREE, NULL_TREE);
13519 gimple_set_location (g, input_location);
13520 gimple_omp_task_set_taskloop_p (g, true);
13521 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
13523 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
13524 gimple_omp_for_collapse (gfor),
13525 gimple_omp_for_pre_body (gfor));
13526 gimple_omp_for_set_pre_body (gfor, NULL);
13527 gimple_omp_for_set_combined_p (gforo, true);
13528 gimple_omp_for_set_combined_into_p (gfor, true);
13529 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
13531 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
13532 tree v = create_tmp_var (type);
13533 gimple_omp_for_set_index (gforo, i, v);
13534 t = unshare_expr (gimple_omp_for_initial (gfor, i));
13535 gimple_omp_for_set_initial (gforo, i, t);
13536 gimple_omp_for_set_cond (gforo, i,
13537 gimple_omp_for_cond (gfor, i));
13538 t = unshare_expr (gimple_omp_for_final (gfor, i));
13539 gimple_omp_for_set_final (gforo, i, t);
13540 t = unshare_expr (gimple_omp_for_incr (gfor, i));
13541 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
13542 TREE_OPERAND (t, 0) = v;
13543 gimple_omp_for_set_incr (gforo, i, t);
13544 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
13545 OMP_CLAUSE_DECL (t) = v;
13546 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
13547 gimple_omp_for_set_clauses (gforo, t);
13548 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
13550 tree *p1 = NULL, *p2 = NULL;
13551 t = gimple_omp_for_initial (gforo, i);
13552 if (TREE_CODE (t) == TREE_VEC)
13553 p1 = &TREE_VEC_ELT (t, 0);
13554 t = gimple_omp_for_final (gforo, i);
13555 if (TREE_CODE (t) == TREE_VEC)
13558 p2 = &TREE_VEC_ELT (t, 0);
13560 p1 = &TREE_VEC_ELT (t, 0);
13565 for (j = 0; j < i; j++)
13566 if (*p1 == gimple_omp_for_index (gfor, j))
13568 *p1 = gimple_omp_for_index (gforo, j);
13573 gcc_assert (j < i);
13577 gimplify_seq_add_stmt (pre_p, gforo);
13580 gimplify_seq_add_stmt (pre_p, gfor);
13582 if (TREE_CODE (orig_for_stmt) == OMP_FOR)
13584 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13585 unsigned lastprivate_conditional = 0;
13587 && (ctx->region_type == ORT_TARGET_DATA
13588 || ctx->region_type == ORT_TASKGROUP))
13589 ctx = ctx->outer_context;
13590 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
13591 for (tree c = gimple_omp_for_clauses (gfor);
13592 c; c = OMP_CLAUSE_CHAIN (c))
13593 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13594 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13595 ++lastprivate_conditional;
13596 if (lastprivate_conditional)
13598 struct omp_for_data fd;
13599 omp_extract_for_data (gfor, &fd, NULL);
13600 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
13601 lastprivate_conditional);
13602 tree var = create_tmp_var_raw (type);
13603 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
13604 OMP_CLAUSE_DECL (c) = var;
13605 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13606 gimple_omp_for_set_clauses (gfor, c);
13607 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
13610 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
13612 unsigned lastprivate_conditional = 0;
13613 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
13614 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13615 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13616 ++lastprivate_conditional;
13617 if (lastprivate_conditional)
13619 struct omp_for_data fd;
13620 omp_extract_for_data (gfor, &fd, NULL);
13621 tree type = unsigned_type_for (fd.iter_type);
13622 while (lastprivate_conditional--)
13624 tree c = build_omp_clause (UNKNOWN_LOCATION,
13625 OMP_CLAUSE__CONDTEMP_);
13626 OMP_CLAUSE_DECL (c) = create_tmp_var (type);
13627 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13628 gimple_omp_for_set_clauses (gfor, c);
13633 if (ret != GS_ALL_DONE)
13635 *expr_p = NULL_TREE;
13636 return GS_ALL_DONE;
13639 /* Helper for gimplify_omp_loop, called through walk_tree. */
13642 note_no_context_vars (tree *tp, int *, void *data)
13645 && DECL_CONTEXT (*tp) == NULL_TREE
13646 && !is_global_var (*tp))
13648 vec<tree> *d = (vec<tree> *) data;
13649 d->safe_push (*tp);
13650 DECL_CONTEXT (*tp) = current_function_decl;
13655 /* Gimplify the gross structure of an OMP_LOOP statement. */
13657 static enum gimplify_status
13658 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
13660 tree for_stmt = *expr_p;
13661 tree clauses = OMP_FOR_CLAUSES (for_stmt);
13662 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
13663 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
13666 /* If order is not present, the behavior is as if order(concurrent)
13668 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
13669 if (order == NULL_TREE)
13671 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
13672 OMP_CLAUSE_CHAIN (order) = clauses;
13673 OMP_FOR_CLAUSES (for_stmt) = clauses = order;
13676 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
13677 if (bind == NULL_TREE)
13679 if (!flag_openmp) /* flag_openmp_simd */
13681 else if (octx && (octx->region_type & ORT_TEAMS) != 0)
13682 kind = OMP_CLAUSE_BIND_TEAMS;
13683 else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
13684 kind = OMP_CLAUSE_BIND_PARALLEL;
13687 for (; octx; octx = octx->outer_context)
13689 if ((octx->region_type & ORT_ACC) != 0
13690 || octx->region_type == ORT_NONE
13691 || octx->region_type == ORT_IMPLICIT_TARGET)
13695 if (octx == NULL && !in_omp_construct)
13696 error_at (EXPR_LOCATION (for_stmt),
13697 "%<bind%> clause not specified on a %<loop%> "
13698 "construct not nested inside another OpenMP construct");
13700 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
13701 OMP_CLAUSE_CHAIN (bind) = clauses;
13702 OMP_CLAUSE_BIND_KIND (bind) = kind;
13703 OMP_FOR_CLAUSES (for_stmt) = bind;
13706 switch (OMP_CLAUSE_BIND_KIND (bind))
13708 case OMP_CLAUSE_BIND_THREAD:
13710 case OMP_CLAUSE_BIND_PARALLEL:
13711 if (!flag_openmp) /* flag_openmp_simd */
13713 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13716 for (; octx; octx = octx->outer_context)
13717 if (octx->region_type == ORT_SIMD
13718 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
13720 error_at (EXPR_LOCATION (for_stmt),
13721 "%<bind(parallel)%> on a %<loop%> construct nested "
13722 "inside %<simd%> construct");
13723 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13726 kind = OMP_CLAUSE_BIND_PARALLEL;
13728 case OMP_CLAUSE_BIND_TEAMS:
13729 if (!flag_openmp) /* flag_openmp_simd */
13731 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13735 && octx->region_type != ORT_IMPLICIT_TARGET
13736 && octx->region_type != ORT_NONE
13737 && (octx->region_type & ORT_TEAMS) == 0)
13738 || in_omp_construct)
13740 error_at (EXPR_LOCATION (for_stmt),
13741 "%<bind(teams)%> on a %<loop%> region not strictly "
13742 "nested inside of a %<teams%> region");
13743 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13746 kind = OMP_CLAUSE_BIND_TEAMS;
13749 gcc_unreachable ();
13752 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
13753 switch (OMP_CLAUSE_CODE (*pc))
13755 case OMP_CLAUSE_REDUCTION:
13756 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
13758 error_at (OMP_CLAUSE_LOCATION (*pc),
13759 "%<inscan%> %<reduction%> clause on "
13760 "%qs construct", "loop");
13761 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
13763 if (OMP_CLAUSE_REDUCTION_TASK (*pc))
13765 error_at (OMP_CLAUSE_LOCATION (*pc),
13766 "invalid %<task%> reduction modifier on construct "
13767 "other than %<parallel%>, %qs or %<sections%>",
13768 lang_GNU_Fortran () ? "do" : "for");
13769 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
13771 pc = &OMP_CLAUSE_CHAIN (*pc);
13773 case OMP_CLAUSE_LASTPRIVATE:
13774 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13776 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13777 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13778 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
13780 if (OMP_FOR_ORIG_DECLS (for_stmt)
13781 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13783 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13786 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13787 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
13791 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
13793 error_at (OMP_CLAUSE_LOCATION (*pc),
13794 "%<lastprivate%> clause on a %<loop%> construct refers "
13795 "to a variable %qD which is not the loop iterator",
13796 OMP_CLAUSE_DECL (*pc));
13797 *pc = OMP_CLAUSE_CHAIN (*pc);
13800 pc = &OMP_CLAUSE_CHAIN (*pc);
13803 pc = &OMP_CLAUSE_CHAIN (*pc);
13807 TREE_SET_CODE (for_stmt, OMP_SIMD);
13812 case OMP_CLAUSE_BIND_THREAD: last = 0; break;
13813 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
13814 case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
13816 for (int pass = 1; pass <= last; pass++)
13820 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
13821 make_node (BLOCK));
13822 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
13823 *expr_p = make_node (OMP_PARALLEL);
13824 TREE_TYPE (*expr_p) = void_type_node;
13825 OMP_PARALLEL_BODY (*expr_p) = bind;
13826 OMP_PARALLEL_COMBINED (*expr_p) = 1;
13827 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
13828 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
13829 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13830 if (OMP_FOR_ORIG_DECLS (for_stmt)
13831 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
13834 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13835 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
13837 *pc = build_omp_clause (UNKNOWN_LOCATION,
13838 OMP_CLAUSE_FIRSTPRIVATE);
13839 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
13840 pc = &OMP_CLAUSE_CHAIN (*pc);
13844 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
13845 tree *pc = &OMP_FOR_CLAUSES (t);
13846 TREE_TYPE (t) = void_type_node;
13847 OMP_FOR_BODY (t) = *expr_p;
13848 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
13849 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
13850 switch (OMP_CLAUSE_CODE (c))
13852 case OMP_CLAUSE_BIND:
13853 case OMP_CLAUSE_ORDER:
13854 case OMP_CLAUSE_COLLAPSE:
13855 *pc = copy_node (c);
13856 pc = &OMP_CLAUSE_CHAIN (*pc);
13858 case OMP_CLAUSE_PRIVATE:
13859 case OMP_CLAUSE_FIRSTPRIVATE:
13860 /* Only needed on innermost. */
13862 case OMP_CLAUSE_LASTPRIVATE:
13863 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
13865 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13866 OMP_CLAUSE_FIRSTPRIVATE);
13867 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
13868 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13869 pc = &OMP_CLAUSE_CHAIN (*pc);
13871 *pc = copy_node (c);
13872 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
13873 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13874 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
13877 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
13879 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13880 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
13882 pc = &OMP_CLAUSE_CHAIN (*pc);
13884 case OMP_CLAUSE_REDUCTION:
13885 *pc = copy_node (c);
13886 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
13887 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13888 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
13890 auto_vec<tree> no_context_vars;
13891 int walk_subtrees = 0;
13892 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13893 &walk_subtrees, &no_context_vars);
13894 if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c))
13895 note_no_context_vars (&p, &walk_subtrees, &no_context_vars);
13896 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c),
13897 note_no_context_vars,
13899 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c),
13900 note_no_context_vars,
13903 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
13904 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
13905 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13906 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
13907 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
13909 hash_map<tree, tree> decl_map;
13910 decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c));
13911 decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13912 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc));
13913 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13914 decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
13915 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc));
13918 memset (&id, 0, sizeof (id));
13919 id.src_fn = current_function_decl;
13920 id.dst_fn = current_function_decl;
13921 id.src_cfun = cfun;
13922 id.decl_map = &decl_map;
13923 id.copy_decl = copy_decl_no_change;
13924 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
13925 id.transform_new_cfg = true;
13926 id.transform_return_to_modify = false;
13928 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r,
13930 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r,
13933 for (tree d : no_context_vars)
13935 DECL_CONTEXT (d) = NULL_TREE;
13936 DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE;
13941 OMP_CLAUSE_REDUCTION_INIT (*pc)
13942 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
13943 OMP_CLAUSE_REDUCTION_MERGE (*pc)
13944 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
13946 pc = &OMP_CLAUSE_CHAIN (*pc);
13949 gcc_unreachable ();
13954 return gimplify_expr (expr_p, pre_p, NULL, is_gimple_stmt, fb_none);
13958 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
13959 of OMP_TARGET's body. */
13962 find_omp_teams (tree *tp, int *walk_subtrees, void *)
13964 *walk_subtrees = 0;
13965 switch (TREE_CODE (*tp))
13970 case STATEMENT_LIST:
13971 *walk_subtrees = 1;
13979 /* Helper function of optimize_target_teams, determine if the expression
13980 can be computed safely before the target construct on the host. */
13983 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
13989 *walk_subtrees = 0;
13992 switch (TREE_CODE (*tp))
13997 *walk_subtrees = 0;
13998 if (error_operand_p (*tp)
13999 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
14000 || DECL_HAS_VALUE_EXPR_P (*tp)
14001 || DECL_THREAD_LOCAL_P (*tp)
14002 || TREE_SIDE_EFFECTS (*tp)
14003 || TREE_THIS_VOLATILE (*tp))
14005 if (is_global_var (*tp)
14006 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
14007 || lookup_attribute ("omp declare target link",
14008 DECL_ATTRIBUTES (*tp))))
14011 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
14012 && !is_global_var (*tp)
14013 && decl_function_context (*tp) == current_function_decl)
14015 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
14016 (splay_tree_key) *tp);
14019 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
14023 else if (n->value & GOVD_LOCAL)
14025 else if (n->value & GOVD_FIRSTPRIVATE)
14027 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
14028 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
14032 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
14036 if (TARGET_EXPR_INITIAL (*tp)
14037 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
14039 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
14040 walk_subtrees, NULL);
14041 /* Allow some reasonable subset of integral arithmetics. */
14045 case TRUNC_DIV_EXPR:
14046 case CEIL_DIV_EXPR:
14047 case FLOOR_DIV_EXPR:
14048 case ROUND_DIV_EXPR:
14049 case TRUNC_MOD_EXPR:
14050 case CEIL_MOD_EXPR:
14051 case FLOOR_MOD_EXPR:
14052 case ROUND_MOD_EXPR:
14054 case EXACT_DIV_EXPR:
14065 case NON_LVALUE_EXPR:
14067 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
14070 /* And disallow anything else, except for comparisons. */
14072 if (COMPARISON_CLASS_P (*tp))
14078 /* Try to determine if the num_teams and/or thread_limit expressions
14079 can have their values determined already before entering the
14081 INTEGER_CSTs trivially are,
14082 integral decls that are firstprivate (explicitly or implicitly)
14083 or explicitly map(always, to:) or map(always, tofrom:) on the target
14084 region too, and expressions involving simple arithmetics on those
14085 too, function calls are not ok, dereferencing something neither etc.
14086 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
14087 EXPR based on what we find:
14088 0 stands for clause not specified at all, use implementation default
14089 -1 stands for value that can't be determined easily before entering
14090 the target construct.
14091 If teams construct is not present at all, use 1 for num_teams
14092 and 0 for thread_limit (only one team is involved, and the thread
14093 limit is implementation defined. */
14096 optimize_target_teams (tree target, gimple_seq *pre_p)
14098 tree body = OMP_BODY (target);
14099 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
14100 tree num_teams_lower = NULL_TREE;
14101 tree num_teams_upper = integer_zero_node;
14102 tree thread_limit = integer_zero_node;
14103 location_t num_teams_loc = EXPR_LOCATION (target);
14104 location_t thread_limit_loc = EXPR_LOCATION (target);
14106 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
14108 if (teams == NULL_TREE)
14109 num_teams_upper = integer_one_node;
14111 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
14113 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
14115 p = &num_teams_upper;
14116 num_teams_loc = OMP_CLAUSE_LOCATION (c);
14117 if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))
14119 expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
14120 if (TREE_CODE (expr) == INTEGER_CST)
14121 num_teams_lower = expr;
14122 else if (walk_tree (&expr, computable_teams_clause,
14124 num_teams_lower = integer_minus_one_node;
14127 num_teams_lower = expr;
14128 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
14129 if (gimplify_expr (&num_teams_lower, pre_p, NULL,
14130 is_gimple_val, fb_rvalue, false)
14133 gimplify_omp_ctxp = target_ctx;
14134 num_teams_lower = integer_minus_one_node;
14138 gimplify_omp_ctxp = target_ctx;
14139 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
14140 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
14146 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
14149 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
14153 expr = OMP_CLAUSE_OPERAND (c, 0);
14154 if (TREE_CODE (expr) == INTEGER_CST)
14159 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
14161 *p = integer_minus_one_node;
14165 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
14166 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
14169 gimplify_omp_ctxp = target_ctx;
14170 *p = integer_minus_one_node;
14173 gimplify_omp_ctxp = target_ctx;
14174 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
14175 OMP_CLAUSE_OPERAND (c, 0) = *p;
14177 if (!omp_find_clause (OMP_TARGET_CLAUSES (target), OMP_CLAUSE_THREAD_LIMIT))
14179 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
14180 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
14181 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
14182 OMP_TARGET_CLAUSES (target) = c;
14184 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
14185 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper;
14186 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower;
14187 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
14188 OMP_TARGET_CLAUSES (target) = c;
14191 /* Gimplify the gross structure of several OMP constructs. */
14194 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
14196 tree expr = *expr_p;
14198 gimple_seq body = NULL;
14199 enum omp_region_type ort;
14201 switch (TREE_CODE (expr))
14205 ort = ORT_WORKSHARE;
14208 ort = ORT_TASKGROUP;
14211 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
14214 ort = ORT_ACC_KERNELS;
14216 case OACC_PARALLEL:
14217 ort = ORT_ACC_PARALLEL;
14220 ort = ORT_ACC_SERIAL;
14223 ort = ORT_ACC_DATA;
14225 case OMP_TARGET_DATA:
14226 ort = ORT_TARGET_DATA;
14229 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
14230 if (gimplify_omp_ctxp == NULL
14231 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
14232 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
14234 case OACC_HOST_DATA:
14235 ort = ORT_ACC_HOST_DATA;
14238 gcc_unreachable ();
14241 bool save_in_omp_construct = in_omp_construct;
14242 if ((ort & ORT_ACC) == 0)
14243 in_omp_construct = false;
14244 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
14246 if (TREE_CODE (expr) == OMP_TARGET)
14247 optimize_target_teams (expr, pre_p);
14248 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
14249 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
14251 push_gimplify_context ();
14252 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
14253 if (gimple_code (g) == GIMPLE_BIND)
14254 pop_gimplify_context (g);
14256 pop_gimplify_context (NULL);
14257 if ((ort & ORT_TARGET_DATA) != 0)
14259 enum built_in_function end_ix;
14260 switch (TREE_CODE (expr))
14263 case OACC_HOST_DATA:
14264 end_ix = BUILT_IN_GOACC_DATA_END;
14266 case OMP_TARGET_DATA:
14267 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
14270 gcc_unreachable ();
14272 tree fn = builtin_decl_explicit (end_ix);
14273 g = gimple_build_call (fn, 0);
14274 gimple_seq cleanup = NULL;
14275 gimple_seq_add_stmt (&cleanup, g);
14276 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
14278 gimple_seq_add_stmt (&body, g);
14282 gimplify_and_add (OMP_BODY (expr), &body);
14283 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
14285 in_omp_construct = save_in_omp_construct;
14287 switch (TREE_CODE (expr))
14290 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
14291 OMP_CLAUSES (expr));
14293 case OACC_HOST_DATA:
14294 if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
14296 for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14297 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
14298 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
14301 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
14302 OMP_CLAUSES (expr));
14305 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
14306 OMP_CLAUSES (expr));
14308 case OACC_PARALLEL:
14309 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
14310 OMP_CLAUSES (expr));
14313 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
14314 OMP_CLAUSES (expr));
14317 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
14320 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
14323 stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr));
14326 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
14327 OMP_CLAUSES (expr));
14329 case OMP_TARGET_DATA:
14330 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
14331 to be evaluated before the use_device_{ptr,addr} clauses if they
14332 refer to the same variables. */
14334 tree use_device_clauses;
14335 tree *pc, *uc = &use_device_clauses;
14336 for (pc = &OMP_CLAUSES (expr); *pc; )
14337 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
14338 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
14341 *pc = OMP_CLAUSE_CHAIN (*pc);
14342 uc = &OMP_CLAUSE_CHAIN (*uc);
14345 pc = &OMP_CLAUSE_CHAIN (*pc);
14347 *pc = use_device_clauses;
14348 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
14349 OMP_CLAUSES (expr));
14353 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
14354 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
14355 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
14358 gcc_unreachable ();
14361 gimplify_seq_add_stmt (pre_p, stmt);
14362 *expr_p = NULL_TREE;
14365 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
14366 target update constructs. */
14369 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
14371 tree expr = *expr_p;
14374 enum omp_region_type ort = ORT_WORKSHARE;
14376 switch (TREE_CODE (expr))
14378 case OACC_ENTER_DATA:
14379 kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA;
14382 case OACC_EXIT_DATA:
14383 kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA;
14387 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
14390 case OMP_TARGET_UPDATE:
14391 kind = GF_OMP_TARGET_KIND_UPDATE;
14393 case OMP_TARGET_ENTER_DATA:
14394 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
14396 case OMP_TARGET_EXIT_DATA:
14397 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
14400 gcc_unreachable ();
14402 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
14403 ort, TREE_CODE (expr));
14404 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
14406 if (TREE_CODE (expr) == OACC_UPDATE
14407 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
14408 OMP_CLAUSE_IF_PRESENT))
14410 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
14412 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14413 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
14414 switch (OMP_CLAUSE_MAP_KIND (c))
14416 case GOMP_MAP_FORCE_TO:
14417 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
14419 case GOMP_MAP_FORCE_FROM:
14420 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
14426 else if (TREE_CODE (expr) == OACC_EXIT_DATA
14427 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
14428 OMP_CLAUSE_FINALIZE))
14430 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
14432 bool have_clause = false;
14433 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14434 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
14435 switch (OMP_CLAUSE_MAP_KIND (c))
14437 case GOMP_MAP_FROM:
14438 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
14439 have_clause = true;
14441 case GOMP_MAP_RELEASE:
14442 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
14443 have_clause = true;
14445 case GOMP_MAP_TO_PSET:
14446 /* Fortran arrays with descriptors must map that descriptor when
14447 doing standalone "attach" operations (in OpenACC). In that
14448 case GOMP_MAP_TO_PSET appears by itself with no preceding
14449 clause (see trans-openmp.cc:gfc_trans_omp_clauses). */
14451 case GOMP_MAP_POINTER:
14452 /* TODO PR92929: we may see these here, but they'll always follow
14453 one of the clauses above, and will be handled by libgomp as
14454 one group, so no handling required here. */
14455 gcc_assert (have_clause);
14457 case GOMP_MAP_DETACH:
14458 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
14459 have_clause = false;
14461 case GOMP_MAP_STRUCT:
14462 have_clause = false;
14465 gcc_unreachable ();
14468 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
14470 gimplify_seq_add_stmt (pre_p, stmt);
14471 *expr_p = NULL_TREE;
14474 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
14475 stabilized the lhs of the atomic operation as *ADDR. Return true if
14476 EXPR is this stabilized form. */
14479 goa_lhs_expr_p (tree expr, tree addr)
14481 /* Also include casts to other type variants. The C front end is fond
14482 of adding these for e.g. volatile variables. This is like
14483 STRIP_TYPE_NOPS but includes the main variant lookup. */
14484 STRIP_USELESS_TYPE_CONVERSION (expr);
14486 if (TREE_CODE (expr) == INDIRECT_REF)
14488 expr = TREE_OPERAND (expr, 0);
14489 while (expr != addr
14490 && (CONVERT_EXPR_P (expr)
14491 || TREE_CODE (expr) == NON_LVALUE_EXPR)
14492 && TREE_CODE (expr) == TREE_CODE (addr)
14493 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
14495 expr = TREE_OPERAND (expr, 0);
14496 addr = TREE_OPERAND (addr, 0);
14500 return (TREE_CODE (addr) == ADDR_EXPR
14501 && TREE_CODE (expr) == ADDR_EXPR
14502 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
14504 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
14509 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
14510 expression does not involve the lhs, evaluate it into a temporary.
14511 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
14512 or -1 if an error was encountered. */
14515 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
14516 tree lhs_var, tree &target_expr, bool rhs, int depth)
14518 tree expr = *expr_p;
14521 if (goa_lhs_expr_p (expr, lhs_addr))
14527 if (is_gimple_val (expr))
14530 /* Maximum depth of lhs in expression is for the
14531 __builtin_clear_padding (...), __builtin_clear_padding (...),
14532 __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs; */
14536 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
14539 case tcc_comparison:
14540 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
14541 lhs_var, target_expr, true, depth);
14544 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
14545 lhs_var, target_expr, true, depth);
14547 case tcc_expression:
14548 switch (TREE_CODE (expr))
14550 case TRUTH_ANDIF_EXPR:
14551 case TRUTH_ORIF_EXPR:
14552 case TRUTH_AND_EXPR:
14553 case TRUTH_OR_EXPR:
14554 case TRUTH_XOR_EXPR:
14555 case BIT_INSERT_EXPR:
14556 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14557 lhs_addr, lhs_var, target_expr, true,
14560 case TRUTH_NOT_EXPR:
14561 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14562 lhs_addr, lhs_var, target_expr, true,
14566 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14567 target_expr, true, depth))
14569 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14570 lhs_addr, lhs_var, target_expr, true,
14572 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14573 lhs_addr, lhs_var, target_expr, false,
14578 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14579 target_expr, true, depth))
14581 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14582 lhs_addr, lhs_var, target_expr, false,
14585 case COMPOUND_EXPR:
14586 /* Break out any preevaluations from cp_build_modify_expr. */
14587 for (; TREE_CODE (expr) == COMPOUND_EXPR;
14588 expr = TREE_OPERAND (expr, 1))
14590 /* Special-case __builtin_clear_padding call before
14591 __builtin_memcmp. */
14592 if (TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR)
14594 tree fndecl = get_callee_fndecl (TREE_OPERAND (expr, 0));
14596 && fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14597 && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
14599 || goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL,
14601 target_expr, true, depth)))
14605 saw_lhs = goa_stabilize_expr (&TREE_OPERAND (expr, 0),
14606 pre_p, lhs_addr, lhs_var,
14607 target_expr, true, depth);
14608 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1),
14609 pre_p, lhs_addr, lhs_var,
14610 target_expr, rhs, depth);
14616 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
14619 return goa_stabilize_expr (&expr, pre_p, lhs_addr, lhs_var,
14620 target_expr, rhs, depth);
14622 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var,
14623 target_expr, rhs, depth);
14625 if (!goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, lhs_addr,
14626 lhs_var, target_expr, true, depth))
14628 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14629 lhs_addr, lhs_var, target_expr, true,
14631 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14632 lhs_addr, lhs_var, target_expr, true,
14634 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 2), pre_p,
14635 lhs_addr, lhs_var, target_expr, true,
14639 if (TARGET_EXPR_INITIAL (expr))
14641 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr,
14642 lhs_var, target_expr, true,
14645 if (expr == target_expr)
14649 saw_lhs = goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr),
14650 pre_p, lhs_addr, lhs_var,
14651 target_expr, true, depth);
14652 if (saw_lhs && target_expr == NULL_TREE && pre_p)
14653 target_expr = expr;
14661 case tcc_reference:
14662 if (TREE_CODE (expr) == BIT_FIELD_REF
14663 || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
14664 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14665 lhs_addr, lhs_var, target_expr, true,
14669 if (TREE_CODE (expr) == CALL_EXPR)
14671 if (tree fndecl = get_callee_fndecl (expr))
14672 if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14673 || fndecl_built_in_p (fndecl, BUILT_IN_MEMCMP))
14675 int nargs = call_expr_nargs (expr);
14676 for (int i = 0; i < nargs; i++)
14677 saw_lhs |= goa_stabilize_expr (&CALL_EXPR_ARG (expr, i),
14678 pre_p, lhs_addr, lhs_var,
14679 target_expr, true, depth);
14688 if (saw_lhs == 0 && pre_p)
14690 enum gimplify_status gs;
14691 if (TREE_CODE (expr) == CALL_EXPR && VOID_TYPE_P (TREE_TYPE (expr)))
14693 gimplify_stmt (&expr, pre_p);
14697 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
14699 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_lvalue, fb_lvalue);
14700 if (gs != GS_ALL_DONE)
14707 /* Gimplify an OMP_ATOMIC statement. */
14709 static enum gimplify_status
14710 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
14712 tree addr = TREE_OPERAND (*expr_p, 0);
14713 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
14714 ? NULL : TREE_OPERAND (*expr_p, 1);
14715 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
14717 gomp_atomic_load *loadstmt;
14718 gomp_atomic_store *storestmt;
14719 tree target_expr = NULL_TREE;
14721 tmp_load = create_tmp_reg (type);
14723 && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load, target_expr,
14727 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
14731 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
14732 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14733 gimplify_seq_add_stmt (pre_p, loadstmt);
14736 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
14737 representatives. Use BIT_FIELD_REF on the lhs instead. */
14739 if (TREE_CODE (rhs) == COND_EXPR)
14740 rhsarg = TREE_OPERAND (rhs, 1);
14741 if (TREE_CODE (rhsarg) == BIT_INSERT_EXPR
14742 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
14744 tree bitpos = TREE_OPERAND (rhsarg, 2);
14745 tree op1 = TREE_OPERAND (rhsarg, 1);
14747 tree tmp_store = tmp_load;
14748 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
14749 tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
14750 if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
14751 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
14753 bitsize = TYPE_SIZE (TREE_TYPE (op1));
14754 gcc_assert (TREE_OPERAND (rhsarg, 0) == tmp_load);
14755 tree t = build2_loc (EXPR_LOCATION (rhsarg),
14756 MODIFY_EXPR, void_type_node,
14757 build3_loc (EXPR_LOCATION (rhsarg),
14758 BIT_FIELD_REF, TREE_TYPE (op1),
14759 tmp_store, bitsize, bitpos), op1);
14760 if (TREE_CODE (rhs) == COND_EXPR)
14761 t = build3_loc (EXPR_LOCATION (rhs), COND_EXPR, void_type_node,
14762 TREE_OPERAND (rhs, 0), t, void_node);
14763 gimplify_and_add (t, pre_p);
14766 bool save_allow_rhs_cond_expr = gimplify_ctxp->allow_rhs_cond_expr;
14767 if (TREE_CODE (rhs) == COND_EXPR)
14768 gimplify_ctxp->allow_rhs_cond_expr = true;
14769 enum gimplify_status gs = gimplify_expr (&rhs, pre_p, NULL,
14770 is_gimple_val, fb_rvalue);
14771 gimplify_ctxp->allow_rhs_cond_expr = save_allow_rhs_cond_expr;
14772 if (gs != GS_ALL_DONE)
14776 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
14779 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14780 if (TREE_CODE (*expr_p) != OMP_ATOMIC_READ && OMP_ATOMIC_WEAK (*expr_p))
14782 gimple_omp_atomic_set_weak (loadstmt);
14783 gimple_omp_atomic_set_weak (storestmt);
14785 gimplify_seq_add_stmt (pre_p, storestmt);
14786 switch (TREE_CODE (*expr_p))
14788 case OMP_ATOMIC_READ:
14789 case OMP_ATOMIC_CAPTURE_OLD:
14790 *expr_p = tmp_load;
14791 gimple_omp_atomic_set_need_value (loadstmt);
14793 case OMP_ATOMIC_CAPTURE_NEW:
14795 gimple_omp_atomic_set_need_value (storestmt);
14802 return GS_ALL_DONE;
14805 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
14806 body, and adding some EH bits. */
14808 static enum gimplify_status
14809 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
14811 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
14813 gtransaction *trans_stmt;
14814 gimple_seq body = NULL;
14817 /* Wrap the transaction body in a BIND_EXPR so we have a context
14818 where to put decls for OMP. */
14819 if (TREE_CODE (tbody) != BIND_EXPR)
14821 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
14822 TREE_SIDE_EFFECTS (bind) = 1;
14823 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
14824 TRANSACTION_EXPR_BODY (expr) = bind;
14827 push_gimplify_context ();
14828 temp = voidify_wrapper_expr (*expr_p, NULL);
14830 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
14831 pop_gimplify_context (body_stmt);
14833 trans_stmt = gimple_build_transaction (body);
14834 if (TRANSACTION_EXPR_OUTER (expr))
14835 subcode = GTMA_IS_OUTER;
14836 else if (TRANSACTION_EXPR_RELAXED (expr))
14837 subcode = GTMA_IS_RELAXED;
14838 gimple_transaction_set_subcode (trans_stmt, subcode);
14840 gimplify_seq_add_stmt (pre_p, trans_stmt);
14848 *expr_p = NULL_TREE;
14849 return GS_ALL_DONE;
14852 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
14853 is the OMP_BODY of the original EXPR (which has already been
14854 gimplified so it's not present in the EXPR).
14856 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
14859 gimplify_omp_ordered (tree expr, gimple_seq body)
14864 tree source_c = NULL_TREE;
14865 tree sink_c = NULL_TREE;
14867 if (gimplify_omp_ctxp)
14869 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14870 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14871 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
14872 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
14873 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
14875 error_at (OMP_CLAUSE_LOCATION (c),
14876 "%<ordered%> construct with %<depend%> clause must be "
14877 "closely nested inside a loop with %<ordered%> clause "
14878 "with a parameter");
14881 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14882 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
14885 for (decls = OMP_CLAUSE_DECL (c), i = 0;
14886 decls && TREE_CODE (decls) == TREE_LIST;
14887 decls = TREE_CHAIN (decls), ++i)
14888 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
14890 else if (TREE_VALUE (decls)
14891 != gimplify_omp_ctxp->loop_iter_var[2 * i])
14893 error_at (OMP_CLAUSE_LOCATION (c),
14894 "variable %qE is not an iteration "
14895 "of outermost loop %d, expected %qE",
14896 TREE_VALUE (decls), i + 1,
14897 gimplify_omp_ctxp->loop_iter_var[2 * i]);
14903 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
14904 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
14906 error_at (OMP_CLAUSE_LOCATION (c),
14907 "number of variables in %<depend%> clause with "
14908 "%<sink%> modifier does not match number of "
14909 "iteration variables");
14914 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14915 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
14919 error_at (OMP_CLAUSE_LOCATION (c),
14920 "more than one %<depend%> clause with %<source%> "
14921 "modifier on an %<ordered%> construct");
14928 if (source_c && sink_c)
14930 error_at (OMP_CLAUSE_LOCATION (source_c),
14931 "%<depend%> clause with %<source%> modifier specified "
14932 "together with %<depend%> clauses with %<sink%> modifier "
14933 "on the same construct");
14938 return gimple_build_nop ();
14939 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
14942 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
14943 expression produces a value to be used as an operand inside a GIMPLE
14944 statement, the value will be stored back in *EXPR_P. This value will
14945 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
14946 an SSA_NAME. The corresponding sequence of GIMPLE statements is
14947 emitted in PRE_P and POST_P.
14949 Additionally, this process may overwrite parts of the input
14950 expression during gimplification. Ideally, it should be
14951 possible to do non-destructive gimplification.
14953 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
14954 the expression needs to evaluate to a value to be used as
14955 an operand in a GIMPLE statement, this value will be stored in
14956 *EXPR_P on exit. This happens when the caller specifies one
14957 of fb_lvalue or fb_rvalue fallback flags.
14959 PRE_P will contain the sequence of GIMPLE statements corresponding
14960 to the evaluation of EXPR and all the side-effects that must
14961 be executed before the main expression. On exit, the last
14962 statement of PRE_P is the core statement being gimplified. For
14963 instance, when gimplifying 'if (++a)' the last statement in
14964 PRE_P will be 'if (t.1)' where t.1 is the result of
14965 pre-incrementing 'a'.
14967 POST_P will contain the sequence of GIMPLE statements corresponding
14968 to the evaluation of all the side-effects that must be executed
14969 after the main expression. If this is NULL, the post
14970 side-effects are stored at the end of PRE_P.
14972 The reason why the output is split in two is to handle post
14973 side-effects explicitly. In some cases, an expression may have
14974 inner and outer post side-effects which need to be emitted in
14975 an order different from the one given by the recursive
14976 traversal. For instance, for the expression (*p--)++ the post
14977 side-effects of '--' must actually occur *after* the post
14978 side-effects of '++'. However, gimplification will first visit
14979 the inner expression, so if a separate POST sequence was not
14980 used, the resulting sequence would be:
14987 However, the post-decrement operation in line #2 must not be
14988 evaluated until after the store to *p at line #4, so the
14989 correct sequence should be:
14996 So, by specifying a separate post queue, it is possible
14997 to emit the post side-effects in the correct order.
14998 If POST_P is NULL, an internal queue will be used. Before
14999 returning to the caller, the sequence POST_P is appended to
15000 the main output sequence PRE_P.
15002 GIMPLE_TEST_F points to a function that takes a tree T and
15003 returns nonzero if T is in the GIMPLE form requested by the
15004 caller. The GIMPLE predicates are in gimple.cc.
15006 FALLBACK tells the function what sort of a temporary we want if
15007 gimplification cannot produce an expression that complies with
15010 fb_none means that no temporary should be generated
15011 fb_rvalue means that an rvalue is OK to generate
15012 fb_lvalue means that an lvalue is OK to generate
15013 fb_either means that either is OK, but an lvalue is preferable.
15014 fb_mayfail means that gimplification may fail (in which case
15015 GS_ERROR will be returned)
15017 The return value is either GS_ERROR or GS_ALL_DONE, since this
15018 function iterates until EXPR is completely gimplified or an error
15021 enum gimplify_status
15022 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
15023 bool (*gimple_test_f) (tree), fallback_t fallback)
15026 gimple_seq internal_pre = NULL;
15027 gimple_seq internal_post = NULL;
15030 location_t saved_location;
15031 enum gimplify_status ret;
15032 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
15035 save_expr = *expr_p;
15036 if (save_expr == NULL_TREE)
15037 return GS_ALL_DONE;
15039 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
15040 is_statement = gimple_test_f == is_gimple_stmt;
15042 gcc_assert (pre_p);
15044 /* Consistency checks. */
15045 if (gimple_test_f == is_gimple_reg)
15046 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
15047 else if (gimple_test_f == is_gimple_val
15048 || gimple_test_f == is_gimple_call_addr
15049 || gimple_test_f == is_gimple_condexpr_for_cond
15050 || gimple_test_f == is_gimple_mem_rhs
15051 || gimple_test_f == is_gimple_mem_rhs_or_call
15052 || gimple_test_f == is_gimple_reg_rhs
15053 || gimple_test_f == is_gimple_reg_rhs_or_call
15054 || gimple_test_f == is_gimple_asm_val
15055 || gimple_test_f == is_gimple_mem_ref_addr)
15056 gcc_assert (fallback & fb_rvalue);
15057 else if (gimple_test_f == is_gimple_min_lval
15058 || gimple_test_f == is_gimple_lvalue)
15059 gcc_assert (fallback & fb_lvalue);
15060 else if (gimple_test_f == is_gimple_addressable)
15061 gcc_assert (fallback & fb_either);
15062 else if (gimple_test_f == is_gimple_stmt)
15063 gcc_assert (fallback == fb_none);
15066 /* We should have recognized the GIMPLE_TEST_F predicate to
15067 know what kind of fallback to use in case a temporary is
15068 needed to hold the value or address of *EXPR_P. */
15069 gcc_unreachable ();
15072 /* We used to check the predicate here and return immediately if it
15073 succeeds. This is wrong; the design is for gimplification to be
15074 idempotent, and for the predicates to only test for valid forms, not
15075 whether they are fully simplified. */
15077 pre_p = &internal_pre;
15079 if (post_p == NULL)
15080 post_p = &internal_post;
15082 /* Remember the last statements added to PRE_P and POST_P. Every
15083 new statement added by the gimplification helpers needs to be
15084 annotated with location information. To centralize the
15085 responsibility, we remember the last statement that had been
15086 added to both queues before gimplifying *EXPR_P. If
15087 gimplification produces new statements in PRE_P and POST_P, those
15088 statements will be annotated with the same location information
15090 pre_last_gsi = gsi_last (*pre_p);
15091 post_last_gsi = gsi_last (*post_p);
15093 saved_location = input_location;
15094 if (save_expr != error_mark_node
15095 && EXPR_HAS_LOCATION (*expr_p))
15096 input_location = EXPR_LOCATION (*expr_p);
15098 /* Loop over the specific gimplifiers until the toplevel node
15099 remains the same. */
15102 /* Strip away as many useless type conversions as possible
15103 at the toplevel. */
15104 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
15106 /* Remember the expr. */
15107 save_expr = *expr_p;
15109 /* Die, die, die, my darling. */
15110 if (error_operand_p (save_expr))
15116 /* Do any language-specific gimplification. */
15117 ret = ((enum gimplify_status)
15118 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
15121 if (*expr_p == NULL_TREE)
15123 if (*expr_p != save_expr)
15126 else if (ret != GS_UNHANDLED)
15129 /* Make sure that all the cases set 'ret' appropriately. */
15130 ret = GS_UNHANDLED;
15131 switch (TREE_CODE (*expr_p))
15133 /* First deal with the special cases. */
15135 case POSTINCREMENT_EXPR:
15136 case POSTDECREMENT_EXPR:
15137 case PREINCREMENT_EXPR:
15138 case PREDECREMENT_EXPR:
15139 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
15140 fallback != fb_none,
15141 TREE_TYPE (*expr_p));
15144 case VIEW_CONVERT_EXPR:
15145 if ((fallback & fb_rvalue)
15146 && is_gimple_reg_type (TREE_TYPE (*expr_p))
15147 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
15149 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15150 post_p, is_gimple_val, fb_rvalue);
15151 recalculate_side_effects (*expr_p);
15157 case ARRAY_RANGE_REF:
15158 case REALPART_EXPR:
15159 case IMAGPART_EXPR:
15160 case COMPONENT_REF:
15161 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
15162 fallback ? fallback : fb_rvalue);
15166 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
15168 /* C99 code may assign to an array in a structure value of a
15169 conditional expression, and this has undefined behavior
15170 only on execution, so create a temporary if an lvalue is
15172 if (fallback == fb_lvalue)
15174 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
15175 mark_addressable (*expr_p);
15181 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
15183 /* C99 code may assign to an array in a structure returned
15184 from a function, and this has undefined behavior only on
15185 execution, so create a temporary if an lvalue is
15187 if (fallback == fb_lvalue)
15189 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
15190 mark_addressable (*expr_p);
15196 gcc_unreachable ();
15198 case COMPOUND_EXPR:
15199 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
15202 case COMPOUND_LITERAL_EXPR:
15203 ret = gimplify_compound_literal_expr (expr_p, pre_p,
15204 gimple_test_f, fallback);
15209 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
15210 fallback != fb_none);
15213 case TRUTH_ANDIF_EXPR:
15214 case TRUTH_ORIF_EXPR:
15216 /* Preserve the original type of the expression and the
15217 source location of the outer expression. */
15218 tree org_type = TREE_TYPE (*expr_p);
15219 *expr_p = gimple_boolify (*expr_p);
15220 *expr_p = build3_loc (input_location, COND_EXPR,
15224 org_type, boolean_true_node),
15227 org_type, boolean_false_node));
15232 case TRUTH_NOT_EXPR:
15234 tree type = TREE_TYPE (*expr_p);
15235 /* The parsers are careful to generate TRUTH_NOT_EXPR
15236 only with operands that are always zero or one.
15237 We do not fold here but handle the only interesting case
15238 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
15239 *expr_p = gimple_boolify (*expr_p);
15240 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
15241 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
15242 TREE_TYPE (*expr_p),
15243 TREE_OPERAND (*expr_p, 0));
15245 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
15246 TREE_TYPE (*expr_p),
15247 TREE_OPERAND (*expr_p, 0),
15248 build_int_cst (TREE_TYPE (*expr_p), 1));
15249 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
15250 *expr_p = fold_convert_loc (input_location, type, *expr_p);
15256 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
15259 case ANNOTATE_EXPR:
15261 tree cond = TREE_OPERAND (*expr_p, 0);
15262 tree kind = TREE_OPERAND (*expr_p, 1);
15263 tree data = TREE_OPERAND (*expr_p, 2);
15264 tree type = TREE_TYPE (cond);
15265 if (!INTEGRAL_TYPE_P (type))
15271 tree tmp = create_tmp_var (type);
15272 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
15274 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
15275 gimple_call_set_lhs (call, tmp);
15276 gimplify_seq_add_stmt (pre_p, call);
15283 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
15287 if (IS_EMPTY_STMT (*expr_p))
15293 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
15294 || fallback == fb_none)
15296 /* Just strip a conversion to void (or in void context) and
15298 *expr_p = TREE_OPERAND (*expr_p, 0);
15303 ret = gimplify_conversion (expr_p);
15304 if (ret == GS_ERROR)
15306 if (*expr_p != save_expr)
15310 case FIX_TRUNC_EXPR:
15311 /* unary_expr: ... | '(' cast ')' val | ... */
15312 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15313 is_gimple_val, fb_rvalue);
15314 recalculate_side_effects (*expr_p);
15319 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
15320 bool notrap = TREE_THIS_NOTRAP (*expr_p);
15321 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
15323 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
15324 if (*expr_p != save_expr)
15330 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15331 is_gimple_reg, fb_rvalue);
15332 if (ret == GS_ERROR)
15335 recalculate_side_effects (*expr_p);
15336 *expr_p = fold_build2_loc (input_location, MEM_REF,
15337 TREE_TYPE (*expr_p),
15338 TREE_OPERAND (*expr_p, 0),
15339 build_int_cst (saved_ptr_type, 0));
15340 TREE_THIS_VOLATILE (*expr_p) = volatilep;
15341 TREE_THIS_NOTRAP (*expr_p) = notrap;
15346 /* We arrive here through the various re-gimplifcation paths. */
15348 /* First try re-folding the whole thing. */
15349 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
15350 TREE_OPERAND (*expr_p, 0),
15351 TREE_OPERAND (*expr_p, 1));
15354 REF_REVERSE_STORAGE_ORDER (tmp)
15355 = REF_REVERSE_STORAGE_ORDER (*expr_p);
15357 recalculate_side_effects (*expr_p);
15361 /* Avoid re-gimplifying the address operand if it is already
15362 in suitable form. Re-gimplifying would mark the address
15363 operand addressable. Always gimplify when not in SSA form
15364 as we still may have to gimplify decls with value-exprs. */
15365 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
15366 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
15368 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15369 is_gimple_mem_ref_addr, fb_rvalue);
15370 if (ret == GS_ERROR)
15373 recalculate_side_effects (*expr_p);
15377 /* Constants need not be gimplified. */
15384 /* Drop the overflow flag on constants, we do not want
15385 that in the GIMPLE IL. */
15386 if (TREE_OVERFLOW_P (*expr_p))
15387 *expr_p = drop_tree_overflow (*expr_p);
15392 /* If we require an lvalue, such as for ADDR_EXPR, retain the
15393 CONST_DECL node. Otherwise the decl is replaceable by its
15395 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
15396 if (fallback & fb_lvalue)
15400 *expr_p = DECL_INITIAL (*expr_p);
15406 ret = gimplify_decl_expr (expr_p, pre_p);
15410 ret = gimplify_bind_expr (expr_p, pre_p);
15414 ret = gimplify_loop_expr (expr_p, pre_p);
15418 ret = gimplify_switch_expr (expr_p, pre_p);
15422 ret = gimplify_exit_expr (expr_p);
15426 /* If the target is not LABEL, then it is a computed jump
15427 and the target needs to be gimplified. */
15428 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
15430 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
15431 NULL, is_gimple_val, fb_rvalue);
15432 if (ret == GS_ERROR)
15435 gimplify_seq_add_stmt (pre_p,
15436 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
15441 gimplify_seq_add_stmt (pre_p,
15442 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
15443 PREDICT_EXPR_OUTCOME (*expr_p)));
15448 ret = gimplify_label_expr (expr_p, pre_p);
15449 label = LABEL_EXPR_LABEL (*expr_p);
15450 gcc_assert (decl_function_context (label) == current_function_decl);
15452 /* If the label is used in a goto statement, or address of the label
15453 is taken, we need to unpoison all variables that were seen so far.
15454 Doing so would prevent us from reporting a false positives. */
15455 if (asan_poisoned_variables
15456 && asan_used_labels != NULL
15457 && asan_used_labels->contains (label)
15458 && !gimplify_omp_ctxp)
15459 asan_poison_variables (asan_poisoned_variables, false, pre_p);
15462 case CASE_LABEL_EXPR:
15463 ret = gimplify_case_label_expr (expr_p, pre_p);
15465 if (gimplify_ctxp->live_switch_vars)
15466 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
15471 ret = gimplify_return_expr (*expr_p, pre_p);
15475 /* Don't reduce this in place; let gimplify_init_constructor work its
15476 magic. Buf if we're just elaborating this for side effects, just
15477 gimplify any element that has side-effects. */
15478 if (fallback == fb_none)
15480 unsigned HOST_WIDE_INT ix;
15482 tree temp = NULL_TREE;
15483 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
15484 if (TREE_SIDE_EFFECTS (val))
15485 append_to_statement_list (val, &temp);
15488 ret = temp ? GS_OK : GS_ALL_DONE;
15490 /* C99 code may assign to an array in a constructed
15491 structure or union, and this has undefined behavior only
15492 on execution, so create a temporary if an lvalue is
15494 else if (fallback == fb_lvalue)
15496 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
15497 mark_addressable (*expr_p);
15504 /* The following are special cases that are not handled by the
15505 original GIMPLE grammar. */
15507 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
15510 ret = gimplify_save_expr (expr_p, pre_p, post_p);
15513 case BIT_FIELD_REF:
15514 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15515 post_p, is_gimple_lvalue, fb_either);
15516 recalculate_side_effects (*expr_p);
15519 case TARGET_MEM_REF:
15521 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
15523 if (TMR_BASE (*expr_p))
15524 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
15525 post_p, is_gimple_mem_ref_addr, fb_either);
15526 if (TMR_INDEX (*expr_p))
15527 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
15528 post_p, is_gimple_val, fb_rvalue);
15529 if (TMR_INDEX2 (*expr_p))
15530 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
15531 post_p, is_gimple_val, fb_rvalue);
15532 /* TMR_STEP and TMR_OFFSET are always integer constants. */
15533 ret = MIN (r0, r1);
15537 case NON_LVALUE_EXPR:
15538 /* This should have been stripped above. */
15539 gcc_unreachable ();
15542 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
15545 case TRY_FINALLY_EXPR:
15546 case TRY_CATCH_EXPR:
15548 gimple_seq eval, cleanup;
15551 /* Calls to destructors are generated automatically in FINALLY/CATCH
15552 block. They should have location as UNKNOWN_LOCATION. However,
15553 gimplify_call_expr will reset these call stmts to input_location
15554 if it finds stmt's location is unknown. To prevent resetting for
15555 destructors, we set the input_location to unknown.
15556 Note that this only affects the destructor calls in FINALLY/CATCH
15557 block, and will automatically reset to its original value by the
15558 end of gimplify_expr. */
15559 input_location = UNKNOWN_LOCATION;
15560 eval = cleanup = NULL;
15561 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
15562 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15563 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
15565 gimple_seq n = NULL, e = NULL;
15566 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15568 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15570 if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
15572 geh_else *stmt = gimple_build_eh_else (n, e);
15573 gimple_seq_add_stmt (&cleanup, stmt);
15577 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
15578 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
15579 if (gimple_seq_empty_p (cleanup))
15581 gimple_seq_add_seq (pre_p, eval);
15585 try_ = gimple_build_try (eval, cleanup,
15586 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15587 ? GIMPLE_TRY_FINALLY
15588 : GIMPLE_TRY_CATCH);
15589 if (EXPR_HAS_LOCATION (save_expr))
15590 gimple_set_location (try_, EXPR_LOCATION (save_expr));
15591 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
15592 gimple_set_location (try_, saved_location);
15593 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
15594 gimple_try_set_catch_is_cleanup (try_,
15595 TRY_CATCH_IS_CLEANUP (*expr_p));
15596 gimplify_seq_add_stmt (pre_p, try_);
15601 case CLEANUP_POINT_EXPR:
15602 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
15606 ret = gimplify_target_expr (expr_p, pre_p, post_p);
15612 gimple_seq handler = NULL;
15613 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
15614 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
15615 gimplify_seq_add_stmt (pre_p, c);
15620 case EH_FILTER_EXPR:
15623 gimple_seq failure = NULL;
15625 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
15626 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
15627 copy_warning (ehf, *expr_p);
15628 gimplify_seq_add_stmt (pre_p, ehf);
15635 enum gimplify_status r0, r1;
15636 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
15637 post_p, is_gimple_val, fb_rvalue);
15638 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
15639 post_p, is_gimple_val, fb_rvalue);
15640 TREE_SIDE_EFFECTS (*expr_p) = 0;
15641 ret = MIN (r0, r1);
15646 /* We get here when taking the address of a label. We mark
15647 the label as "forced"; meaning it can never be removed and
15648 it is a potential target for any computed goto. */
15649 FORCED_LABEL (*expr_p) = 1;
15653 case STATEMENT_LIST:
15654 ret = gimplify_statement_list (expr_p, pre_p);
15657 case WITH_SIZE_EXPR:
15659 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15660 post_p == &internal_post ? NULL : post_p,
15661 gimple_test_f, fallback);
15662 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15663 is_gimple_val, fb_rvalue);
15670 ret = gimplify_var_or_parm_decl (expr_p);
15674 /* When within an OMP context, notice uses of variables. */
15675 if (gimplify_omp_ctxp)
15676 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
15680 case DEBUG_EXPR_DECL:
15681 gcc_unreachable ();
15683 case DEBUG_BEGIN_STMT:
15684 gimplify_seq_add_stmt (pre_p,
15685 gimple_build_debug_begin_stmt
15686 (TREE_BLOCK (*expr_p),
15687 EXPR_LOCATION (*expr_p)));
15693 /* Allow callbacks into the gimplifier during optimization. */
15698 gimplify_omp_parallel (expr_p, pre_p);
15703 gimplify_omp_task (expr_p, pre_p);
15709 /* Temporarily disable into_ssa, as scan_omp_simd
15710 which calls copy_gimple_seq_and_replace_locals can't deal
15711 with SSA_NAMEs defined outside of the body properly. */
15712 bool saved_into_ssa = gimplify_ctxp->into_ssa;
15713 gimplify_ctxp->into_ssa = false;
15714 ret = gimplify_omp_for (expr_p, pre_p);
15715 gimplify_ctxp->into_ssa = saved_into_ssa;
15720 case OMP_DISTRIBUTE:
15723 ret = gimplify_omp_for (expr_p, pre_p);
15727 ret = gimplify_omp_loop (expr_p, pre_p);
15731 gimplify_oacc_cache (expr_p, pre_p);
15736 gimplify_oacc_declare (expr_p, pre_p);
15740 case OACC_HOST_DATA:
15743 case OACC_PARALLEL:
15749 case OMP_TARGET_DATA:
15751 gimplify_omp_workshare (expr_p, pre_p);
15755 case OACC_ENTER_DATA:
15756 case OACC_EXIT_DATA:
15758 case OMP_TARGET_UPDATE:
15759 case OMP_TARGET_ENTER_DATA:
15760 case OMP_TARGET_EXIT_DATA:
15761 gimplify_omp_target_update (expr_p, pre_p);
15772 gimple_seq body = NULL;
15774 bool saved_in_omp_construct = in_omp_construct;
15776 in_omp_construct = true;
15777 gimplify_and_add (OMP_BODY (*expr_p), &body);
15778 in_omp_construct = saved_in_omp_construct;
15779 switch (TREE_CODE (*expr_p))
15782 g = gimple_build_omp_section (body);
15785 g = gimple_build_omp_master (body);
15788 g = gimplify_omp_ordered (*expr_p, body);
15791 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p),
15792 pre_p, ORT_WORKSHARE, OMP_MASKED);
15793 gimplify_adjust_omp_clauses (pre_p, body,
15794 &OMP_MASKED_CLAUSES (*expr_p),
15796 g = gimple_build_omp_masked (body,
15797 OMP_MASKED_CLAUSES (*expr_p));
15800 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
15801 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
15802 gimplify_adjust_omp_clauses (pre_p, body,
15803 &OMP_CRITICAL_CLAUSES (*expr_p),
15805 g = gimple_build_omp_critical (body,
15806 OMP_CRITICAL_NAME (*expr_p),
15807 OMP_CRITICAL_CLAUSES (*expr_p));
15810 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
15811 pre_p, ORT_WORKSHARE, OMP_SCAN);
15812 gimplify_adjust_omp_clauses (pre_p, body,
15813 &OMP_SCAN_CLAUSES (*expr_p),
15815 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
15818 gcc_unreachable ();
15820 gimplify_seq_add_stmt (pre_p, g);
15825 case OMP_TASKGROUP:
15827 gimple_seq body = NULL;
15829 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
15830 bool saved_in_omp_construct = in_omp_construct;
15831 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
15833 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
15835 in_omp_construct = true;
15836 gimplify_and_add (OMP_BODY (*expr_p), &body);
15837 in_omp_construct = saved_in_omp_construct;
15838 gimple_seq cleanup = NULL;
15839 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
15840 gimple *g = gimple_build_call (fn, 0);
15841 gimple_seq_add_stmt (&cleanup, g);
15842 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
15844 gimple_seq_add_stmt (&body, g);
15845 g = gimple_build_omp_taskgroup (body, *pclauses);
15846 gimplify_seq_add_stmt (pre_p, g);
15852 case OMP_ATOMIC_READ:
15853 case OMP_ATOMIC_CAPTURE_OLD:
15854 case OMP_ATOMIC_CAPTURE_NEW:
15855 ret = gimplify_omp_atomic (expr_p, pre_p);
15858 case TRANSACTION_EXPR:
15859 ret = gimplify_transaction (expr_p, pre_p);
15862 case TRUTH_AND_EXPR:
15863 case TRUTH_OR_EXPR:
15864 case TRUTH_XOR_EXPR:
15866 tree orig_type = TREE_TYPE (*expr_p);
15867 tree new_type, xop0, xop1;
15868 *expr_p = gimple_boolify (*expr_p);
15869 new_type = TREE_TYPE (*expr_p);
15870 if (!useless_type_conversion_p (orig_type, new_type))
15872 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
15877 /* Boolified binary truth expressions are semantically equivalent
15878 to bitwise binary expressions. Canonicalize them to the
15879 bitwise variant. */
15880 switch (TREE_CODE (*expr_p))
15882 case TRUTH_AND_EXPR:
15883 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
15885 case TRUTH_OR_EXPR:
15886 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
15888 case TRUTH_XOR_EXPR:
15889 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
15894 /* Now make sure that operands have compatible type to
15895 expression's new_type. */
15896 xop0 = TREE_OPERAND (*expr_p, 0);
15897 xop1 = TREE_OPERAND (*expr_p, 1);
15898 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
15899 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
15902 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
15903 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
15906 /* Continue classified as tcc_binary. */
15910 case VEC_COND_EXPR:
15913 case VEC_PERM_EXPR:
15914 /* Classified as tcc_expression. */
15917 case BIT_INSERT_EXPR:
15918 /* Argument 3 is a constant. */
15921 case POINTER_PLUS_EXPR:
15923 enum gimplify_status r0, r1;
15924 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15925 post_p, is_gimple_val, fb_rvalue);
15926 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15927 post_p, is_gimple_val, fb_rvalue);
15928 recalculate_side_effects (*expr_p);
15929 ret = MIN (r0, r1);
15934 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
15936 case tcc_comparison:
15937 /* Handle comparison of objects of non scalar mode aggregates
15938 with a call to memcmp. It would be nice to only have to do
15939 this for variable-sized objects, but then we'd have to allow
15940 the same nest of reference nodes we allow for MODIFY_EXPR and
15941 that's too complex.
15943 Compare scalar mode aggregates as scalar mode values. Using
15944 memcmp for them would be very inefficient at best, and is
15945 plain wrong if bitfields are involved. */
15947 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
15949 /* Vector comparisons need no boolification. */
15950 if (TREE_CODE (type) == VECTOR_TYPE)
15952 else if (!AGGREGATE_TYPE_P (type))
15954 tree org_type = TREE_TYPE (*expr_p);
15955 *expr_p = gimple_boolify (*expr_p);
15956 if (!useless_type_conversion_p (org_type,
15957 TREE_TYPE (*expr_p)))
15959 *expr_p = fold_convert_loc (input_location,
15960 org_type, *expr_p);
15966 else if (TYPE_MODE (type) != BLKmode)
15967 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
15969 ret = gimplify_variable_sized_compare (expr_p);
15974 /* If *EXPR_P does not need to be special-cased, handle it
15975 according to its class. */
15977 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15978 post_p, is_gimple_val, fb_rvalue);
15984 enum gimplify_status r0, r1;
15986 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15987 post_p, is_gimple_val, fb_rvalue);
15988 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15989 post_p, is_gimple_val, fb_rvalue);
15991 ret = MIN (r0, r1);
15997 enum gimplify_status r0, r1, r2;
15999 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
16000 post_p, is_gimple_val, fb_rvalue);
16001 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
16002 post_p, is_gimple_val, fb_rvalue);
16003 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
16004 post_p, is_gimple_val, fb_rvalue);
16006 ret = MIN (MIN (r0, r1), r2);
16010 case tcc_declaration:
16013 goto dont_recalculate;
16016 gcc_unreachable ();
16019 recalculate_side_effects (*expr_p);
16025 gcc_assert (*expr_p || ret != GS_OK);
16027 while (ret == GS_OK);
16029 /* If we encountered an error_mark somewhere nested inside, either
16030 stub out the statement or propagate the error back out. */
16031 if (ret == GS_ERROR)
16038 /* This was only valid as a return value from the langhook, which
16039 we handled. Make sure it doesn't escape from any other context. */
16040 gcc_assert (ret != GS_UNHANDLED);
16042 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
16044 /* We aren't looking for a value, and we don't have a valid
16045 statement. If it doesn't have side-effects, throw it away.
16046 We can also get here with code such as "*&&L;", where L is
16047 a LABEL_DECL that is marked as FORCED_LABEL. */
16048 if (TREE_CODE (*expr_p) == LABEL_DECL
16049 || !TREE_SIDE_EFFECTS (*expr_p))
16051 else if (!TREE_THIS_VOLATILE (*expr_p))
16053 /* This is probably a _REF that contains something nested that
16054 has side effects. Recurse through the operands to find it. */
16055 enum tree_code code = TREE_CODE (*expr_p);
16059 case COMPONENT_REF:
16060 case REALPART_EXPR:
16061 case IMAGPART_EXPR:
16062 case VIEW_CONVERT_EXPR:
16063 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
16064 gimple_test_f, fallback);
16068 case ARRAY_RANGE_REF:
16069 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
16070 gimple_test_f, fallback);
16071 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
16072 gimple_test_f, fallback);
16076 /* Anything else with side-effects must be converted to
16077 a valid statement before we get here. */
16078 gcc_unreachable ();
16083 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
16084 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode
16085 && !is_empty_type (TREE_TYPE (*expr_p)))
16087 /* Historically, the compiler has treated a bare reference
16088 to a non-BLKmode volatile lvalue as forcing a load. */
16089 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
16091 /* Normally, we do not want to create a temporary for a
16092 TREE_ADDRESSABLE type because such a type should not be
16093 copied by bitwise-assignment. However, we make an
16094 exception here, as all we are doing here is ensuring that
16095 we read the bytes that make up the type. We use
16096 create_tmp_var_raw because create_tmp_var will abort when
16097 given a TREE_ADDRESSABLE type. */
16098 tree tmp = create_tmp_var_raw (type, "vol");
16099 gimple_add_tmp_var (tmp);
16100 gimplify_assign (tmp, *expr_p, pre_p);
16104 /* We can't do anything useful with a volatile reference to
16105 an incomplete type, so just throw it away. Likewise for
16106 a BLKmode type, since any implicit inner load should
16107 already have been turned into an explicit one by the
16108 gimplification process. */
16112 /* If we are gimplifying at the statement level, we're done. Tack
16113 everything together and return. */
16114 if (fallback == fb_none || is_statement)
16116 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
16117 it out for GC to reclaim it. */
16118 *expr_p = NULL_TREE;
16120 if (!gimple_seq_empty_p (internal_pre)
16121 || !gimple_seq_empty_p (internal_post))
16123 gimplify_seq_add_seq (&internal_pre, internal_post);
16124 gimplify_seq_add_seq (pre_p, internal_pre);
16127 /* The result of gimplifying *EXPR_P is going to be the last few
16128 statements in *PRE_P and *POST_P. Add location information
16129 to all the statements that were added by the gimplification
16131 if (!gimple_seq_empty_p (*pre_p))
16132 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
16134 if (!gimple_seq_empty_p (*post_p))
16135 annotate_all_with_location_after (*post_p, post_last_gsi,
16141 #ifdef ENABLE_GIMPLE_CHECKING
16144 enum tree_code code = TREE_CODE (*expr_p);
16145 /* These expressions should already be in gimple IR form. */
16146 gcc_assert (code != MODIFY_EXPR
16147 && code != ASM_EXPR
16148 && code != BIND_EXPR
16149 && code != CATCH_EXPR
16150 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
16151 && code != EH_FILTER_EXPR
16152 && code != GOTO_EXPR
16153 && code != LABEL_EXPR
16154 && code != LOOP_EXPR
16155 && code != SWITCH_EXPR
16156 && code != TRY_FINALLY_EXPR
16157 && code != EH_ELSE_EXPR
16158 && code != OACC_PARALLEL
16159 && code != OACC_KERNELS
16160 && code != OACC_SERIAL
16161 && code != OACC_DATA
16162 && code != OACC_HOST_DATA
16163 && code != OACC_DECLARE
16164 && code != OACC_UPDATE
16165 && code != OACC_ENTER_DATA
16166 && code != OACC_EXIT_DATA
16167 && code != OACC_CACHE
16168 && code != OMP_CRITICAL
16170 && code != OACC_LOOP
16171 && code != OMP_MASTER
16172 && code != OMP_MASKED
16173 && code != OMP_TASKGROUP
16174 && code != OMP_ORDERED
16175 && code != OMP_PARALLEL
16176 && code != OMP_SCAN
16177 && code != OMP_SECTIONS
16178 && code != OMP_SECTION
16179 && code != OMP_SINGLE
16180 && code != OMP_SCOPE);
16184 /* Otherwise we're gimplifying a subexpression, so the resulting
16185 value is interesting. If it's a valid operand that matches
16186 GIMPLE_TEST_F, we're done. Unless we are handling some
16187 post-effects internally; if that's the case, we need to copy into
16188 a temporary before adding the post-effects to POST_P. */
16189 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
16192 /* Otherwise, we need to create a new temporary for the gimplified
16195 /* We can't return an lvalue if we have an internal postqueue. The
16196 object the lvalue refers to would (probably) be modified by the
16197 postqueue; we need to copy the value out first, which means an
16199 if ((fallback & fb_lvalue)
16200 && gimple_seq_empty_p (internal_post)
16201 && is_gimple_addressable (*expr_p))
16203 /* An lvalue will do. Take the address of the expression, store it
16204 in a temporary, and replace the expression with an INDIRECT_REF of
16206 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
16207 unsigned int ref_align = get_object_alignment (*expr_p);
16208 tree ref_type = TREE_TYPE (*expr_p);
16209 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
16210 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
16211 if (TYPE_ALIGN (ref_type) != ref_align)
16212 ref_type = build_aligned_type (ref_type, ref_align);
16213 *expr_p = build2 (MEM_REF, ref_type,
16214 tmp, build_zero_cst (ref_alias_type));
16216 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
16218 /* An rvalue will do. Assign the gimplified expression into a
16219 new temporary TMP and replace the original expression with
16220 TMP. First, make sure that the expression has a type so that
16221 it can be assigned into a temporary. */
16222 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
16223 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
16227 #ifdef ENABLE_GIMPLE_CHECKING
16228 if (!(fallback & fb_mayfail))
16230 fprintf (stderr, "gimplification failed:\n");
16231 print_generic_expr (stderr, *expr_p);
16232 debug_tree (*expr_p);
16233 internal_error ("gimplification failed");
16236 gcc_assert (fallback & fb_mayfail);
16238 /* If this is an asm statement, and the user asked for the
16239 impossible, don't die. Fail and let gimplify_asm_expr
16245 /* Make sure the temporary matches our predicate. */
16246 gcc_assert ((*gimple_test_f) (*expr_p));
16248 if (!gimple_seq_empty_p (internal_post))
16250 annotate_all_with_location (internal_post, input_location);
16251 gimplify_seq_add_seq (pre_p, internal_post);
16255 input_location = saved_location;
16259 /* Like gimplify_expr but make sure the gimplified result is not itself
16260 a SSA name (but a decl if it were). Temporaries required by
16261 evaluating *EXPR_P may be still SSA names. */
16263 static enum gimplify_status
16264 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
16265 bool (*gimple_test_f) (tree), fallback_t fallback,
16268 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
16269 gimple_test_f, fallback);
16271 && TREE_CODE (*expr_p) == SSA_NAME)
16272 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
16276 /* Look through TYPE for variable-sized objects and gimplify each such
16277 size that we find. Add to LIST_P any statements generated. */
16280 gimplify_type_sizes (tree type, gimple_seq *list_p)
16282 if (type == NULL || type == error_mark_node)
16285 const bool ignored_p
16287 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
16288 && DECL_IGNORED_P (TYPE_NAME (type));
16291 /* We first do the main variant, then copy into any other variants. */
16292 type = TYPE_MAIN_VARIANT (type);
16294 /* Avoid infinite recursion. */
16295 if (TYPE_SIZES_GIMPLIFIED (type))
16298 TYPE_SIZES_GIMPLIFIED (type) = 1;
16300 switch (TREE_CODE (type))
16303 case ENUMERAL_TYPE:
16306 case FIXED_POINT_TYPE:
16307 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
16308 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
16310 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
16312 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
16313 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
16318 /* These types may not have declarations, so handle them here. */
16319 gimplify_type_sizes (TREE_TYPE (type), list_p);
16320 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
16321 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
16322 with assigned stack slots, for -O1+ -g they should be tracked
16325 && TYPE_DOMAIN (type)
16326 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
16328 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
16329 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
16330 DECL_IGNORED_P (t) = 0;
16331 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
16332 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
16333 DECL_IGNORED_P (t) = 0;
16339 case QUAL_UNION_TYPE:
16340 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
16341 if (TREE_CODE (field) == FIELD_DECL)
16343 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
16344 /* Likewise, ensure variable offsets aren't removed. */
16346 && (t = DECL_FIELD_OFFSET (field))
16348 && DECL_ARTIFICIAL (t))
16349 DECL_IGNORED_P (t) = 0;
16350 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
16351 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
16352 gimplify_type_sizes (TREE_TYPE (field), list_p);
16357 case REFERENCE_TYPE:
16358 /* We used to recurse on the pointed-to type here, which turned out to
16359 be incorrect because its definition might refer to variables not
16360 yet initialized at this point if a forward declaration is involved.
16362 It was actually useful for anonymous pointed-to types to ensure
16363 that the sizes evaluation dominates every possible later use of the
16364 values. Restricting to such types here would be safe since there
16365 is no possible forward declaration around, but would introduce an
16366 undesirable middle-end semantic to anonymity. We then defer to
16367 front-ends the responsibility of ensuring that the sizes are
16368 evaluated both early and late enough, e.g. by attaching artificial
16369 type declarations to the tree. */
16376 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
16377 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
16379 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
16381 TYPE_SIZE (t) = TYPE_SIZE (type);
16382 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
16383 TYPE_SIZES_GIMPLIFIED (t) = 1;
16387 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
16388 a size or position, has had all of its SAVE_EXPRs evaluated.
16389 We add any required statements to *STMT_P. */
16392 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
16394 tree expr = *expr_p;
16396 /* We don't do anything if the value isn't there, is constant, or contains
16397 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
16398 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
16399 will want to replace it with a new variable, but that will cause problems
16400 if this type is from outside the function. It's OK to have that here. */
16401 if (expr == NULL_TREE
16402 || is_gimple_constant (expr)
16403 || TREE_CODE (expr) == VAR_DECL
16404 || CONTAINS_PLACEHOLDER_P (expr))
16407 *expr_p = unshare_expr (expr);
16409 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
16410 if the def vanishes. */
16411 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
16413 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
16414 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
16415 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
16416 if (is_gimple_constant (*expr_p))
16417 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
16420 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
16421 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
16422 is true, also gimplify the parameters. */
16425 gimplify_body (tree fndecl, bool do_parms)
16427 location_t saved_location = input_location;
16428 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
16429 gimple *outer_stmt;
16432 timevar_push (TV_TREE_GIMPLIFY);
16434 init_tree_ssa (cfun);
16436 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
16438 default_rtl_profile ();
16440 gcc_assert (gimplify_ctxp == NULL);
16441 push_gimplify_context (true);
16443 if (flag_openacc || flag_openmp)
16445 gcc_assert (gimplify_omp_ctxp == NULL);
16446 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
16447 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
16450 /* Unshare most shared trees in the body and in that of any nested functions.
16451 It would seem we don't have to do this for nested functions because
16452 they are supposed to be output and then the outer function gimplified
16453 first, but the g++ front end doesn't always do it that way. */
16454 unshare_body (fndecl);
16455 unvisit_body (fndecl);
16457 /* Make sure input_location isn't set to something weird. */
16458 input_location = DECL_SOURCE_LOCATION (fndecl);
16460 /* Resolve callee-copies. This has to be done before processing
16461 the body so that DECL_VALUE_EXPR gets processed correctly. */
16462 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
16464 /* Gimplify the function's body. */
16466 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
16467 outer_stmt = gimple_seq_first_nondebug_stmt (seq);
16470 outer_stmt = gimple_build_nop ();
16471 gimplify_seq_add_stmt (&seq, outer_stmt);
16474 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
16475 not the case, wrap everything in a GIMPLE_BIND to make it so. */
16476 if (gimple_code (outer_stmt) == GIMPLE_BIND
16477 && (gimple_seq_first_nondebug_stmt (seq)
16478 == gimple_seq_last_nondebug_stmt (seq)))
16480 outer_bind = as_a <gbind *> (outer_stmt);
16481 if (gimple_seq_first_stmt (seq) != outer_stmt
16482 || gimple_seq_last_stmt (seq) != outer_stmt)
16484 /* If there are debug stmts before or after outer_stmt, move them
16485 inside of outer_bind body. */
16486 gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
16487 gimple_seq second_seq = NULL;
16488 if (gimple_seq_first_stmt (seq) != outer_stmt
16489 && gimple_seq_last_stmt (seq) != outer_stmt)
16491 second_seq = gsi_split_seq_after (gsi);
16492 gsi_remove (&gsi, false);
16494 else if (gimple_seq_first_stmt (seq) != outer_stmt)
16495 gsi_remove (&gsi, false);
16498 gsi_remove (&gsi, false);
16502 gimple_seq_add_seq_without_update (&seq,
16503 gimple_bind_body (outer_bind));
16504 gimple_seq_add_seq_without_update (&seq, second_seq);
16505 gimple_bind_set_body (outer_bind, seq);
16509 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
16511 DECL_SAVED_TREE (fndecl) = NULL_TREE;
16513 /* If we had callee-copies statements, insert them at the beginning
16514 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
16515 if (!gimple_seq_empty_p (parm_stmts))
16519 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
16522 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
16523 GIMPLE_TRY_FINALLY);
16525 gimple_seq_add_stmt (&parm_stmts, g);
16527 gimple_bind_set_body (outer_bind, parm_stmts);
16529 for (parm = DECL_ARGUMENTS (current_function_decl);
16530 parm; parm = DECL_CHAIN (parm))
16531 if (DECL_HAS_VALUE_EXPR_P (parm))
16533 DECL_HAS_VALUE_EXPR_P (parm) = 0;
16534 DECL_IGNORED_P (parm) = 0;
16538 if ((flag_openacc || flag_openmp || flag_openmp_simd)
16539 && gimplify_omp_ctxp)
16541 delete_omp_context (gimplify_omp_ctxp);
16542 gimplify_omp_ctxp = NULL;
16545 pop_gimplify_context (outer_bind);
16546 gcc_assert (gimplify_ctxp == NULL);
16548 if (flag_checking && !seen_error ())
16549 verify_gimple_in_seq (gimple_bind_body (outer_bind));
16551 timevar_pop (TV_TREE_GIMPLIFY);
16552 input_location = saved_location;
16557 typedef char *char_p; /* For DEF_VEC_P. */
16559 /* Return whether we should exclude FNDECL from instrumentation. */
16562 flag_instrument_functions_exclude_p (tree fndecl)
16566 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
16567 if (v && v->length () > 0)
16573 name = lang_hooks.decl_printable_name (fndecl, 1);
16574 FOR_EACH_VEC_ELT (*v, i, s)
16575 if (strstr (name, s) != NULL)
16579 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
16580 if (v && v->length () > 0)
16586 name = DECL_SOURCE_FILE (fndecl);
16587 FOR_EACH_VEC_ELT (*v, i, s)
16588 if (strstr (name, s) != NULL)
16595 /* Build a call to the instrumentation function FNCODE and add it to SEQ.
16596 If COND_VAR is not NULL, it is a boolean variable guarding the call to
16597 the instrumentation function. IF STMT is not NULL, it is a statement
16598 to be executed just before the call to the instrumentation function. */
16601 build_instrumentation_call (gimple_seq *seq, enum built_in_function fncode,
16602 tree cond_var, gimple *stmt)
16604 /* The instrumentation hooks aren't going to call the instrumented
16605 function and the address they receive is expected to be matchable
16606 against symbol addresses. Make sure we don't create a trampoline,
16607 in case the current function is nested. */
16608 tree this_fn_addr = build_fold_addr_expr (current_function_decl);
16609 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
16611 tree label_true, label_false;
16614 label_true = create_artificial_label (UNKNOWN_LOCATION);
16615 label_false = create_artificial_label (UNKNOWN_LOCATION);
16616 gcond *cond = gimple_build_cond (EQ_EXPR, cond_var, boolean_false_node,
16617 label_true, label_false);
16618 gimplify_seq_add_stmt (seq, cond);
16619 gimplify_seq_add_stmt (seq, gimple_build_label (label_true));
16620 gimplify_seq_add_stmt (seq, gimple_build_predict (PRED_COLD_LABEL,
16625 gimplify_seq_add_stmt (seq, stmt);
16627 tree x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
16628 gcall *call = gimple_build_call (x, 1, integer_zero_node);
16629 tree tmp_var = create_tmp_var (ptr_type_node, "return_addr");
16630 gimple_call_set_lhs (call, tmp_var);
16631 gimplify_seq_add_stmt (seq, call);
16632 x = builtin_decl_implicit (fncode);
16633 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
16634 gimplify_seq_add_stmt (seq, call);
16637 gimplify_seq_add_stmt (seq, gimple_build_label (label_false));
16640 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
16641 node for the function we want to gimplify.
16643 Return the sequence of GIMPLE statements corresponding to the body
16647 gimplify_function_tree (tree fndecl)
16652 gcc_assert (!gimple_body (fndecl));
16654 if (DECL_STRUCT_FUNCTION (fndecl))
16655 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
16657 push_struct_function (fndecl);
16659 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
16661 cfun->curr_properties |= PROP_gimple_lva;
16663 if (asan_sanitize_use_after_scope ())
16664 asan_poisoned_variables = new hash_set<tree> ();
16665 bind = gimplify_body (fndecl, true);
16666 if (asan_poisoned_variables)
16668 delete asan_poisoned_variables;
16669 asan_poisoned_variables = NULL;
16672 /* The tree body of the function is no longer needed, replace it
16673 with the new GIMPLE body. */
16675 gimple_seq_add_stmt (&seq, bind);
16676 gimple_set_body (fndecl, seq);
16678 /* If we're instrumenting function entry/exit, then prepend the call to
16679 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
16680 catch the exit hook. */
16681 /* ??? Add some way to ignore exceptions for this TFE. */
16682 if (flag_instrument_function_entry_exit
16683 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
16684 /* Do not instrument extern inline functions. */
16685 && !(DECL_DECLARED_INLINE_P (fndecl)
16686 && DECL_EXTERNAL (fndecl)
16687 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
16688 && !flag_instrument_functions_exclude_p (fndecl))
16690 gimple_seq body = NULL, cleanup = NULL;
16694 /* If -finstrument-functions-once is specified, generate:
16696 static volatile bool C.0 = false;
16703 [call profiling enter function]
16706 without specific protection for data races. */
16707 if (flag_instrument_function_entry_exit > 1)
16710 = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
16712 create_tmp_var_name ("C"),
16713 boolean_type_node);
16714 DECL_ARTIFICIAL (first_var) = 1;
16715 DECL_IGNORED_P (first_var) = 1;
16716 TREE_STATIC (first_var) = 1;
16717 TREE_THIS_VOLATILE (first_var) = 1;
16718 TREE_USED (first_var) = 1;
16719 DECL_INITIAL (first_var) = boolean_false_node;
16720 varpool_node::add (first_var);
16722 cond_var = create_tmp_var (boolean_type_node, "tmp_called");
16723 assign = gimple_build_assign (cond_var, first_var);
16724 gimplify_seq_add_stmt (&body, assign);
16726 assign = gimple_build_assign (first_var, boolean_true_node);
16731 cond_var = NULL_TREE;
16735 build_instrumentation_call (&body, BUILT_IN_PROFILE_FUNC_ENTER,
16738 /* If -finstrument-functions-once is specified, generate:
16741 [call profiling exit function]
16743 without specific protection for data races. */
16744 build_instrumentation_call (&cleanup, BUILT_IN_PROFILE_FUNC_EXIT,
16747 gimple *tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
16748 gimplify_seq_add_stmt (&body, tf);
16749 gbind *new_bind = gimple_build_bind (NULL, body, NULL);
16751 /* Replace the current function body with the body
16752 wrapped in the try/finally TF. */
16754 gimple_seq_add_stmt (&seq, new_bind);
16755 gimple_set_body (fndecl, seq);
16759 if (sanitize_flags_p (SANITIZE_THREAD)
16760 && param_tsan_instrument_func_entry_exit)
16762 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
16763 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
16764 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
16765 /* Replace the current function body with the body
16766 wrapped in the try/finally TF. */
16768 gimple_seq_add_stmt (&seq, new_bind);
16769 gimple_set_body (fndecl, seq);
16772 DECL_SAVED_TREE (fndecl) = NULL_TREE;
16773 cfun->curr_properties |= PROP_gimple_any;
16777 dump_function (TDI_gimple, fndecl);
16780 /* Return a dummy expression of type TYPE in order to keep going after an
16784 dummy_object (tree type)
16786 tree t = build_int_cst (build_pointer_type (type), 0);
16787 return build2 (MEM_REF, type, t, t);
16790 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
16791 builtin function, but a very special sort of operator. */
16793 enum gimplify_status
16794 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
16795 gimple_seq *post_p ATTRIBUTE_UNUSED)
16797 tree promoted_type, have_va_type;
16798 tree valist = TREE_OPERAND (*expr_p, 0);
16799 tree type = TREE_TYPE (*expr_p);
16800 tree t, tag, aptag;
16801 location_t loc = EXPR_LOCATION (*expr_p);
16803 /* Verify that valist is of the proper type. */
16804 have_va_type = TREE_TYPE (valist);
16805 if (have_va_type == error_mark_node)
16807 have_va_type = targetm.canonical_va_list_type (have_va_type);
16808 if (have_va_type == NULL_TREE
16809 && POINTER_TYPE_P (TREE_TYPE (valist)))
16810 /* Handle 'Case 1: Not an array type' from c-common.cc/build_va_arg. */
16812 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
16813 gcc_assert (have_va_type != NULL_TREE);
16815 /* Generate a diagnostic for requesting data of a type that cannot
16816 be passed through `...' due to type promotion at the call site. */
16817 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
16820 static bool gave_help;
16822 /* Use the expansion point to handle cases such as passing bool (defined
16823 in a system header) through `...'. */
16825 = expansion_point_location_if_in_system_header (loc);
16827 /* Unfortunately, this is merely undefined, rather than a constraint
16828 violation, so we cannot make this an error. If this call is never
16829 executed, the program is still strictly conforming. */
16830 auto_diagnostic_group d;
16831 warned = warning_at (xloc, 0,
16832 "%qT is promoted to %qT when passed through %<...%>",
16833 type, promoted_type);
16834 if (!gave_help && warned)
16837 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
16838 promoted_type, type);
16841 /* We can, however, treat "undefined" any way we please.
16842 Call abort to encourage the user to fix the program. */
16844 inform (xloc, "if this code is reached, the program will abort");
16845 /* Before the abort, allow the evaluation of the va_list
16846 expression to exit or longjmp. */
16847 gimplify_and_add (valist, pre_p);
16848 t = build_call_expr_loc (loc,
16849 builtin_decl_implicit (BUILT_IN_TRAP), 0);
16850 gimplify_and_add (t, pre_p);
16852 /* This is dead code, but go ahead and finish so that the
16853 mode of the result comes out right. */
16854 *expr_p = dummy_object (type);
16855 return GS_ALL_DONE;
16858 tag = build_int_cst (build_pointer_type (type), 0);
16859 aptag = build_int_cst (TREE_TYPE (valist), 0);
16861 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
16862 valist, tag, aptag);
16864 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
16865 needs to be expanded. */
16866 cfun->curr_properties &= ~PROP_gimple_lva;
16871 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
16873 DST/SRC are the destination and source respectively. You can pass
16874 ungimplified trees in DST or SRC, in which case they will be
16875 converted to a gimple operand if necessary.
16877 This function returns the newly created GIMPLE_ASSIGN tuple. */
16880 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
16882 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
16883 gimplify_and_add (t, seq_p);
16885 return gimple_seq_last_stmt (*seq_p);
16889 gimplify_hasher::hash (const elt_t *p)
16892 return iterative_hash_expr (t, 0);
16896 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
16900 enum tree_code code = TREE_CODE (t1);
16902 if (TREE_CODE (t2) != code
16903 || TREE_TYPE (t1) != TREE_TYPE (t2))
16906 if (!operand_equal_p (t1, t2, 0))
16909 /* Only allow them to compare equal if they also hash equal; otherwise
16910 results are nondeterminate, and we fail bootstrap comparison. */
16911 gcc_checking_assert (hash (p1) == hash (p2));