Daily bump.
[official-gcc.git] / gcc / gimplify.c
blob816cdaf8a18a3aa8659270f2628c6710d8c53742
1 /* Tree lowering pass. This pass converts the GENERIC functions-as-trees
2 tree representation into the GIMPLE form.
3 Copyright (C) 2002-2021 Free Software Foundation, Inc.
4 Major work done by Sebastian Pop <s.pop@laposte.net>,
5 Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "backend.h"
27 #include "target.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "memmodel.h"
31 #include "tm_p.h"
32 #include "gimple.h"
33 #include "gimple-predict.h"
34 #include "tree-pass.h" /* FIXME: only for PROP_gimple_any */
35 #include "ssa.h"
36 #include "cgraph.h"
37 #include "tree-pretty-print.h"
38 #include "diagnostic-core.h"
39 #include "alias.h"
40 #include "fold-const.h"
41 #include "calls.h"
42 #include "varasm.h"
43 #include "stmt.h"
44 #include "expr.h"
45 #include "gimple-fold.h"
46 #include "tree-eh.h"
47 #include "gimplify.h"
48 #include "gimple-iterator.h"
49 #include "stor-layout.h"
50 #include "print-tree.h"
51 #include "tree-iterator.h"
52 #include "tree-inline.h"
53 #include "langhooks.h"
54 #include "tree-cfg.h"
55 #include "tree-ssa.h"
56 #include "omp-general.h"
57 #include "omp-low.h"
58 #include "gimple-low.h"
59 #include "gomp-constants.h"
60 #include "splay-tree.h"
61 #include "gimple-walk.h"
62 #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
63 #include "builtins.h"
64 #include "stringpool.h"
65 #include "attribs.h"
66 #include "asan.h"
67 #include "dbgcnt.h"
68 #include "omp-offload.h"
69 #include "context.h"
70 #include "tree-nested.h"
72 /* Hash set of poisoned variables in a bind expr. */
73 static hash_set<tree> *asan_poisoned_variables = NULL;
75 enum gimplify_omp_var_data
77 GOVD_SEEN = 0x000001,
78 GOVD_EXPLICIT = 0x000002,
79 GOVD_SHARED = 0x000004,
80 GOVD_PRIVATE = 0x000008,
81 GOVD_FIRSTPRIVATE = 0x000010,
82 GOVD_LASTPRIVATE = 0x000020,
83 GOVD_REDUCTION = 0x000040,
84 GOVD_LOCAL = 0x00080,
85 GOVD_MAP = 0x000100,
86 GOVD_DEBUG_PRIVATE = 0x000200,
87 GOVD_PRIVATE_OUTER_REF = 0x000400,
88 GOVD_LINEAR = 0x000800,
89 GOVD_ALIGNED = 0x001000,
91 /* Flag for GOVD_MAP: don't copy back. */
92 GOVD_MAP_TO_ONLY = 0x002000,
94 /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
95 GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 0x004000,
97 GOVD_MAP_0LEN_ARRAY = 0x008000,
99 /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
100 GOVD_MAP_ALWAYS_TO = 0x010000,
102 /* Flag for shared vars that are or might be stored to in the region. */
103 GOVD_WRITTEN = 0x020000,
105 /* Flag for GOVD_MAP, if it is a forced mapping. */
106 GOVD_MAP_FORCE = 0x040000,
108 /* Flag for GOVD_MAP: must be present already. */
109 GOVD_MAP_FORCE_PRESENT = 0x080000,
111 /* Flag for GOVD_MAP: only allocate. */
112 GOVD_MAP_ALLOC_ONLY = 0x100000,
114 /* Flag for GOVD_MAP: only copy back. */
115 GOVD_MAP_FROM_ONLY = 0x200000,
117 GOVD_NONTEMPORAL = 0x400000,
119 /* Flag for GOVD_LASTPRIVATE: conditional modifier. */
120 GOVD_LASTPRIVATE_CONDITIONAL = 0x800000,
122 GOVD_CONDTEMP = 0x1000000,
124 /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause. */
125 GOVD_REDUCTION_INSCAN = 0x2000000,
127 /* Flag for GOVD_MAP: (struct) vars that have pointer attachments for
128 fields. */
129 GOVD_MAP_HAS_ATTACHMENTS = 0x4000000,
131 /* Flag for GOVD_FIRSTPRIVATE: OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT. */
132 GOVD_FIRSTPRIVATE_IMPLICIT = 0x8000000,
134 GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
135 | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
136 | GOVD_LOCAL)
140 enum omp_region_type
142 ORT_WORKSHARE = 0x00,
143 ORT_TASKGROUP = 0x01,
144 ORT_SIMD = 0x04,
146 ORT_PARALLEL = 0x08,
147 ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1,
149 ORT_TASK = 0x10,
150 ORT_UNTIED_TASK = ORT_TASK | 1,
151 ORT_TASKLOOP = ORT_TASK | 2,
152 ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2,
154 ORT_TEAMS = 0x20,
155 ORT_COMBINED_TEAMS = ORT_TEAMS | 1,
156 ORT_HOST_TEAMS = ORT_TEAMS | 2,
157 ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2,
159 /* Data region. */
160 ORT_TARGET_DATA = 0x40,
162 /* Data region with offloading. */
163 ORT_TARGET = 0x80,
164 ORT_COMBINED_TARGET = ORT_TARGET | 1,
165 ORT_IMPLICIT_TARGET = ORT_TARGET | 2,
167 /* OpenACC variants. */
168 ORT_ACC = 0x100, /* A generic OpenACC region. */
169 ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct. */
170 ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET, /* Parallel construct */
171 ORT_ACC_KERNELS = ORT_ACC | ORT_TARGET | 2, /* Kernels construct. */
172 ORT_ACC_SERIAL = ORT_ACC | ORT_TARGET | 4, /* Serial construct. */
173 ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2, /* Host data. */
175 /* Dummy OpenMP region, used to disable expansion of
176 DECL_VALUE_EXPRs in taskloop pre body. */
177 ORT_NONE = 0x200
180 /* Gimplify hashtable helper. */
182 struct gimplify_hasher : free_ptr_hash <elt_t>
184 static inline hashval_t hash (const elt_t *);
185 static inline bool equal (const elt_t *, const elt_t *);
188 struct gimplify_ctx
190 struct gimplify_ctx *prev_context;
192 vec<gbind *> bind_expr_stack;
193 tree temps;
194 gimple_seq conditional_cleanups;
195 tree exit_label;
196 tree return_temp;
198 vec<tree> case_labels;
199 hash_set<tree> *live_switch_vars;
200 /* The formal temporary table. Should this be persistent? */
201 hash_table<gimplify_hasher> *temp_htab;
203 int conditions;
204 unsigned into_ssa : 1;
205 unsigned allow_rhs_cond_expr : 1;
206 unsigned in_cleanup_point_expr : 1;
207 unsigned keep_stack : 1;
208 unsigned save_stack : 1;
209 unsigned in_switch_expr : 1;
212 enum gimplify_defaultmap_kind
214 GDMK_SCALAR,
215 GDMK_SCALAR_TARGET, /* w/ Fortran's target attr, implicit mapping, only. */
216 GDMK_AGGREGATE,
217 GDMK_ALLOCATABLE,
218 GDMK_POINTER
221 struct gimplify_omp_ctx
223 struct gimplify_omp_ctx *outer_context;
224 splay_tree variables;
225 hash_set<tree> *privatized_types;
226 tree clauses;
227 /* Iteration variables in an OMP_FOR. */
228 vec<tree> loop_iter_var;
229 location_t location;
230 enum omp_clause_default_kind default_kind;
231 enum omp_region_type region_type;
232 enum tree_code code;
233 bool combined_loop;
234 bool distribute;
235 bool target_firstprivatize_array_bases;
236 bool add_safelen1;
237 bool order_concurrent;
238 bool has_depend;
239 bool in_for_exprs;
240 int defaultmap[5];
243 static struct gimplify_ctx *gimplify_ctxp;
244 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
245 static bool in_omp_construct;
247 /* Forward declaration. */
248 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
249 static hash_map<tree, tree> *oacc_declare_returns;
250 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
251 bool (*) (tree), fallback_t, bool);
253 /* Shorter alias name for the above function for use in gimplify.c
254 only. */
256 static inline void
257 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
259 gimple_seq_add_stmt_without_update (seq_p, gs);
262 /* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
263 NULL, a new sequence is allocated. This function is
264 similar to gimple_seq_add_seq, but does not scan the operands.
265 During gimplification, we need to manipulate statement sequences
266 before the def/use vectors have been constructed. */
268 static void
269 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
271 gimple_stmt_iterator si;
273 if (src == NULL)
274 return;
276 si = gsi_last (*dst_p);
277 gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
281 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
282 and popping gimplify contexts. */
284 static struct gimplify_ctx *ctx_pool = NULL;
286 /* Return a gimplify context struct from the pool. */
288 static inline struct gimplify_ctx *
289 ctx_alloc (void)
291 struct gimplify_ctx * c = ctx_pool;
293 if (c)
294 ctx_pool = c->prev_context;
295 else
296 c = XNEW (struct gimplify_ctx);
298 memset (c, '\0', sizeof (*c));
299 return c;
302 /* Put gimplify context C back into the pool. */
304 static inline void
305 ctx_free (struct gimplify_ctx *c)
307 c->prev_context = ctx_pool;
308 ctx_pool = c;
311 /* Free allocated ctx stack memory. */
313 void
314 free_gimplify_stack (void)
316 struct gimplify_ctx *c;
318 while ((c = ctx_pool))
320 ctx_pool = c->prev_context;
321 free (c);
326 /* Set up a context for the gimplifier. */
328 void
329 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
331 struct gimplify_ctx *c = ctx_alloc ();
333 c->prev_context = gimplify_ctxp;
334 gimplify_ctxp = c;
335 gimplify_ctxp->into_ssa = in_ssa;
336 gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
339 /* Tear down a context for the gimplifier. If BODY is non-null, then
340 put the temporaries into the outer BIND_EXPR. Otherwise, put them
341 in the local_decls.
343 BODY is not a sequence, but the first tuple in a sequence. */
345 void
346 pop_gimplify_context (gimple *body)
348 struct gimplify_ctx *c = gimplify_ctxp;
350 gcc_assert (c
351 && (!c->bind_expr_stack.exists ()
352 || c->bind_expr_stack.is_empty ()));
353 c->bind_expr_stack.release ();
354 gimplify_ctxp = c->prev_context;
356 if (body)
357 declare_vars (c->temps, body, false);
358 else
359 record_vars (c->temps);
361 delete c->temp_htab;
362 c->temp_htab = NULL;
363 ctx_free (c);
366 /* Push a GIMPLE_BIND tuple onto the stack of bindings. */
368 static void
369 gimple_push_bind_expr (gbind *bind_stmt)
371 gimplify_ctxp->bind_expr_stack.reserve (8);
372 gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
375 /* Pop the first element off the stack of bindings. */
377 static void
378 gimple_pop_bind_expr (void)
380 gimplify_ctxp->bind_expr_stack.pop ();
383 /* Return the first element of the stack of bindings. */
385 gbind *
386 gimple_current_bind_expr (void)
388 return gimplify_ctxp->bind_expr_stack.last ();
391 /* Return the stack of bindings created during gimplification. */
393 vec<gbind *>
394 gimple_bind_expr_stack (void)
396 return gimplify_ctxp->bind_expr_stack;
399 /* Return true iff there is a COND_EXPR between us and the innermost
400 CLEANUP_POINT_EXPR. This info is used by gimple_push_cleanup. */
402 static bool
403 gimple_conditional_context (void)
405 return gimplify_ctxp->conditions > 0;
408 /* Note that we've entered a COND_EXPR. */
410 static void
411 gimple_push_condition (void)
413 #ifdef ENABLE_GIMPLE_CHECKING
414 if (gimplify_ctxp->conditions == 0)
415 gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
416 #endif
417 ++(gimplify_ctxp->conditions);
420 /* Note that we've left a COND_EXPR. If we're back at unconditional scope
421 now, add any conditional cleanups we've seen to the prequeue. */
423 static void
424 gimple_pop_condition (gimple_seq *pre_p)
426 int conds = --(gimplify_ctxp->conditions);
428 gcc_assert (conds >= 0);
429 if (conds == 0)
431 gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
432 gimplify_ctxp->conditional_cleanups = NULL;
436 /* A stable comparison routine for use with splay trees and DECLs. */
438 static int
439 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
441 tree a = (tree) xa;
442 tree b = (tree) xb;
444 return DECL_UID (a) - DECL_UID (b);
447 /* Create a new omp construct that deals with variable remapping. */
449 static struct gimplify_omp_ctx *
450 new_omp_context (enum omp_region_type region_type)
452 struct gimplify_omp_ctx *c;
454 c = XCNEW (struct gimplify_omp_ctx);
455 c->outer_context = gimplify_omp_ctxp;
456 c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
457 c->privatized_types = new hash_set<tree>;
458 c->location = input_location;
459 c->region_type = region_type;
460 if ((region_type & ORT_TASK) == 0)
461 c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
462 else
463 c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
464 c->defaultmap[GDMK_SCALAR] = GOVD_MAP;
465 c->defaultmap[GDMK_SCALAR_TARGET] = GOVD_MAP;
466 c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
467 c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
468 c->defaultmap[GDMK_POINTER] = GOVD_MAP;
470 return c;
473 /* Destroy an omp construct that deals with variable remapping. */
475 static void
476 delete_omp_context (struct gimplify_omp_ctx *c)
478 splay_tree_delete (c->variables);
479 delete c->privatized_types;
480 c->loop_iter_var.release ();
481 XDELETE (c);
484 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
485 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
487 /* Both gimplify the statement T and append it to *SEQ_P. This function
488 behaves exactly as gimplify_stmt, but you don't have to pass T as a
489 reference. */
491 void
492 gimplify_and_add (tree t, gimple_seq *seq_p)
494 gimplify_stmt (&t, seq_p);
497 /* Gimplify statement T into sequence *SEQ_P, and return the first
498 tuple in the sequence of generated tuples for this statement.
499 Return NULL if gimplifying T produced no tuples. */
501 static gimple *
502 gimplify_and_return_first (tree t, gimple_seq *seq_p)
504 gimple_stmt_iterator last = gsi_last (*seq_p);
506 gimplify_and_add (t, seq_p);
508 if (!gsi_end_p (last))
510 gsi_next (&last);
511 return gsi_stmt (last);
513 else
514 return gimple_seq_first_stmt (*seq_p);
517 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
518 LHS, or for a call argument. */
520 static bool
521 is_gimple_mem_rhs (tree t)
523 /* If we're dealing with a renamable type, either source or dest must be
524 a renamed variable. */
525 if (is_gimple_reg_type (TREE_TYPE (t)))
526 return is_gimple_val (t);
527 else
528 return is_gimple_val (t) || is_gimple_lvalue (t);
531 /* Return true if T is a CALL_EXPR or an expression that can be
532 assigned to a temporary. Note that this predicate should only be
533 used during gimplification. See the rationale for this in
534 gimplify_modify_expr. */
536 static bool
537 is_gimple_reg_rhs_or_call (tree t)
539 return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
540 || TREE_CODE (t) == CALL_EXPR);
543 /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
544 this predicate should only be used during gimplification. See the
545 rationale for this in gimplify_modify_expr. */
547 static bool
548 is_gimple_mem_rhs_or_call (tree t)
550 /* If we're dealing with a renamable type, either source or dest must be
551 a renamed variable. */
552 if (is_gimple_reg_type (TREE_TYPE (t)))
553 return is_gimple_val (t);
554 else
555 return (is_gimple_val (t)
556 || is_gimple_lvalue (t)
557 || TREE_CLOBBER_P (t)
558 || TREE_CODE (t) == CALL_EXPR);
561 /* Create a temporary with a name derived from VAL. Subroutine of
562 lookup_tmp_var; nobody else should call this function. */
564 static inline tree
565 create_tmp_from_val (tree val)
567 /* Drop all qualifiers and address-space information from the value type. */
568 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
569 tree var = create_tmp_var (type, get_name (val));
570 return var;
573 /* Create a temporary to hold the value of VAL. If IS_FORMAL, try to reuse
574 an existing expression temporary. */
576 static tree
577 lookup_tmp_var (tree val, bool is_formal)
579 tree ret;
581 /* If not optimizing, never really reuse a temporary. local-alloc
582 won't allocate any variable that is used in more than one basic
583 block, which means it will go into memory, causing much extra
584 work in reload and final and poorer code generation, outweighing
585 the extra memory allocation here. */
586 if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
587 ret = create_tmp_from_val (val);
588 else
590 elt_t elt, *elt_p;
591 elt_t **slot;
593 elt.val = val;
594 if (!gimplify_ctxp->temp_htab)
595 gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
596 slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
597 if (*slot == NULL)
599 elt_p = XNEW (elt_t);
600 elt_p->val = val;
601 elt_p->temp = ret = create_tmp_from_val (val);
602 *slot = elt_p;
604 else
606 elt_p = *slot;
607 ret = elt_p->temp;
611 return ret;
614 /* Helper for get_formal_tmp_var and get_initialized_tmp_var. */
616 static tree
617 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
618 bool is_formal, bool allow_ssa)
620 tree t, mod;
622 /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
623 can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
624 gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
625 fb_rvalue);
627 if (allow_ssa
628 && gimplify_ctxp->into_ssa
629 && is_gimple_reg_type (TREE_TYPE (val)))
631 t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
632 if (! gimple_in_ssa_p (cfun))
634 const char *name = get_name (val);
635 if (name)
636 SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
639 else
640 t = lookup_tmp_var (val, is_formal);
642 mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
644 SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
646 /* gimplify_modify_expr might want to reduce this further. */
647 gimplify_and_add (mod, pre_p);
648 ggc_free (mod);
650 return t;
653 /* Return a formal temporary variable initialized with VAL. PRE_P is as
654 in gimplify_expr. Only use this function if:
656 1) The value of the unfactored expression represented by VAL will not
657 change between the initialization and use of the temporary, and
658 2) The temporary will not be otherwise modified.
660 For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
661 and #2 means it is inappropriate for && temps.
663 For other cases, use get_initialized_tmp_var instead. */
665 tree
666 get_formal_tmp_var (tree val, gimple_seq *pre_p)
668 return internal_get_tmp_var (val, pre_p, NULL, true, true);
671 /* Return a temporary variable initialized with VAL. PRE_P and POST_P
672 are as in gimplify_expr. */
674 tree
675 get_initialized_tmp_var (tree val, gimple_seq *pre_p,
676 gimple_seq *post_p /* = NULL */,
677 bool allow_ssa /* = true */)
679 return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
682 /* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
683 generate debug info for them; otherwise don't. */
685 void
686 declare_vars (tree vars, gimple *gs, bool debug_info)
688 tree last = vars;
689 if (last)
691 tree temps, block;
693 gbind *scope = as_a <gbind *> (gs);
695 temps = nreverse (last);
697 block = gimple_bind_block (scope);
698 gcc_assert (!block || TREE_CODE (block) == BLOCK);
699 if (!block || !debug_info)
701 DECL_CHAIN (last) = gimple_bind_vars (scope);
702 gimple_bind_set_vars (scope, temps);
704 else
706 /* We need to attach the nodes both to the BIND_EXPR and to its
707 associated BLOCK for debugging purposes. The key point here
708 is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
709 is a subchain of the BIND_EXPR_VARS of the BIND_EXPR. */
710 if (BLOCK_VARS (block))
711 BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
712 else
714 gimple_bind_set_vars (scope,
715 chainon (gimple_bind_vars (scope), temps));
716 BLOCK_VARS (block) = temps;
722 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
723 for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly. Abort if
724 no such upper bound can be obtained. */
726 static void
727 force_constant_size (tree var)
729 /* The only attempt we make is by querying the maximum size of objects
730 of the variable's type. */
732 HOST_WIDE_INT max_size;
734 gcc_assert (VAR_P (var));
736 max_size = max_int_size_in_bytes (TREE_TYPE (var));
738 gcc_assert (max_size >= 0);
740 DECL_SIZE_UNIT (var)
741 = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
742 DECL_SIZE (var)
743 = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
746 /* Push the temporary variable TMP into the current binding. */
748 void
749 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
751 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
753 /* Later processing assumes that the object size is constant, which might
754 not be true at this point. Force the use of a constant upper bound in
755 this case. */
756 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
757 force_constant_size (tmp);
759 DECL_CONTEXT (tmp) = fn->decl;
760 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
762 record_vars_into (tmp, fn->decl);
765 /* Push the temporary variable TMP into the current binding. */
767 void
768 gimple_add_tmp_var (tree tmp)
770 gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
772 /* Later processing assumes that the object size is constant, which might
773 not be true at this point. Force the use of a constant upper bound in
774 this case. */
775 if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
776 force_constant_size (tmp);
778 DECL_CONTEXT (tmp) = current_function_decl;
779 DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
781 if (gimplify_ctxp)
783 DECL_CHAIN (tmp) = gimplify_ctxp->temps;
784 gimplify_ctxp->temps = tmp;
786 /* Mark temporaries local within the nearest enclosing parallel. */
787 if (gimplify_omp_ctxp)
789 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
790 int flag = GOVD_LOCAL | GOVD_SEEN;
791 while (ctx
792 && (ctx->region_type == ORT_WORKSHARE
793 || ctx->region_type == ORT_TASKGROUP
794 || ctx->region_type == ORT_SIMD
795 || ctx->region_type == ORT_ACC))
797 if (ctx->region_type == ORT_SIMD
798 && TREE_ADDRESSABLE (tmp)
799 && !TREE_STATIC (tmp))
801 if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
802 ctx->add_safelen1 = true;
803 else if (ctx->in_for_exprs)
804 flag = GOVD_PRIVATE;
805 else
806 flag = GOVD_PRIVATE | GOVD_SEEN;
807 break;
809 ctx = ctx->outer_context;
811 if (ctx)
812 omp_add_variable (ctx, tmp, flag);
815 else if (cfun)
816 record_vars (tmp);
817 else
819 gimple_seq body_seq;
821 /* This case is for nested functions. We need to expose the locals
822 they create. */
823 body_seq = gimple_body (current_function_decl);
824 declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
830 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
831 nodes that are referenced more than once in GENERIC functions. This is
832 necessary because gimplification (translation into GIMPLE) is performed
833 by modifying tree nodes in-place, so gimplication of a shared node in a
834 first context could generate an invalid GIMPLE form in a second context.
836 This is achieved with a simple mark/copy/unmark algorithm that walks the
837 GENERIC representation top-down, marks nodes with TREE_VISITED the first
838 time it encounters them, duplicates them if they already have TREE_VISITED
839 set, and finally removes the TREE_VISITED marks it has set.
841 The algorithm works only at the function level, i.e. it generates a GENERIC
842 representation of a function with no nodes shared within the function when
843 passed a GENERIC function (except for nodes that are allowed to be shared).
845 At the global level, it is also necessary to unshare tree nodes that are
846 referenced in more than one function, for the same aforementioned reason.
847 This requires some cooperation from the front-end. There are 2 strategies:
849 1. Manual unsharing. The front-end needs to call unshare_expr on every
850 expression that might end up being shared across functions.
852 2. Deep unsharing. This is an extension of regular unsharing. Instead
853 of calling unshare_expr on expressions that might be shared across
854 functions, the front-end pre-marks them with TREE_VISITED. This will
855 ensure that they are unshared on the first reference within functions
856 when the regular unsharing algorithm runs. The counterpart is that
857 this algorithm must look deeper than for manual unsharing, which is
858 specified by LANG_HOOKS_DEEP_UNSHARING.
860 If there are only few specific cases of node sharing across functions, it is
861 probably easier for a front-end to unshare the expressions manually. On the
862 contrary, if the expressions generated at the global level are as widespread
863 as expressions generated within functions, deep unsharing is very likely the
864 way to go. */
866 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
867 These nodes model computations that must be done once. If we were to
868 unshare something like SAVE_EXPR(i++), the gimplification process would
869 create wrong code. However, if DATA is non-null, it must hold a pointer
870 set that is used to unshare the subtrees of these nodes. */
872 static tree
873 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
875 tree t = *tp;
876 enum tree_code code = TREE_CODE (t);
878 /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
879 copy their subtrees if we can make sure to do it only once. */
880 if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
882 if (data && !((hash_set<tree> *)data)->add (t))
884 else
885 *walk_subtrees = 0;
888 /* Stop at types, decls, constants like copy_tree_r. */
889 else if (TREE_CODE_CLASS (code) == tcc_type
890 || TREE_CODE_CLASS (code) == tcc_declaration
891 || TREE_CODE_CLASS (code) == tcc_constant)
892 *walk_subtrees = 0;
894 /* Cope with the statement expression extension. */
895 else if (code == STATEMENT_LIST)
898 /* Leave the bulk of the work to copy_tree_r itself. */
899 else
900 copy_tree_r (tp, walk_subtrees, NULL);
902 return NULL_TREE;
905 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
906 If *TP has been visited already, then *TP is deeply copied by calling
907 mostly_copy_tree_r. DATA is passed to mostly_copy_tree_r unmodified. */
909 static tree
910 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
912 tree t = *tp;
913 enum tree_code code = TREE_CODE (t);
915 /* Skip types, decls, and constants. But we do want to look at their
916 types and the bounds of types. Mark them as visited so we properly
917 unmark their subtrees on the unmark pass. If we've already seen them,
918 don't look down further. */
919 if (TREE_CODE_CLASS (code) == tcc_type
920 || TREE_CODE_CLASS (code) == tcc_declaration
921 || TREE_CODE_CLASS (code) == tcc_constant)
923 if (TREE_VISITED (t))
924 *walk_subtrees = 0;
925 else
926 TREE_VISITED (t) = 1;
929 /* If this node has been visited already, unshare it and don't look
930 any deeper. */
931 else if (TREE_VISITED (t))
933 walk_tree (tp, mostly_copy_tree_r, data, NULL);
934 *walk_subtrees = 0;
937 /* Otherwise, mark the node as visited and keep looking. */
938 else
939 TREE_VISITED (t) = 1;
941 return NULL_TREE;
944 /* Unshare most of the shared trees rooted at *TP. DATA is passed to the
945 copy_if_shared_r callback unmodified. */
947 void
948 copy_if_shared (tree *tp, void *data)
950 walk_tree (tp, copy_if_shared_r, data, NULL);
953 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
954 any nested functions. */
956 static void
957 unshare_body (tree fndecl)
959 struct cgraph_node *cgn = cgraph_node::get (fndecl);
960 /* If the language requires deep unsharing, we need a pointer set to make
961 sure we don't repeatedly unshare subtrees of unshareable nodes. */
962 hash_set<tree> *visited
963 = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
965 copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
966 copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
967 copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
969 delete visited;
971 if (cgn)
972 for (cgn = first_nested_function (cgn); cgn;
973 cgn = next_nested_function (cgn))
974 unshare_body (cgn->decl);
977 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
978 Subtrees are walked until the first unvisited node is encountered. */
980 static tree
981 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
983 tree t = *tp;
985 /* If this node has been visited, unmark it and keep looking. */
986 if (TREE_VISITED (t))
987 TREE_VISITED (t) = 0;
989 /* Otherwise, don't look any deeper. */
990 else
991 *walk_subtrees = 0;
993 return NULL_TREE;
996 /* Unmark the visited trees rooted at *TP. */
998 static inline void
999 unmark_visited (tree *tp)
1001 walk_tree (tp, unmark_visited_r, NULL, NULL);
1004 /* Likewise, but mark all trees as not visited. */
1006 static void
1007 unvisit_body (tree fndecl)
1009 struct cgraph_node *cgn = cgraph_node::get (fndecl);
1011 unmark_visited (&DECL_SAVED_TREE (fndecl));
1012 unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
1013 unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
1015 if (cgn)
1016 for (cgn = first_nested_function (cgn);
1017 cgn; cgn = next_nested_function (cgn))
1018 unvisit_body (cgn->decl);
1021 /* Unconditionally make an unshared copy of EXPR. This is used when using
1022 stored expressions which span multiple functions, such as BINFO_VTABLE,
1023 as the normal unsharing process can't tell that they're shared. */
1025 tree
1026 unshare_expr (tree expr)
1028 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1029 return expr;
1032 /* Worker for unshare_expr_without_location. */
1034 static tree
1035 prune_expr_location (tree *tp, int *walk_subtrees, void *)
1037 if (EXPR_P (*tp))
1038 SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
1039 else
1040 *walk_subtrees = 0;
1041 return NULL_TREE;
1044 /* Similar to unshare_expr but also prune all expression locations
1045 from EXPR. */
1047 tree
1048 unshare_expr_without_location (tree expr)
1050 walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1051 if (EXPR_P (expr))
1052 walk_tree (&expr, prune_expr_location, NULL, NULL);
1053 return expr;
1056 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1057 one, OR_ELSE otherwise. The location of a STATEMENT_LISTs
1058 comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1059 EXPR is the location of the EXPR. */
1061 static location_t
1062 rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION)
1064 if (!expr)
1065 return or_else;
1067 if (EXPR_HAS_LOCATION (expr))
1068 return EXPR_LOCATION (expr);
1070 if (TREE_CODE (expr) != STATEMENT_LIST)
1071 return or_else;
1073 tree_stmt_iterator i = tsi_start (expr);
1075 bool found = false;
1076 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
1078 found = true;
1079 tsi_next (&i);
1082 if (!found || !tsi_one_before_end_p (i))
1083 return or_else;
1085 return rexpr_location (tsi_stmt (i), or_else);
1088 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1089 rexpr_location for the potential recursion. */
1091 static inline bool
1092 rexpr_has_location (tree expr)
1094 return rexpr_location (expr) != UNKNOWN_LOCATION;
1098 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1099 contain statements and have a value. Assign its value to a temporary
1100 and give it void_type_node. Return the temporary, or NULL_TREE if
1101 WRAPPER was already void. */
1103 tree
1104 voidify_wrapper_expr (tree wrapper, tree temp)
1106 tree type = TREE_TYPE (wrapper);
1107 if (type && !VOID_TYPE_P (type))
1109 tree *p;
1111 /* Set p to point to the body of the wrapper. Loop until we find
1112 something that isn't a wrapper. */
1113 for (p = &wrapper; p && *p; )
1115 switch (TREE_CODE (*p))
1117 case BIND_EXPR:
1118 TREE_SIDE_EFFECTS (*p) = 1;
1119 TREE_TYPE (*p) = void_type_node;
1120 /* For a BIND_EXPR, the body is operand 1. */
1121 p = &BIND_EXPR_BODY (*p);
1122 break;
1124 case CLEANUP_POINT_EXPR:
1125 case TRY_FINALLY_EXPR:
1126 case TRY_CATCH_EXPR:
1127 TREE_SIDE_EFFECTS (*p) = 1;
1128 TREE_TYPE (*p) = void_type_node;
1129 p = &TREE_OPERAND (*p, 0);
1130 break;
1132 case STATEMENT_LIST:
1134 tree_stmt_iterator i = tsi_last (*p);
1135 TREE_SIDE_EFFECTS (*p) = 1;
1136 TREE_TYPE (*p) = void_type_node;
1137 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1139 break;
1141 case COMPOUND_EXPR:
1142 /* Advance to the last statement. Set all container types to
1143 void. */
1144 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1146 TREE_SIDE_EFFECTS (*p) = 1;
1147 TREE_TYPE (*p) = void_type_node;
1149 break;
1151 case TRANSACTION_EXPR:
1152 TREE_SIDE_EFFECTS (*p) = 1;
1153 TREE_TYPE (*p) = void_type_node;
1154 p = &TRANSACTION_EXPR_BODY (*p);
1155 break;
1157 default:
1158 /* Assume that any tree upon which voidify_wrapper_expr is
1159 directly called is a wrapper, and that its body is op0. */
1160 if (p == &wrapper)
1162 TREE_SIDE_EFFECTS (*p) = 1;
1163 TREE_TYPE (*p) = void_type_node;
1164 p = &TREE_OPERAND (*p, 0);
1165 break;
1167 goto out;
1171 out:
1172 if (p == NULL || IS_EMPTY_STMT (*p))
1173 temp = NULL_TREE;
1174 else if (temp)
1176 /* The wrapper is on the RHS of an assignment that we're pushing
1177 down. */
1178 gcc_assert (TREE_CODE (temp) == INIT_EXPR
1179 || TREE_CODE (temp) == MODIFY_EXPR);
1180 TREE_OPERAND (temp, 1) = *p;
1181 *p = temp;
1183 else
1185 temp = create_tmp_var (type, "retval");
1186 *p = build2 (INIT_EXPR, type, temp, *p);
1189 return temp;
1192 return NULL_TREE;
1195 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1196 a temporary through which they communicate. */
1198 static void
1199 build_stack_save_restore (gcall **save, gcall **restore)
1201 tree tmp_var;
1203 *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1204 tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1205 gimple_call_set_lhs (*save, tmp_var);
1207 *restore
1208 = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1209 1, tmp_var);
1212 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable. */
1214 static tree
1215 build_asan_poison_call_expr (tree decl)
1217 /* Do not poison variables that have size equal to zero. */
1218 tree unit_size = DECL_SIZE_UNIT (decl);
1219 if (zerop (unit_size))
1220 return NULL_TREE;
1222 tree base = build_fold_addr_expr (decl);
1224 return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
1225 void_type_node, 3,
1226 build_int_cst (integer_type_node,
1227 ASAN_MARK_POISON),
1228 base, unit_size);
1231 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1232 on POISON flag, shadow memory of a DECL variable. The call will be
1233 put on location identified by IT iterator, where BEFORE flag drives
1234 position where the stmt will be put. */
1236 static void
1237 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
1238 bool before)
1240 tree unit_size = DECL_SIZE_UNIT (decl);
1241 tree base = build_fold_addr_expr (decl);
1243 /* Do not poison variables that have size equal to zero. */
1244 if (zerop (unit_size))
1245 return;
1247 /* It's necessary to have all stack variables aligned to ASAN granularity
1248 bytes. */
1249 gcc_assert (!hwasan_sanitize_p () || hwasan_sanitize_stack_p ());
1250 unsigned shadow_granularity
1251 = hwasan_sanitize_p () ? HWASAN_TAG_GRANULE_SIZE : ASAN_SHADOW_GRANULARITY;
1252 if (DECL_ALIGN_UNIT (decl) <= shadow_granularity)
1253 SET_DECL_ALIGN (decl, BITS_PER_UNIT * shadow_granularity);
1255 HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
1257 gimple *g
1258 = gimple_build_call_internal (IFN_ASAN_MARK, 3,
1259 build_int_cst (integer_type_node, flags),
1260 base, unit_size);
1262 if (before)
1263 gsi_insert_before (it, g, GSI_NEW_STMT);
1264 else
1265 gsi_insert_after (it, g, GSI_NEW_STMT);
1268 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1269 either poisons or unpoisons a DECL. Created statement is appended
1270 to SEQ_P gimple sequence. */
1272 static void
1273 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
1275 gimple_stmt_iterator it = gsi_last (*seq_p);
1276 bool before = false;
1278 if (gsi_end_p (it))
1279 before = true;
1281 asan_poison_variable (decl, poison, &it, before);
1284 /* Sort pair of VAR_DECLs A and B by DECL_UID. */
1286 static int
1287 sort_by_decl_uid (const void *a, const void *b)
1289 const tree *t1 = (const tree *)a;
1290 const tree *t2 = (const tree *)b;
1292 int uid1 = DECL_UID (*t1);
1293 int uid2 = DECL_UID (*t2);
1295 if (uid1 < uid2)
1296 return -1;
1297 else if (uid1 > uid2)
1298 return 1;
1299 else
1300 return 0;
1303 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1304 depending on POISON flag. Created statement is appended
1305 to SEQ_P gimple sequence. */
1307 static void
1308 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
1310 unsigned c = variables->elements ();
1311 if (c == 0)
1312 return;
1314 auto_vec<tree> sorted_variables (c);
1316 for (hash_set<tree>::iterator it = variables->begin ();
1317 it != variables->end (); ++it)
1318 sorted_variables.safe_push (*it);
1320 sorted_variables.qsort (sort_by_decl_uid);
1322 unsigned i;
1323 tree var;
1324 FOR_EACH_VEC_ELT (sorted_variables, i, var)
1326 asan_poison_variable (var, poison, seq_p);
1328 /* Add use_after_scope_memory attribute for the variable in order
1329 to prevent re-written into SSA. */
1330 if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
1331 DECL_ATTRIBUTES (var)))
1332 DECL_ATTRIBUTES (var)
1333 = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
1334 integer_one_node,
1335 DECL_ATTRIBUTES (var));
1339 /* Gimplify a BIND_EXPR. Just voidify and recurse. */
1341 static enum gimplify_status
1342 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1344 tree bind_expr = *expr_p;
1345 bool old_keep_stack = gimplify_ctxp->keep_stack;
1346 bool old_save_stack = gimplify_ctxp->save_stack;
1347 tree t;
1348 gbind *bind_stmt;
1349 gimple_seq body, cleanup;
1350 gcall *stack_save;
1351 location_t start_locus = 0, end_locus = 0;
1352 tree ret_clauses = NULL;
1354 tree temp = voidify_wrapper_expr (bind_expr, NULL);
1356 /* Mark variables seen in this bind expr. */
1357 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1359 if (VAR_P (t))
1361 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1363 /* Mark variable as local. */
1364 if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t))
1366 if (! DECL_SEEN_IN_BIND_EXPR_P (t)
1367 || splay_tree_lookup (ctx->variables,
1368 (splay_tree_key) t) == NULL)
1370 int flag = GOVD_LOCAL;
1371 if (ctx->region_type == ORT_SIMD
1372 && TREE_ADDRESSABLE (t)
1373 && !TREE_STATIC (t))
1375 if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST)
1376 ctx->add_safelen1 = true;
1377 else
1378 flag = GOVD_PRIVATE;
1380 omp_add_variable (ctx, t, flag | GOVD_SEEN);
1382 /* Static locals inside of target construct or offloaded
1383 routines need to be "omp declare target". */
1384 if (TREE_STATIC (t))
1385 for (; ctx; ctx = ctx->outer_context)
1386 if ((ctx->region_type & ORT_TARGET) != 0)
1388 if (!lookup_attribute ("omp declare target",
1389 DECL_ATTRIBUTES (t)))
1391 tree id = get_identifier ("omp declare target");
1392 DECL_ATTRIBUTES (t)
1393 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
1394 varpool_node *node = varpool_node::get (t);
1395 if (node)
1397 node->offloadable = 1;
1398 if (ENABLE_OFFLOADING && !DECL_EXTERNAL (t))
1400 g->have_offload = true;
1401 if (!in_lto_p)
1402 vec_safe_push (offload_vars, t);
1406 break;
1410 DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1412 if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1413 cfun->has_local_explicit_reg_vars = true;
1417 bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1418 BIND_EXPR_BLOCK (bind_expr));
1419 gimple_push_bind_expr (bind_stmt);
1421 gimplify_ctxp->keep_stack = false;
1422 gimplify_ctxp->save_stack = false;
1424 /* Gimplify the body into the GIMPLE_BIND tuple's body. */
1425 body = NULL;
1426 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1427 gimple_bind_set_body (bind_stmt, body);
1429 /* Source location wise, the cleanup code (stack_restore and clobbers)
1430 belongs to the end of the block, so propagate what we have. The
1431 stack_save operation belongs to the beginning of block, which we can
1432 infer from the bind_expr directly if the block has no explicit
1433 assignment. */
1434 if (BIND_EXPR_BLOCK (bind_expr))
1436 end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1437 start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1439 if (start_locus == 0)
1440 start_locus = EXPR_LOCATION (bind_expr);
1442 cleanup = NULL;
1443 stack_save = NULL;
1445 /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1446 the stack space allocated to the VLAs. */
1447 if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1449 gcall *stack_restore;
1451 /* Save stack on entry and restore it on exit. Add a try_finally
1452 block to achieve this. */
1453 build_stack_save_restore (&stack_save, &stack_restore);
1455 gimple_set_location (stack_save, start_locus);
1456 gimple_set_location (stack_restore, end_locus);
1458 gimplify_seq_add_stmt (&cleanup, stack_restore);
1461 /* Add clobbers for all variables that go out of scope. */
1462 for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1464 if (VAR_P (t)
1465 && !is_global_var (t)
1466 && DECL_CONTEXT (t) == current_function_decl)
1468 if (!DECL_HARD_REGISTER (t)
1469 && !TREE_THIS_VOLATILE (t)
1470 && !DECL_HAS_VALUE_EXPR_P (t)
1471 /* Only care for variables that have to be in memory. Others
1472 will be rewritten into SSA names, hence moved to the
1473 top-level. */
1474 && !is_gimple_reg (t)
1475 && flag_stack_reuse != SR_NONE)
1477 tree clobber = build_clobber (TREE_TYPE (t));
1478 gimple *clobber_stmt;
1479 clobber_stmt = gimple_build_assign (t, clobber);
1480 gimple_set_location (clobber_stmt, end_locus);
1481 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1484 if (flag_openacc && oacc_declare_returns != NULL)
1486 tree key = t;
1487 if (DECL_HAS_VALUE_EXPR_P (key))
1489 key = DECL_VALUE_EXPR (key);
1490 if (TREE_CODE (key) == INDIRECT_REF)
1491 key = TREE_OPERAND (key, 0);
1493 tree *c = oacc_declare_returns->get (key);
1494 if (c != NULL)
1496 if (ret_clauses)
1497 OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1499 ret_clauses = unshare_expr (*c);
1501 oacc_declare_returns->remove (key);
1503 if (oacc_declare_returns->is_empty ())
1505 delete oacc_declare_returns;
1506 oacc_declare_returns = NULL;
1512 if (asan_poisoned_variables != NULL
1513 && asan_poisoned_variables->contains (t))
1515 asan_poisoned_variables->remove (t);
1516 asan_poison_variable (t, true, &cleanup);
1519 if (gimplify_ctxp->live_switch_vars != NULL
1520 && gimplify_ctxp->live_switch_vars->contains (t))
1521 gimplify_ctxp->live_switch_vars->remove (t);
1524 if (ret_clauses)
1526 gomp_target *stmt;
1527 gimple_stmt_iterator si = gsi_start (cleanup);
1529 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1530 ret_clauses);
1531 gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1534 if (cleanup)
1536 gtry *gs;
1537 gimple_seq new_body;
1539 new_body = NULL;
1540 gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1541 GIMPLE_TRY_FINALLY);
1543 if (stack_save)
1544 gimplify_seq_add_stmt (&new_body, stack_save);
1545 gimplify_seq_add_stmt (&new_body, gs);
1546 gimple_bind_set_body (bind_stmt, new_body);
1549 /* keep_stack propagates all the way up to the outermost BIND_EXPR. */
1550 if (!gimplify_ctxp->keep_stack)
1551 gimplify_ctxp->keep_stack = old_keep_stack;
1552 gimplify_ctxp->save_stack = old_save_stack;
1554 gimple_pop_bind_expr ();
1556 gimplify_seq_add_stmt (pre_p, bind_stmt);
1558 if (temp)
1560 *expr_p = temp;
1561 return GS_OK;
1564 *expr_p = NULL_TREE;
1565 return GS_ALL_DONE;
1568 /* Maybe add early return predict statement to PRE_P sequence. */
1570 static void
1571 maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
1573 /* If we are not in a conditional context, add PREDICT statement. */
1574 if (gimple_conditional_context ())
1576 gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
1577 NOT_TAKEN);
1578 gimplify_seq_add_stmt (pre_p, predict);
1582 /* Gimplify a RETURN_EXPR. If the expression to be returned is not a
1583 GIMPLE value, it is assigned to a new temporary and the statement is
1584 re-written to return the temporary.
1586 PRE_P points to the sequence where side effects that must happen before
1587 STMT should be stored. */
1589 static enum gimplify_status
1590 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1592 greturn *ret;
1593 tree ret_expr = TREE_OPERAND (stmt, 0);
1594 tree result_decl, result;
1596 if (ret_expr == error_mark_node)
1597 return GS_ERROR;
1599 if (!ret_expr
1600 || TREE_CODE (ret_expr) == RESULT_DECL)
1602 maybe_add_early_return_predict_stmt (pre_p);
1603 greturn *ret = gimple_build_return (ret_expr);
1604 copy_warning (ret, stmt);
1605 gimplify_seq_add_stmt (pre_p, ret);
1606 return GS_ALL_DONE;
1609 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1610 result_decl = NULL_TREE;
1611 else if (TREE_CODE (ret_expr) == COMPOUND_EXPR)
1613 /* Used in C++ for handling EH cleanup of the return value if a local
1614 cleanup throws. Assume the front-end knows what it's doing. */
1615 result_decl = DECL_RESULT (current_function_decl);
1616 /* But crash if we end up trying to modify ret_expr below. */
1617 ret_expr = NULL_TREE;
1619 else
1621 result_decl = TREE_OPERAND (ret_expr, 0);
1623 /* See through a return by reference. */
1624 if (TREE_CODE (result_decl) == INDIRECT_REF)
1625 result_decl = TREE_OPERAND (result_decl, 0);
1627 gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1628 || TREE_CODE (ret_expr) == INIT_EXPR)
1629 && TREE_CODE (result_decl) == RESULT_DECL);
1632 /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1633 Recall that aggregate_value_p is FALSE for any aggregate type that is
1634 returned in registers. If we're returning values in registers, then
1635 we don't want to extend the lifetime of the RESULT_DECL, particularly
1636 across another call. In addition, for those aggregates for which
1637 hard_function_value generates a PARALLEL, we'll die during normal
1638 expansion of structure assignments; there's special code in expand_return
1639 to handle this case that does not exist in expand_expr. */
1640 if (!result_decl)
1641 result = NULL_TREE;
1642 else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1644 if (!poly_int_tree_p (DECL_SIZE (result_decl)))
1646 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1647 gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1648 /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1649 should be effectively allocated by the caller, i.e. all calls to
1650 this function must be subject to the Return Slot Optimization. */
1651 gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1652 gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1654 result = result_decl;
1656 else if (gimplify_ctxp->return_temp)
1657 result = gimplify_ctxp->return_temp;
1658 else
1660 result = create_tmp_reg (TREE_TYPE (result_decl));
1662 /* ??? With complex control flow (usually involving abnormal edges),
1663 we can wind up warning about an uninitialized value for this. Due
1664 to how this variable is constructed and initialized, this is never
1665 true. Give up and never warn. */
1666 suppress_warning (result, OPT_Wuninitialized);
1668 gimplify_ctxp->return_temp = result;
1671 /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1672 Then gimplify the whole thing. */
1673 if (result != result_decl)
1674 TREE_OPERAND (ret_expr, 0) = result;
1676 gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1678 maybe_add_early_return_predict_stmt (pre_p);
1679 ret = gimple_build_return (result);
1680 copy_warning (ret, stmt);
1681 gimplify_seq_add_stmt (pre_p, ret);
1683 return GS_ALL_DONE;
1686 /* Gimplify a variable-length array DECL. */
1688 static void
1689 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1691 /* This is a variable-sized decl. Simplify its size and mark it
1692 for deferred expansion. */
1693 tree t, addr, ptr_type;
1695 gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1696 gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1698 /* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
1699 if (DECL_HAS_VALUE_EXPR_P (decl))
1700 return;
1702 /* All occurrences of this decl in final gimplified code will be
1703 replaced by indirection. Setting DECL_VALUE_EXPR does two
1704 things: First, it lets the rest of the gimplifier know what
1705 replacement to use. Second, it lets the debug info know
1706 where to find the value. */
1707 ptr_type = build_pointer_type (TREE_TYPE (decl));
1708 addr = create_tmp_var (ptr_type, get_name (decl));
1709 DECL_IGNORED_P (addr) = 0;
1710 t = build_fold_indirect_ref (addr);
1711 TREE_THIS_NOTRAP (t) = 1;
1712 SET_DECL_VALUE_EXPR (decl, t);
1713 DECL_HAS_VALUE_EXPR_P (decl) = 1;
1715 t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
1716 max_int_size_in_bytes (TREE_TYPE (decl)));
1717 /* The call has been built for a variable-sized object. */
1718 CALL_ALLOCA_FOR_VAR_P (t) = 1;
1719 t = fold_convert (ptr_type, t);
1720 t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1722 gimplify_and_add (t, seq_p);
1724 /* Record the dynamic allocation associated with DECL if requested. */
1725 if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)
1726 record_dynamic_alloc (decl);
1729 /* A helper function to be called via walk_tree. Mark all labels under *TP
1730 as being forced. To be called for DECL_INITIAL of static variables. */
1732 static tree
1733 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1735 if (TYPE_P (*tp))
1736 *walk_subtrees = 0;
1737 if (TREE_CODE (*tp) == LABEL_DECL)
1739 FORCED_LABEL (*tp) = 1;
1740 cfun->has_forced_label_in_static = 1;
1743 return NULL_TREE;
1746 /* Generate an initialization to automatic variable DECL based on INIT_TYPE.
1747 Build a call to internal const function DEFERRED_INIT:
1748 1st argument: SIZE of the DECL;
1749 2nd argument: INIT_TYPE;
1750 3rd argument: IS_VLA, 0 NO, 1 YES;
1752 as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, IS_VLA)
1753 if IS_VLA is false, the LHS is the DECL itself,
1754 if IS_VLA is true, the LHS is a MEM_REF whose address is the pointer
1755 to this DECL. */
1756 static void
1757 gimple_add_init_for_auto_var (tree decl,
1758 enum auto_init_type init_type,
1759 bool is_vla,
1760 gimple_seq *seq_p)
1762 gcc_assert (auto_var_p (decl));
1763 gcc_assert (init_type > AUTO_INIT_UNINITIALIZED);
1764 location_t loc = EXPR_LOCATION (decl);
1765 tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl));
1767 tree init_type_node
1768 = build_int_cst (integer_type_node, (int) init_type);
1769 tree is_vla_node
1770 = build_int_cst (integer_type_node, (int) is_vla);
1772 tree call = build_call_expr_internal_loc (loc, IFN_DEFERRED_INIT,
1773 TREE_TYPE (decl), 3,
1774 decl_size, init_type_node,
1775 is_vla_node);
1777 gimplify_assign (decl, call, seq_p);
1780 /* Generate padding initialization for automatic vairable DECL.
1781 C guarantees that brace-init with fewer initializers than members
1782 aggregate will initialize the rest of the aggregate as-if it were
1783 static initialization. In turn static initialization guarantees
1784 that padding is initialized to zero. So, we always initialize paddings
1785 to zeroes regardless INIT_TYPE.
1786 To do the padding initialization, we insert a call to
1787 __builtin_clear_padding (&decl, 0, for_auto_init = true).
1788 Note, we add an additional dummy argument for __builtin_clear_padding,
1789 'for_auto_init' to distinguish whether this call is for automatic
1790 variable initialization or not.
1792 static void
1793 gimple_add_padding_init_for_auto_var (tree decl, bool is_vla,
1794 gimple_seq *seq_p)
1796 tree addr_of_decl = NULL_TREE;
1797 bool for_auto_init = true;
1798 tree fn = builtin_decl_explicit (BUILT_IN_CLEAR_PADDING);
1800 if (is_vla)
1802 /* The temporary address variable for this vla should be
1803 created in gimplify_vla_decl. */
1804 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
1805 gcc_assert (TREE_CODE (DECL_VALUE_EXPR (decl)) == INDIRECT_REF);
1806 addr_of_decl = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
1808 else
1810 mark_addressable (decl);
1811 addr_of_decl = build_fold_addr_expr (decl);
1814 gimple *call = gimple_build_call (fn,
1815 3, addr_of_decl,
1816 build_zero_cst (TREE_TYPE (addr_of_decl)),
1817 build_int_cst (integer_type_node,
1818 (int) for_auto_init));
1819 gimplify_seq_add_stmt (seq_p, call);
1822 /* Return true if the DECL need to be automaticly initialized by the
1823 compiler. */
1824 static bool
1825 is_var_need_auto_init (tree decl)
1827 if (auto_var_p (decl)
1828 && (TREE_CODE (decl) != VAR_DECL
1829 || !DECL_HARD_REGISTER (decl))
1830 && (flag_auto_var_init > AUTO_INIT_UNINITIALIZED)
1831 && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl)))
1832 && !is_empty_type (TREE_TYPE (decl)))
1833 return true;
1834 return false;
1837 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1838 and initialization explicit. */
1840 static enum gimplify_status
1841 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1843 tree stmt = *stmt_p;
1844 tree decl = DECL_EXPR_DECL (stmt);
1846 *stmt_p = NULL_TREE;
1848 if (TREE_TYPE (decl) == error_mark_node)
1849 return GS_ERROR;
1851 if ((TREE_CODE (decl) == TYPE_DECL
1852 || VAR_P (decl))
1853 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1855 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1856 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1857 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1860 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1861 in case its size expressions contain problematic nodes like CALL_EXPR. */
1862 if (TREE_CODE (decl) == TYPE_DECL
1863 && DECL_ORIGINAL_TYPE (decl)
1864 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1866 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1867 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1868 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1871 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1873 tree init = DECL_INITIAL (decl);
1874 bool is_vla = false;
1875 /* Check whether a decl has FE created VALUE_EXPR here BEFORE
1876 gimplify_vla_decl creates VALUE_EXPR for a vla decl.
1877 If the decl has VALUE_EXPR that was created by FE (usually
1878 C++FE), it's a proxy varaible, and FE already initialized
1879 the VALUE_EXPR of it, we should not initialize it anymore. */
1880 bool decl_had_value_expr_p = DECL_HAS_VALUE_EXPR_P (decl);
1882 poly_uint64 size;
1883 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
1884 || (!TREE_STATIC (decl)
1885 && flag_stack_check == GENERIC_STACK_CHECK
1886 && maybe_gt (size,
1887 (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
1889 gimplify_vla_decl (decl, seq_p);
1890 is_vla = true;
1893 if (asan_poisoned_variables
1894 && !is_vla
1895 && TREE_ADDRESSABLE (decl)
1896 && !TREE_STATIC (decl)
1897 && !DECL_HAS_VALUE_EXPR_P (decl)
1898 && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
1899 && dbg_cnt (asan_use_after_scope)
1900 && !gimplify_omp_ctxp
1901 /* GNAT introduces temporaries to hold return values of calls in
1902 initializers of variables defined in other units, so the
1903 declaration of the variable is discarded completely. We do not
1904 want to issue poison calls for such dropped variables. */
1905 && (DECL_SEEN_IN_BIND_EXPR_P (decl)
1906 || (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)))
1908 asan_poisoned_variables->add (decl);
1909 asan_poison_variable (decl, false, seq_p);
1910 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
1911 gimplify_ctxp->live_switch_vars->add (decl);
1914 /* Some front ends do not explicitly declare all anonymous
1915 artificial variables. We compensate here by declaring the
1916 variables, though it would be better if the front ends would
1917 explicitly declare them. */
1918 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1919 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1920 gimple_add_tmp_var (decl);
1922 if (init && init != error_mark_node)
1924 if (!TREE_STATIC (decl))
1926 DECL_INITIAL (decl) = NULL_TREE;
1927 init = build2 (INIT_EXPR, void_type_node, decl, init);
1928 gimplify_and_add (init, seq_p);
1929 ggc_free (init);
1930 /* Clear TREE_READONLY if we really have an initialization. */
1931 if (!DECL_INITIAL (decl)
1932 && !omp_privatize_by_reference (decl))
1933 TREE_READONLY (decl) = 0;
1935 else
1936 /* We must still examine initializers for static variables
1937 as they may contain a label address. */
1938 walk_tree (&init, force_labels_r, NULL, NULL);
1940 /* When there is no explicit initializer, if the user requested,
1941 We should insert an artifical initializer for this automatic
1942 variable. */
1943 else if (is_var_need_auto_init (decl)
1944 && !decl_had_value_expr_p)
1946 gimple_add_init_for_auto_var (decl,
1947 flag_auto_var_init,
1948 is_vla,
1949 seq_p);
1950 /* The expanding of a call to the above .DEFERRED_INIT will apply
1951 block initialization to the whole space covered by this variable.
1952 As a result, all the paddings will be initialized to zeroes
1953 for zero initialization and 0xFE byte-repeatable patterns for
1954 pattern initialization.
1955 In order to make the paddings as zeroes for pattern init, We
1956 should add a call to __builtin_clear_padding to clear the
1957 paddings to zero in compatiple with CLANG.
1958 We cannot insert this call if the variable is a gimple register
1959 since __builtin_clear_padding will take the address of the
1960 variable. As a result, if a long double/_Complex long double
1961 variable will spilled into stack later, its padding is 0XFE. */
1962 if (flag_auto_var_init == AUTO_INIT_PATTERN
1963 && !is_gimple_reg (decl)
1964 && clear_padding_type_may_have_padding_p (TREE_TYPE (decl)))
1965 gimple_add_padding_init_for_auto_var (decl, is_vla, seq_p);
1969 return GS_ALL_DONE;
1972 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1973 and replacing the LOOP_EXPR with goto, but if the loop contains an
1974 EXIT_EXPR, we need to append a label for it to jump to. */
1976 static enum gimplify_status
1977 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1979 tree saved_label = gimplify_ctxp->exit_label;
1980 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1982 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1984 gimplify_ctxp->exit_label = NULL_TREE;
1986 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1988 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
1990 if (gimplify_ctxp->exit_label)
1991 gimplify_seq_add_stmt (pre_p,
1992 gimple_build_label (gimplify_ctxp->exit_label));
1994 gimplify_ctxp->exit_label = saved_label;
1996 *expr_p = NULL;
1997 return GS_ALL_DONE;
2000 /* Gimplify a statement list onto a sequence. These may be created either
2001 by an enlightened front-end, or by shortcut_cond_expr. */
2003 static enum gimplify_status
2004 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
2006 tree temp = voidify_wrapper_expr (*expr_p, NULL);
2008 tree_stmt_iterator i = tsi_start (*expr_p);
2010 while (!tsi_end_p (i))
2012 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
2013 tsi_delink (&i);
2016 if (temp)
2018 *expr_p = temp;
2019 return GS_OK;
2022 return GS_ALL_DONE;
2025 /* Callback for walk_gimple_seq. */
2027 static tree
2028 warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2029 struct walk_stmt_info *wi)
2031 gimple *stmt = gsi_stmt (*gsi_p);
2033 *handled_ops_p = true;
2034 switch (gimple_code (stmt))
2036 case GIMPLE_TRY:
2037 /* A compiler-generated cleanup or a user-written try block.
2038 If it's empty, don't dive into it--that would result in
2039 worse location info. */
2040 if (gimple_try_eval (stmt) == NULL)
2042 wi->info = stmt;
2043 return integer_zero_node;
2045 /* Fall through. */
2046 case GIMPLE_BIND:
2047 case GIMPLE_CATCH:
2048 case GIMPLE_EH_FILTER:
2049 case GIMPLE_TRANSACTION:
2050 /* Walk the sub-statements. */
2051 *handled_ops_p = false;
2052 break;
2054 case GIMPLE_DEBUG:
2055 /* Ignore these. We may generate them before declarations that
2056 are never executed. If there's something to warn about,
2057 there will be non-debug stmts too, and we'll catch those. */
2058 break;
2060 case GIMPLE_CALL:
2061 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2063 *handled_ops_p = false;
2064 break;
2066 /* Fall through. */
2067 default:
2068 /* Save the first "real" statement (not a decl/lexical scope/...). */
2069 wi->info = stmt;
2070 return integer_zero_node;
2072 return NULL_TREE;
2075 /* Possibly warn about unreachable statements between switch's controlling
2076 expression and the first case. SEQ is the body of a switch expression. */
2078 static void
2079 maybe_warn_switch_unreachable (gimple_seq seq)
2081 if (!warn_switch_unreachable
2082 /* This warning doesn't play well with Fortran when optimizations
2083 are on. */
2084 || lang_GNU_Fortran ()
2085 || seq == NULL)
2086 return;
2088 struct walk_stmt_info wi;
2089 memset (&wi, 0, sizeof (wi));
2090 walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi);
2091 gimple *stmt = (gimple *) wi.info;
2093 if (stmt && gimple_code (stmt) != GIMPLE_LABEL)
2095 if (gimple_code (stmt) == GIMPLE_GOTO
2096 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
2097 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
2098 /* Don't warn for compiler-generated gotos. These occur
2099 in Duff's devices, for example. */;
2100 else
2101 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
2102 "statement will never be executed");
2107 /* A label entry that pairs label and a location. */
2108 struct label_entry
2110 tree label;
2111 location_t loc;
2114 /* Find LABEL in vector of label entries VEC. */
2116 static struct label_entry *
2117 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
2119 unsigned int i;
2120 struct label_entry *l;
2122 FOR_EACH_VEC_ELT (*vec, i, l)
2123 if (l->label == label)
2124 return l;
2125 return NULL;
2128 /* Return true if LABEL, a LABEL_DECL, represents a case label
2129 in a vector of labels CASES. */
2131 static bool
2132 case_label_p (const vec<tree> *cases, tree label)
2134 unsigned int i;
2135 tree l;
2137 FOR_EACH_VEC_ELT (*cases, i, l)
2138 if (CASE_LABEL (l) == label)
2139 return true;
2140 return false;
2143 /* Find the last nondebug statement in a scope STMT. */
2145 static gimple *
2146 last_stmt_in_scope (gimple *stmt)
2148 if (!stmt)
2149 return NULL;
2151 switch (gimple_code (stmt))
2153 case GIMPLE_BIND:
2155 gbind *bind = as_a <gbind *> (stmt);
2156 stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
2157 return last_stmt_in_scope (stmt);
2160 case GIMPLE_TRY:
2162 gtry *try_stmt = as_a <gtry *> (stmt);
2163 stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
2164 gimple *last_eval = last_stmt_in_scope (stmt);
2165 if (gimple_stmt_may_fallthru (last_eval)
2166 && (last_eval == NULL
2167 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
2168 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
2170 stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
2171 return last_stmt_in_scope (stmt);
2173 else
2174 return last_eval;
2177 case GIMPLE_DEBUG:
2178 gcc_unreachable ();
2180 default:
2181 return stmt;
2185 /* Collect interesting labels in LABELS and return the statement preceding
2186 another case label, or a user-defined label. Store a location useful
2187 to give warnings at *PREVLOC (usually the location of the returned
2188 statement or of its surrounding scope). */
2190 static gimple *
2191 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
2192 auto_vec <struct label_entry> *labels,
2193 location_t *prevloc)
2195 gimple *prev = NULL;
2197 *prevloc = UNKNOWN_LOCATION;
2200 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
2202 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2203 which starts on a GIMPLE_SWITCH and ends with a break label.
2204 Handle that as a single statement that can fall through. */
2205 gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
2206 gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
2207 gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
2208 if (last
2209 && gimple_code (first) == GIMPLE_SWITCH
2210 && gimple_code (last) == GIMPLE_LABEL)
2212 tree label = gimple_label_label (as_a <glabel *> (last));
2213 if (SWITCH_BREAK_LABEL_P (label))
2215 prev = bind;
2216 gsi_next (gsi_p);
2217 continue;
2221 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
2222 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
2224 /* Nested scope. Only look at the last statement of
2225 the innermost scope. */
2226 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
2227 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
2228 if (last)
2230 prev = last;
2231 /* It might be a label without a location. Use the
2232 location of the scope then. */
2233 if (!gimple_has_location (prev))
2234 *prevloc = bind_loc;
2236 gsi_next (gsi_p);
2237 continue;
2240 /* Ifs are tricky. */
2241 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
2243 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
2244 tree false_lab = gimple_cond_false_label (cond_stmt);
2245 location_t if_loc = gimple_location (cond_stmt);
2247 /* If we have e.g.
2248 if (i > 1) goto <D.2259>; else goto D;
2249 we can't do much with the else-branch. */
2250 if (!DECL_ARTIFICIAL (false_lab))
2251 break;
2253 /* Go on until the false label, then one step back. */
2254 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
2256 gimple *stmt = gsi_stmt (*gsi_p);
2257 if (gimple_code (stmt) == GIMPLE_LABEL
2258 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
2259 break;
2262 /* Not found? Oops. */
2263 if (gsi_end_p (*gsi_p))
2264 break;
2266 struct label_entry l = { false_lab, if_loc };
2267 labels->safe_push (l);
2269 /* Go to the last statement of the then branch. */
2270 gsi_prev (gsi_p);
2272 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2273 <D.1759>:
2274 <stmt>;
2275 goto <D.1761>;
2276 <D.1760>:
2278 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2279 && !gimple_has_location (gsi_stmt (*gsi_p)))
2281 /* Look at the statement before, it might be
2282 attribute fallthrough, in which case don't warn. */
2283 gsi_prev (gsi_p);
2284 bool fallthru_before_dest
2285 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2286 gsi_next (gsi_p);
2287 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2288 if (!fallthru_before_dest)
2290 struct label_entry l = { goto_dest, if_loc };
2291 labels->safe_push (l);
2294 /* And move back. */
2295 gsi_next (gsi_p);
2298 /* Remember the last statement. Skip labels that are of no interest
2299 to us. */
2300 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2302 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2303 if (find_label_entry (labels, label))
2304 prev = gsi_stmt (*gsi_p);
2306 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2308 else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
2310 else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2311 prev = gsi_stmt (*gsi_p);
2312 gsi_next (gsi_p);
2314 while (!gsi_end_p (*gsi_p)
2315 /* Stop if we find a case or a user-defined label. */
2316 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2317 || !gimple_has_location (gsi_stmt (*gsi_p))));
2319 if (prev && gimple_has_location (prev))
2320 *prevloc = gimple_location (prev);
2321 return prev;
2324 /* Return true if the switch fallthough warning should occur. LABEL is
2325 the label statement that we're falling through to. */
2327 static bool
2328 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2330 gimple_stmt_iterator gsi = *gsi_p;
2332 /* Don't warn if the label is marked with a "falls through" comment. */
2333 if (FALLTHROUGH_LABEL_P (label))
2334 return false;
2336 /* Don't warn for non-case labels followed by a statement:
2337 case 0:
2338 foo ();
2339 label:
2340 bar ();
2341 as these are likely intentional. */
2342 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2344 tree l;
2345 while (!gsi_end_p (gsi)
2346 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2347 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2348 && !case_label_p (&gimplify_ctxp->case_labels, l))
2349 gsi_next_nondebug (&gsi);
2350 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2351 return false;
2354 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2355 immediately breaks. */
2356 gsi = *gsi_p;
2358 /* Skip all immediately following labels. */
2359 while (!gsi_end_p (gsi)
2360 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2361 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2362 gsi_next_nondebug (&gsi);
2364 /* { ... something; default:; } */
2365 if (gsi_end_p (gsi)
2366 /* { ... something; default: break; } or
2367 { ... something; default: goto L; } */
2368 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2369 /* { ... something; default: return; } */
2370 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2371 return false;
2373 return true;
2376 /* Callback for walk_gimple_seq. */
2378 static tree
2379 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2380 struct walk_stmt_info *)
2382 gimple *stmt = gsi_stmt (*gsi_p);
2384 *handled_ops_p = true;
2385 switch (gimple_code (stmt))
2387 case GIMPLE_TRY:
2388 case GIMPLE_BIND:
2389 case GIMPLE_CATCH:
2390 case GIMPLE_EH_FILTER:
2391 case GIMPLE_TRANSACTION:
2392 /* Walk the sub-statements. */
2393 *handled_ops_p = false;
2394 break;
2396 /* Find a sequence of form:
2398 GIMPLE_LABEL
2399 [...]
2400 <may fallthru stmt>
2401 GIMPLE_LABEL
2403 and possibly warn. */
2404 case GIMPLE_LABEL:
2406 /* Found a label. Skip all immediately following labels. */
2407 while (!gsi_end_p (*gsi_p)
2408 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2409 gsi_next_nondebug (gsi_p);
2411 /* There might be no more statements. */
2412 if (gsi_end_p (*gsi_p))
2413 return integer_zero_node;
2415 /* Vector of labels that fall through. */
2416 auto_vec <struct label_entry> labels;
2417 location_t prevloc;
2418 gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
2420 /* There might be no more statements. */
2421 if (gsi_end_p (*gsi_p))
2422 return integer_zero_node;
2424 gimple *next = gsi_stmt (*gsi_p);
2425 tree label;
2426 /* If what follows is a label, then we may have a fallthrough. */
2427 if (gimple_code (next) == GIMPLE_LABEL
2428 && gimple_has_location (next)
2429 && (label = gimple_label_label (as_a <glabel *> (next)))
2430 && prev != NULL)
2432 struct label_entry *l;
2433 bool warned_p = false;
2434 auto_diagnostic_group d;
2435 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2436 /* Quiet. */;
2437 else if (gimple_code (prev) == GIMPLE_LABEL
2438 && (label = gimple_label_label (as_a <glabel *> (prev)))
2439 && (l = find_label_entry (&labels, label)))
2440 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2441 "this statement may fall through");
2442 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2443 /* Try to be clever and don't warn when the statement
2444 can't actually fall through. */
2445 && gimple_stmt_may_fallthru (prev)
2446 && prevloc != UNKNOWN_LOCATION)
2447 warned_p = warning_at (prevloc,
2448 OPT_Wimplicit_fallthrough_,
2449 "this statement may fall through");
2450 if (warned_p)
2451 inform (gimple_location (next), "here");
2453 /* Mark this label as processed so as to prevent multiple
2454 warnings in nested switches. */
2455 FALLTHROUGH_LABEL_P (label) = true;
2457 /* So that next warn_implicit_fallthrough_r will start looking for
2458 a new sequence starting with this label. */
2459 gsi_prev (gsi_p);
2462 break;
2463 default:
2464 break;
2466 return NULL_TREE;
2469 /* Warn when a switch case falls through. */
2471 static void
2472 maybe_warn_implicit_fallthrough (gimple_seq seq)
2474 if (!warn_implicit_fallthrough)
2475 return;
2477 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2478 if (!(lang_GNU_C ()
2479 || lang_GNU_CXX ()
2480 || lang_GNU_OBJC ()))
2481 return;
2483 struct walk_stmt_info wi;
2484 memset (&wi, 0, sizeof (wi));
2485 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2488 /* Callback for walk_gimple_seq. */
2490 static tree
2491 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2492 struct walk_stmt_info *wi)
2494 gimple *stmt = gsi_stmt (*gsi_p);
2496 *handled_ops_p = true;
2497 switch (gimple_code (stmt))
2499 case GIMPLE_TRY:
2500 case GIMPLE_BIND:
2501 case GIMPLE_CATCH:
2502 case GIMPLE_EH_FILTER:
2503 case GIMPLE_TRANSACTION:
2504 /* Walk the sub-statements. */
2505 *handled_ops_p = false;
2506 break;
2507 case GIMPLE_CALL:
2508 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2510 gsi_remove (gsi_p, true);
2511 if (gsi_end_p (*gsi_p))
2513 *static_cast<location_t *>(wi->info) = gimple_location (stmt);
2514 return integer_zero_node;
2517 bool found = false;
2518 location_t loc = gimple_location (stmt);
2520 gimple_stmt_iterator gsi2 = *gsi_p;
2521 stmt = gsi_stmt (gsi2);
2522 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2524 /* Go on until the artificial label. */
2525 tree goto_dest = gimple_goto_dest (stmt);
2526 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2528 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2529 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2530 == goto_dest)
2531 break;
2534 /* Not found? Stop. */
2535 if (gsi_end_p (gsi2))
2536 break;
2538 /* Look one past it. */
2539 gsi_next (&gsi2);
2542 /* We're looking for a case label or default label here. */
2543 while (!gsi_end_p (gsi2))
2545 stmt = gsi_stmt (gsi2);
2546 if (gimple_code (stmt) == GIMPLE_LABEL)
2548 tree label = gimple_label_label (as_a <glabel *> (stmt));
2549 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2551 found = true;
2552 break;
2555 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2557 else if (!is_gimple_debug (stmt))
2558 /* Anything else is not expected. */
2559 break;
2560 gsi_next (&gsi2);
2562 if (!found)
2563 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2564 "a case label or default label");
2566 break;
2567 default:
2568 break;
2570 return NULL_TREE;
2573 /* Expand all FALLTHROUGH () calls in SEQ. */
2575 static void
2576 expand_FALLTHROUGH (gimple_seq *seq_p)
2578 struct walk_stmt_info wi;
2579 location_t loc;
2580 memset (&wi, 0, sizeof (wi));
2581 wi.info = (void *) &loc;
2582 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2583 if (wi.callback_result == integer_zero_node)
2584 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2585 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2586 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2587 "a case label or default label");
2591 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2592 branch to. */
2594 static enum gimplify_status
2595 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2597 tree switch_expr = *expr_p;
2598 gimple_seq switch_body_seq = NULL;
2599 enum gimplify_status ret;
2600 tree index_type = TREE_TYPE (switch_expr);
2601 if (index_type == NULL_TREE)
2602 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2604 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2605 fb_rvalue);
2606 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2607 return ret;
2609 if (SWITCH_BODY (switch_expr))
2611 vec<tree> labels;
2612 vec<tree> saved_labels;
2613 hash_set<tree> *saved_live_switch_vars = NULL;
2614 tree default_case = NULL_TREE;
2615 gswitch *switch_stmt;
2617 /* Save old labels, get new ones from body, then restore the old
2618 labels. Save all the things from the switch body to append after. */
2619 saved_labels = gimplify_ctxp->case_labels;
2620 gimplify_ctxp->case_labels.create (8);
2622 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2623 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2624 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2625 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2626 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2627 else
2628 gimplify_ctxp->live_switch_vars = NULL;
2630 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2631 gimplify_ctxp->in_switch_expr = true;
2633 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2635 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2636 maybe_warn_switch_unreachable (switch_body_seq);
2637 maybe_warn_implicit_fallthrough (switch_body_seq);
2638 /* Only do this for the outermost GIMPLE_SWITCH. */
2639 if (!gimplify_ctxp->in_switch_expr)
2640 expand_FALLTHROUGH (&switch_body_seq);
2642 labels = gimplify_ctxp->case_labels;
2643 gimplify_ctxp->case_labels = saved_labels;
2645 if (gimplify_ctxp->live_switch_vars)
2647 gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
2648 delete gimplify_ctxp->live_switch_vars;
2650 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2652 preprocess_case_label_vec_for_gimple (labels, index_type,
2653 &default_case);
2655 bool add_bind = false;
2656 if (!default_case)
2658 glabel *new_default;
2660 default_case
2661 = build_case_label (NULL_TREE, NULL_TREE,
2662 create_artificial_label (UNKNOWN_LOCATION));
2663 if (old_in_switch_expr)
2665 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2666 add_bind = true;
2668 new_default = gimple_build_label (CASE_LABEL (default_case));
2669 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2671 else if (old_in_switch_expr)
2673 gimple *last = gimple_seq_last_stmt (switch_body_seq);
2674 if (last && gimple_code (last) == GIMPLE_LABEL)
2676 tree label = gimple_label_label (as_a <glabel *> (last));
2677 if (SWITCH_BREAK_LABEL_P (label))
2678 add_bind = true;
2682 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2683 default_case, labels);
2684 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2685 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2686 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2687 so that we can easily find the start and end of the switch
2688 statement. */
2689 if (add_bind)
2691 gimple_seq bind_body = NULL;
2692 gimplify_seq_add_stmt (&bind_body, switch_stmt);
2693 gimple_seq_add_seq (&bind_body, switch_body_seq);
2694 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
2695 gimple_set_location (bind, EXPR_LOCATION (switch_expr));
2696 gimplify_seq_add_stmt (pre_p, bind);
2698 else
2700 gimplify_seq_add_stmt (pre_p, switch_stmt);
2701 gimplify_seq_add_seq (pre_p, switch_body_seq);
2703 labels.release ();
2705 else
2706 gcc_unreachable ();
2708 return GS_ALL_DONE;
2711 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2713 static enum gimplify_status
2714 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2716 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2717 == current_function_decl);
2719 tree label = LABEL_EXPR_LABEL (*expr_p);
2720 glabel *label_stmt = gimple_build_label (label);
2721 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2722 gimplify_seq_add_stmt (pre_p, label_stmt);
2724 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2725 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2726 NOT_TAKEN));
2727 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2728 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2729 TAKEN));
2731 return GS_ALL_DONE;
2734 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2736 static enum gimplify_status
2737 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2739 struct gimplify_ctx *ctxp;
2740 glabel *label_stmt;
2742 /* Invalid programs can play Duff's Device type games with, for example,
2743 #pragma omp parallel. At least in the C front end, we don't
2744 detect such invalid branches until after gimplification, in the
2745 diagnose_omp_blocks pass. */
2746 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2747 if (ctxp->case_labels.exists ())
2748 break;
2750 tree label = CASE_LABEL (*expr_p);
2751 label_stmt = gimple_build_label (label);
2752 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2753 ctxp->case_labels.safe_push (*expr_p);
2754 gimplify_seq_add_stmt (pre_p, label_stmt);
2756 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2757 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2758 NOT_TAKEN));
2759 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2760 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2761 TAKEN));
2763 return GS_ALL_DONE;
2766 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2767 if necessary. */
2769 tree
2770 build_and_jump (tree *label_p)
2772 if (label_p == NULL)
2773 /* If there's nowhere to jump, just fall through. */
2774 return NULL_TREE;
2776 if (*label_p == NULL_TREE)
2778 tree label = create_artificial_label (UNKNOWN_LOCATION);
2779 *label_p = label;
2782 return build1 (GOTO_EXPR, void_type_node, *label_p);
2785 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2786 This also involves building a label to jump to and communicating it to
2787 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2789 static enum gimplify_status
2790 gimplify_exit_expr (tree *expr_p)
2792 tree cond = TREE_OPERAND (*expr_p, 0);
2793 tree expr;
2795 expr = build_and_jump (&gimplify_ctxp->exit_label);
2796 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2797 *expr_p = expr;
2799 return GS_OK;
2802 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2803 different from its canonical type, wrap the whole thing inside a
2804 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2805 type.
2807 The canonical type of a COMPONENT_REF is the type of the field being
2808 referenced--unless the field is a bit-field which can be read directly
2809 in a smaller mode, in which case the canonical type is the
2810 sign-appropriate type corresponding to that mode. */
2812 static void
2813 canonicalize_component_ref (tree *expr_p)
2815 tree expr = *expr_p;
2816 tree type;
2818 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2820 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2821 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2822 else
2823 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2825 /* One could argue that all the stuff below is not necessary for
2826 the non-bitfield case and declare it a FE error if type
2827 adjustment would be needed. */
2828 if (TREE_TYPE (expr) != type)
2830 #ifdef ENABLE_TYPES_CHECKING
2831 tree old_type = TREE_TYPE (expr);
2832 #endif
2833 int type_quals;
2835 /* We need to preserve qualifiers and propagate them from
2836 operand 0. */
2837 type_quals = TYPE_QUALS (type)
2838 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2839 if (TYPE_QUALS (type) != type_quals)
2840 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2842 /* Set the type of the COMPONENT_REF to the underlying type. */
2843 TREE_TYPE (expr) = type;
2845 #ifdef ENABLE_TYPES_CHECKING
2846 /* It is now a FE error, if the conversion from the canonical
2847 type to the original expression type is not useless. */
2848 gcc_assert (useless_type_conversion_p (old_type, type));
2849 #endif
2853 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2854 to foo, embed that change in the ADDR_EXPR by converting
2855 T array[U];
2856 (T *)&array
2858 &array[L]
2859 where L is the lower bound. For simplicity, only do this for constant
2860 lower bound.
2861 The constraint is that the type of &array[L] is trivially convertible
2862 to T *. */
2864 static void
2865 canonicalize_addr_expr (tree *expr_p)
2867 tree expr = *expr_p;
2868 tree addr_expr = TREE_OPERAND (expr, 0);
2869 tree datype, ddatype, pddatype;
2871 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2872 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2873 || TREE_CODE (addr_expr) != ADDR_EXPR)
2874 return;
2876 /* The addr_expr type should be a pointer to an array. */
2877 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2878 if (TREE_CODE (datype) != ARRAY_TYPE)
2879 return;
2881 /* The pointer to element type shall be trivially convertible to
2882 the expression pointer type. */
2883 ddatype = TREE_TYPE (datype);
2884 pddatype = build_pointer_type (ddatype);
2885 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2886 pddatype))
2887 return;
2889 /* The lower bound and element sizes must be constant. */
2890 if (!TYPE_SIZE_UNIT (ddatype)
2891 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2892 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2893 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2894 return;
2896 /* All checks succeeded. Build a new node to merge the cast. */
2897 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2898 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2899 NULL_TREE, NULL_TREE);
2900 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2902 /* We can have stripped a required restrict qualifier above. */
2903 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2904 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2907 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2908 underneath as appropriate. */
2910 static enum gimplify_status
2911 gimplify_conversion (tree *expr_p)
2913 location_t loc = EXPR_LOCATION (*expr_p);
2914 gcc_assert (CONVERT_EXPR_P (*expr_p));
2916 /* Then strip away all but the outermost conversion. */
2917 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
2919 /* And remove the outermost conversion if it's useless. */
2920 if (tree_ssa_useless_type_conversion (*expr_p))
2921 *expr_p = TREE_OPERAND (*expr_p, 0);
2923 /* If we still have a conversion at the toplevel,
2924 then canonicalize some constructs. */
2925 if (CONVERT_EXPR_P (*expr_p))
2927 tree sub = TREE_OPERAND (*expr_p, 0);
2929 /* If a NOP conversion is changing the type of a COMPONENT_REF
2930 expression, then canonicalize its type now in order to expose more
2931 redundant conversions. */
2932 if (TREE_CODE (sub) == COMPONENT_REF)
2933 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
2935 /* If a NOP conversion is changing a pointer to array of foo
2936 to a pointer to foo, embed that change in the ADDR_EXPR. */
2937 else if (TREE_CODE (sub) == ADDR_EXPR)
2938 canonicalize_addr_expr (expr_p);
2941 /* If we have a conversion to a non-register type force the
2942 use of a VIEW_CONVERT_EXPR instead. */
2943 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
2944 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
2945 TREE_OPERAND (*expr_p, 0));
2947 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2948 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
2949 TREE_SET_CODE (*expr_p, NOP_EXPR);
2951 return GS_OK;
2954 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2955 DECL_VALUE_EXPR, and it's worth re-examining things. */
2957 static enum gimplify_status
2958 gimplify_var_or_parm_decl (tree *expr_p)
2960 tree decl = *expr_p;
2962 /* ??? If this is a local variable, and it has not been seen in any
2963 outer BIND_EXPR, then it's probably the result of a duplicate
2964 declaration, for which we've already issued an error. It would
2965 be really nice if the front end wouldn't leak these at all.
2966 Currently the only known culprit is C++ destructors, as seen
2967 in g++.old-deja/g++.jason/binding.C.
2968 Another possible culpit are size expressions for variably modified
2969 types which are lost in the FE or not gimplified correctly. */
2970 if (VAR_P (decl)
2971 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
2972 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
2973 && decl_function_context (decl) == current_function_decl)
2975 gcc_assert (seen_error ());
2976 return GS_ERROR;
2979 /* When within an OMP context, notice uses of variables. */
2980 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
2981 return GS_ALL_DONE;
2983 /* If the decl is an alias for another expression, substitute it now. */
2984 if (DECL_HAS_VALUE_EXPR_P (decl))
2986 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
2987 return GS_OK;
2990 return GS_ALL_DONE;
2993 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2995 static void
2996 recalculate_side_effects (tree t)
2998 enum tree_code code = TREE_CODE (t);
2999 int len = TREE_OPERAND_LENGTH (t);
3000 int i;
3002 switch (TREE_CODE_CLASS (code))
3004 case tcc_expression:
3005 switch (code)
3007 case INIT_EXPR:
3008 case MODIFY_EXPR:
3009 case VA_ARG_EXPR:
3010 case PREDECREMENT_EXPR:
3011 case PREINCREMENT_EXPR:
3012 case POSTDECREMENT_EXPR:
3013 case POSTINCREMENT_EXPR:
3014 /* All of these have side-effects, no matter what their
3015 operands are. */
3016 return;
3018 default:
3019 break;
3021 /* Fall through. */
3023 case tcc_comparison: /* a comparison expression */
3024 case tcc_unary: /* a unary arithmetic expression */
3025 case tcc_binary: /* a binary arithmetic expression */
3026 case tcc_reference: /* a reference */
3027 case tcc_vl_exp: /* a function call */
3028 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
3029 for (i = 0; i < len; ++i)
3031 tree op = TREE_OPERAND (t, i);
3032 if (op && TREE_SIDE_EFFECTS (op))
3033 TREE_SIDE_EFFECTS (t) = 1;
3035 break;
3037 case tcc_constant:
3038 /* No side-effects. */
3039 return;
3041 default:
3042 gcc_unreachable ();
3046 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
3047 node *EXPR_P.
3049 compound_lval
3050 : min_lval '[' val ']'
3051 | min_lval '.' ID
3052 | compound_lval '[' val ']'
3053 | compound_lval '.' ID
3055 This is not part of the original SIMPLE definition, which separates
3056 array and member references, but it seems reasonable to handle them
3057 together. Also, this way we don't run into problems with union
3058 aliasing; gcc requires that for accesses through a union to alias, the
3059 union reference must be explicit, which was not always the case when we
3060 were splitting up array and member refs.
3062 PRE_P points to the sequence where side effects that must happen before
3063 *EXPR_P should be stored.
3065 POST_P points to the sequence where side effects that must happen after
3066 *EXPR_P should be stored. */
3068 static enum gimplify_status
3069 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3070 fallback_t fallback)
3072 tree *p;
3073 enum gimplify_status ret = GS_ALL_DONE, tret;
3074 int i;
3075 location_t loc = EXPR_LOCATION (*expr_p);
3076 tree expr = *expr_p;
3078 /* Create a stack of the subexpressions so later we can walk them in
3079 order from inner to outer. */
3080 auto_vec<tree, 10> expr_stack;
3082 /* We can handle anything that get_inner_reference can deal with. */
3083 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
3085 restart:
3086 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
3087 if (TREE_CODE (*p) == INDIRECT_REF)
3088 *p = fold_indirect_ref_loc (loc, *p);
3090 if (handled_component_p (*p))
3092 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
3093 additional COMPONENT_REFs. */
3094 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
3095 && gimplify_var_or_parm_decl (p) == GS_OK)
3096 goto restart;
3097 else
3098 break;
3100 expr_stack.safe_push (*p);
3103 gcc_assert (expr_stack.length ());
3105 /* Now EXPR_STACK is a stack of pointers to all the refs we've
3106 walked through and P points to the innermost expression.
3108 Java requires that we elaborated nodes in source order. That
3109 means we must gimplify the inner expression followed by each of
3110 the indices, in order. But we can't gimplify the inner
3111 expression until we deal with any variable bounds, sizes, or
3112 positions in order to deal with PLACEHOLDER_EXPRs.
3114 The base expression may contain a statement expression that
3115 has declarations used in size expressions, so has to be
3116 gimplified before gimplifying the size expressions.
3118 So we do this in three steps. First we deal with variable
3119 bounds, sizes, and positions, then we gimplify the base,
3120 then we deal with the annotations for any variables in the
3121 components and any indices, from left to right. */
3123 for (i = expr_stack.length () - 1; i >= 0; i--)
3125 tree t = expr_stack[i];
3127 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3129 /* Deal with the low bound and element type size and put them into
3130 the ARRAY_REF. If these values are set, they have already been
3131 gimplified. */
3132 if (TREE_OPERAND (t, 2) == NULL_TREE)
3134 tree low = unshare_expr (array_ref_low_bound (t));
3135 if (!is_gimple_min_invariant (low))
3137 TREE_OPERAND (t, 2) = low;
3141 if (TREE_OPERAND (t, 3) == NULL_TREE)
3143 tree elmt_size = array_ref_element_size (t);
3144 if (!is_gimple_min_invariant (elmt_size))
3146 elmt_size = unshare_expr (elmt_size);
3147 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
3148 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
3150 /* Divide the element size by the alignment of the element
3151 type (above). */
3152 elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR,
3153 elmt_size, factor);
3155 TREE_OPERAND (t, 3) = elmt_size;
3159 else if (TREE_CODE (t) == COMPONENT_REF)
3161 /* Set the field offset into T and gimplify it. */
3162 if (TREE_OPERAND (t, 2) == NULL_TREE)
3164 tree offset = component_ref_field_offset (t);
3165 if (!is_gimple_min_invariant (offset))
3167 offset = unshare_expr (offset);
3168 tree field = TREE_OPERAND (t, 1);
3169 tree factor
3170 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
3172 /* Divide the offset by its alignment. */
3173 offset = size_binop_loc (loc, EXACT_DIV_EXPR,
3174 offset, factor);
3176 TREE_OPERAND (t, 2) = offset;
3182 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3183 so as to match the min_lval predicate. Failure to do so may result
3184 in the creation of large aggregate temporaries. */
3185 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
3186 fallback | fb_lvalue);
3187 ret = MIN (ret, tret);
3189 /* Step 3: gimplify size expressions and the indices and operands of
3190 ARRAY_REF. During this loop we also remove any useless conversions. */
3192 for (; expr_stack.length () > 0; )
3194 tree t = expr_stack.pop ();
3196 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3198 /* Gimplify the low bound and element type size. */
3199 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3200 is_gimple_reg, fb_rvalue);
3201 ret = MIN (ret, tret);
3203 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
3204 is_gimple_reg, fb_rvalue);
3205 ret = MIN (ret, tret);
3207 /* Gimplify the dimension. */
3208 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
3209 is_gimple_val, fb_rvalue);
3210 ret = MIN (ret, tret);
3212 else if (TREE_CODE (t) == COMPONENT_REF)
3214 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3215 is_gimple_reg, fb_rvalue);
3216 ret = MIN (ret, tret);
3219 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
3221 /* The innermost expression P may have originally had
3222 TREE_SIDE_EFFECTS set which would have caused all the outer
3223 expressions in *EXPR_P leading to P to also have had
3224 TREE_SIDE_EFFECTS set. */
3225 recalculate_side_effects (t);
3228 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3229 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
3231 canonicalize_component_ref (expr_p);
3234 expr_stack.release ();
3236 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
3238 return ret;
3241 /* Gimplify the self modifying expression pointed to by EXPR_P
3242 (++, --, +=, -=).
3244 PRE_P points to the list where side effects that must happen before
3245 *EXPR_P should be stored.
3247 POST_P points to the list where side effects that must happen after
3248 *EXPR_P should be stored.
3250 WANT_VALUE is nonzero iff we want to use the value of this expression
3251 in another expression.
3253 ARITH_TYPE is the type the computation should be performed in. */
3255 enum gimplify_status
3256 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3257 bool want_value, tree arith_type)
3259 enum tree_code code;
3260 tree lhs, lvalue, rhs, t1;
3261 gimple_seq post = NULL, *orig_post_p = post_p;
3262 bool postfix;
3263 enum tree_code arith_code;
3264 enum gimplify_status ret;
3265 location_t loc = EXPR_LOCATION (*expr_p);
3267 code = TREE_CODE (*expr_p);
3269 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3270 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3272 /* Prefix or postfix? */
3273 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3274 /* Faster to treat as prefix if result is not used. */
3275 postfix = want_value;
3276 else
3277 postfix = false;
3279 /* For postfix, make sure the inner expression's post side effects
3280 are executed after side effects from this expression. */
3281 if (postfix)
3282 post_p = &post;
3284 /* Add or subtract? */
3285 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3286 arith_code = PLUS_EXPR;
3287 else
3288 arith_code = MINUS_EXPR;
3290 /* Gimplify the LHS into a GIMPLE lvalue. */
3291 lvalue = TREE_OPERAND (*expr_p, 0);
3292 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3293 if (ret == GS_ERROR)
3294 return ret;
3296 /* Extract the operands to the arithmetic operation. */
3297 lhs = lvalue;
3298 rhs = TREE_OPERAND (*expr_p, 1);
3300 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3301 that as the result value and in the postqueue operation. */
3302 if (postfix)
3304 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3305 if (ret == GS_ERROR)
3306 return ret;
3308 lhs = get_initialized_tmp_var (lhs, pre_p);
3311 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3312 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3314 rhs = convert_to_ptrofftype_loc (loc, rhs);
3315 if (arith_code == MINUS_EXPR)
3316 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3317 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3319 else
3320 t1 = fold_convert (TREE_TYPE (*expr_p),
3321 fold_build2 (arith_code, arith_type,
3322 fold_convert (arith_type, lhs),
3323 fold_convert (arith_type, rhs)));
3325 if (postfix)
3327 gimplify_assign (lvalue, t1, pre_p);
3328 gimplify_seq_add_seq (orig_post_p, post);
3329 *expr_p = lhs;
3330 return GS_ALL_DONE;
3332 else
3334 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3335 return GS_OK;
3339 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3341 static void
3342 maybe_with_size_expr (tree *expr_p)
3344 tree expr = *expr_p;
3345 tree type = TREE_TYPE (expr);
3346 tree size;
3348 /* If we've already wrapped this or the type is error_mark_node, we can't do
3349 anything. */
3350 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3351 || type == error_mark_node)
3352 return;
3354 /* If the size isn't known or is a constant, we have nothing to do. */
3355 size = TYPE_SIZE_UNIT (type);
3356 if (!size || poly_int_tree_p (size))
3357 return;
3359 /* Otherwise, make a WITH_SIZE_EXPR. */
3360 size = unshare_expr (size);
3361 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3362 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3365 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3366 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3367 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3368 gimplified to an SSA name. */
3370 enum gimplify_status
3371 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3372 bool allow_ssa)
3374 bool (*test) (tree);
3375 fallback_t fb;
3377 /* In general, we allow lvalues for function arguments to avoid
3378 extra overhead of copying large aggregates out of even larger
3379 aggregates into temporaries only to copy the temporaries to
3380 the argument list. Make optimizers happy by pulling out to
3381 temporaries those types that fit in registers. */
3382 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3383 test = is_gimple_val, fb = fb_rvalue;
3384 else
3386 test = is_gimple_lvalue, fb = fb_either;
3387 /* Also strip a TARGET_EXPR that would force an extra copy. */
3388 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3390 tree init = TARGET_EXPR_INITIAL (*arg_p);
3391 if (init
3392 && !VOID_TYPE_P (TREE_TYPE (init)))
3393 *arg_p = init;
3397 /* If this is a variable sized type, we must remember the size. */
3398 maybe_with_size_expr (arg_p);
3400 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3401 /* Make sure arguments have the same location as the function call
3402 itself. */
3403 protected_set_expr_location (*arg_p, call_location);
3405 /* There is a sequence point before a function call. Side effects in
3406 the argument list must occur before the actual call. So, when
3407 gimplifying arguments, force gimplify_expr to use an internal
3408 post queue which is then appended to the end of PRE_P. */
3409 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3412 /* Don't fold inside offloading or taskreg regions: it can break code by
3413 adding decl references that weren't in the source. We'll do it during
3414 omplower pass instead. */
3416 static bool
3417 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3419 struct gimplify_omp_ctx *ctx;
3420 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3421 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3422 return false;
3423 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3424 return false;
3425 /* Delay folding of builtins until the IL is in consistent state
3426 so the diagnostic machinery can do a better job. */
3427 if (gimple_call_builtin_p (gsi_stmt (*gsi)))
3428 return false;
3429 return fold_stmt (gsi);
3432 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3433 WANT_VALUE is true if the result of the call is desired. */
3435 static enum gimplify_status
3436 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3438 tree fndecl, parms, p, fnptrtype;
3439 enum gimplify_status ret;
3440 int i, nargs;
3441 gcall *call;
3442 bool builtin_va_start_p = false;
3443 location_t loc = EXPR_LOCATION (*expr_p);
3445 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3447 /* For reliable diagnostics during inlining, it is necessary that
3448 every call_expr be annotated with file and line. */
3449 if (! EXPR_HAS_LOCATION (*expr_p))
3450 SET_EXPR_LOCATION (*expr_p, input_location);
3452 /* Gimplify internal functions created in the FEs. */
3453 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3455 if (want_value)
3456 return GS_ALL_DONE;
3458 nargs = call_expr_nargs (*expr_p);
3459 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3460 auto_vec<tree> vargs (nargs);
3462 for (i = 0; i < nargs; i++)
3464 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3465 EXPR_LOCATION (*expr_p));
3466 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3469 gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3470 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3471 gimplify_seq_add_stmt (pre_p, call);
3472 return GS_ALL_DONE;
3475 /* This may be a call to a builtin function.
3477 Builtin function calls may be transformed into different
3478 (and more efficient) builtin function calls under certain
3479 circumstances. Unfortunately, gimplification can muck things
3480 up enough that the builtin expanders are not aware that certain
3481 transformations are still valid.
3483 So we attempt transformation/gimplification of the call before
3484 we gimplify the CALL_EXPR. At this time we do not manage to
3485 transform all calls in the same manner as the expanders do, but
3486 we do transform most of them. */
3487 fndecl = get_callee_fndecl (*expr_p);
3488 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3489 switch (DECL_FUNCTION_CODE (fndecl))
3491 CASE_BUILT_IN_ALLOCA:
3492 /* If the call has been built for a variable-sized object, then we
3493 want to restore the stack level when the enclosing BIND_EXPR is
3494 exited to reclaim the allocated space; otherwise, we precisely
3495 need to do the opposite and preserve the latest stack level. */
3496 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3497 gimplify_ctxp->save_stack = true;
3498 else
3499 gimplify_ctxp->keep_stack = true;
3500 break;
3502 case BUILT_IN_VA_START:
3504 builtin_va_start_p = TRUE;
3505 if (call_expr_nargs (*expr_p) < 2)
3507 error ("too few arguments to function %<va_start%>");
3508 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3509 return GS_OK;
3512 if (fold_builtin_next_arg (*expr_p, true))
3514 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3515 return GS_OK;
3517 break;
3520 case BUILT_IN_EH_RETURN:
3521 cfun->calls_eh_return = true;
3522 break;
3524 case BUILT_IN_CLEAR_PADDING:
3525 if (call_expr_nargs (*expr_p) == 1)
3527 /* Remember the original type of the argument in an internal
3528 dummy second argument, as in GIMPLE pointer conversions are
3529 useless. also mark this call as not for automatic initialization
3530 in the internal dummy third argument. */
3531 p = CALL_EXPR_ARG (*expr_p, 0);
3532 bool for_auto_init = false;
3533 *expr_p
3534 = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 3, p,
3535 build_zero_cst (TREE_TYPE (p)),
3536 build_int_cst (integer_type_node,
3537 (int) for_auto_init));
3538 return GS_OK;
3540 break;
3542 default:
3545 if (fndecl && fndecl_built_in_p (fndecl))
3547 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3548 if (new_tree && new_tree != *expr_p)
3550 /* There was a transformation of this call which computes the
3551 same value, but in a more efficient way. Return and try
3552 again. */
3553 *expr_p = new_tree;
3554 return GS_OK;
3558 /* Remember the original function pointer type. */
3559 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3561 if (flag_openmp
3562 && fndecl
3563 && cfun
3564 && (cfun->curr_properties & PROP_gimple_any) == 0)
3566 tree variant = omp_resolve_declare_variant (fndecl);
3567 if (variant != fndecl)
3568 CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
3571 /* There is a sequence point before the call, so any side effects in
3572 the calling expression must occur before the actual call. Force
3573 gimplify_expr to use an internal post queue. */
3574 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3575 is_gimple_call_addr, fb_rvalue);
3577 nargs = call_expr_nargs (*expr_p);
3579 /* Get argument types for verification. */
3580 fndecl = get_callee_fndecl (*expr_p);
3581 parms = NULL_TREE;
3582 if (fndecl)
3583 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3584 else
3585 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3587 if (fndecl && DECL_ARGUMENTS (fndecl))
3588 p = DECL_ARGUMENTS (fndecl);
3589 else if (parms)
3590 p = parms;
3591 else
3592 p = NULL_TREE;
3593 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3596 /* If the last argument is __builtin_va_arg_pack () and it is not
3597 passed as a named argument, decrease the number of CALL_EXPR
3598 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3599 if (!p
3600 && i < nargs
3601 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3603 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3604 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3606 if (last_arg_fndecl
3607 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3609 tree call = *expr_p;
3611 --nargs;
3612 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3613 CALL_EXPR_FN (call),
3614 nargs, CALL_EXPR_ARGP (call));
3616 /* Copy all CALL_EXPR flags, location and block, except
3617 CALL_EXPR_VA_ARG_PACK flag. */
3618 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3619 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3620 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3621 = CALL_EXPR_RETURN_SLOT_OPT (call);
3622 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3623 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3625 /* Set CALL_EXPR_VA_ARG_PACK. */
3626 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3630 /* If the call returns twice then after building the CFG the call
3631 argument computations will no longer dominate the call because
3632 we add an abnormal incoming edge to the call. So do not use SSA
3633 vars there. */
3634 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3636 /* Gimplify the function arguments. */
3637 if (nargs > 0)
3639 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3640 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3641 PUSH_ARGS_REVERSED ? i-- : i++)
3643 enum gimplify_status t;
3645 /* Avoid gimplifying the second argument to va_start, which needs to
3646 be the plain PARM_DECL. */
3647 if ((i != 1) || !builtin_va_start_p)
3649 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3650 EXPR_LOCATION (*expr_p), ! returns_twice);
3652 if (t == GS_ERROR)
3653 ret = GS_ERROR;
3658 /* Gimplify the static chain. */
3659 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3661 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3662 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3663 else
3665 enum gimplify_status t;
3666 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3667 EXPR_LOCATION (*expr_p), ! returns_twice);
3668 if (t == GS_ERROR)
3669 ret = GS_ERROR;
3673 /* Verify the function result. */
3674 if (want_value && fndecl
3675 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3677 error_at (loc, "using result of function returning %<void%>");
3678 ret = GS_ERROR;
3681 /* Try this again in case gimplification exposed something. */
3682 if (ret != GS_ERROR)
3684 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3686 if (new_tree && new_tree != *expr_p)
3688 /* There was a transformation of this call which computes the
3689 same value, but in a more efficient way. Return and try
3690 again. */
3691 *expr_p = new_tree;
3692 return GS_OK;
3695 else
3697 *expr_p = error_mark_node;
3698 return GS_ERROR;
3701 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3702 decl. This allows us to eliminate redundant or useless
3703 calls to "const" functions. */
3704 if (TREE_CODE (*expr_p) == CALL_EXPR)
3706 int flags = call_expr_flags (*expr_p);
3707 if (flags & (ECF_CONST | ECF_PURE)
3708 /* An infinite loop is considered a side effect. */
3709 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3710 TREE_SIDE_EFFECTS (*expr_p) = 0;
3713 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3714 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3715 form and delegate the creation of a GIMPLE_CALL to
3716 gimplify_modify_expr. This is always possible because when
3717 WANT_VALUE is true, the caller wants the result of this call into
3718 a temporary, which means that we will emit an INIT_EXPR in
3719 internal_get_tmp_var which will then be handled by
3720 gimplify_modify_expr. */
3721 if (!want_value)
3723 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3724 have to do is replicate it as a GIMPLE_CALL tuple. */
3725 gimple_stmt_iterator gsi;
3726 call = gimple_build_call_from_tree (*expr_p, fnptrtype);
3727 notice_special_calls (call);
3728 gimplify_seq_add_stmt (pre_p, call);
3729 gsi = gsi_last (*pre_p);
3730 maybe_fold_stmt (&gsi);
3731 *expr_p = NULL_TREE;
3733 else
3734 /* Remember the original function type. */
3735 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3736 CALL_EXPR_FN (*expr_p));
3738 return ret;
3741 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3742 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3744 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3745 condition is true or false, respectively. If null, we should generate
3746 our own to skip over the evaluation of this specific expression.
3748 LOCUS is the source location of the COND_EXPR.
3750 This function is the tree equivalent of do_jump.
3752 shortcut_cond_r should only be called by shortcut_cond_expr. */
3754 static tree
3755 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3756 location_t locus)
3758 tree local_label = NULL_TREE;
3759 tree t, expr = NULL;
3761 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3762 retain the shortcut semantics. Just insert the gotos here;
3763 shortcut_cond_expr will append the real blocks later. */
3764 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3766 location_t new_locus;
3768 /* Turn if (a && b) into
3770 if (a); else goto no;
3771 if (b) goto yes; else goto no;
3772 (no:) */
3774 if (false_label_p == NULL)
3775 false_label_p = &local_label;
3777 /* Keep the original source location on the first 'if'. */
3778 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3779 append_to_statement_list (t, &expr);
3781 /* Set the source location of the && on the second 'if'. */
3782 new_locus = rexpr_location (pred, locus);
3783 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3784 new_locus);
3785 append_to_statement_list (t, &expr);
3787 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3789 location_t new_locus;
3791 /* Turn if (a || b) into
3793 if (a) goto yes;
3794 if (b) goto yes; else goto no;
3795 (yes:) */
3797 if (true_label_p == NULL)
3798 true_label_p = &local_label;
3800 /* Keep the original source location on the first 'if'. */
3801 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3802 append_to_statement_list (t, &expr);
3804 /* Set the source location of the || on the second 'if'. */
3805 new_locus = rexpr_location (pred, locus);
3806 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3807 new_locus);
3808 append_to_statement_list (t, &expr);
3810 else if (TREE_CODE (pred) == COND_EXPR
3811 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3812 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3814 location_t new_locus;
3816 /* As long as we're messing with gotos, turn if (a ? b : c) into
3817 if (a)
3818 if (b) goto yes; else goto no;
3819 else
3820 if (c) goto yes; else goto no;
3822 Don't do this if one of the arms has void type, which can happen
3823 in C++ when the arm is throw. */
3825 /* Keep the original source location on the first 'if'. Set the source
3826 location of the ? on the second 'if'. */
3827 new_locus = rexpr_location (pred, locus);
3828 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3829 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3830 false_label_p, locus),
3831 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3832 false_label_p, new_locus));
3834 else
3836 expr = build3 (COND_EXPR, void_type_node, pred,
3837 build_and_jump (true_label_p),
3838 build_and_jump (false_label_p));
3839 SET_EXPR_LOCATION (expr, locus);
3842 if (local_label)
3844 t = build1 (LABEL_EXPR, void_type_node, local_label);
3845 append_to_statement_list (t, &expr);
3848 return expr;
3851 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3852 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3853 statement, if it is the last one. Otherwise, return NULL. */
3855 static tree
3856 find_goto (tree expr)
3858 if (!expr)
3859 return NULL_TREE;
3861 if (TREE_CODE (expr) == GOTO_EXPR)
3862 return expr;
3864 if (TREE_CODE (expr) != STATEMENT_LIST)
3865 return NULL_TREE;
3867 tree_stmt_iterator i = tsi_start (expr);
3869 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
3870 tsi_next (&i);
3872 if (!tsi_one_before_end_p (i))
3873 return NULL_TREE;
3875 return find_goto (tsi_stmt (i));
3878 /* Same as find_goto, except that it returns NULL if the destination
3879 is not a LABEL_DECL. */
3881 static inline tree
3882 find_goto_label (tree expr)
3884 tree dest = find_goto (expr);
3885 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
3886 return dest;
3887 return NULL_TREE;
3890 /* Given a conditional expression EXPR with short-circuit boolean
3891 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3892 predicate apart into the equivalent sequence of conditionals. */
3894 static tree
3895 shortcut_cond_expr (tree expr)
3897 tree pred = TREE_OPERAND (expr, 0);
3898 tree then_ = TREE_OPERAND (expr, 1);
3899 tree else_ = TREE_OPERAND (expr, 2);
3900 tree true_label, false_label, end_label, t;
3901 tree *true_label_p;
3902 tree *false_label_p;
3903 bool emit_end, emit_false, jump_over_else;
3904 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3905 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3907 /* First do simple transformations. */
3908 if (!else_se)
3910 /* If there is no 'else', turn
3911 if (a && b) then c
3912 into
3913 if (a) if (b) then c. */
3914 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3916 /* Keep the original source location on the first 'if'. */
3917 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3918 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3919 /* Set the source location of the && on the second 'if'. */
3920 if (rexpr_has_location (pred))
3921 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3922 then_ = shortcut_cond_expr (expr);
3923 then_se = then_ && TREE_SIDE_EFFECTS (then_);
3924 pred = TREE_OPERAND (pred, 0);
3925 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
3926 SET_EXPR_LOCATION (expr, locus);
3930 if (!then_se)
3932 /* If there is no 'then', turn
3933 if (a || b); else d
3934 into
3935 if (a); else if (b); else d. */
3936 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3938 /* Keep the original source location on the first 'if'. */
3939 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3940 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3941 /* Set the source location of the || on the second 'if'. */
3942 if (rexpr_has_location (pred))
3943 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3944 else_ = shortcut_cond_expr (expr);
3945 else_se = else_ && TREE_SIDE_EFFECTS (else_);
3946 pred = TREE_OPERAND (pred, 0);
3947 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
3948 SET_EXPR_LOCATION (expr, locus);
3952 /* If we're done, great. */
3953 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
3954 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
3955 return expr;
3957 /* Otherwise we need to mess with gotos. Change
3958 if (a) c; else d;
3960 if (a); else goto no;
3961 c; goto end;
3962 no: d; end:
3963 and recursively gimplify the condition. */
3965 true_label = false_label = end_label = NULL_TREE;
3967 /* If our arms just jump somewhere, hijack those labels so we don't
3968 generate jumps to jumps. */
3970 if (tree then_goto = find_goto_label (then_))
3972 true_label = GOTO_DESTINATION (then_goto);
3973 then_ = NULL;
3974 then_se = false;
3977 if (tree else_goto = find_goto_label (else_))
3979 false_label = GOTO_DESTINATION (else_goto);
3980 else_ = NULL;
3981 else_se = false;
3984 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3985 if (true_label)
3986 true_label_p = &true_label;
3987 else
3988 true_label_p = NULL;
3990 /* The 'else' branch also needs a label if it contains interesting code. */
3991 if (false_label || else_se)
3992 false_label_p = &false_label;
3993 else
3994 false_label_p = NULL;
3996 /* If there was nothing else in our arms, just forward the label(s). */
3997 if (!then_se && !else_se)
3998 return shortcut_cond_r (pred, true_label_p, false_label_p,
3999 EXPR_LOC_OR_LOC (expr, input_location));
4001 /* If our last subexpression already has a terminal label, reuse it. */
4002 if (else_se)
4003 t = expr_last (else_);
4004 else if (then_se)
4005 t = expr_last (then_);
4006 else
4007 t = NULL;
4008 if (t && TREE_CODE (t) == LABEL_EXPR)
4009 end_label = LABEL_EXPR_LABEL (t);
4011 /* If we don't care about jumping to the 'else' branch, jump to the end
4012 if the condition is false. */
4013 if (!false_label_p)
4014 false_label_p = &end_label;
4016 /* We only want to emit these labels if we aren't hijacking them. */
4017 emit_end = (end_label == NULL_TREE);
4018 emit_false = (false_label == NULL_TREE);
4020 /* We only emit the jump over the else clause if we have to--if the
4021 then clause may fall through. Otherwise we can wind up with a
4022 useless jump and a useless label at the end of gimplified code,
4023 which will cause us to think that this conditional as a whole
4024 falls through even if it doesn't. If we then inline a function
4025 which ends with such a condition, that can cause us to issue an
4026 inappropriate warning about control reaching the end of a
4027 non-void function. */
4028 jump_over_else = block_may_fallthru (then_);
4030 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
4031 EXPR_LOC_OR_LOC (expr, input_location));
4033 expr = NULL;
4034 append_to_statement_list (pred, &expr);
4036 append_to_statement_list (then_, &expr);
4037 if (else_se)
4039 if (jump_over_else)
4041 tree last = expr_last (expr);
4042 t = build_and_jump (&end_label);
4043 if (rexpr_has_location (last))
4044 SET_EXPR_LOCATION (t, rexpr_location (last));
4045 append_to_statement_list (t, &expr);
4047 if (emit_false)
4049 t = build1 (LABEL_EXPR, void_type_node, false_label);
4050 append_to_statement_list (t, &expr);
4052 append_to_statement_list (else_, &expr);
4054 if (emit_end && end_label)
4056 t = build1 (LABEL_EXPR, void_type_node, end_label);
4057 append_to_statement_list (t, &expr);
4060 return expr;
4063 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
4065 tree
4066 gimple_boolify (tree expr)
4068 tree type = TREE_TYPE (expr);
4069 location_t loc = EXPR_LOCATION (expr);
4071 if (TREE_CODE (expr) == NE_EXPR
4072 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
4073 && integer_zerop (TREE_OPERAND (expr, 1)))
4075 tree call = TREE_OPERAND (expr, 0);
4076 tree fn = get_callee_fndecl (call);
4078 /* For __builtin_expect ((long) (x), y) recurse into x as well
4079 if x is truth_value_p. */
4080 if (fn
4081 && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
4082 && call_expr_nargs (call) == 2)
4084 tree arg = CALL_EXPR_ARG (call, 0);
4085 if (arg)
4087 if (TREE_CODE (arg) == NOP_EXPR
4088 && TREE_TYPE (arg) == TREE_TYPE (call))
4089 arg = TREE_OPERAND (arg, 0);
4090 if (truth_value_p (TREE_CODE (arg)))
4092 arg = gimple_boolify (arg);
4093 CALL_EXPR_ARG (call, 0)
4094 = fold_convert_loc (loc, TREE_TYPE (call), arg);
4100 switch (TREE_CODE (expr))
4102 case TRUTH_AND_EXPR:
4103 case TRUTH_OR_EXPR:
4104 case TRUTH_XOR_EXPR:
4105 case TRUTH_ANDIF_EXPR:
4106 case TRUTH_ORIF_EXPR:
4107 /* Also boolify the arguments of truth exprs. */
4108 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
4109 /* FALLTHRU */
4111 case TRUTH_NOT_EXPR:
4112 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4114 /* These expressions always produce boolean results. */
4115 if (TREE_CODE (type) != BOOLEAN_TYPE)
4116 TREE_TYPE (expr) = boolean_type_node;
4117 return expr;
4119 case ANNOTATE_EXPR:
4120 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
4122 case annot_expr_ivdep_kind:
4123 case annot_expr_unroll_kind:
4124 case annot_expr_no_vector_kind:
4125 case annot_expr_vector_kind:
4126 case annot_expr_parallel_kind:
4127 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4128 if (TREE_CODE (type) != BOOLEAN_TYPE)
4129 TREE_TYPE (expr) = boolean_type_node;
4130 return expr;
4131 default:
4132 gcc_unreachable ();
4135 default:
4136 if (COMPARISON_CLASS_P (expr))
4138 /* There expressions always prduce boolean results. */
4139 if (TREE_CODE (type) != BOOLEAN_TYPE)
4140 TREE_TYPE (expr) = boolean_type_node;
4141 return expr;
4143 /* Other expressions that get here must have boolean values, but
4144 might need to be converted to the appropriate mode. */
4145 if (TREE_CODE (type) == BOOLEAN_TYPE)
4146 return expr;
4147 return fold_convert_loc (loc, boolean_type_node, expr);
4151 /* Given a conditional expression *EXPR_P without side effects, gimplify
4152 its operands. New statements are inserted to PRE_P. */
4154 static enum gimplify_status
4155 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
4157 tree expr = *expr_p, cond;
4158 enum gimplify_status ret, tret;
4159 enum tree_code code;
4161 cond = gimple_boolify (COND_EXPR_COND (expr));
4163 /* We need to handle && and || specially, as their gimplification
4164 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4165 code = TREE_CODE (cond);
4166 if (code == TRUTH_ANDIF_EXPR)
4167 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
4168 else if (code == TRUTH_ORIF_EXPR)
4169 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
4170 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
4171 COND_EXPR_COND (*expr_p) = cond;
4173 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
4174 is_gimple_val, fb_rvalue);
4175 ret = MIN (ret, tret);
4176 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
4177 is_gimple_val, fb_rvalue);
4179 return MIN (ret, tret);
4182 /* Return true if evaluating EXPR could trap.
4183 EXPR is GENERIC, while tree_could_trap_p can be called
4184 only on GIMPLE. */
4186 bool
4187 generic_expr_could_trap_p (tree expr)
4189 unsigned i, n;
4191 if (!expr || is_gimple_val (expr))
4192 return false;
4194 if (!EXPR_P (expr) || tree_could_trap_p (expr))
4195 return true;
4197 n = TREE_OPERAND_LENGTH (expr);
4198 for (i = 0; i < n; i++)
4199 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
4200 return true;
4202 return false;
4205 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4206 into
4208 if (p) if (p)
4209 t1 = a; a;
4210 else or else
4211 t1 = b; b;
4214 The second form is used when *EXPR_P is of type void.
4216 PRE_P points to the list where side effects that must happen before
4217 *EXPR_P should be stored. */
4219 static enum gimplify_status
4220 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
4222 tree expr = *expr_p;
4223 tree type = TREE_TYPE (expr);
4224 location_t loc = EXPR_LOCATION (expr);
4225 tree tmp, arm1, arm2;
4226 enum gimplify_status ret;
4227 tree label_true, label_false, label_cont;
4228 bool have_then_clause_p, have_else_clause_p;
4229 gcond *cond_stmt;
4230 enum tree_code pred_code;
4231 gimple_seq seq = NULL;
4233 /* If this COND_EXPR has a value, copy the values into a temporary within
4234 the arms. */
4235 if (!VOID_TYPE_P (type))
4237 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
4238 tree result;
4240 /* If either an rvalue is ok or we do not require an lvalue, create the
4241 temporary. But we cannot do that if the type is addressable. */
4242 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
4243 && !TREE_ADDRESSABLE (type))
4245 if (gimplify_ctxp->allow_rhs_cond_expr
4246 /* If either branch has side effects or could trap, it can't be
4247 evaluated unconditionally. */
4248 && !TREE_SIDE_EFFECTS (then_)
4249 && !generic_expr_could_trap_p (then_)
4250 && !TREE_SIDE_EFFECTS (else_)
4251 && !generic_expr_could_trap_p (else_))
4252 return gimplify_pure_cond_expr (expr_p, pre_p);
4254 tmp = create_tmp_var (type, "iftmp");
4255 result = tmp;
4258 /* Otherwise, only create and copy references to the values. */
4259 else
4261 type = build_pointer_type (type);
4263 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4264 then_ = build_fold_addr_expr_loc (loc, then_);
4266 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4267 else_ = build_fold_addr_expr_loc (loc, else_);
4269 expr
4270 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
4272 tmp = create_tmp_var (type, "iftmp");
4273 result = build_simple_mem_ref_loc (loc, tmp);
4276 /* Build the new then clause, `tmp = then_;'. But don't build the
4277 assignment if the value is void; in C++ it can be if it's a throw. */
4278 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4279 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
4281 /* Similarly, build the new else clause, `tmp = else_;'. */
4282 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4283 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
4285 TREE_TYPE (expr) = void_type_node;
4286 recalculate_side_effects (expr);
4288 /* Move the COND_EXPR to the prequeue. */
4289 gimplify_stmt (&expr, pre_p);
4291 *expr_p = result;
4292 return GS_ALL_DONE;
4295 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4296 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4297 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4298 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4300 /* Make sure the condition has BOOLEAN_TYPE. */
4301 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4303 /* Break apart && and || conditions. */
4304 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4305 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4307 expr = shortcut_cond_expr (expr);
4309 if (expr != *expr_p)
4311 *expr_p = expr;
4313 /* We can't rely on gimplify_expr to re-gimplify the expanded
4314 form properly, as cleanups might cause the target labels to be
4315 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4316 set up a conditional context. */
4317 gimple_push_condition ();
4318 gimplify_stmt (expr_p, &seq);
4319 gimple_pop_condition (pre_p);
4320 gimple_seq_add_seq (pre_p, seq);
4322 return GS_ALL_DONE;
4326 /* Now do the normal gimplification. */
4328 /* Gimplify condition. */
4329 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
4330 is_gimple_condexpr_for_cond, fb_rvalue);
4331 if (ret == GS_ERROR)
4332 return GS_ERROR;
4333 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4335 gimple_push_condition ();
4337 have_then_clause_p = have_else_clause_p = false;
4338 label_true = find_goto_label (TREE_OPERAND (expr, 1));
4339 if (label_true
4340 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4341 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4342 have different locations, otherwise we end up with incorrect
4343 location information on the branches. */
4344 && (optimize
4345 || !EXPR_HAS_LOCATION (expr)
4346 || !rexpr_has_location (label_true)
4347 || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4349 have_then_clause_p = true;
4350 label_true = GOTO_DESTINATION (label_true);
4352 else
4353 label_true = create_artificial_label (UNKNOWN_LOCATION);
4354 label_false = find_goto_label (TREE_OPERAND (expr, 2));
4355 if (label_false
4356 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4357 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4358 have different locations, otherwise we end up with incorrect
4359 location information on the branches. */
4360 && (optimize
4361 || !EXPR_HAS_LOCATION (expr)
4362 || !rexpr_has_location (label_false)
4363 || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4365 have_else_clause_p = true;
4366 label_false = GOTO_DESTINATION (label_false);
4368 else
4369 label_false = create_artificial_label (UNKNOWN_LOCATION);
4371 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4372 &arm2);
4373 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4374 label_false);
4375 gimple_set_location (cond_stmt, EXPR_LOCATION (expr));
4376 copy_warning (cond_stmt, COND_EXPR_COND (expr));
4377 gimplify_seq_add_stmt (&seq, cond_stmt);
4378 gimple_stmt_iterator gsi = gsi_last (seq);
4379 maybe_fold_stmt (&gsi);
4381 label_cont = NULL_TREE;
4382 if (!have_then_clause_p)
4384 /* For if (...) {} else { code; } put label_true after
4385 the else block. */
4386 if (TREE_OPERAND (expr, 1) == NULL_TREE
4387 && !have_else_clause_p
4388 && TREE_OPERAND (expr, 2) != NULL_TREE)
4389 label_cont = label_true;
4390 else
4392 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4393 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4394 /* For if (...) { code; } else {} or
4395 if (...) { code; } else goto label; or
4396 if (...) { code; return; } else { ... }
4397 label_cont isn't needed. */
4398 if (!have_else_clause_p
4399 && TREE_OPERAND (expr, 2) != NULL_TREE
4400 && gimple_seq_may_fallthru (seq))
4402 gimple *g;
4403 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4405 g = gimple_build_goto (label_cont);
4407 /* GIMPLE_COND's are very low level; they have embedded
4408 gotos. This particular embedded goto should not be marked
4409 with the location of the original COND_EXPR, as it would
4410 correspond to the COND_EXPR's condition, not the ELSE or the
4411 THEN arms. To avoid marking it with the wrong location, flag
4412 it as "no location". */
4413 gimple_set_do_not_emit_location (g);
4415 gimplify_seq_add_stmt (&seq, g);
4419 if (!have_else_clause_p)
4421 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4422 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4424 if (label_cont)
4425 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4427 gimple_pop_condition (pre_p);
4428 gimple_seq_add_seq (pre_p, seq);
4430 if (ret == GS_ERROR)
4431 ; /* Do nothing. */
4432 else if (have_then_clause_p || have_else_clause_p)
4433 ret = GS_ALL_DONE;
4434 else
4436 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4437 expr = TREE_OPERAND (expr, 0);
4438 gimplify_stmt (&expr, pre_p);
4441 *expr_p = NULL;
4442 return ret;
4445 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4446 to be marked addressable.
4448 We cannot rely on such an expression being directly markable if a temporary
4449 has been created by the gimplification. In this case, we create another
4450 temporary and initialize it with a copy, which will become a store after we
4451 mark it addressable. This can happen if the front-end passed us something
4452 that it could not mark addressable yet, like a Fortran pass-by-reference
4453 parameter (int) floatvar. */
4455 static void
4456 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4458 while (handled_component_p (*expr_p))
4459 expr_p = &TREE_OPERAND (*expr_p, 0);
4460 if (is_gimple_reg (*expr_p))
4462 /* Do not allow an SSA name as the temporary. */
4463 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
4464 DECL_NOT_GIMPLE_REG_P (var) = 1;
4465 *expr_p = var;
4469 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4470 a call to __builtin_memcpy. */
4472 static enum gimplify_status
4473 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4474 gimple_seq *seq_p)
4476 tree t, to, to_ptr, from, from_ptr;
4477 gcall *gs;
4478 location_t loc = EXPR_LOCATION (*expr_p);
4480 to = TREE_OPERAND (*expr_p, 0);
4481 from = TREE_OPERAND (*expr_p, 1);
4483 /* Mark the RHS addressable. Beware that it may not be possible to do so
4484 directly if a temporary has been created by the gimplification. */
4485 prepare_gimple_addressable (&from, seq_p);
4487 mark_addressable (from);
4488 from_ptr = build_fold_addr_expr_loc (loc, from);
4489 gimplify_arg (&from_ptr, seq_p, loc);
4491 mark_addressable (to);
4492 to_ptr = build_fold_addr_expr_loc (loc, to);
4493 gimplify_arg (&to_ptr, seq_p, loc);
4495 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4497 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4498 gimple_call_set_alloca_for_var (gs, true);
4500 if (want_value)
4502 /* tmp = memcpy() */
4503 t = create_tmp_var (TREE_TYPE (to_ptr));
4504 gimple_call_set_lhs (gs, t);
4505 gimplify_seq_add_stmt (seq_p, gs);
4507 *expr_p = build_simple_mem_ref (t);
4508 return GS_ALL_DONE;
4511 gimplify_seq_add_stmt (seq_p, gs);
4512 *expr_p = NULL;
4513 return GS_ALL_DONE;
4516 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4517 a call to __builtin_memset. In this case we know that the RHS is
4518 a CONSTRUCTOR with an empty element list. */
4520 static enum gimplify_status
4521 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4522 gimple_seq *seq_p)
4524 tree t, from, to, to_ptr;
4525 gcall *gs;
4526 location_t loc = EXPR_LOCATION (*expr_p);
4528 /* Assert our assumptions, to abort instead of producing wrong code
4529 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4530 not be immediately exposed. */
4531 from = TREE_OPERAND (*expr_p, 1);
4532 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4533 from = TREE_OPERAND (from, 0);
4535 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4536 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4538 /* Now proceed. */
4539 to = TREE_OPERAND (*expr_p, 0);
4541 to_ptr = build_fold_addr_expr_loc (loc, to);
4542 gimplify_arg (&to_ptr, seq_p, loc);
4543 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4545 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4547 if (want_value)
4549 /* tmp = memset() */
4550 t = create_tmp_var (TREE_TYPE (to_ptr));
4551 gimple_call_set_lhs (gs, t);
4552 gimplify_seq_add_stmt (seq_p, gs);
4554 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4555 return GS_ALL_DONE;
4558 gimplify_seq_add_stmt (seq_p, gs);
4559 *expr_p = NULL;
4560 return GS_ALL_DONE;
4563 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4564 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4565 assignment. Return non-null if we detect a potential overlap. */
4567 struct gimplify_init_ctor_preeval_data
4569 /* The base decl of the lhs object. May be NULL, in which case we
4570 have to assume the lhs is indirect. */
4571 tree lhs_base_decl;
4573 /* The alias set of the lhs object. */
4574 alias_set_type lhs_alias_set;
4577 static tree
4578 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4580 struct gimplify_init_ctor_preeval_data *data
4581 = (struct gimplify_init_ctor_preeval_data *) xdata;
4582 tree t = *tp;
4584 /* If we find the base object, obviously we have overlap. */
4585 if (data->lhs_base_decl == t)
4586 return t;
4588 /* If the constructor component is indirect, determine if we have a
4589 potential overlap with the lhs. The only bits of information we
4590 have to go on at this point are addressability and alias sets. */
4591 if ((INDIRECT_REF_P (t)
4592 || TREE_CODE (t) == MEM_REF)
4593 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4594 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4595 return t;
4597 /* If the constructor component is a call, determine if it can hide a
4598 potential overlap with the lhs through an INDIRECT_REF like above.
4599 ??? Ugh - this is completely broken. In fact this whole analysis
4600 doesn't look conservative. */
4601 if (TREE_CODE (t) == CALL_EXPR)
4603 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4605 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4606 if (POINTER_TYPE_P (TREE_VALUE (type))
4607 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4608 && alias_sets_conflict_p (data->lhs_alias_set,
4609 get_alias_set
4610 (TREE_TYPE (TREE_VALUE (type)))))
4611 return t;
4614 if (IS_TYPE_OR_DECL_P (t))
4615 *walk_subtrees = 0;
4616 return NULL;
4619 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4620 force values that overlap with the lhs (as described by *DATA)
4621 into temporaries. */
4623 static void
4624 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4625 struct gimplify_init_ctor_preeval_data *data)
4627 enum gimplify_status one;
4629 /* If the value is constant, then there's nothing to pre-evaluate. */
4630 if (TREE_CONSTANT (*expr_p))
4632 /* Ensure it does not have side effects, it might contain a reference to
4633 the object we're initializing. */
4634 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4635 return;
4638 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4639 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4640 return;
4642 /* Recurse for nested constructors. */
4643 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4645 unsigned HOST_WIDE_INT ix;
4646 constructor_elt *ce;
4647 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4649 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4650 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4652 return;
4655 /* If this is a variable sized type, we must remember the size. */
4656 maybe_with_size_expr (expr_p);
4658 /* Gimplify the constructor element to something appropriate for the rhs
4659 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4660 the gimplifier will consider this a store to memory. Doing this
4661 gimplification now means that we won't have to deal with complicated
4662 language-specific trees, nor trees like SAVE_EXPR that can induce
4663 exponential search behavior. */
4664 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4665 if (one == GS_ERROR)
4667 *expr_p = NULL;
4668 return;
4671 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4672 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4673 always be true for all scalars, since is_gimple_mem_rhs insists on a
4674 temporary variable for them. */
4675 if (DECL_P (*expr_p))
4676 return;
4678 /* If this is of variable size, we have no choice but to assume it doesn't
4679 overlap since we can't make a temporary for it. */
4680 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4681 return;
4683 /* Otherwise, we must search for overlap ... */
4684 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4685 return;
4687 /* ... and if found, force the value into a temporary. */
4688 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4691 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4692 a RANGE_EXPR in a CONSTRUCTOR for an array.
4694 var = lower;
4695 loop_entry:
4696 object[var] = value;
4697 if (var == upper)
4698 goto loop_exit;
4699 var = var + 1;
4700 goto loop_entry;
4701 loop_exit:
4703 We increment var _after_ the loop exit check because we might otherwise
4704 fail if upper == TYPE_MAX_VALUE (type for upper).
4706 Note that we never have to deal with SAVE_EXPRs here, because this has
4707 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4709 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4710 gimple_seq *, bool);
4712 static void
4713 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4714 tree value, tree array_elt_type,
4715 gimple_seq *pre_p, bool cleared)
4717 tree loop_entry_label, loop_exit_label, fall_thru_label;
4718 tree var, var_type, cref, tmp;
4720 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4721 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4722 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4724 /* Create and initialize the index variable. */
4725 var_type = TREE_TYPE (upper);
4726 var = create_tmp_var (var_type);
4727 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4729 /* Add the loop entry label. */
4730 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4732 /* Build the reference. */
4733 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4734 var, NULL_TREE, NULL_TREE);
4736 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4737 the store. Otherwise just assign value to the reference. */
4739 if (TREE_CODE (value) == CONSTRUCTOR)
4740 /* NB we might have to call ourself recursively through
4741 gimplify_init_ctor_eval if the value is a constructor. */
4742 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4743 pre_p, cleared);
4744 else
4746 if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue)
4747 != GS_ERROR)
4748 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4751 /* We exit the loop when the index var is equal to the upper bound. */
4752 gimplify_seq_add_stmt (pre_p,
4753 gimple_build_cond (EQ_EXPR, var, upper,
4754 loop_exit_label, fall_thru_label));
4756 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4758 /* Otherwise, increment the index var... */
4759 tmp = build2 (PLUS_EXPR, var_type, var,
4760 fold_convert (var_type, integer_one_node));
4761 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4763 /* ...and jump back to the loop entry. */
4764 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4766 /* Add the loop exit label. */
4767 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4770 /* A subroutine of gimplify_init_constructor. Generate individual
4771 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4772 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4773 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4774 zeroed first. */
4776 static void
4777 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4778 gimple_seq *pre_p, bool cleared)
4780 tree array_elt_type = NULL;
4781 unsigned HOST_WIDE_INT ix;
4782 tree purpose, value;
4784 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4785 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4787 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4789 tree cref;
4791 /* NULL values are created above for gimplification errors. */
4792 if (value == NULL)
4793 continue;
4795 if (cleared && initializer_zerop (value))
4796 continue;
4798 /* ??? Here's to hoping the front end fills in all of the indices,
4799 so we don't have to figure out what's missing ourselves. */
4800 gcc_assert (purpose);
4802 /* Skip zero-sized fields, unless value has side-effects. This can
4803 happen with calls to functions returning a empty type, which
4804 we shouldn't discard. As a number of downstream passes don't
4805 expect sets of empty type fields, we rely on the gimplification of
4806 the MODIFY_EXPR we make below to drop the assignment statement. */
4807 if (!TREE_SIDE_EFFECTS (value)
4808 && TREE_CODE (purpose) == FIELD_DECL
4809 && is_empty_type (TREE_TYPE (purpose)))
4810 continue;
4812 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4813 whole range. */
4814 if (TREE_CODE (purpose) == RANGE_EXPR)
4816 tree lower = TREE_OPERAND (purpose, 0);
4817 tree upper = TREE_OPERAND (purpose, 1);
4819 /* If the lower bound is equal to upper, just treat it as if
4820 upper was the index. */
4821 if (simple_cst_equal (lower, upper))
4822 purpose = upper;
4823 else
4825 gimplify_init_ctor_eval_range (object, lower, upper, value,
4826 array_elt_type, pre_p, cleared);
4827 continue;
4831 if (array_elt_type)
4833 /* Do not use bitsizetype for ARRAY_REF indices. */
4834 if (TYPE_DOMAIN (TREE_TYPE (object)))
4835 purpose
4836 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4837 purpose);
4838 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4839 purpose, NULL_TREE, NULL_TREE);
4841 else
4843 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4844 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4845 unshare_expr (object), purpose, NULL_TREE);
4848 if (TREE_CODE (value) == CONSTRUCTOR
4849 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4850 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4851 pre_p, cleared);
4852 else
4854 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4855 gimplify_and_add (init, pre_p);
4856 ggc_free (init);
4861 /* Return the appropriate RHS predicate for this LHS. */
4863 gimple_predicate
4864 rhs_predicate_for (tree lhs)
4866 if (is_gimple_reg (lhs))
4867 return is_gimple_reg_rhs_or_call;
4868 else
4869 return is_gimple_mem_rhs_or_call;
4872 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4873 before the LHS has been gimplified. */
4875 static gimple_predicate
4876 initial_rhs_predicate_for (tree lhs)
4878 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4879 return is_gimple_reg_rhs_or_call;
4880 else
4881 return is_gimple_mem_rhs_or_call;
4884 /* Gimplify a C99 compound literal expression. This just means adding
4885 the DECL_EXPR before the current statement and using its anonymous
4886 decl instead. */
4888 static enum gimplify_status
4889 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
4890 bool (*gimple_test_f) (tree),
4891 fallback_t fallback)
4893 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
4894 tree decl = DECL_EXPR_DECL (decl_s);
4895 tree init = DECL_INITIAL (decl);
4896 /* Mark the decl as addressable if the compound literal
4897 expression is addressable now, otherwise it is marked too late
4898 after we gimplify the initialization expression. */
4899 if (TREE_ADDRESSABLE (*expr_p))
4900 TREE_ADDRESSABLE (decl) = 1;
4901 /* Otherwise, if we don't need an lvalue and have a literal directly
4902 substitute it. Check if it matches the gimple predicate, as
4903 otherwise we'd generate a new temporary, and we can as well just
4904 use the decl we already have. */
4905 else if (!TREE_ADDRESSABLE (decl)
4906 && !TREE_THIS_VOLATILE (decl)
4907 && init
4908 && (fallback & fb_lvalue) == 0
4909 && gimple_test_f (init))
4911 *expr_p = init;
4912 return GS_OK;
4915 /* If the decl is not addressable, then it is being used in some
4916 expression or on the right hand side of a statement, and it can
4917 be put into a readonly data section. */
4918 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
4919 TREE_READONLY (decl) = 1;
4921 /* This decl isn't mentioned in the enclosing block, so add it to the
4922 list of temps. FIXME it seems a bit of a kludge to say that
4923 anonymous artificial vars aren't pushed, but everything else is. */
4924 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
4925 gimple_add_tmp_var (decl);
4927 gimplify_and_add (decl_s, pre_p);
4928 *expr_p = decl;
4929 return GS_OK;
4932 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4933 return a new CONSTRUCTOR if something changed. */
4935 static tree
4936 optimize_compound_literals_in_ctor (tree orig_ctor)
4938 tree ctor = orig_ctor;
4939 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
4940 unsigned int idx, num = vec_safe_length (elts);
4942 for (idx = 0; idx < num; idx++)
4944 tree value = (*elts)[idx].value;
4945 tree newval = value;
4946 if (TREE_CODE (value) == CONSTRUCTOR)
4947 newval = optimize_compound_literals_in_ctor (value);
4948 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
4950 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
4951 tree decl = DECL_EXPR_DECL (decl_s);
4952 tree init = DECL_INITIAL (decl);
4954 if (!TREE_ADDRESSABLE (value)
4955 && !TREE_ADDRESSABLE (decl)
4956 && init
4957 && TREE_CODE (init) == CONSTRUCTOR)
4958 newval = optimize_compound_literals_in_ctor (init);
4960 if (newval == value)
4961 continue;
4963 if (ctor == orig_ctor)
4965 ctor = copy_node (orig_ctor);
4966 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
4967 elts = CONSTRUCTOR_ELTS (ctor);
4969 (*elts)[idx].value = newval;
4971 return ctor;
4974 /* A subroutine of gimplify_modify_expr. Break out elements of a
4975 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4977 Note that we still need to clear any elements that don't have explicit
4978 initializers, so if not all elements are initialized we keep the
4979 original MODIFY_EXPR, we just remove all of the constructor elements.
4981 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4982 GS_ERROR if we would have to create a temporary when gimplifying
4983 this constructor. Otherwise, return GS_OK.
4985 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4987 static enum gimplify_status
4988 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4989 bool want_value, bool notify_temp_creation)
4991 tree object, ctor, type;
4992 enum gimplify_status ret;
4993 vec<constructor_elt, va_gc> *elts;
4994 bool cleared = false;
4995 bool is_empty_ctor = false;
4996 bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR);
4998 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
5000 if (!notify_temp_creation)
5002 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5003 is_gimple_lvalue, fb_lvalue);
5004 if (ret == GS_ERROR)
5005 return ret;
5008 object = TREE_OPERAND (*expr_p, 0);
5009 ctor = TREE_OPERAND (*expr_p, 1)
5010 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
5011 type = TREE_TYPE (ctor);
5012 elts = CONSTRUCTOR_ELTS (ctor);
5013 ret = GS_ALL_DONE;
5015 switch (TREE_CODE (type))
5017 case RECORD_TYPE:
5018 case UNION_TYPE:
5019 case QUAL_UNION_TYPE:
5020 case ARRAY_TYPE:
5022 /* Use readonly data for initializers of this or smaller size
5023 regardless of the num_nonzero_elements / num_unique_nonzero_elements
5024 ratio. */
5025 const HOST_WIDE_INT min_unique_size = 64;
5026 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
5027 is smaller than this, use readonly data. */
5028 const int unique_nonzero_ratio = 8;
5029 /* True if a single access of the object must be ensured. This is the
5030 case if the target is volatile, the type is non-addressable and more
5031 than one field need to be assigned. */
5032 const bool ensure_single_access
5033 = TREE_THIS_VOLATILE (object)
5034 && !TREE_ADDRESSABLE (type)
5035 && vec_safe_length (elts) > 1;
5036 struct gimplify_init_ctor_preeval_data preeval_data;
5037 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
5038 HOST_WIDE_INT num_unique_nonzero_elements;
5039 bool complete_p, valid_const_initializer;
5041 /* Aggregate types must lower constructors to initialization of
5042 individual elements. The exception is that a CONSTRUCTOR node
5043 with no elements indicates zero-initialization of the whole. */
5044 if (vec_safe_is_empty (elts))
5046 if (notify_temp_creation)
5047 return GS_OK;
5048 is_empty_ctor = true;
5049 break;
5052 /* Fetch information about the constructor to direct later processing.
5053 We might want to make static versions of it in various cases, and
5054 can only do so if it known to be a valid constant initializer. */
5055 valid_const_initializer
5056 = categorize_ctor_elements (ctor, &num_nonzero_elements,
5057 &num_unique_nonzero_elements,
5058 &num_ctor_elements, &complete_p);
5060 /* If a const aggregate variable is being initialized, then it
5061 should never be a lose to promote the variable to be static. */
5062 if (valid_const_initializer
5063 && num_nonzero_elements > 1
5064 && TREE_READONLY (object)
5065 && VAR_P (object)
5066 && !DECL_REGISTER (object)
5067 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))
5068 /* For ctors that have many repeated nonzero elements
5069 represented through RANGE_EXPRs, prefer initializing
5070 those through runtime loops over copies of large amounts
5071 of data from readonly data section. */
5072 && (num_unique_nonzero_elements
5073 > num_nonzero_elements / unique_nonzero_ratio
5074 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
5075 <= (unsigned HOST_WIDE_INT) min_unique_size)))
5077 if (notify_temp_creation)
5078 return GS_ERROR;
5080 DECL_INITIAL (object) = ctor;
5081 TREE_STATIC (object) = 1;
5082 if (!DECL_NAME (object))
5083 DECL_NAME (object) = create_tmp_var_name ("C");
5084 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
5086 /* ??? C++ doesn't automatically append a .<number> to the
5087 assembler name, and even when it does, it looks at FE private
5088 data structures to figure out what that number should be,
5089 which are not set for this variable. I suppose this is
5090 important for local statics for inline functions, which aren't
5091 "local" in the object file sense. So in order to get a unique
5092 TU-local symbol, we must invoke the lhd version now. */
5093 lhd_set_decl_assembler_name (object);
5095 *expr_p = NULL_TREE;
5096 break;
5099 /* If there are "lots" of initialized elements, even discounting
5100 those that are not address constants (and thus *must* be
5101 computed at runtime), then partition the constructor into
5102 constant and non-constant parts. Block copy the constant
5103 parts in, then generate code for the non-constant parts. */
5104 /* TODO. There's code in cp/typeck.c to do this. */
5106 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
5107 /* store_constructor will ignore the clearing of variable-sized
5108 objects. Initializers for such objects must explicitly set
5109 every field that needs to be set. */
5110 cleared = false;
5111 else if (!complete_p)
5112 /* If the constructor isn't complete, clear the whole object
5113 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
5115 ??? This ought not to be needed. For any element not present
5116 in the initializer, we should simply set them to zero. Except
5117 we'd need to *find* the elements that are not present, and that
5118 requires trickery to avoid quadratic compile-time behavior in
5119 large cases or excessive memory use in small cases. */
5120 cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
5121 else if (num_ctor_elements - num_nonzero_elements
5122 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
5123 && num_nonzero_elements < num_ctor_elements / 4)
5124 /* If there are "lots" of zeros, it's more efficient to clear
5125 the memory and then set the nonzero elements. */
5126 cleared = true;
5127 else if (ensure_single_access && num_nonzero_elements == 0)
5128 /* If a single access to the target must be ensured and all elements
5129 are zero, then it's optimal to clear whatever their number. */
5130 cleared = true;
5131 else
5132 cleared = false;
5134 /* If there are "lots" of initialized elements, and all of them
5135 are valid address constants, then the entire initializer can
5136 be dropped to memory, and then memcpy'd out. Don't do this
5137 for sparse arrays, though, as it's more efficient to follow
5138 the standard CONSTRUCTOR behavior of memset followed by
5139 individual element initialization. Also don't do this for small
5140 all-zero initializers (which aren't big enough to merit
5141 clearing), and don't try to make bitwise copies of
5142 TREE_ADDRESSABLE types. */
5143 if (valid_const_initializer
5144 && complete_p
5145 && !(cleared || num_nonzero_elements == 0)
5146 && !TREE_ADDRESSABLE (type))
5148 HOST_WIDE_INT size = int_size_in_bytes (type);
5149 unsigned int align;
5151 /* ??? We can still get unbounded array types, at least
5152 from the C++ front end. This seems wrong, but attempt
5153 to work around it for now. */
5154 if (size < 0)
5156 size = int_size_in_bytes (TREE_TYPE (object));
5157 if (size >= 0)
5158 TREE_TYPE (ctor) = type = TREE_TYPE (object);
5161 /* Find the maximum alignment we can assume for the object. */
5162 /* ??? Make use of DECL_OFFSET_ALIGN. */
5163 if (DECL_P (object))
5164 align = DECL_ALIGN (object);
5165 else
5166 align = TYPE_ALIGN (type);
5168 /* Do a block move either if the size is so small as to make
5169 each individual move a sub-unit move on average, or if it
5170 is so large as to make individual moves inefficient. */
5171 if (size > 0
5172 && num_nonzero_elements > 1
5173 /* For ctors that have many repeated nonzero elements
5174 represented through RANGE_EXPRs, prefer initializing
5175 those through runtime loops over copies of large amounts
5176 of data from readonly data section. */
5177 && (num_unique_nonzero_elements
5178 > num_nonzero_elements / unique_nonzero_ratio
5179 || size <= min_unique_size)
5180 && (size < num_nonzero_elements
5181 || !can_move_by_pieces (size, align)))
5183 if (notify_temp_creation)
5184 return GS_ERROR;
5186 walk_tree (&ctor, force_labels_r, NULL, NULL);
5187 ctor = tree_output_constant_def (ctor);
5188 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
5189 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
5190 TREE_OPERAND (*expr_p, 1) = ctor;
5192 /* This is no longer an assignment of a CONSTRUCTOR, but
5193 we still may have processing to do on the LHS. So
5194 pretend we didn't do anything here to let that happen. */
5195 return GS_UNHANDLED;
5199 /* If a single access to the target must be ensured and there are
5200 nonzero elements or the zero elements are not assigned en masse,
5201 initialize the target from a temporary. */
5202 if (ensure_single_access && (num_nonzero_elements > 0 || !cleared))
5204 if (notify_temp_creation)
5205 return GS_ERROR;
5207 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
5208 TREE_OPERAND (*expr_p, 0) = temp;
5209 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
5210 *expr_p,
5211 build2 (MODIFY_EXPR, void_type_node,
5212 object, temp));
5213 return GS_OK;
5216 if (notify_temp_creation)
5217 return GS_OK;
5219 /* If there are nonzero elements and if needed, pre-evaluate to capture
5220 elements overlapping with the lhs into temporaries. We must do this
5221 before clearing to fetch the values before they are zeroed-out. */
5222 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
5224 preeval_data.lhs_base_decl = get_base_address (object);
5225 if (!DECL_P (preeval_data.lhs_base_decl))
5226 preeval_data.lhs_base_decl = NULL;
5227 preeval_data.lhs_alias_set = get_alias_set (object);
5229 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
5230 pre_p, post_p, &preeval_data);
5233 bool ctor_has_side_effects_p
5234 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
5236 if (cleared)
5238 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5239 Note that we still have to gimplify, in order to handle the
5240 case of variable sized types. Avoid shared tree structures. */
5241 CONSTRUCTOR_ELTS (ctor) = NULL;
5242 TREE_SIDE_EFFECTS (ctor) = 0;
5243 object = unshare_expr (object);
5244 gimplify_stmt (expr_p, pre_p);
5247 /* If we have not block cleared the object, or if there are nonzero
5248 elements in the constructor, or if the constructor has side effects,
5249 add assignments to the individual scalar fields of the object. */
5250 if (!cleared
5251 || num_nonzero_elements > 0
5252 || ctor_has_side_effects_p)
5253 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
5255 *expr_p = NULL_TREE;
5257 break;
5259 case COMPLEX_TYPE:
5261 tree r, i;
5263 if (notify_temp_creation)
5264 return GS_OK;
5266 /* Extract the real and imaginary parts out of the ctor. */
5267 gcc_assert (elts->length () == 2);
5268 r = (*elts)[0].value;
5269 i = (*elts)[1].value;
5270 if (r == NULL || i == NULL)
5272 tree zero = build_zero_cst (TREE_TYPE (type));
5273 if (r == NULL)
5274 r = zero;
5275 if (i == NULL)
5276 i = zero;
5279 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5280 represent creation of a complex value. */
5281 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
5283 ctor = build_complex (type, r, i);
5284 TREE_OPERAND (*expr_p, 1) = ctor;
5286 else
5288 ctor = build2 (COMPLEX_EXPR, type, r, i);
5289 TREE_OPERAND (*expr_p, 1) = ctor;
5290 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
5291 pre_p,
5292 post_p,
5293 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
5294 fb_rvalue);
5297 break;
5299 case VECTOR_TYPE:
5301 unsigned HOST_WIDE_INT ix;
5302 constructor_elt *ce;
5304 if (notify_temp_creation)
5305 return GS_OK;
5307 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5308 if (TREE_CONSTANT (ctor))
5310 bool constant_p = true;
5311 tree value;
5313 /* Even when ctor is constant, it might contain non-*_CST
5314 elements, such as addresses or trapping values like
5315 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5316 in VECTOR_CST nodes. */
5317 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5318 if (!CONSTANT_CLASS_P (value))
5320 constant_p = false;
5321 break;
5324 if (constant_p)
5326 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5327 break;
5330 TREE_CONSTANT (ctor) = 0;
5333 /* Vector types use CONSTRUCTOR all the way through gimple
5334 compilation as a general initializer. */
5335 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5337 enum gimplify_status tret;
5338 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5339 fb_rvalue);
5340 if (tret == GS_ERROR)
5341 ret = GS_ERROR;
5342 else if (TREE_STATIC (ctor)
5343 && !initializer_constant_valid_p (ce->value,
5344 TREE_TYPE (ce->value)))
5345 TREE_STATIC (ctor) = 0;
5347 recompute_constructor_flags (ctor);
5348 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5349 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5351 break;
5353 default:
5354 /* So how did we get a CONSTRUCTOR for a scalar type? */
5355 gcc_unreachable ();
5358 if (ret == GS_ERROR)
5359 return GS_ERROR;
5360 /* If we have gimplified both sides of the initializer but have
5361 not emitted an assignment, do so now. */
5362 if (*expr_p)
5364 tree lhs = TREE_OPERAND (*expr_p, 0);
5365 tree rhs = TREE_OPERAND (*expr_p, 1);
5366 if (want_value && object == lhs)
5367 lhs = unshare_expr (lhs);
5368 gassign *init = gimple_build_assign (lhs, rhs);
5369 gimplify_seq_add_stmt (pre_p, init);
5371 if (want_value)
5373 *expr_p = object;
5374 ret = GS_OK;
5376 else
5378 *expr_p = NULL;
5379 ret = GS_ALL_DONE;
5382 /* If the user requests to initialize automatic variables, we
5383 should initialize paddings inside the variable. Add a call to
5384 __builtin_clear_pading (&object, 0, for_auto_init = true) to
5385 initialize paddings of object always to zero regardless of
5386 INIT_TYPE. Note, we will not insert this call if the aggregate
5387 variable has be completely cleared already or it's initialized
5388 with an empty constructor. We cannot insert this call if the
5389 variable is a gimple register since __builtin_clear_padding will take
5390 the address of the variable. As a result, if a long double/_Complex long
5391 double variable will be spilled into stack later, its padding cannot
5392 be cleared with __builtin_clear_padding. We should clear its padding
5393 when it is spilled into memory. */
5394 if (is_init_expr
5395 && !is_gimple_reg (object)
5396 && clear_padding_type_may_have_padding_p (type)
5397 && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor)
5398 || !AGGREGATE_TYPE_P (type))
5399 && is_var_need_auto_init (object))
5400 gimple_add_padding_init_for_auto_var (object, false, pre_p);
5402 return ret;
5405 /* Given a pointer value OP0, return a simplified version of an
5406 indirection through OP0, or NULL_TREE if no simplification is
5407 possible. This may only be applied to a rhs of an expression.
5408 Note that the resulting type may be different from the type pointed
5409 to in the sense that it is still compatible from the langhooks
5410 point of view. */
5412 static tree
5413 gimple_fold_indirect_ref_rhs (tree t)
5415 return gimple_fold_indirect_ref (t);
5418 /* Subroutine of gimplify_modify_expr to do simplifications of
5419 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5420 something changes. */
5422 static enum gimplify_status
5423 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5424 gimple_seq *pre_p, gimple_seq *post_p,
5425 bool want_value)
5427 enum gimplify_status ret = GS_UNHANDLED;
5428 bool changed;
5432 changed = false;
5433 switch (TREE_CODE (*from_p))
5435 case VAR_DECL:
5436 /* If we're assigning from a read-only variable initialized with
5437 a constructor and not volatile, do the direct assignment from
5438 the constructor, but only if the target is not volatile either
5439 since this latter assignment might end up being done on a per
5440 field basis. However, if the target is volatile and the type
5441 is aggregate and non-addressable, gimplify_init_constructor
5442 knows that it needs to ensure a single access to the target
5443 and it will return GS_OK only in this case. */
5444 if (TREE_READONLY (*from_p)
5445 && DECL_INITIAL (*from_p)
5446 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR
5447 && !TREE_THIS_VOLATILE (*from_p)
5448 && (!TREE_THIS_VOLATILE (*to_p)
5449 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p))
5450 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p)))))
5452 tree old_from = *from_p;
5453 enum gimplify_status subret;
5455 /* Move the constructor into the RHS. */
5456 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5458 /* Let's see if gimplify_init_constructor will need to put
5459 it in memory. */
5460 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5461 false, true);
5462 if (subret == GS_ERROR)
5464 /* If so, revert the change. */
5465 *from_p = old_from;
5467 else
5469 ret = GS_OK;
5470 changed = true;
5473 break;
5474 case INDIRECT_REF:
5476 /* If we have code like
5478 *(const A*)(A*)&x
5480 where the type of "x" is a (possibly cv-qualified variant
5481 of "A"), treat the entire expression as identical to "x".
5482 This kind of code arises in C++ when an object is bound
5483 to a const reference, and if "x" is a TARGET_EXPR we want
5484 to take advantage of the optimization below. */
5485 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5486 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5487 if (t)
5489 if (TREE_THIS_VOLATILE (t) != volatile_p)
5491 if (DECL_P (t))
5492 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5493 build_fold_addr_expr (t));
5494 if (REFERENCE_CLASS_P (t))
5495 TREE_THIS_VOLATILE (t) = volatile_p;
5497 *from_p = t;
5498 ret = GS_OK;
5499 changed = true;
5501 break;
5504 case TARGET_EXPR:
5506 /* If we are initializing something from a TARGET_EXPR, strip the
5507 TARGET_EXPR and initialize it directly, if possible. This can't
5508 be done if the initializer is void, since that implies that the
5509 temporary is set in some non-trivial way.
5511 ??? What about code that pulls out the temp and uses it
5512 elsewhere? I think that such code never uses the TARGET_EXPR as
5513 an initializer. If I'm wrong, we'll die because the temp won't
5514 have any RTL. In that case, I guess we'll need to replace
5515 references somehow. */
5516 tree init = TARGET_EXPR_INITIAL (*from_p);
5518 if (init
5519 && (TREE_CODE (*expr_p) != MODIFY_EXPR
5520 || !TARGET_EXPR_NO_ELIDE (*from_p))
5521 && !VOID_TYPE_P (TREE_TYPE (init)))
5523 *from_p = init;
5524 ret = GS_OK;
5525 changed = true;
5528 break;
5530 case COMPOUND_EXPR:
5531 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5532 caught. */
5533 gimplify_compound_expr (from_p, pre_p, true);
5534 ret = GS_OK;
5535 changed = true;
5536 break;
5538 case CONSTRUCTOR:
5539 /* If we already made some changes, let the front end have a
5540 crack at this before we break it down. */
5541 if (ret != GS_UNHANDLED)
5542 break;
5544 /* If we're initializing from a CONSTRUCTOR, break this into
5545 individual MODIFY_EXPRs. */
5546 ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5547 false);
5548 return ret;
5550 case COND_EXPR:
5551 /* If we're assigning to a non-register type, push the assignment
5552 down into the branches. This is mandatory for ADDRESSABLE types,
5553 since we cannot generate temporaries for such, but it saves a
5554 copy in other cases as well. */
5555 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5557 /* This code should mirror the code in gimplify_cond_expr. */
5558 enum tree_code code = TREE_CODE (*expr_p);
5559 tree cond = *from_p;
5560 tree result = *to_p;
5562 ret = gimplify_expr (&result, pre_p, post_p,
5563 is_gimple_lvalue, fb_lvalue);
5564 if (ret != GS_ERROR)
5565 ret = GS_OK;
5567 /* If we are going to write RESULT more than once, clear
5568 TREE_READONLY flag, otherwise we might incorrectly promote
5569 the variable to static const and initialize it at compile
5570 time in one of the branches. */
5571 if (VAR_P (result)
5572 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5573 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5574 TREE_READONLY (result) = 0;
5575 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5576 TREE_OPERAND (cond, 1)
5577 = build2 (code, void_type_node, result,
5578 TREE_OPERAND (cond, 1));
5579 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5580 TREE_OPERAND (cond, 2)
5581 = build2 (code, void_type_node, unshare_expr (result),
5582 TREE_OPERAND (cond, 2));
5584 TREE_TYPE (cond) = void_type_node;
5585 recalculate_side_effects (cond);
5587 if (want_value)
5589 gimplify_and_add (cond, pre_p);
5590 *expr_p = unshare_expr (result);
5592 else
5593 *expr_p = cond;
5594 return ret;
5596 break;
5598 case CALL_EXPR:
5599 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5600 return slot so that we don't generate a temporary. */
5601 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5602 && aggregate_value_p (*from_p, *from_p))
5604 bool use_target;
5606 if (!(rhs_predicate_for (*to_p))(*from_p))
5607 /* If we need a temporary, *to_p isn't accurate. */
5608 use_target = false;
5609 /* It's OK to use the return slot directly unless it's an NRV. */
5610 else if (TREE_CODE (*to_p) == RESULT_DECL
5611 && DECL_NAME (*to_p) == NULL_TREE
5612 && needs_to_live_in_memory (*to_p))
5613 use_target = true;
5614 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5615 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5616 /* Don't force regs into memory. */
5617 use_target = false;
5618 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5619 /* It's OK to use the target directly if it's being
5620 initialized. */
5621 use_target = true;
5622 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5623 != INTEGER_CST)
5624 /* Always use the target and thus RSO for variable-sized types.
5625 GIMPLE cannot deal with a variable-sized assignment
5626 embedded in a call statement. */
5627 use_target = true;
5628 else if (TREE_CODE (*to_p) != SSA_NAME
5629 && (!is_gimple_variable (*to_p)
5630 || needs_to_live_in_memory (*to_p)))
5631 /* Don't use the original target if it's already addressable;
5632 if its address escapes, and the called function uses the
5633 NRV optimization, a conforming program could see *to_p
5634 change before the called function returns; see c++/19317.
5635 When optimizing, the return_slot pass marks more functions
5636 as safe after we have escape info. */
5637 use_target = false;
5638 else
5639 use_target = true;
5641 if (use_target)
5643 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5644 mark_addressable (*to_p);
5647 break;
5649 case WITH_SIZE_EXPR:
5650 /* Likewise for calls that return an aggregate of non-constant size,
5651 since we would not be able to generate a temporary at all. */
5652 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5654 *from_p = TREE_OPERAND (*from_p, 0);
5655 /* We don't change ret in this case because the
5656 WITH_SIZE_EXPR might have been added in
5657 gimplify_modify_expr, so returning GS_OK would lead to an
5658 infinite loop. */
5659 changed = true;
5661 break;
5663 /* If we're initializing from a container, push the initialization
5664 inside it. */
5665 case CLEANUP_POINT_EXPR:
5666 case BIND_EXPR:
5667 case STATEMENT_LIST:
5669 tree wrap = *from_p;
5670 tree t;
5672 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5673 fb_lvalue);
5674 if (ret != GS_ERROR)
5675 ret = GS_OK;
5677 t = voidify_wrapper_expr (wrap, *expr_p);
5678 gcc_assert (t == *expr_p);
5680 if (want_value)
5682 gimplify_and_add (wrap, pre_p);
5683 *expr_p = unshare_expr (*to_p);
5685 else
5686 *expr_p = wrap;
5687 return GS_OK;
5690 case NOP_EXPR:
5691 /* Pull out compound literal expressions from a NOP_EXPR.
5692 Those are created in the C FE to drop qualifiers during
5693 lvalue conversion. */
5694 if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
5695 && tree_ssa_useless_type_conversion (*from_p))
5697 *from_p = TREE_OPERAND (*from_p, 0);
5698 ret = GS_OK;
5699 changed = true;
5701 break;
5703 case COMPOUND_LITERAL_EXPR:
5705 tree complit = TREE_OPERAND (*expr_p, 1);
5706 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5707 tree decl = DECL_EXPR_DECL (decl_s);
5708 tree init = DECL_INITIAL (decl);
5710 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5711 into struct T x = { 0, 1, 2 } if the address of the
5712 compound literal has never been taken. */
5713 if (!TREE_ADDRESSABLE (complit)
5714 && !TREE_ADDRESSABLE (decl)
5715 && init)
5717 *expr_p = copy_node (*expr_p);
5718 TREE_OPERAND (*expr_p, 1) = init;
5719 return GS_OK;
5723 default:
5724 break;
5727 while (changed);
5729 return ret;
5733 /* Return true if T looks like a valid GIMPLE statement. */
5735 static bool
5736 is_gimple_stmt (tree t)
5738 const enum tree_code code = TREE_CODE (t);
5740 switch (code)
5742 case NOP_EXPR:
5743 /* The only valid NOP_EXPR is the empty statement. */
5744 return IS_EMPTY_STMT (t);
5746 case BIND_EXPR:
5747 case COND_EXPR:
5748 /* These are only valid if they're void. */
5749 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5751 case SWITCH_EXPR:
5752 case GOTO_EXPR:
5753 case RETURN_EXPR:
5754 case LABEL_EXPR:
5755 case CASE_LABEL_EXPR:
5756 case TRY_CATCH_EXPR:
5757 case TRY_FINALLY_EXPR:
5758 case EH_FILTER_EXPR:
5759 case CATCH_EXPR:
5760 case ASM_EXPR:
5761 case STATEMENT_LIST:
5762 case OACC_PARALLEL:
5763 case OACC_KERNELS:
5764 case OACC_SERIAL:
5765 case OACC_DATA:
5766 case OACC_HOST_DATA:
5767 case OACC_DECLARE:
5768 case OACC_UPDATE:
5769 case OACC_ENTER_DATA:
5770 case OACC_EXIT_DATA:
5771 case OACC_CACHE:
5772 case OMP_PARALLEL:
5773 case OMP_FOR:
5774 case OMP_SIMD:
5775 case OMP_DISTRIBUTE:
5776 case OMP_LOOP:
5777 case OACC_LOOP:
5778 case OMP_SCAN:
5779 case OMP_SCOPE:
5780 case OMP_SECTIONS:
5781 case OMP_SECTION:
5782 case OMP_SINGLE:
5783 case OMP_MASTER:
5784 case OMP_MASKED:
5785 case OMP_TASKGROUP:
5786 case OMP_ORDERED:
5787 case OMP_CRITICAL:
5788 case OMP_TASK:
5789 case OMP_TARGET:
5790 case OMP_TARGET_DATA:
5791 case OMP_TARGET_UPDATE:
5792 case OMP_TARGET_ENTER_DATA:
5793 case OMP_TARGET_EXIT_DATA:
5794 case OMP_TASKLOOP:
5795 case OMP_TEAMS:
5796 /* These are always void. */
5797 return true;
5799 case CALL_EXPR:
5800 case MODIFY_EXPR:
5801 case PREDICT_EXPR:
5802 /* These are valid regardless of their type. */
5803 return true;
5805 default:
5806 return false;
5811 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5812 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
5814 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5815 other, unmodified part of the complex object just before the total store.
5816 As a consequence, if the object is still uninitialized, an undefined value
5817 will be loaded into a register, which may result in a spurious exception
5818 if the register is floating-point and the value happens to be a signaling
5819 NaN for example. Then the fully-fledged complex operations lowering pass
5820 followed by a DCE pass are necessary in order to fix things up. */
5822 static enum gimplify_status
5823 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5824 bool want_value)
5826 enum tree_code code, ocode;
5827 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5829 lhs = TREE_OPERAND (*expr_p, 0);
5830 rhs = TREE_OPERAND (*expr_p, 1);
5831 code = TREE_CODE (lhs);
5832 lhs = TREE_OPERAND (lhs, 0);
5834 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5835 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5836 suppress_warning (other);
5837 other = get_formal_tmp_var (other, pre_p);
5839 realpart = code == REALPART_EXPR ? rhs : other;
5840 imagpart = code == REALPART_EXPR ? other : rhs;
5842 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5843 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5844 else
5845 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5847 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5848 *expr_p = (want_value) ? rhs : NULL_TREE;
5850 return GS_ALL_DONE;
5853 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5855 modify_expr
5856 : varname '=' rhs
5857 | '*' ID '=' rhs
5859 PRE_P points to the list where side effects that must happen before
5860 *EXPR_P should be stored.
5862 POST_P points to the list where side effects that must happen after
5863 *EXPR_P should be stored.
5865 WANT_VALUE is nonzero iff we want to use the value of this expression
5866 in another expression. */
5868 static enum gimplify_status
5869 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5870 bool want_value)
5872 tree *from_p = &TREE_OPERAND (*expr_p, 1);
5873 tree *to_p = &TREE_OPERAND (*expr_p, 0);
5874 enum gimplify_status ret = GS_UNHANDLED;
5875 gimple *assign;
5876 location_t loc = EXPR_LOCATION (*expr_p);
5877 gimple_stmt_iterator gsi;
5879 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
5880 || TREE_CODE (*expr_p) == INIT_EXPR);
5882 /* Trying to simplify a clobber using normal logic doesn't work,
5883 so handle it here. */
5884 if (TREE_CLOBBER_P (*from_p))
5886 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5887 if (ret == GS_ERROR)
5888 return ret;
5889 gcc_assert (!want_value);
5890 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
5892 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
5893 pre_p, post_p);
5894 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
5896 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
5897 *expr_p = NULL;
5898 return GS_ALL_DONE;
5901 /* Insert pointer conversions required by the middle-end that are not
5902 required by the frontend. This fixes middle-end type checking for
5903 for example gcc.dg/redecl-6.c. */
5904 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
5906 STRIP_USELESS_TYPE_CONVERSION (*from_p);
5907 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
5908 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
5911 /* See if any simplifications can be done based on what the RHS is. */
5912 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5913 want_value);
5914 if (ret != GS_UNHANDLED)
5915 return ret;
5917 /* For empty types only gimplify the left hand side and right hand
5918 side as statements and throw away the assignment. Do this after
5919 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5920 types properly. */
5921 if (is_empty_type (TREE_TYPE (*from_p))
5922 && !want_value
5923 /* Don't do this for calls that return addressable types, expand_call
5924 relies on those having a lhs. */
5925 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
5926 && TREE_CODE (*from_p) == CALL_EXPR))
5928 gimplify_stmt (from_p, pre_p);
5929 gimplify_stmt (to_p, pre_p);
5930 *expr_p = NULL_TREE;
5931 return GS_ALL_DONE;
5934 /* If the value being copied is of variable width, compute the length
5935 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5936 before gimplifying any of the operands so that we can resolve any
5937 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5938 the size of the expression to be copied, not of the destination, so
5939 that is what we must do here. */
5940 maybe_with_size_expr (from_p);
5942 /* As a special case, we have to temporarily allow for assignments
5943 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5944 a toplevel statement, when gimplifying the GENERIC expression
5945 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5946 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5948 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5949 prevent gimplify_expr from trying to create a new temporary for
5950 foo's LHS, we tell it that it should only gimplify until it
5951 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5952 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5953 and all we need to do here is set 'a' to be its LHS. */
5955 /* Gimplify the RHS first for C++17 and bug 71104. */
5956 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
5957 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
5958 if (ret == GS_ERROR)
5959 return ret;
5961 /* Then gimplify the LHS. */
5962 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5963 twice we have to make sure to gimplify into non-SSA as otherwise
5964 the abnormal edge added later will make those defs not dominate
5965 their uses.
5966 ??? Technically this applies only to the registers used in the
5967 resulting non-register *TO_P. */
5968 bool saved_into_ssa = gimplify_ctxp->into_ssa;
5969 if (saved_into_ssa
5970 && TREE_CODE (*from_p) == CALL_EXPR
5971 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
5972 gimplify_ctxp->into_ssa = false;
5973 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5974 gimplify_ctxp->into_ssa = saved_into_ssa;
5975 if (ret == GS_ERROR)
5976 return ret;
5978 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5979 guess for the predicate was wrong. */
5980 gimple_predicate final_pred = rhs_predicate_for (*to_p);
5981 if (final_pred != initial_pred)
5983 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
5984 if (ret == GS_ERROR)
5985 return ret;
5988 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5989 size as argument to the call. */
5990 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5992 tree call = TREE_OPERAND (*from_p, 0);
5993 tree vlasize = TREE_OPERAND (*from_p, 1);
5995 if (TREE_CODE (call) == CALL_EXPR
5996 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
5998 int nargs = call_expr_nargs (call);
5999 tree type = TREE_TYPE (call);
6000 tree ap = CALL_EXPR_ARG (call, 0);
6001 tree tag = CALL_EXPR_ARG (call, 1);
6002 tree aptag = CALL_EXPR_ARG (call, 2);
6003 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
6004 IFN_VA_ARG, type,
6005 nargs + 1, ap, tag,
6006 aptag, vlasize);
6007 TREE_OPERAND (*from_p, 0) = newcall;
6011 /* Now see if the above changed *from_p to something we handle specially. */
6012 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
6013 want_value);
6014 if (ret != GS_UNHANDLED)
6015 return ret;
6017 /* If we've got a variable sized assignment between two lvalues (i.e. does
6018 not involve a call), then we can make things a bit more straightforward
6019 by converting the assignment to memcpy or memset. */
6020 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
6022 tree from = TREE_OPERAND (*from_p, 0);
6023 tree size = TREE_OPERAND (*from_p, 1);
6025 if (TREE_CODE (from) == CONSTRUCTOR)
6026 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
6028 if (is_gimple_addressable (from))
6030 *from_p = from;
6031 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
6032 pre_p);
6036 /* Transform partial stores to non-addressable complex variables into
6037 total stores. This allows us to use real instead of virtual operands
6038 for these variables, which improves optimization. */
6039 if ((TREE_CODE (*to_p) == REALPART_EXPR
6040 || TREE_CODE (*to_p) == IMAGPART_EXPR)
6041 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
6042 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
6044 /* Try to alleviate the effects of the gimplification creating artificial
6045 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
6046 make sure not to create DECL_DEBUG_EXPR links across functions. */
6047 if (!gimplify_ctxp->into_ssa
6048 && VAR_P (*from_p)
6049 && DECL_IGNORED_P (*from_p)
6050 && DECL_P (*to_p)
6051 && !DECL_IGNORED_P (*to_p)
6052 && decl_function_context (*to_p) == current_function_decl
6053 && decl_function_context (*from_p) == current_function_decl)
6055 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
6056 DECL_NAME (*from_p)
6057 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
6058 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
6059 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
6062 if (want_value && TREE_THIS_VOLATILE (*to_p))
6063 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
6065 if (TREE_CODE (*from_p) == CALL_EXPR)
6067 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
6068 instead of a GIMPLE_ASSIGN. */
6069 gcall *call_stmt;
6070 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
6072 /* Gimplify internal functions created in the FEs. */
6073 int nargs = call_expr_nargs (*from_p), i;
6074 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
6075 auto_vec<tree> vargs (nargs);
6077 for (i = 0; i < nargs; i++)
6079 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
6080 EXPR_LOCATION (*from_p));
6081 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
6083 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
6084 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
6085 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
6087 else
6089 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
6090 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
6091 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
6092 tree fndecl = get_callee_fndecl (*from_p);
6093 if (fndecl
6094 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
6095 && call_expr_nargs (*from_p) == 3)
6096 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
6097 CALL_EXPR_ARG (*from_p, 0),
6098 CALL_EXPR_ARG (*from_p, 1),
6099 CALL_EXPR_ARG (*from_p, 2));
6100 else
6102 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
6105 notice_special_calls (call_stmt);
6106 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
6107 gimple_call_set_lhs (call_stmt, *to_p);
6108 else if (TREE_CODE (*to_p) == SSA_NAME)
6109 /* The above is somewhat premature, avoid ICEing later for a
6110 SSA name w/o a definition. We may have uses in the GIMPLE IL.
6111 ??? This doesn't make it a default-def. */
6112 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
6114 assign = call_stmt;
6116 else
6118 assign = gimple_build_assign (*to_p, *from_p);
6119 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
6120 if (COMPARISON_CLASS_P (*from_p))
6121 copy_warning (assign, *from_p);
6124 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
6126 /* We should have got an SSA name from the start. */
6127 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
6128 || ! gimple_in_ssa_p (cfun));
6131 gimplify_seq_add_stmt (pre_p, assign);
6132 gsi = gsi_last (*pre_p);
6133 maybe_fold_stmt (&gsi);
6135 if (want_value)
6137 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
6138 return GS_OK;
6140 else
6141 *expr_p = NULL;
6143 return GS_ALL_DONE;
6146 /* Gimplify a comparison between two variable-sized objects. Do this
6147 with a call to BUILT_IN_MEMCMP. */
6149 static enum gimplify_status
6150 gimplify_variable_sized_compare (tree *expr_p)
6152 location_t loc = EXPR_LOCATION (*expr_p);
6153 tree op0 = TREE_OPERAND (*expr_p, 0);
6154 tree op1 = TREE_OPERAND (*expr_p, 1);
6155 tree t, arg, dest, src, expr;
6157 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
6158 arg = unshare_expr (arg);
6159 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
6160 src = build_fold_addr_expr_loc (loc, op1);
6161 dest = build_fold_addr_expr_loc (loc, op0);
6162 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
6163 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
6165 expr
6166 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
6167 SET_EXPR_LOCATION (expr, loc);
6168 *expr_p = expr;
6170 return GS_OK;
6173 /* Gimplify a comparison between two aggregate objects of integral scalar
6174 mode as a comparison between the bitwise equivalent scalar values. */
6176 static enum gimplify_status
6177 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
6179 location_t loc = EXPR_LOCATION (*expr_p);
6180 tree op0 = TREE_OPERAND (*expr_p, 0);
6181 tree op1 = TREE_OPERAND (*expr_p, 1);
6183 tree type = TREE_TYPE (op0);
6184 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
6186 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
6187 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
6189 *expr_p
6190 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
6192 return GS_OK;
6195 /* Gimplify an expression sequence. This function gimplifies each
6196 expression and rewrites the original expression with the last
6197 expression of the sequence in GIMPLE form.
6199 PRE_P points to the list where the side effects for all the
6200 expressions in the sequence will be emitted.
6202 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6204 static enum gimplify_status
6205 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
6207 tree t = *expr_p;
6211 tree *sub_p = &TREE_OPERAND (t, 0);
6213 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
6214 gimplify_compound_expr (sub_p, pre_p, false);
6215 else
6216 gimplify_stmt (sub_p, pre_p);
6218 t = TREE_OPERAND (t, 1);
6220 while (TREE_CODE (t) == COMPOUND_EXPR);
6222 *expr_p = t;
6223 if (want_value)
6224 return GS_OK;
6225 else
6227 gimplify_stmt (expr_p, pre_p);
6228 return GS_ALL_DONE;
6232 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6233 gimplify. After gimplification, EXPR_P will point to a new temporary
6234 that holds the original value of the SAVE_EXPR node.
6236 PRE_P points to the list where side effects that must happen before
6237 *EXPR_P should be stored. */
6239 static enum gimplify_status
6240 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6242 enum gimplify_status ret = GS_ALL_DONE;
6243 tree val;
6245 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
6246 val = TREE_OPERAND (*expr_p, 0);
6248 if (TREE_TYPE (val) == error_mark_node)
6249 return GS_ERROR;
6251 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6252 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
6254 /* The operand may be a void-valued expression. It is
6255 being executed only for its side-effects. */
6256 if (TREE_TYPE (val) == void_type_node)
6258 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
6259 is_gimple_stmt, fb_none);
6260 val = NULL;
6262 else
6263 /* The temporary may not be an SSA name as later abnormal and EH
6264 control flow may invalidate use/def domination. When in SSA
6265 form then assume there are no such issues and SAVE_EXPRs only
6266 appear via GENERIC foldings. */
6267 val = get_initialized_tmp_var (val, pre_p, post_p,
6268 gimple_in_ssa_p (cfun));
6270 TREE_OPERAND (*expr_p, 0) = val;
6271 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
6274 *expr_p = val;
6276 return ret;
6279 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6281 unary_expr
6282 : ...
6283 | '&' varname
6286 PRE_P points to the list where side effects that must happen before
6287 *EXPR_P should be stored.
6289 POST_P points to the list where side effects that must happen after
6290 *EXPR_P should be stored. */
6292 static enum gimplify_status
6293 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6295 tree expr = *expr_p;
6296 tree op0 = TREE_OPERAND (expr, 0);
6297 enum gimplify_status ret;
6298 location_t loc = EXPR_LOCATION (*expr_p);
6300 switch (TREE_CODE (op0))
6302 case INDIRECT_REF:
6303 do_indirect_ref:
6304 /* Check if we are dealing with an expression of the form '&*ptr'.
6305 While the front end folds away '&*ptr' into 'ptr', these
6306 expressions may be generated internally by the compiler (e.g.,
6307 builtins like __builtin_va_end). */
6308 /* Caution: the silent array decomposition semantics we allow for
6309 ADDR_EXPR means we can't always discard the pair. */
6310 /* Gimplification of the ADDR_EXPR operand may drop
6311 cv-qualification conversions, so make sure we add them if
6312 needed. */
6314 tree op00 = TREE_OPERAND (op0, 0);
6315 tree t_expr = TREE_TYPE (expr);
6316 tree t_op00 = TREE_TYPE (op00);
6318 if (!useless_type_conversion_p (t_expr, t_op00))
6319 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
6320 *expr_p = op00;
6321 ret = GS_OK;
6323 break;
6325 case VIEW_CONVERT_EXPR:
6326 /* Take the address of our operand and then convert it to the type of
6327 this ADDR_EXPR.
6329 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6330 all clear. The impact of this transformation is even less clear. */
6332 /* If the operand is a useless conversion, look through it. Doing so
6333 guarantees that the ADDR_EXPR and its operand will remain of the
6334 same type. */
6335 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
6336 op0 = TREE_OPERAND (op0, 0);
6338 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
6339 build_fold_addr_expr_loc (loc,
6340 TREE_OPERAND (op0, 0)));
6341 ret = GS_OK;
6342 break;
6344 case MEM_REF:
6345 if (integer_zerop (TREE_OPERAND (op0, 1)))
6346 goto do_indirect_ref;
6348 /* fall through */
6350 default:
6351 /* If we see a call to a declared builtin or see its address
6352 being taken (we can unify those cases here) then we can mark
6353 the builtin for implicit generation by GCC. */
6354 if (TREE_CODE (op0) == FUNCTION_DECL
6355 && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6356 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6357 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6359 /* We use fb_either here because the C frontend sometimes takes
6360 the address of a call that returns a struct; see
6361 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6362 the implied temporary explicit. */
6364 /* Make the operand addressable. */
6365 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6366 is_gimple_addressable, fb_either);
6367 if (ret == GS_ERROR)
6368 break;
6370 /* Then mark it. Beware that it may not be possible to do so directly
6371 if a temporary has been created by the gimplification. */
6372 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6374 op0 = TREE_OPERAND (expr, 0);
6376 /* For various reasons, the gimplification of the expression
6377 may have made a new INDIRECT_REF. */
6378 if (TREE_CODE (op0) == INDIRECT_REF
6379 || (TREE_CODE (op0) == MEM_REF
6380 && integer_zerop (TREE_OPERAND (op0, 1))))
6381 goto do_indirect_ref;
6383 mark_addressable (TREE_OPERAND (expr, 0));
6385 /* The FEs may end up building ADDR_EXPRs early on a decl with
6386 an incomplete type. Re-build ADDR_EXPRs in canonical form
6387 here. */
6388 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6389 *expr_p = build_fold_addr_expr (op0);
6391 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6392 recompute_tree_invariant_for_addr_expr (*expr_p);
6394 /* If we re-built the ADDR_EXPR add a conversion to the original type
6395 if required. */
6396 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6397 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6399 break;
6402 return ret;
6405 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6406 value; output operands should be a gimple lvalue. */
6408 static enum gimplify_status
6409 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6411 tree expr;
6412 int noutputs;
6413 const char **oconstraints;
6414 int i;
6415 tree link;
6416 const char *constraint;
6417 bool allows_mem, allows_reg, is_inout;
6418 enum gimplify_status ret, tret;
6419 gasm *stmt;
6420 vec<tree, va_gc> *inputs;
6421 vec<tree, va_gc> *outputs;
6422 vec<tree, va_gc> *clobbers;
6423 vec<tree, va_gc> *labels;
6424 tree link_next;
6426 expr = *expr_p;
6427 noutputs = list_length (ASM_OUTPUTS (expr));
6428 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6430 inputs = NULL;
6431 outputs = NULL;
6432 clobbers = NULL;
6433 labels = NULL;
6435 ret = GS_ALL_DONE;
6436 link_next = NULL_TREE;
6437 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6439 bool ok;
6440 size_t constraint_len;
6442 link_next = TREE_CHAIN (link);
6444 oconstraints[i]
6445 = constraint
6446 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6447 constraint_len = strlen (constraint);
6448 if (constraint_len == 0)
6449 continue;
6451 ok = parse_output_constraint (&constraint, i, 0, 0,
6452 &allows_mem, &allows_reg, &is_inout);
6453 if (!ok)
6455 ret = GS_ERROR;
6456 is_inout = false;
6459 /* If we can't make copies, we can only accept memory.
6460 Similarly for VLAs. */
6461 tree outtype = TREE_TYPE (TREE_VALUE (link));
6462 if (outtype != error_mark_node
6463 && (TREE_ADDRESSABLE (outtype)
6464 || !COMPLETE_TYPE_P (outtype)
6465 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
6467 if (allows_mem)
6468 allows_reg = 0;
6469 else
6471 error ("impossible constraint in %<asm%>");
6472 error ("non-memory output %d must stay in memory", i);
6473 return GS_ERROR;
6477 if (!allows_reg && allows_mem)
6478 mark_addressable (TREE_VALUE (link));
6480 tree orig = TREE_VALUE (link);
6481 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6482 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6483 fb_lvalue | fb_mayfail);
6484 if (tret == GS_ERROR)
6486 if (orig != error_mark_node)
6487 error ("invalid lvalue in %<asm%> output %d", i);
6488 ret = tret;
6491 /* If the constraint does not allow memory make sure we gimplify
6492 it to a register if it is not already but its base is. This
6493 happens for complex and vector components. */
6494 if (!allows_mem)
6496 tree op = TREE_VALUE (link);
6497 if (! is_gimple_val (op)
6498 && is_gimple_reg_type (TREE_TYPE (op))
6499 && is_gimple_reg (get_base_address (op)))
6501 tree tem = create_tmp_reg (TREE_TYPE (op));
6502 tree ass;
6503 if (is_inout)
6505 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6506 tem, unshare_expr (op));
6507 gimplify_and_add (ass, pre_p);
6509 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6510 gimplify_and_add (ass, post_p);
6512 TREE_VALUE (link) = tem;
6513 tret = GS_OK;
6517 vec_safe_push (outputs, link);
6518 TREE_CHAIN (link) = NULL_TREE;
6520 if (is_inout)
6522 /* An input/output operand. To give the optimizers more
6523 flexibility, split it into separate input and output
6524 operands. */
6525 tree input;
6526 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6527 char buf[11];
6529 /* Turn the in/out constraint into an output constraint. */
6530 char *p = xstrdup (constraint);
6531 p[0] = '=';
6532 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6534 /* And add a matching input constraint. */
6535 if (allows_reg)
6537 sprintf (buf, "%u", i);
6539 /* If there are multiple alternatives in the constraint,
6540 handle each of them individually. Those that allow register
6541 will be replaced with operand number, the others will stay
6542 unchanged. */
6543 if (strchr (p, ',') != NULL)
6545 size_t len = 0, buflen = strlen (buf);
6546 char *beg, *end, *str, *dst;
6548 for (beg = p + 1;;)
6550 end = strchr (beg, ',');
6551 if (end == NULL)
6552 end = strchr (beg, '\0');
6553 if ((size_t) (end - beg) < buflen)
6554 len += buflen + 1;
6555 else
6556 len += end - beg + 1;
6557 if (*end)
6558 beg = end + 1;
6559 else
6560 break;
6563 str = (char *) alloca (len);
6564 for (beg = p + 1, dst = str;;)
6566 const char *tem;
6567 bool mem_p, reg_p, inout_p;
6569 end = strchr (beg, ',');
6570 if (end)
6571 *end = '\0';
6572 beg[-1] = '=';
6573 tem = beg - 1;
6574 parse_output_constraint (&tem, i, 0, 0,
6575 &mem_p, &reg_p, &inout_p);
6576 if (dst != str)
6577 *dst++ = ',';
6578 if (reg_p)
6580 memcpy (dst, buf, buflen);
6581 dst += buflen;
6583 else
6585 if (end)
6586 len = end - beg;
6587 else
6588 len = strlen (beg);
6589 memcpy (dst, beg, len);
6590 dst += len;
6592 if (end)
6593 beg = end + 1;
6594 else
6595 break;
6597 *dst = '\0';
6598 input = build_string (dst - str, str);
6600 else
6601 input = build_string (strlen (buf), buf);
6603 else
6604 input = build_string (constraint_len - 1, constraint + 1);
6606 free (p);
6608 input = build_tree_list (build_tree_list (NULL_TREE, input),
6609 unshare_expr (TREE_VALUE (link)));
6610 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6614 link_next = NULL_TREE;
6615 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6617 link_next = TREE_CHAIN (link);
6618 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6619 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6620 oconstraints, &allows_mem, &allows_reg);
6622 /* If we can't make copies, we can only accept memory. */
6623 tree intype = TREE_TYPE (TREE_VALUE (link));
6624 if (intype != error_mark_node
6625 && (TREE_ADDRESSABLE (intype)
6626 || !COMPLETE_TYPE_P (intype)
6627 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
6629 if (allows_mem)
6630 allows_reg = 0;
6631 else
6633 error ("impossible constraint in %<asm%>");
6634 error ("non-memory input %d must stay in memory", i);
6635 return GS_ERROR;
6639 /* If the operand is a memory input, it should be an lvalue. */
6640 if (!allows_reg && allows_mem)
6642 tree inputv = TREE_VALUE (link);
6643 STRIP_NOPS (inputv);
6644 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6645 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6646 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6647 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6648 || TREE_CODE (inputv) == MODIFY_EXPR)
6649 TREE_VALUE (link) = error_mark_node;
6650 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6651 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6652 if (tret != GS_ERROR)
6654 /* Unlike output operands, memory inputs are not guaranteed
6655 to be lvalues by the FE, and while the expressions are
6656 marked addressable there, if it is e.g. a statement
6657 expression, temporaries in it might not end up being
6658 addressable. They might be already used in the IL and thus
6659 it is too late to make them addressable now though. */
6660 tree x = TREE_VALUE (link);
6661 while (handled_component_p (x))
6662 x = TREE_OPERAND (x, 0);
6663 if (TREE_CODE (x) == MEM_REF
6664 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6665 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6666 if ((VAR_P (x)
6667 || TREE_CODE (x) == PARM_DECL
6668 || TREE_CODE (x) == RESULT_DECL)
6669 && !TREE_ADDRESSABLE (x)
6670 && is_gimple_reg (x))
6672 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6673 input_location), 0,
6674 "memory input %d is not directly addressable",
6676 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6679 mark_addressable (TREE_VALUE (link));
6680 if (tret == GS_ERROR)
6682 if (inputv != error_mark_node)
6683 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6684 "memory input %d is not directly addressable", i);
6685 ret = tret;
6688 else
6690 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6691 is_gimple_asm_val, fb_rvalue);
6692 if (tret == GS_ERROR)
6693 ret = tret;
6696 TREE_CHAIN (link) = NULL_TREE;
6697 vec_safe_push (inputs, link);
6700 link_next = NULL_TREE;
6701 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6703 link_next = TREE_CHAIN (link);
6704 TREE_CHAIN (link) = NULL_TREE;
6705 vec_safe_push (clobbers, link);
6708 link_next = NULL_TREE;
6709 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6711 link_next = TREE_CHAIN (link);
6712 TREE_CHAIN (link) = NULL_TREE;
6713 vec_safe_push (labels, link);
6716 /* Do not add ASMs with errors to the gimple IL stream. */
6717 if (ret != GS_ERROR)
6719 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6720 inputs, outputs, clobbers, labels);
6722 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
6723 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6724 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
6726 gimplify_seq_add_stmt (pre_p, stmt);
6729 return ret;
6732 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6733 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6734 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6735 return to this function.
6737 FIXME should we complexify the prequeue handling instead? Or use flags
6738 for all the cleanups and let the optimizer tighten them up? The current
6739 code seems pretty fragile; it will break on a cleanup within any
6740 non-conditional nesting. But any such nesting would be broken, anyway;
6741 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6742 and continues out of it. We can do that at the RTL level, though, so
6743 having an optimizer to tighten up try/finally regions would be a Good
6744 Thing. */
6746 static enum gimplify_status
6747 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6749 gimple_stmt_iterator iter;
6750 gimple_seq body_sequence = NULL;
6752 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6754 /* We only care about the number of conditions between the innermost
6755 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6756 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6757 int old_conds = gimplify_ctxp->conditions;
6758 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6759 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6760 gimplify_ctxp->conditions = 0;
6761 gimplify_ctxp->conditional_cleanups = NULL;
6762 gimplify_ctxp->in_cleanup_point_expr = true;
6764 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6766 gimplify_ctxp->conditions = old_conds;
6767 gimplify_ctxp->conditional_cleanups = old_cleanups;
6768 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6770 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6772 gimple *wce = gsi_stmt (iter);
6774 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6776 if (gsi_one_before_end_p (iter))
6778 /* Note that gsi_insert_seq_before and gsi_remove do not
6779 scan operands, unlike some other sequence mutators. */
6780 if (!gimple_wce_cleanup_eh_only (wce))
6781 gsi_insert_seq_before_without_update (&iter,
6782 gimple_wce_cleanup (wce),
6783 GSI_SAME_STMT);
6784 gsi_remove (&iter, true);
6785 break;
6787 else
6789 gtry *gtry;
6790 gimple_seq seq;
6791 enum gimple_try_flags kind;
6793 if (gimple_wce_cleanup_eh_only (wce))
6794 kind = GIMPLE_TRY_CATCH;
6795 else
6796 kind = GIMPLE_TRY_FINALLY;
6797 seq = gsi_split_seq_after (iter);
6799 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6800 /* Do not use gsi_replace here, as it may scan operands.
6801 We want to do a simple structural modification only. */
6802 gsi_set_stmt (&iter, gtry);
6803 iter = gsi_start (gtry->eval);
6806 else
6807 gsi_next (&iter);
6810 gimplify_seq_add_seq (pre_p, body_sequence);
6811 if (temp)
6813 *expr_p = temp;
6814 return GS_OK;
6816 else
6818 *expr_p = NULL;
6819 return GS_ALL_DONE;
6823 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6824 is the cleanup action required. EH_ONLY is true if the cleanup should
6825 only be executed if an exception is thrown, not on normal exit.
6826 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6827 only valid for clobbers. */
6829 static void
6830 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6831 bool force_uncond = false)
6833 gimple *wce;
6834 gimple_seq cleanup_stmts = NULL;
6836 /* Errors can result in improperly nested cleanups. Which results in
6837 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6838 if (seen_error ())
6839 return;
6841 if (gimple_conditional_context ())
6843 /* If we're in a conditional context, this is more complex. We only
6844 want to run the cleanup if we actually ran the initialization that
6845 necessitates it, but we want to run it after the end of the
6846 conditional context. So we wrap the try/finally around the
6847 condition and use a flag to determine whether or not to actually
6848 run the destructor. Thus
6850 test ? f(A()) : 0
6852 becomes (approximately)
6854 flag = 0;
6855 try {
6856 if (test) { A::A(temp); flag = 1; val = f(temp); }
6857 else { val = 0; }
6858 } finally {
6859 if (flag) A::~A(temp);
6863 if (force_uncond)
6865 gimplify_stmt (&cleanup, &cleanup_stmts);
6866 wce = gimple_build_wce (cleanup_stmts);
6867 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6869 else
6871 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6872 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
6873 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
6875 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
6876 gimplify_stmt (&cleanup, &cleanup_stmts);
6877 wce = gimple_build_wce (cleanup_stmts);
6879 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
6880 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6881 gimplify_seq_add_stmt (pre_p, ftrue);
6883 /* Because of this manipulation, and the EH edges that jump
6884 threading cannot redirect, the temporary (VAR) will appear
6885 to be used uninitialized. Don't warn. */
6886 suppress_warning (var, OPT_Wuninitialized);
6889 else
6891 gimplify_stmt (&cleanup, &cleanup_stmts);
6892 wce = gimple_build_wce (cleanup_stmts);
6893 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6894 gimplify_seq_add_stmt (pre_p, wce);
6898 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6900 static enum gimplify_status
6901 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6903 tree targ = *expr_p;
6904 tree temp = TARGET_EXPR_SLOT (targ);
6905 tree init = TARGET_EXPR_INITIAL (targ);
6906 enum gimplify_status ret;
6908 bool unpoison_empty_seq = false;
6909 gimple_stmt_iterator unpoison_it;
6911 if (init)
6913 tree cleanup = NULL_TREE;
6915 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6916 to the temps list. Handle also variable length TARGET_EXPRs. */
6917 if (!poly_int_tree_p (DECL_SIZE (temp)))
6919 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
6920 gimplify_type_sizes (TREE_TYPE (temp), pre_p);
6921 /* FIXME: this is correct only when the size of the type does
6922 not depend on expressions evaluated in init. */
6923 gimplify_vla_decl (temp, pre_p);
6925 else
6927 /* Save location where we need to place unpoisoning. It's possible
6928 that a variable will be converted to needs_to_live_in_memory. */
6929 unpoison_it = gsi_last (*pre_p);
6930 unpoison_empty_seq = gsi_end_p (unpoison_it);
6932 gimple_add_tmp_var (temp);
6935 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6936 expression is supposed to initialize the slot. */
6937 if (VOID_TYPE_P (TREE_TYPE (init)))
6938 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6939 else
6941 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
6942 init = init_expr;
6943 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6944 init = NULL;
6945 ggc_free (init_expr);
6947 if (ret == GS_ERROR)
6949 /* PR c++/28266 Make sure this is expanded only once. */
6950 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6951 return GS_ERROR;
6953 if (init)
6954 gimplify_and_add (init, pre_p);
6956 /* If needed, push the cleanup for the temp. */
6957 if (TARGET_EXPR_CLEANUP (targ))
6959 if (CLEANUP_EH_ONLY (targ))
6960 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
6961 CLEANUP_EH_ONLY (targ), pre_p);
6962 else
6963 cleanup = TARGET_EXPR_CLEANUP (targ);
6966 /* Add a clobber for the temporary going out of scope, like
6967 gimplify_bind_expr. */
6968 if (gimplify_ctxp->in_cleanup_point_expr
6969 && needs_to_live_in_memory (temp))
6971 if (flag_stack_reuse == SR_ALL)
6973 tree clobber = build_clobber (TREE_TYPE (temp));
6974 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
6975 gimple_push_cleanup (temp, clobber, false, pre_p, true);
6977 if (asan_poisoned_variables
6978 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
6979 && !TREE_STATIC (temp)
6980 && dbg_cnt (asan_use_after_scope)
6981 && !gimplify_omp_ctxp)
6983 tree asan_cleanup = build_asan_poison_call_expr (temp);
6984 if (asan_cleanup)
6986 if (unpoison_empty_seq)
6987 unpoison_it = gsi_start (*pre_p);
6989 asan_poison_variable (temp, false, &unpoison_it,
6990 unpoison_empty_seq);
6991 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
6995 if (cleanup)
6996 gimple_push_cleanup (temp, cleanup, false, pre_p);
6998 /* Only expand this once. */
6999 TREE_OPERAND (targ, 3) = init;
7000 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
7002 else
7003 /* We should have expanded this before. */
7004 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
7006 *expr_p = temp;
7007 return GS_OK;
7010 /* Gimplification of expression trees. */
7012 /* Gimplify an expression which appears at statement context. The
7013 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
7014 NULL, a new sequence is allocated.
7016 Return true if we actually added a statement to the queue. */
7018 bool
7019 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
7021 gimple_seq_node last;
7023 last = gimple_seq_last (*seq_p);
7024 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
7025 return last != gimple_seq_last (*seq_p);
7028 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
7029 to CTX. If entries already exist, force them to be some flavor of private.
7030 If there is no enclosing parallel, do nothing. */
7032 void
7033 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
7035 splay_tree_node n;
7037 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
7038 return;
7042 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7043 if (n != NULL)
7045 if (n->value & GOVD_SHARED)
7046 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
7047 else if (n->value & GOVD_MAP)
7048 n->value |= GOVD_MAP_TO_ONLY;
7049 else
7050 return;
7052 else if ((ctx->region_type & ORT_TARGET) != 0)
7054 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
7055 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7056 else
7057 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
7059 else if (ctx->region_type != ORT_WORKSHARE
7060 && ctx->region_type != ORT_TASKGROUP
7061 && ctx->region_type != ORT_SIMD
7062 && ctx->region_type != ORT_ACC
7063 && !(ctx->region_type & ORT_TARGET_DATA))
7064 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7066 ctx = ctx->outer_context;
7068 while (ctx);
7071 /* Similarly for each of the type sizes of TYPE. */
7073 static void
7074 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
7076 if (type == NULL || type == error_mark_node)
7077 return;
7078 type = TYPE_MAIN_VARIANT (type);
7080 if (ctx->privatized_types->add (type))
7081 return;
7083 switch (TREE_CODE (type))
7085 case INTEGER_TYPE:
7086 case ENUMERAL_TYPE:
7087 case BOOLEAN_TYPE:
7088 case REAL_TYPE:
7089 case FIXED_POINT_TYPE:
7090 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
7091 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
7092 break;
7094 case ARRAY_TYPE:
7095 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7096 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
7097 break;
7099 case RECORD_TYPE:
7100 case UNION_TYPE:
7101 case QUAL_UNION_TYPE:
7103 tree field;
7104 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
7105 if (TREE_CODE (field) == FIELD_DECL)
7107 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
7108 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
7111 break;
7113 case POINTER_TYPE:
7114 case REFERENCE_TYPE:
7115 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7116 break;
7118 default:
7119 break;
7122 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
7123 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
7124 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
7127 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
7129 static void
7130 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
7132 splay_tree_node n;
7133 unsigned int nflags;
7134 tree t;
7136 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
7137 return;
7139 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
7140 there are constructors involved somewhere. Exception is a shared clause,
7141 there is nothing privatized in that case. */
7142 if ((flags & GOVD_SHARED) == 0
7143 && (TREE_ADDRESSABLE (TREE_TYPE (decl))
7144 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
7145 flags |= GOVD_SEEN;
7147 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7148 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7150 /* We shouldn't be re-adding the decl with the same data
7151 sharing class. */
7152 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
7153 nflags = n->value | flags;
7154 /* The only combination of data sharing classes we should see is
7155 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
7156 reduction variables to be used in data sharing clauses. */
7157 gcc_assert ((ctx->region_type & ORT_ACC) != 0
7158 || ((nflags & GOVD_DATA_SHARE_CLASS)
7159 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
7160 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
7161 n->value = nflags;
7162 return;
7165 /* When adding a variable-sized variable, we have to handle all sorts
7166 of additional bits of data: the pointer replacement variable, and
7167 the parameters of the type. */
7168 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7170 /* Add the pointer replacement variable as PRIVATE if the variable
7171 replacement is private, else FIRSTPRIVATE since we'll need the
7172 address of the original variable either for SHARED, or for the
7173 copy into or out of the context. */
7174 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
7176 if (flags & GOVD_MAP)
7177 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
7178 else if (flags & GOVD_PRIVATE)
7179 nflags = GOVD_PRIVATE;
7180 else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7181 && (flags & GOVD_FIRSTPRIVATE))
7182 || (ctx->region_type == ORT_TARGET_DATA
7183 && (flags & GOVD_DATA_SHARE_CLASS) == 0))
7184 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
7185 else
7186 nflags = GOVD_FIRSTPRIVATE;
7187 nflags |= flags & GOVD_SEEN;
7188 t = DECL_VALUE_EXPR (decl);
7189 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7190 t = TREE_OPERAND (t, 0);
7191 gcc_assert (DECL_P (t));
7192 omp_add_variable (ctx, t, nflags);
7195 /* Add all of the variable and type parameters (which should have
7196 been gimplified to a formal temporary) as FIRSTPRIVATE. */
7197 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
7198 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
7199 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7201 /* The variable-sized variable itself is never SHARED, only some form
7202 of PRIVATE. The sharing would take place via the pointer variable
7203 which we remapped above. */
7204 if (flags & GOVD_SHARED)
7205 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
7206 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
7208 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7209 alloca statement we generate for the variable, so make sure it
7210 is available. This isn't automatically needed for the SHARED
7211 case, since we won't be allocating local storage then.
7212 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7213 in this case omp_notice_variable will be called later
7214 on when it is gimplified. */
7215 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
7216 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
7217 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
7219 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
7220 && omp_privatize_by_reference (decl))
7222 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7224 /* Similar to the direct variable sized case above, we'll need the
7225 size of references being privatized. */
7226 if ((flags & GOVD_SHARED) == 0)
7228 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7229 if (t && DECL_P (t))
7230 omp_notice_variable (ctx, t, true);
7234 if (n != NULL)
7235 n->value |= flags;
7236 else
7237 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
7239 /* For reductions clauses in OpenACC loop directives, by default create a
7240 copy clause on the enclosing parallel construct for carrying back the
7241 results. */
7242 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
7244 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
7245 while (outer_ctx)
7247 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
7248 if (n != NULL)
7250 /* Ignore local variables and explicitly declared clauses. */
7251 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
7252 break;
7253 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
7255 /* According to the OpenACC spec, such a reduction variable
7256 should already have a copy map on a kernels construct,
7257 verify that here. */
7258 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
7259 && (n->value & GOVD_MAP));
7261 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7263 /* Remove firstprivate and make it a copy map. */
7264 n->value &= ~GOVD_FIRSTPRIVATE;
7265 n->value |= GOVD_MAP;
7268 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7270 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
7271 GOVD_MAP | GOVD_SEEN);
7272 break;
7274 outer_ctx = outer_ctx->outer_context;
7279 /* Notice a threadprivate variable DECL used in OMP context CTX.
7280 This just prints out diagnostics about threadprivate variable uses
7281 in untied tasks. If DECL2 is non-NULL, prevent this warning
7282 on that variable. */
7284 static bool
7285 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
7286 tree decl2)
7288 splay_tree_node n;
7289 struct gimplify_omp_ctx *octx;
7291 for (octx = ctx; octx; octx = octx->outer_context)
7292 if ((octx->region_type & ORT_TARGET) != 0
7293 || octx->order_concurrent)
7295 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
7296 if (n == NULL)
7298 if (octx->order_concurrent)
7300 error ("threadprivate variable %qE used in a region with"
7301 " %<order(concurrent)%> clause", DECL_NAME (decl));
7302 inform (octx->location, "enclosing region");
7304 else
7306 error ("threadprivate variable %qE used in target region",
7307 DECL_NAME (decl));
7308 inform (octx->location, "enclosing target region");
7310 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
7312 if (decl2)
7313 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
7316 if (ctx->region_type != ORT_UNTIED_TASK)
7317 return false;
7318 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7319 if (n == NULL)
7321 error ("threadprivate variable %qE used in untied task",
7322 DECL_NAME (decl));
7323 inform (ctx->location, "enclosing task");
7324 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
7326 if (decl2)
7327 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
7328 return false;
7331 /* Return true if global var DECL is device resident. */
7333 static bool
7334 device_resident_p (tree decl)
7336 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
7338 if (!attr)
7339 return false;
7341 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
7343 tree c = TREE_VALUE (t);
7344 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
7345 return true;
7348 return false;
7351 /* Return true if DECL has an ACC DECLARE attribute. */
7353 static bool
7354 is_oacc_declared (tree decl)
7356 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
7357 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
7358 return declared != NULL_TREE;
7361 /* Determine outer default flags for DECL mentioned in an OMP region
7362 but not declared in an enclosing clause.
7364 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7365 remapped firstprivate instead of shared. To some extent this is
7366 addressed in omp_firstprivatize_type_sizes, but not
7367 effectively. */
7369 static unsigned
7370 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
7371 bool in_code, unsigned flags)
7373 enum omp_clause_default_kind default_kind = ctx->default_kind;
7374 enum omp_clause_default_kind kind;
7376 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
7377 if (ctx->region_type & ORT_TASK)
7379 tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH);
7381 /* The event-handle specified by a detach clause should always be firstprivate,
7382 regardless of the current default. */
7383 if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl)
7384 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
7386 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7387 default_kind = kind;
7388 else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
7389 default_kind = OMP_CLAUSE_DEFAULT_SHARED;
7390 /* For C/C++ default({,first}private), variables with static storage duration
7391 declared in a namespace or global scope and referenced in construct
7392 must be explicitly specified, i.e. acts as default(none). */
7393 else if ((default_kind == OMP_CLAUSE_DEFAULT_PRIVATE
7394 || default_kind == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
7395 && VAR_P (decl)
7396 && is_global_var (decl)
7397 && (DECL_FILE_SCOPE_P (decl)
7398 || (DECL_CONTEXT (decl)
7399 && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
7400 && !lang_GNU_Fortran ())
7401 default_kind = OMP_CLAUSE_DEFAULT_NONE;
7403 switch (default_kind)
7405 case OMP_CLAUSE_DEFAULT_NONE:
7407 const char *rtype;
7409 if (ctx->region_type & ORT_PARALLEL)
7410 rtype = "parallel";
7411 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
7412 rtype = "taskloop";
7413 else if (ctx->region_type & ORT_TASK)
7414 rtype = "task";
7415 else if (ctx->region_type & ORT_TEAMS)
7416 rtype = "teams";
7417 else
7418 gcc_unreachable ();
7420 error ("%qE not specified in enclosing %qs",
7421 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7422 inform (ctx->location, "enclosing %qs", rtype);
7424 /* FALLTHRU */
7425 case OMP_CLAUSE_DEFAULT_SHARED:
7426 flags |= GOVD_SHARED;
7427 break;
7428 case OMP_CLAUSE_DEFAULT_PRIVATE:
7429 flags |= GOVD_PRIVATE;
7430 break;
7431 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7432 flags |= GOVD_FIRSTPRIVATE;
7433 break;
7434 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7435 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7436 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7437 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7439 omp_notice_variable (octx, decl, in_code);
7440 for (; octx; octx = octx->outer_context)
7442 splay_tree_node n2;
7444 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7445 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7446 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7447 continue;
7448 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7450 flags |= GOVD_FIRSTPRIVATE;
7451 goto found_outer;
7453 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7455 flags |= GOVD_SHARED;
7456 goto found_outer;
7461 if (TREE_CODE (decl) == PARM_DECL
7462 || (!is_global_var (decl)
7463 && DECL_CONTEXT (decl) == current_function_decl))
7464 flags |= GOVD_FIRSTPRIVATE;
7465 else
7466 flags |= GOVD_SHARED;
7467 found_outer:
7468 break;
7470 default:
7471 gcc_unreachable ();
7474 return flags;
7478 /* Determine outer default flags for DECL mentioned in an OACC region
7479 but not declared in an enclosing clause. */
7481 static unsigned
7482 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7484 const char *rkind;
7485 bool on_device = false;
7486 bool is_private = false;
7487 bool declared = is_oacc_declared (decl);
7488 tree type = TREE_TYPE (decl);
7490 if (omp_privatize_by_reference (decl))
7491 type = TREE_TYPE (type);
7493 /* For Fortran COMMON blocks, only used variables in those blocks are
7494 transfered and remapped. The block itself will have a private clause to
7495 avoid transfering the data twice.
7496 The hook evaluates to false by default. For a variable in Fortran's COMMON
7497 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7498 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7499 the whole block. For C++ and Fortran, it can also be true under certain
7500 other conditions, if DECL_HAS_VALUE_EXPR. */
7501 if (RECORD_OR_UNION_TYPE_P (type))
7502 is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
7504 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7505 && is_global_var (decl)
7506 && device_resident_p (decl)
7507 && !is_private)
7509 on_device = true;
7510 flags |= GOVD_MAP_TO_ONLY;
7513 switch (ctx->region_type)
7515 case ORT_ACC_KERNELS:
7516 rkind = "kernels";
7518 if (is_private)
7519 flags |= GOVD_FIRSTPRIVATE;
7520 else if (AGGREGATE_TYPE_P (type))
7522 /* Aggregates default to 'present_or_copy', or 'present'. */
7523 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7524 flags |= GOVD_MAP;
7525 else
7526 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7528 else
7529 /* Scalars default to 'copy'. */
7530 flags |= GOVD_MAP | GOVD_MAP_FORCE;
7532 break;
7534 case ORT_ACC_PARALLEL:
7535 case ORT_ACC_SERIAL:
7536 rkind = ctx->region_type == ORT_ACC_PARALLEL ? "parallel" : "serial";
7538 if (is_private)
7539 flags |= GOVD_FIRSTPRIVATE;
7540 else if (on_device || declared)
7541 flags |= GOVD_MAP;
7542 else if (AGGREGATE_TYPE_P (type))
7544 /* Aggregates default to 'present_or_copy', or 'present'. */
7545 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7546 flags |= GOVD_MAP;
7547 else
7548 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7550 else
7551 /* Scalars default to 'firstprivate'. */
7552 flags |= GOVD_FIRSTPRIVATE;
7554 break;
7556 default:
7557 gcc_unreachable ();
7560 if (DECL_ARTIFICIAL (decl))
7561 ; /* We can get compiler-generated decls, and should not complain
7562 about them. */
7563 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7565 error ("%qE not specified in enclosing OpenACC %qs construct",
7566 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
7567 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
7569 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7570 ; /* Handled above. */
7571 else
7572 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7574 return flags;
7577 /* Record the fact that DECL was used within the OMP context CTX.
7578 IN_CODE is true when real code uses DECL, and false when we should
7579 merely emit default(none) errors. Return true if DECL is going to
7580 be remapped and thus DECL shouldn't be gimplified into its
7581 DECL_VALUE_EXPR (if any). */
7583 static bool
7584 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7586 splay_tree_node n;
7587 unsigned flags = in_code ? GOVD_SEEN : 0;
7588 bool ret = false, shared;
7590 if (error_operand_p (decl))
7591 return false;
7593 if (ctx->region_type == ORT_NONE)
7594 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7596 if (is_global_var (decl))
7598 /* Threadprivate variables are predetermined. */
7599 if (DECL_THREAD_LOCAL_P (decl))
7600 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7602 if (DECL_HAS_VALUE_EXPR_P (decl))
7604 if (ctx->region_type & ORT_ACC)
7605 /* For OpenACC, defer expansion of value to avoid transfering
7606 privatized common block data instead of im-/explicitly transfered
7607 variables which are in common blocks. */
7609 else
7611 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7613 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7614 return omp_notice_threadprivate_variable (ctx, decl, value);
7618 if (gimplify_omp_ctxp->outer_context == NULL
7619 && VAR_P (decl)
7620 && oacc_get_fn_attrib (current_function_decl))
7622 location_t loc = DECL_SOURCE_LOCATION (decl);
7624 if (lookup_attribute ("omp declare target link",
7625 DECL_ATTRIBUTES (decl)))
7627 error_at (loc,
7628 "%qE with %<link%> clause used in %<routine%> function",
7629 DECL_NAME (decl));
7630 return false;
7632 else if (!lookup_attribute ("omp declare target",
7633 DECL_ATTRIBUTES (decl)))
7635 error_at (loc,
7636 "%qE requires a %<declare%> directive for use "
7637 "in a %<routine%> function", DECL_NAME (decl));
7638 return false;
7643 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7644 if ((ctx->region_type & ORT_TARGET) != 0)
7646 if (ctx->region_type & ORT_ACC)
7647 /* For OpenACC, as remarked above, defer expansion. */
7648 shared = false;
7649 else
7650 shared = true;
7652 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7653 if (n == NULL)
7655 unsigned nflags = flags;
7656 if ((ctx->region_type & ORT_ACC) == 0)
7658 bool is_declare_target = false;
7659 if (is_global_var (decl)
7660 && varpool_node::get_create (decl)->offloadable)
7662 struct gimplify_omp_ctx *octx;
7663 for (octx = ctx->outer_context;
7664 octx; octx = octx->outer_context)
7666 n = splay_tree_lookup (octx->variables,
7667 (splay_tree_key)decl);
7668 if (n
7669 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7670 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7671 break;
7673 is_declare_target = octx == NULL;
7675 if (!is_declare_target)
7677 int gdmk;
7678 enum omp_clause_defaultmap_kind kind;
7679 if (lang_hooks.decls.omp_allocatable_p (decl))
7680 gdmk = GDMK_ALLOCATABLE;
7681 else if (lang_hooks.decls.omp_scalar_target_p (decl))
7682 gdmk = GDMK_SCALAR_TARGET;
7683 else if (lang_hooks.decls.omp_scalar_p (decl, false))
7684 gdmk = GDMK_SCALAR;
7685 else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7686 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7687 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7688 == POINTER_TYPE)))
7689 gdmk = GDMK_POINTER;
7690 else
7691 gdmk = GDMK_AGGREGATE;
7692 kind = lang_hooks.decls.omp_predetermined_mapping (decl);
7693 if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
7695 if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
7696 nflags |= GOVD_FIRSTPRIVATE;
7697 else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
7698 nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
7699 else
7700 gcc_unreachable ();
7702 else if (ctx->defaultmap[gdmk] == 0)
7704 tree d = lang_hooks.decls.omp_report_decl (decl);
7705 error ("%qE not specified in enclosing %<target%>",
7706 DECL_NAME (d));
7707 inform (ctx->location, "enclosing %<target%>");
7709 else if (ctx->defaultmap[gdmk]
7710 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
7711 nflags |= ctx->defaultmap[gdmk];
7712 else
7714 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
7715 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
7720 struct gimplify_omp_ctx *octx = ctx->outer_context;
7721 if ((ctx->region_type & ORT_ACC) && octx)
7723 /* Look in outer OpenACC contexts, to see if there's a
7724 data attribute for this variable. */
7725 omp_notice_variable (octx, decl, in_code);
7727 for (; octx; octx = octx->outer_context)
7729 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7730 break;
7731 splay_tree_node n2
7732 = splay_tree_lookup (octx->variables,
7733 (splay_tree_key) decl);
7734 if (n2)
7736 if (octx->region_type == ORT_ACC_HOST_DATA)
7737 error ("variable %qE declared in enclosing "
7738 "%<host_data%> region", DECL_NAME (decl));
7739 nflags |= GOVD_MAP;
7740 if (octx->region_type == ORT_ACC_DATA
7741 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7742 nflags |= GOVD_MAP_0LEN_ARRAY;
7743 goto found_outer;
7748 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
7749 | GOVD_MAP_ALLOC_ONLY)) == flags)
7751 tree type = TREE_TYPE (decl);
7753 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
7754 && omp_privatize_by_reference (decl))
7755 type = TREE_TYPE (type);
7756 if (!lang_hooks.types.omp_mappable_type (type))
7758 error ("%qD referenced in target region does not have "
7759 "a mappable type", decl);
7760 nflags |= GOVD_MAP | GOVD_EXPLICIT;
7762 else
7764 if ((ctx->region_type & ORT_ACC) != 0)
7765 nflags = oacc_default_clause (ctx, decl, flags);
7766 else
7767 nflags |= GOVD_MAP;
7770 found_outer:
7771 omp_add_variable (ctx, decl, nflags);
7773 else
7775 /* If nothing changed, there's nothing left to do. */
7776 if ((n->value & flags) == flags)
7777 return ret;
7778 flags |= n->value;
7779 n->value = flags;
7781 goto do_outer;
7784 if (n == NULL)
7786 if (ctx->region_type == ORT_WORKSHARE
7787 || ctx->region_type == ORT_TASKGROUP
7788 || ctx->region_type == ORT_SIMD
7789 || ctx->region_type == ORT_ACC
7790 || (ctx->region_type & ORT_TARGET_DATA) != 0)
7791 goto do_outer;
7793 flags = omp_default_clause (ctx, decl, in_code, flags);
7795 if ((flags & GOVD_PRIVATE)
7796 && lang_hooks.decls.omp_private_outer_ref (decl))
7797 flags |= GOVD_PRIVATE_OUTER_REF;
7799 omp_add_variable (ctx, decl, flags);
7801 shared = (flags & GOVD_SHARED) != 0;
7802 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7803 goto do_outer;
7806 /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
7807 lb, b or incr expressions, those shouldn't be turned into simd arrays. */
7808 if (ctx->region_type == ORT_SIMD
7809 && ctx->in_for_exprs
7810 && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
7811 == GOVD_PRIVATE))
7812 flags &= ~GOVD_SEEN;
7814 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7815 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7816 && DECL_SIZE (decl))
7818 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7820 splay_tree_node n2;
7821 tree t = DECL_VALUE_EXPR (decl);
7822 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7823 t = TREE_OPERAND (t, 0);
7824 gcc_assert (DECL_P (t));
7825 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7826 n2->value |= GOVD_SEEN;
7828 else if (omp_privatize_by_reference (decl)
7829 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7830 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7831 != INTEGER_CST))
7833 splay_tree_node n2;
7834 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7835 gcc_assert (DECL_P (t));
7836 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7837 if (n2)
7838 omp_notice_variable (ctx, t, true);
7842 if (ctx->region_type & ORT_ACC)
7843 /* For OpenACC, as remarked above, defer expansion. */
7844 shared = false;
7845 else
7846 shared = ((flags | n->value) & GOVD_SHARED) != 0;
7847 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7849 /* If nothing changed, there's nothing left to do. */
7850 if ((n->value & flags) == flags)
7851 return ret;
7852 flags |= n->value;
7853 n->value = flags;
7855 do_outer:
7856 /* If the variable is private in the current context, then we don't
7857 need to propagate anything to an outer context. */
7858 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7859 return ret;
7860 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7861 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7862 return ret;
7863 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7864 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7865 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7866 return ret;
7867 if (ctx->outer_context
7868 && omp_notice_variable (ctx->outer_context, decl, in_code))
7869 return true;
7870 return ret;
7873 /* Verify that DECL is private within CTX. If there's specific information
7874 to the contrary in the innermost scope, generate an error. */
7876 static bool
7877 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
7879 splay_tree_node n;
7881 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7882 if (n != NULL)
7884 if (n->value & GOVD_SHARED)
7886 if (ctx == gimplify_omp_ctxp)
7888 if (simd)
7889 error ("iteration variable %qE is predetermined linear",
7890 DECL_NAME (decl));
7891 else
7892 error ("iteration variable %qE should be private",
7893 DECL_NAME (decl));
7894 n->value = GOVD_PRIVATE;
7895 return true;
7897 else
7898 return false;
7900 else if ((n->value & GOVD_EXPLICIT) != 0
7901 && (ctx == gimplify_omp_ctxp
7902 || (ctx->region_type == ORT_COMBINED_PARALLEL
7903 && gimplify_omp_ctxp->outer_context == ctx)))
7905 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
7906 error ("iteration variable %qE should not be firstprivate",
7907 DECL_NAME (decl));
7908 else if ((n->value & GOVD_REDUCTION) != 0)
7909 error ("iteration variable %qE should not be reduction",
7910 DECL_NAME (decl));
7911 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
7912 error ("iteration variable %qE should not be linear",
7913 DECL_NAME (decl));
7915 return (ctx == gimplify_omp_ctxp
7916 || (ctx->region_type == ORT_COMBINED_PARALLEL
7917 && gimplify_omp_ctxp->outer_context == ctx));
7920 if (ctx->region_type != ORT_WORKSHARE
7921 && ctx->region_type != ORT_TASKGROUP
7922 && ctx->region_type != ORT_SIMD
7923 && ctx->region_type != ORT_ACC)
7924 return false;
7925 else if (ctx->outer_context)
7926 return omp_is_private (ctx->outer_context, decl, simd);
7927 return false;
7930 /* Return true if DECL is private within a parallel region
7931 that binds to the current construct's context or in parallel
7932 region's REDUCTION clause. */
7934 static bool
7935 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
7937 splay_tree_node n;
7941 ctx = ctx->outer_context;
7942 if (ctx == NULL)
7944 if (is_global_var (decl))
7945 return false;
7947 /* References might be private, but might be shared too,
7948 when checking for copyprivate, assume they might be
7949 private, otherwise assume they might be shared. */
7950 if (copyprivate)
7951 return true;
7953 if (omp_privatize_by_reference (decl))
7954 return false;
7956 /* Treat C++ privatized non-static data members outside
7957 of the privatization the same. */
7958 if (omp_member_access_dummy_var (decl))
7959 return false;
7961 return true;
7964 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
7966 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7967 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
7969 if ((ctx->region_type & ORT_TARGET_DATA) != 0
7970 || n == NULL
7971 || (n->value & GOVD_MAP) == 0)
7972 continue;
7973 return false;
7976 if (n != NULL)
7978 if ((n->value & GOVD_LOCAL) != 0
7979 && omp_member_access_dummy_var (decl))
7980 return false;
7981 return (n->value & GOVD_SHARED) == 0;
7984 if (ctx->region_type == ORT_WORKSHARE
7985 || ctx->region_type == ORT_TASKGROUP
7986 || ctx->region_type == ORT_SIMD
7987 || ctx->region_type == ORT_ACC)
7988 continue;
7990 break;
7992 while (1);
7993 return false;
7996 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7998 static tree
7999 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
8001 tree t = *tp;
8003 /* If this node has been visited, unmark it and keep looking. */
8004 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
8005 return t;
8007 if (IS_TYPE_OR_DECL_P (t))
8008 *walk_subtrees = 0;
8009 return NULL_TREE;
8013 /* Gimplify the affinity clause but effectively ignore it.
8014 Generate:
8015 var = begin;
8016 if ((step > 1) ? var <= end : var > end)
8017 locatator_var_expr; */
8019 static void
8020 gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p)
8022 tree last_iter = NULL_TREE;
8023 tree last_bind = NULL_TREE;
8024 tree label = NULL_TREE;
8025 tree *last_body = NULL;
8026 for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8027 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
8029 tree t = OMP_CLAUSE_DECL (c);
8030 if (TREE_CODE (t) == TREE_LIST
8031 && TREE_PURPOSE (t)
8032 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8034 if (TREE_VALUE (t) == null_pointer_node)
8035 continue;
8036 if (TREE_PURPOSE (t) != last_iter)
8038 if (last_bind)
8040 append_to_statement_list (label, last_body);
8041 gimplify_and_add (last_bind, pre_p);
8042 last_bind = NULL_TREE;
8044 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8046 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8047 is_gimple_val, fb_rvalue) == GS_ERROR
8048 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8049 is_gimple_val, fb_rvalue) == GS_ERROR
8050 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8051 is_gimple_val, fb_rvalue) == GS_ERROR
8052 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8053 is_gimple_val, fb_rvalue)
8054 == GS_ERROR))
8055 return;
8057 last_iter = TREE_PURPOSE (t);
8058 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8059 last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
8060 NULL, block);
8061 last_body = &BIND_EXPR_BODY (last_bind);
8062 tree cond = NULL_TREE;
8063 location_t loc = OMP_CLAUSE_LOCATION (c);
8064 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8066 tree var = TREE_VEC_ELT (it, 0);
8067 tree begin = TREE_VEC_ELT (it, 1);
8068 tree end = TREE_VEC_ELT (it, 2);
8069 tree step = TREE_VEC_ELT (it, 3);
8070 loc = DECL_SOURCE_LOCATION (var);
8071 tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8072 var, begin);
8073 append_to_statement_list_force (tem, last_body);
8075 tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8076 step, build_zero_cst (TREE_TYPE (step)));
8077 tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node,
8078 var, end);
8079 tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8080 var, end);
8081 cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node,
8082 cond1, cond2, cond3);
8083 if (cond)
8084 cond = fold_build2_loc (loc, TRUTH_AND_EXPR,
8085 boolean_type_node, cond, cond1);
8086 else
8087 cond = cond1;
8089 tree cont_label = create_artificial_label (loc);
8090 label = build1 (LABEL_EXPR, void_type_node, cont_label);
8091 tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
8092 void_node,
8093 build_and_jump (&cont_label));
8094 append_to_statement_list_force (tem, last_body);
8096 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8098 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0),
8099 last_body);
8100 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8102 if (error_operand_p (TREE_VALUE (t)))
8103 return;
8104 append_to_statement_list_force (TREE_VALUE (t), last_body);
8105 TREE_VALUE (t) = null_pointer_node;
8107 else
8109 if (last_bind)
8111 append_to_statement_list (label, last_body);
8112 gimplify_and_add (last_bind, pre_p);
8113 last_bind = NULL_TREE;
8115 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8117 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8118 NULL, is_gimple_val, fb_rvalue);
8119 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8121 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8122 return;
8123 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8124 is_gimple_val, fb_rvalue) == GS_ERROR)
8125 return;
8126 gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p);
8129 if (last_bind)
8131 append_to_statement_list (label, last_body);
8132 gimplify_and_add (last_bind, pre_p);
8134 return;
8137 /* If *LIST_P contains any OpenMP depend clauses with iterators,
8138 lower all the depend clauses by populating corresponding depend
8139 array. Returns 0 if there are no such depend clauses, or
8140 2 if all depend clauses should be removed, 1 otherwise. */
8142 static int
8143 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
8145 tree c;
8146 gimple *g;
8147 size_t n[4] = { 0, 0, 0, 0 };
8148 bool unused[4];
8149 tree counts[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
8150 tree last_iter = NULL_TREE, last_count = NULL_TREE;
8151 size_t i, j;
8152 location_t first_loc = UNKNOWN_LOCATION;
8154 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8155 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8157 switch (OMP_CLAUSE_DEPEND_KIND (c))
8159 case OMP_CLAUSE_DEPEND_IN:
8160 i = 2;
8161 break;
8162 case OMP_CLAUSE_DEPEND_OUT:
8163 case OMP_CLAUSE_DEPEND_INOUT:
8164 i = 0;
8165 break;
8166 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8167 i = 1;
8168 break;
8169 case OMP_CLAUSE_DEPEND_DEPOBJ:
8170 i = 3;
8171 break;
8172 case OMP_CLAUSE_DEPEND_SOURCE:
8173 case OMP_CLAUSE_DEPEND_SINK:
8174 continue;
8175 default:
8176 gcc_unreachable ();
8178 tree t = OMP_CLAUSE_DECL (c);
8179 if (first_loc == UNKNOWN_LOCATION)
8180 first_loc = OMP_CLAUSE_LOCATION (c);
8181 if (TREE_CODE (t) == TREE_LIST
8182 && TREE_PURPOSE (t)
8183 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8185 if (TREE_PURPOSE (t) != last_iter)
8187 tree tcnt = size_one_node;
8188 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8190 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8191 is_gimple_val, fb_rvalue) == GS_ERROR
8192 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8193 is_gimple_val, fb_rvalue) == GS_ERROR
8194 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8195 is_gimple_val, fb_rvalue) == GS_ERROR
8196 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8197 is_gimple_val, fb_rvalue)
8198 == GS_ERROR))
8199 return 2;
8200 tree var = TREE_VEC_ELT (it, 0);
8201 tree begin = TREE_VEC_ELT (it, 1);
8202 tree end = TREE_VEC_ELT (it, 2);
8203 tree step = TREE_VEC_ELT (it, 3);
8204 tree orig_step = TREE_VEC_ELT (it, 4);
8205 tree type = TREE_TYPE (var);
8206 tree stype = TREE_TYPE (step);
8207 location_t loc = DECL_SOURCE_LOCATION (var);
8208 tree endmbegin;
8209 /* Compute count for this iterator as
8210 orig_step > 0
8211 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
8212 : (begin > end ? (end - begin + (step + 1)) / step : 0)
8213 and compute product of those for the entire depend
8214 clause. */
8215 if (POINTER_TYPE_P (type))
8216 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
8217 stype, end, begin);
8218 else
8219 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
8220 end, begin);
8221 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
8222 step,
8223 build_int_cst (stype, 1));
8224 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
8225 build_int_cst (stype, 1));
8226 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
8227 unshare_expr (endmbegin),
8228 stepm1);
8229 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8230 pos, step);
8231 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
8232 endmbegin, stepp1);
8233 if (TYPE_UNSIGNED (stype))
8235 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
8236 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
8238 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8239 neg, step);
8240 step = NULL_TREE;
8241 tree cond = fold_build2_loc (loc, LT_EXPR,
8242 boolean_type_node,
8243 begin, end);
8244 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
8245 build_int_cst (stype, 0));
8246 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
8247 end, begin);
8248 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
8249 build_int_cst (stype, 0));
8250 tree osteptype = TREE_TYPE (orig_step);
8251 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8252 orig_step,
8253 build_int_cst (osteptype, 0));
8254 tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
8255 cond, pos, neg);
8256 cnt = fold_convert_loc (loc, sizetype, cnt);
8257 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
8258 fb_rvalue) == GS_ERROR)
8259 return 2;
8260 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
8262 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
8263 fb_rvalue) == GS_ERROR)
8264 return 2;
8265 last_iter = TREE_PURPOSE (t);
8266 last_count = tcnt;
8268 if (counts[i] == NULL_TREE)
8269 counts[i] = last_count;
8270 else
8271 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
8272 PLUS_EXPR, counts[i], last_count);
8274 else
8275 n[i]++;
8277 for (i = 0; i < 4; i++)
8278 if (counts[i])
8279 break;
8280 if (i == 4)
8281 return 0;
8283 tree total = size_zero_node;
8284 for (i = 0; i < 4; i++)
8286 unused[i] = counts[i] == NULL_TREE && n[i] == 0;
8287 if (counts[i] == NULL_TREE)
8288 counts[i] = size_zero_node;
8289 if (n[i])
8290 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
8291 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
8292 fb_rvalue) == GS_ERROR)
8293 return 2;
8294 total = size_binop (PLUS_EXPR, total, counts[i]);
8297 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
8298 == GS_ERROR)
8299 return 2;
8300 bool is_old = unused[1] && unused[3];
8301 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
8302 size_int (is_old ? 1 : 4));
8303 tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
8304 tree array = create_tmp_var_raw (type);
8305 TREE_ADDRESSABLE (array) = 1;
8306 if (!poly_int_tree_p (totalpx))
8308 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
8309 gimplify_type_sizes (TREE_TYPE (array), pre_p);
8310 if (gimplify_omp_ctxp)
8312 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8313 while (ctx
8314 && (ctx->region_type == ORT_WORKSHARE
8315 || ctx->region_type == ORT_TASKGROUP
8316 || ctx->region_type == ORT_SIMD
8317 || ctx->region_type == ORT_ACC))
8318 ctx = ctx->outer_context;
8319 if (ctx)
8320 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
8322 gimplify_vla_decl (array, pre_p);
8324 else
8325 gimple_add_tmp_var (array);
8326 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
8327 NULL_TREE);
8328 tree tem;
8329 if (!is_old)
8331 tem = build2 (MODIFY_EXPR, void_type_node, r,
8332 build_int_cst (ptr_type_node, 0));
8333 gimplify_and_add (tem, pre_p);
8334 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
8335 NULL_TREE);
8337 tem = build2 (MODIFY_EXPR, void_type_node, r,
8338 fold_convert (ptr_type_node, total));
8339 gimplify_and_add (tem, pre_p);
8340 for (i = 1; i < (is_old ? 2 : 4); i++)
8342 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
8343 NULL_TREE, NULL_TREE);
8344 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
8345 gimplify_and_add (tem, pre_p);
8348 tree cnts[4];
8349 for (j = 4; j; j--)
8350 if (!unused[j - 1])
8351 break;
8352 for (i = 0; i < 4; i++)
8354 if (i && (i >= j || unused[i - 1]))
8356 cnts[i] = cnts[i - 1];
8357 continue;
8359 cnts[i] = create_tmp_var (sizetype);
8360 if (i == 0)
8361 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
8362 else
8364 tree t;
8365 if (is_old)
8366 t = size_binop (PLUS_EXPR, counts[0], size_int (2));
8367 else
8368 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
8369 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
8370 == GS_ERROR)
8371 return 2;
8372 g = gimple_build_assign (cnts[i], t);
8374 gimple_seq_add_stmt (pre_p, g);
8377 last_iter = NULL_TREE;
8378 tree last_bind = NULL_TREE;
8379 tree *last_body = NULL;
8380 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8381 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8383 switch (OMP_CLAUSE_DEPEND_KIND (c))
8385 case OMP_CLAUSE_DEPEND_IN:
8386 i = 2;
8387 break;
8388 case OMP_CLAUSE_DEPEND_OUT:
8389 case OMP_CLAUSE_DEPEND_INOUT:
8390 i = 0;
8391 break;
8392 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8393 i = 1;
8394 break;
8395 case OMP_CLAUSE_DEPEND_DEPOBJ:
8396 i = 3;
8397 break;
8398 case OMP_CLAUSE_DEPEND_SOURCE:
8399 case OMP_CLAUSE_DEPEND_SINK:
8400 continue;
8401 default:
8402 gcc_unreachable ();
8404 tree t = OMP_CLAUSE_DECL (c);
8405 if (TREE_CODE (t) == TREE_LIST
8406 && TREE_PURPOSE (t)
8407 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8409 if (TREE_PURPOSE (t) != last_iter)
8411 if (last_bind)
8412 gimplify_and_add (last_bind, pre_p);
8413 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8414 last_bind = build3 (BIND_EXPR, void_type_node,
8415 BLOCK_VARS (block), NULL, block);
8416 TREE_SIDE_EFFECTS (last_bind) = 1;
8417 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
8418 tree *p = &BIND_EXPR_BODY (last_bind);
8419 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8421 tree var = TREE_VEC_ELT (it, 0);
8422 tree begin = TREE_VEC_ELT (it, 1);
8423 tree end = TREE_VEC_ELT (it, 2);
8424 tree step = TREE_VEC_ELT (it, 3);
8425 tree orig_step = TREE_VEC_ELT (it, 4);
8426 tree type = TREE_TYPE (var);
8427 location_t loc = DECL_SOURCE_LOCATION (var);
8428 /* Emit:
8429 var = begin;
8430 goto cond_label;
8431 beg_label:
8433 var = var + step;
8434 cond_label:
8435 if (orig_step > 0) {
8436 if (var < end) goto beg_label;
8437 } else {
8438 if (var > end) goto beg_label;
8440 for each iterator, with inner iterators added to
8441 the ... above. */
8442 tree beg_label = create_artificial_label (loc);
8443 tree cond_label = NULL_TREE;
8444 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8445 var, begin);
8446 append_to_statement_list_force (tem, p);
8447 tem = build_and_jump (&cond_label);
8448 append_to_statement_list_force (tem, p);
8449 tem = build1 (LABEL_EXPR, void_type_node, beg_label);
8450 append_to_statement_list (tem, p);
8451 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
8452 NULL_TREE, NULL_TREE);
8453 TREE_SIDE_EFFECTS (bind) = 1;
8454 SET_EXPR_LOCATION (bind, loc);
8455 append_to_statement_list_force (bind, p);
8456 if (POINTER_TYPE_P (type))
8457 tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
8458 var, fold_convert_loc (loc, sizetype,
8459 step));
8460 else
8461 tem = build2_loc (loc, PLUS_EXPR, type, var, step);
8462 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8463 var, tem);
8464 append_to_statement_list_force (tem, p);
8465 tem = build1 (LABEL_EXPR, void_type_node, cond_label);
8466 append_to_statement_list (tem, p);
8467 tree cond = fold_build2_loc (loc, LT_EXPR,
8468 boolean_type_node,
8469 var, end);
8470 tree pos
8471 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8472 cond, build_and_jump (&beg_label),
8473 void_node);
8474 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8475 var, end);
8476 tree neg
8477 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8478 cond, build_and_jump (&beg_label),
8479 void_node);
8480 tree osteptype = TREE_TYPE (orig_step);
8481 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8482 orig_step,
8483 build_int_cst (osteptype, 0));
8484 tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
8485 cond, pos, neg);
8486 append_to_statement_list_force (tem, p);
8487 p = &BIND_EXPR_BODY (bind);
8489 last_body = p;
8491 last_iter = TREE_PURPOSE (t);
8492 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8494 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
8495 0), last_body);
8496 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8498 if (error_operand_p (TREE_VALUE (t)))
8499 return 2;
8500 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
8501 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8502 NULL_TREE, NULL_TREE);
8503 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8504 void_type_node, r, TREE_VALUE (t));
8505 append_to_statement_list_force (tem, last_body);
8506 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8507 void_type_node, cnts[i],
8508 size_binop (PLUS_EXPR, cnts[i], size_int (1)));
8509 append_to_statement_list_force (tem, last_body);
8510 TREE_VALUE (t) = null_pointer_node;
8512 else
8514 if (last_bind)
8516 gimplify_and_add (last_bind, pre_p);
8517 last_bind = NULL_TREE;
8519 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8521 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8522 NULL, is_gimple_val, fb_rvalue);
8523 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8525 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8526 return 2;
8527 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8528 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8529 is_gimple_val, fb_rvalue) == GS_ERROR)
8530 return 2;
8531 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8532 NULL_TREE, NULL_TREE);
8533 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
8534 gimplify_and_add (tem, pre_p);
8535 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, cnts[i],
8536 size_int (1)));
8537 gimple_seq_add_stmt (pre_p, g);
8540 if (last_bind)
8541 gimplify_and_add (last_bind, pre_p);
8542 tree cond = boolean_false_node;
8543 if (is_old)
8545 if (!unused[0])
8546 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
8547 size_binop_loc (first_loc, PLUS_EXPR, counts[0],
8548 size_int (2)));
8549 if (!unused[2])
8550 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8551 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8552 cnts[2],
8553 size_binop_loc (first_loc, PLUS_EXPR,
8554 totalpx,
8555 size_int (1))));
8557 else
8559 tree prev = size_int (5);
8560 for (i = 0; i < 4; i++)
8562 if (unused[i])
8563 continue;
8564 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
8565 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8566 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8567 cnts[i], unshare_expr (prev)));
8570 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
8571 build_call_expr_loc (first_loc,
8572 builtin_decl_explicit (BUILT_IN_TRAP),
8573 0), void_node);
8574 gimplify_and_add (tem, pre_p);
8575 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
8576 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
8577 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
8578 OMP_CLAUSE_CHAIN (c) = *list_p;
8579 *list_p = c;
8580 return 1;
8583 /* Insert a GOMP_MAP_ALLOC or GOMP_MAP_RELEASE node following a
8584 GOMP_MAP_STRUCT mapping. C is an always_pointer mapping. STRUCT_NODE is
8585 the struct node to insert the new mapping after (when the struct node is
8586 initially created). PREV_NODE is the first of two or three mappings for a
8587 pointer, and is either:
8588 - the node before C, when a pair of mappings is used, e.g. for a C/C++
8589 array section.
8590 - not the node before C. This is true when we have a reference-to-pointer
8591 type (with a mapping for the reference and for the pointer), or for
8592 Fortran derived-type mappings with a GOMP_MAP_TO_PSET.
8593 If SCP is non-null, the new node is inserted before *SCP.
8594 if SCP is null, the new node is inserted before PREV_NODE.
8595 The return type is:
8596 - PREV_NODE, if SCP is non-null.
8597 - The newly-created ALLOC or RELEASE node, if SCP is null.
8598 - The second newly-created ALLOC or RELEASE node, if we are mapping a
8599 reference to a pointer. */
8601 static tree
8602 insert_struct_comp_map (enum tree_code code, tree c, tree struct_node,
8603 tree prev_node, tree *scp)
8605 enum gomp_map_kind mkind
8606 = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
8607 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8609 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8610 tree cl = scp ? prev_node : c2;
8611 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8612 OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (c));
8613 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : prev_node;
8614 if (OMP_CLAUSE_CHAIN (prev_node) != c
8615 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8616 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8617 == GOMP_MAP_TO_PSET))
8618 OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (OMP_CLAUSE_CHAIN (prev_node));
8619 else
8620 OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
8621 if (struct_node)
8622 OMP_CLAUSE_CHAIN (struct_node) = c2;
8624 /* We might need to create an additional mapping if we have a reference to a
8625 pointer (in C++). Don't do this if we have something other than a
8626 GOMP_MAP_ALWAYS_POINTER though, i.e. a GOMP_MAP_TO_PSET. */
8627 if (OMP_CLAUSE_CHAIN (prev_node) != c
8628 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8629 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8630 == GOMP_MAP_ALWAYS_POINTER)
8631 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8632 == GOMP_MAP_ATTACH_DETACH)))
8634 tree c4 = OMP_CLAUSE_CHAIN (prev_node);
8635 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8636 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8637 OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (c4));
8638 OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
8639 OMP_CLAUSE_CHAIN (c3) = prev_node;
8640 if (!scp)
8641 OMP_CLAUSE_CHAIN (c2) = c3;
8642 else
8643 cl = c3;
8646 if (scp)
8647 *scp = c2;
8649 return cl;
8652 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
8653 and set *BITPOSP and *POFFSETP to the bit offset of the access.
8654 If BASE_REF is non-NULL and the containing object is a reference, set
8655 *BASE_REF to that reference before dereferencing the object.
8656 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
8657 has array type, else return NULL. */
8659 static tree
8660 extract_base_bit_offset (tree base, tree *base_ref, poly_int64 *bitposp,
8661 poly_offset_int *poffsetp)
8663 tree offset;
8664 poly_int64 bitsize, bitpos;
8665 machine_mode mode;
8666 int unsignedp, reversep, volatilep = 0;
8667 poly_offset_int poffset;
8669 if (base_ref)
8671 *base_ref = NULL_TREE;
8673 while (TREE_CODE (base) == ARRAY_REF)
8674 base = TREE_OPERAND (base, 0);
8676 if (TREE_CODE (base) == INDIRECT_REF)
8677 base = TREE_OPERAND (base, 0);
8679 else
8681 if (TREE_CODE (base) == ARRAY_REF)
8683 while (TREE_CODE (base) == ARRAY_REF)
8684 base = TREE_OPERAND (base, 0);
8685 if (TREE_CODE (base) != COMPONENT_REF
8686 || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
8687 return NULL_TREE;
8689 else if (TREE_CODE (base) == INDIRECT_REF
8690 && TREE_CODE (TREE_OPERAND (base, 0)) == COMPONENT_REF
8691 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
8692 == REFERENCE_TYPE))
8693 base = TREE_OPERAND (base, 0);
8696 base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
8697 &unsignedp, &reversep, &volatilep);
8699 tree orig_base = base;
8701 if ((TREE_CODE (base) == INDIRECT_REF
8702 || (TREE_CODE (base) == MEM_REF
8703 && integer_zerop (TREE_OPERAND (base, 1))))
8704 && DECL_P (TREE_OPERAND (base, 0))
8705 && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == REFERENCE_TYPE)
8706 base = TREE_OPERAND (base, 0);
8708 gcc_assert (offset == NULL_TREE || poly_int_tree_p (offset));
8710 if (offset)
8711 poffset = wi::to_poly_offset (offset);
8712 else
8713 poffset = 0;
8715 if (maybe_ne (bitpos, 0))
8716 poffset += bits_to_bytes_round_down (bitpos);
8718 *bitposp = bitpos;
8719 *poffsetp = poffset;
8721 /* Set *BASE_REF if BASE was a dereferenced reference variable. */
8722 if (base_ref && orig_base != base)
8723 *base_ref = orig_base;
8725 return base;
8728 /* Returns true if EXPR is or contains (as a sub-component) BASE_PTR. */
8730 static bool
8731 is_or_contains_p (tree expr, tree base_ptr)
8733 while (expr != base_ptr)
8734 if (TREE_CODE (base_ptr) == COMPONENT_REF)
8735 base_ptr = TREE_OPERAND (base_ptr, 0);
8736 else
8737 break;
8738 return expr == base_ptr;
8741 /* Implement OpenMP 5.x map ordering rules for target directives. There are
8742 several rules, and with some level of ambiguity, hopefully we can at least
8743 collect the complexity here in one place. */
8745 static void
8746 omp_target_reorder_clauses (tree *list_p)
8748 /* Collect refs to alloc/release/delete maps. */
8749 auto_vec<tree, 32> ard;
8750 tree *cp = list_p;
8751 while (*cp != NULL_TREE)
8752 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8753 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALLOC
8754 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_RELEASE
8755 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_DELETE))
8757 /* Unlink cp and push to ard. */
8758 tree c = *cp;
8759 tree nc = OMP_CLAUSE_CHAIN (c);
8760 *cp = nc;
8761 ard.safe_push (c);
8763 /* Any associated pointer type maps should also move along. */
8764 while (*cp != NULL_TREE
8765 && OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8766 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
8767 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_POINTER
8768 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH
8769 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_POINTER
8770 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALWAYS_POINTER
8771 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_TO_PSET))
8773 c = *cp;
8774 nc = OMP_CLAUSE_CHAIN (c);
8775 *cp = nc;
8776 ard.safe_push (c);
8779 else
8780 cp = &OMP_CLAUSE_CHAIN (*cp);
8782 /* Link alloc/release/delete maps to the end of list. */
8783 for (unsigned int i = 0; i < ard.length (); i++)
8785 *cp = ard[i];
8786 cp = &OMP_CLAUSE_CHAIN (ard[i]);
8788 *cp = NULL_TREE;
8790 /* OpenMP 5.0 requires that pointer variables are mapped before
8791 its use as a base-pointer. */
8792 auto_vec<tree *, 32> atf;
8793 for (tree *cp = list_p; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
8794 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
8796 /* Collect alloc, to, from, to/from clause tree pointers. */
8797 gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
8798 if (k == GOMP_MAP_ALLOC
8799 || k == GOMP_MAP_TO
8800 || k == GOMP_MAP_FROM
8801 || k == GOMP_MAP_TOFROM
8802 || k == GOMP_MAP_ALWAYS_TO
8803 || k == GOMP_MAP_ALWAYS_FROM
8804 || k == GOMP_MAP_ALWAYS_TOFROM)
8805 atf.safe_push (cp);
8808 for (unsigned int i = 0; i < atf.length (); i++)
8809 if (atf[i])
8811 tree *cp = atf[i];
8812 tree decl = OMP_CLAUSE_DECL (*cp);
8813 if (TREE_CODE (decl) == INDIRECT_REF || TREE_CODE (decl) == MEM_REF)
8815 tree base_ptr = TREE_OPERAND (decl, 0);
8816 STRIP_TYPE_NOPS (base_ptr);
8817 for (unsigned int j = i + 1; j < atf.length (); j++)
8819 tree *cp2 = atf[j];
8820 tree decl2 = OMP_CLAUSE_DECL (*cp2);
8821 if (is_or_contains_p (decl2, base_ptr))
8823 /* Move *cp2 to before *cp. */
8824 tree c = *cp2;
8825 *cp2 = OMP_CLAUSE_CHAIN (c);
8826 OMP_CLAUSE_CHAIN (c) = *cp;
8827 *cp = c;
8828 atf[j] = NULL;
8835 /* DECL is supposed to have lastprivate semantics in the outer contexts
8836 of combined/composite constructs, starting with OCTX.
8837 Add needed lastprivate, shared or map clause if no data sharing or
8838 mapping clause are present. IMPLICIT_P is true if it is an implicit
8839 clause (IV on simd), in which case the lastprivate will not be
8840 copied to some constructs. */
8842 static void
8843 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx,
8844 tree decl, bool implicit_p)
8846 struct gimplify_omp_ctx *orig_octx = octx;
8847 for (; octx; octx = octx->outer_context)
8849 if ((octx->region_type == ORT_COMBINED_PARALLEL
8850 || (octx->region_type & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS)
8851 && splay_tree_lookup (octx->variables,
8852 (splay_tree_key) decl) == NULL)
8854 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
8855 continue;
8857 if ((octx->region_type & ORT_TASK) != 0
8858 && octx->combined_loop
8859 && splay_tree_lookup (octx->variables,
8860 (splay_tree_key) decl) == NULL)
8862 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8863 continue;
8865 if (implicit_p
8866 && octx->region_type == ORT_WORKSHARE
8867 && octx->combined_loop
8868 && splay_tree_lookup (octx->variables,
8869 (splay_tree_key) decl) == NULL
8870 && octx->outer_context
8871 && octx->outer_context->region_type == ORT_COMBINED_PARALLEL
8872 && splay_tree_lookup (octx->outer_context->variables,
8873 (splay_tree_key) decl) == NULL)
8875 octx = octx->outer_context;
8876 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8877 continue;
8879 if ((octx->region_type == ORT_WORKSHARE || octx->region_type == ORT_ACC)
8880 && octx->combined_loop
8881 && splay_tree_lookup (octx->variables,
8882 (splay_tree_key) decl) == NULL
8883 && !omp_check_private (octx, decl, false))
8885 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8886 continue;
8888 if (octx->region_type == ORT_COMBINED_TARGET)
8890 splay_tree_node n = splay_tree_lookup (octx->variables,
8891 (splay_tree_key) decl);
8892 if (n == NULL)
8894 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
8895 octx = octx->outer_context;
8897 else if (!implicit_p
8898 && (n->value & GOVD_FIRSTPRIVATE_IMPLICIT))
8900 n->value &= ~(GOVD_FIRSTPRIVATE
8901 | GOVD_FIRSTPRIVATE_IMPLICIT
8902 | GOVD_EXPLICIT);
8903 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
8904 octx = octx->outer_context;
8907 break;
8909 if (octx && (implicit_p || octx != orig_octx))
8910 omp_notice_variable (octx, decl, true);
8913 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
8914 and previous omp contexts. */
8916 static void
8917 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
8918 enum omp_region_type region_type,
8919 enum tree_code code)
8921 struct gimplify_omp_ctx *ctx, *outer_ctx;
8922 tree c;
8923 hash_map<tree, tree> *struct_map_to_clause = NULL;
8924 hash_set<tree> *struct_deref_set = NULL;
8925 tree *prev_list_p = NULL, *orig_list_p = list_p;
8926 int handled_depend_iterators = -1;
8927 int nowait = -1;
8929 ctx = new_omp_context (region_type);
8930 ctx->code = code;
8931 outer_ctx = ctx->outer_context;
8932 if (code == OMP_TARGET)
8934 if (!lang_GNU_Fortran ())
8935 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
8936 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
8937 ctx->defaultmap[GDMK_SCALAR_TARGET] = (lang_GNU_Fortran ()
8938 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
8940 if (!lang_GNU_Fortran ())
8941 switch (code)
8943 case OMP_TARGET:
8944 case OMP_TARGET_DATA:
8945 case OMP_TARGET_ENTER_DATA:
8946 case OMP_TARGET_EXIT_DATA:
8947 case OACC_DECLARE:
8948 case OACC_HOST_DATA:
8949 case OACC_PARALLEL:
8950 case OACC_KERNELS:
8951 ctx->target_firstprivatize_array_bases = true;
8952 default:
8953 break;
8956 if (code == OMP_TARGET
8957 || code == OMP_TARGET_DATA
8958 || code == OMP_TARGET_ENTER_DATA
8959 || code == OMP_TARGET_EXIT_DATA)
8960 omp_target_reorder_clauses (list_p);
8962 while ((c = *list_p) != NULL)
8964 bool remove = false;
8965 bool notice_outer = true;
8966 const char *check_non_private = NULL;
8967 unsigned int flags;
8968 tree decl;
8970 switch (OMP_CLAUSE_CODE (c))
8972 case OMP_CLAUSE_PRIVATE:
8973 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
8974 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
8976 flags |= GOVD_PRIVATE_OUTER_REF;
8977 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
8979 else
8980 notice_outer = false;
8981 goto do_add;
8982 case OMP_CLAUSE_SHARED:
8983 flags = GOVD_SHARED | GOVD_EXPLICIT;
8984 goto do_add;
8985 case OMP_CLAUSE_FIRSTPRIVATE:
8986 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8987 check_non_private = "firstprivate";
8988 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
8990 gcc_assert (code == OMP_TARGET);
8991 flags |= GOVD_FIRSTPRIVATE_IMPLICIT;
8993 goto do_add;
8994 case OMP_CLAUSE_LASTPRIVATE:
8995 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
8996 switch (code)
8998 case OMP_DISTRIBUTE:
8999 error_at (OMP_CLAUSE_LOCATION (c),
9000 "conditional %<lastprivate%> clause on "
9001 "%qs construct", "distribute");
9002 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9003 break;
9004 case OMP_TASKLOOP:
9005 error_at (OMP_CLAUSE_LOCATION (c),
9006 "conditional %<lastprivate%> clause on "
9007 "%qs construct", "taskloop");
9008 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9009 break;
9010 default:
9011 break;
9013 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
9014 if (code != OMP_LOOP)
9015 check_non_private = "lastprivate";
9016 decl = OMP_CLAUSE_DECL (c);
9017 if (error_operand_p (decl))
9018 goto do_add;
9019 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
9020 && !lang_hooks.decls.omp_scalar_p (decl, true))
9022 error_at (OMP_CLAUSE_LOCATION (c),
9023 "non-scalar variable %qD in conditional "
9024 "%<lastprivate%> clause", decl);
9025 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9027 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
9028 flags |= GOVD_LASTPRIVATE_CONDITIONAL;
9029 omp_lastprivate_for_combined_outer_constructs (outer_ctx, decl,
9030 false);
9031 goto do_add;
9032 case OMP_CLAUSE_REDUCTION:
9033 if (OMP_CLAUSE_REDUCTION_TASK (c))
9035 if (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
9037 if (nowait == -1)
9038 nowait = omp_find_clause (*list_p,
9039 OMP_CLAUSE_NOWAIT) != NULL_TREE;
9040 if (nowait
9041 && (outer_ctx == NULL
9042 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
9044 error_at (OMP_CLAUSE_LOCATION (c),
9045 "%<task%> reduction modifier on a construct "
9046 "with a %<nowait%> clause");
9047 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
9050 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
9052 error_at (OMP_CLAUSE_LOCATION (c),
9053 "invalid %<task%> reduction modifier on construct "
9054 "other than %<parallel%>, %qs, %<sections%> or "
9055 "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
9056 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
9059 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
9060 switch (code)
9062 case OMP_SECTIONS:
9063 error_at (OMP_CLAUSE_LOCATION (c),
9064 "%<inscan%> %<reduction%> clause on "
9065 "%qs construct", "sections");
9066 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9067 break;
9068 case OMP_PARALLEL:
9069 error_at (OMP_CLAUSE_LOCATION (c),
9070 "%<inscan%> %<reduction%> clause on "
9071 "%qs construct", "parallel");
9072 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9073 break;
9074 case OMP_TEAMS:
9075 error_at (OMP_CLAUSE_LOCATION (c),
9076 "%<inscan%> %<reduction%> clause on "
9077 "%qs construct", "teams");
9078 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9079 break;
9080 case OMP_TASKLOOP:
9081 error_at (OMP_CLAUSE_LOCATION (c),
9082 "%<inscan%> %<reduction%> clause on "
9083 "%qs construct", "taskloop");
9084 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9085 break;
9086 case OMP_SCOPE:
9087 error_at (OMP_CLAUSE_LOCATION (c),
9088 "%<inscan%> %<reduction%> clause on "
9089 "%qs construct", "scope");
9090 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9091 break;
9092 default:
9093 break;
9095 /* FALLTHRU */
9096 case OMP_CLAUSE_IN_REDUCTION:
9097 case OMP_CLAUSE_TASK_REDUCTION:
9098 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
9099 /* OpenACC permits reductions on private variables. */
9100 if (!(region_type & ORT_ACC)
9101 /* taskgroup is actually not a worksharing region. */
9102 && code != OMP_TASKGROUP)
9103 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
9104 decl = OMP_CLAUSE_DECL (c);
9105 if (TREE_CODE (decl) == MEM_REF)
9107 tree type = TREE_TYPE (decl);
9108 bool saved_into_ssa = gimplify_ctxp->into_ssa;
9109 gimplify_ctxp->into_ssa = false;
9110 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
9111 NULL, is_gimple_val, fb_rvalue, false)
9112 == GS_ERROR)
9114 gimplify_ctxp->into_ssa = saved_into_ssa;
9115 remove = true;
9116 break;
9118 gimplify_ctxp->into_ssa = saved_into_ssa;
9119 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
9120 if (DECL_P (v))
9122 omp_firstprivatize_variable (ctx, v);
9123 omp_notice_variable (ctx, v, true);
9125 decl = TREE_OPERAND (decl, 0);
9126 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
9128 gimplify_ctxp->into_ssa = false;
9129 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
9130 NULL, is_gimple_val, fb_rvalue, false)
9131 == GS_ERROR)
9133 gimplify_ctxp->into_ssa = saved_into_ssa;
9134 remove = true;
9135 break;
9137 gimplify_ctxp->into_ssa = saved_into_ssa;
9138 v = TREE_OPERAND (decl, 1);
9139 if (DECL_P (v))
9141 omp_firstprivatize_variable (ctx, v);
9142 omp_notice_variable (ctx, v, true);
9144 decl = TREE_OPERAND (decl, 0);
9146 if (TREE_CODE (decl) == ADDR_EXPR
9147 || TREE_CODE (decl) == INDIRECT_REF)
9148 decl = TREE_OPERAND (decl, 0);
9150 goto do_add_decl;
9151 case OMP_CLAUSE_LINEAR:
9152 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
9153 is_gimple_val, fb_rvalue) == GS_ERROR)
9155 remove = true;
9156 break;
9158 else
9160 if (code == OMP_SIMD
9161 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9163 struct gimplify_omp_ctx *octx = outer_ctx;
9164 if (octx
9165 && octx->region_type == ORT_WORKSHARE
9166 && octx->combined_loop
9167 && !octx->distribute)
9169 if (octx->outer_context
9170 && (octx->outer_context->region_type
9171 == ORT_COMBINED_PARALLEL))
9172 octx = octx->outer_context->outer_context;
9173 else
9174 octx = octx->outer_context;
9176 if (octx
9177 && octx->region_type == ORT_WORKSHARE
9178 && octx->combined_loop
9179 && octx->distribute)
9181 error_at (OMP_CLAUSE_LOCATION (c),
9182 "%<linear%> clause for variable other than "
9183 "loop iterator specified on construct "
9184 "combined with %<distribute%>");
9185 remove = true;
9186 break;
9189 /* For combined #pragma omp parallel for simd, need to put
9190 lastprivate and perhaps firstprivate too on the
9191 parallel. Similarly for #pragma omp for simd. */
9192 struct gimplify_omp_ctx *octx = outer_ctx;
9193 bool taskloop_seen = false;
9194 decl = NULL_TREE;
9197 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9198 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9199 break;
9200 decl = OMP_CLAUSE_DECL (c);
9201 if (error_operand_p (decl))
9203 decl = NULL_TREE;
9204 break;
9206 flags = GOVD_SEEN;
9207 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9208 flags |= GOVD_FIRSTPRIVATE;
9209 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9210 flags |= GOVD_LASTPRIVATE;
9211 if (octx
9212 && octx->region_type == ORT_WORKSHARE
9213 && octx->combined_loop)
9215 if (octx->outer_context
9216 && (octx->outer_context->region_type
9217 == ORT_COMBINED_PARALLEL))
9218 octx = octx->outer_context;
9219 else if (omp_check_private (octx, decl, false))
9220 break;
9222 else if (octx
9223 && (octx->region_type & ORT_TASK) != 0
9224 && octx->combined_loop)
9225 taskloop_seen = true;
9226 else if (octx
9227 && octx->region_type == ORT_COMBINED_PARALLEL
9228 && ((ctx->region_type == ORT_WORKSHARE
9229 && octx == outer_ctx)
9230 || taskloop_seen))
9231 flags = GOVD_SEEN | GOVD_SHARED;
9232 else if (octx
9233 && ((octx->region_type & ORT_COMBINED_TEAMS)
9234 == ORT_COMBINED_TEAMS))
9235 flags = GOVD_SEEN | GOVD_SHARED;
9236 else if (octx
9237 && octx->region_type == ORT_COMBINED_TARGET)
9239 if (flags & GOVD_LASTPRIVATE)
9240 flags = GOVD_SEEN | GOVD_MAP;
9242 else
9243 break;
9244 splay_tree_node on
9245 = splay_tree_lookup (octx->variables,
9246 (splay_tree_key) decl);
9247 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
9249 octx = NULL;
9250 break;
9252 omp_add_variable (octx, decl, flags);
9253 if (octx->outer_context == NULL)
9254 break;
9255 octx = octx->outer_context;
9257 while (1);
9258 if (octx
9259 && decl
9260 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9261 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
9262 omp_notice_variable (octx, decl, true);
9264 flags = GOVD_LINEAR | GOVD_EXPLICIT;
9265 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9266 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9268 notice_outer = false;
9269 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9271 goto do_add;
9273 case OMP_CLAUSE_MAP:
9274 decl = OMP_CLAUSE_DECL (c);
9275 if (error_operand_p (decl))
9276 remove = true;
9277 switch (code)
9279 case OMP_TARGET:
9280 break;
9281 case OACC_DATA:
9282 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
9283 break;
9284 /* FALLTHRU */
9285 case OMP_TARGET_DATA:
9286 case OMP_TARGET_ENTER_DATA:
9287 case OMP_TARGET_EXIT_DATA:
9288 case OACC_ENTER_DATA:
9289 case OACC_EXIT_DATA:
9290 case OACC_HOST_DATA:
9291 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9292 || (OMP_CLAUSE_MAP_KIND (c)
9293 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9294 /* For target {,enter ,exit }data only the array slice is
9295 mapped, but not the pointer to it. */
9296 remove = true;
9297 break;
9298 default:
9299 break;
9301 /* For Fortran, not only the pointer to the data is mapped but also
9302 the address of the pointer, the array descriptor etc.; for
9303 'exit data' - and in particular for 'delete:' - having an 'alloc:'
9304 does not make sense. Likewise, for 'update' only transferring the
9305 data itself is needed as the rest has been handled in previous
9306 directives. However, for 'exit data', the array descriptor needs
9307 to be delete; hence, we turn the MAP_TO_PSET into a MAP_DELETE.
9309 NOTE: Generally, it is not safe to perform "enter data" operations
9310 on arrays where the data *or the descriptor* may go out of scope
9311 before a corresponding "exit data" operation -- and such a
9312 descriptor may be synthesized temporarily, e.g. to pass an
9313 explicit-shape array to a function expecting an assumed-shape
9314 argument. Performing "enter data" inside the called function
9315 would thus be problematic. */
9316 if (code == OMP_TARGET_EXIT_DATA
9317 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
9318 OMP_CLAUSE_SET_MAP_KIND (c, OMP_CLAUSE_MAP_KIND (*prev_list_p)
9319 == GOMP_MAP_DELETE
9320 ? GOMP_MAP_DELETE : GOMP_MAP_RELEASE);
9321 else if ((code == OMP_TARGET_EXIT_DATA || code == OMP_TARGET_UPDATE)
9322 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9323 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET))
9324 remove = true;
9326 if (remove)
9327 break;
9328 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
9330 struct gimplify_omp_ctx *octx;
9331 for (octx = outer_ctx; octx; octx = octx->outer_context)
9333 if (octx->region_type != ORT_ACC_HOST_DATA)
9334 break;
9335 splay_tree_node n2
9336 = splay_tree_lookup (octx->variables,
9337 (splay_tree_key) decl);
9338 if (n2)
9339 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
9340 "declared in enclosing %<host_data%> region",
9341 DECL_NAME (decl));
9344 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9345 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
9346 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
9347 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
9348 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
9350 remove = true;
9351 break;
9353 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9354 || (OMP_CLAUSE_MAP_KIND (c)
9355 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9356 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9357 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
9359 OMP_CLAUSE_SIZE (c)
9360 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
9361 false);
9362 if ((region_type & ORT_TARGET) != 0)
9363 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
9364 GOVD_FIRSTPRIVATE | GOVD_SEEN);
9367 if (!DECL_P (decl))
9369 tree d = decl, *pd;
9370 if (TREE_CODE (d) == ARRAY_REF)
9372 while (TREE_CODE (d) == ARRAY_REF)
9373 d = TREE_OPERAND (d, 0);
9374 if (TREE_CODE (d) == COMPONENT_REF
9375 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
9376 decl = d;
9378 pd = &OMP_CLAUSE_DECL (c);
9379 if (d == decl
9380 && TREE_CODE (decl) == INDIRECT_REF
9381 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
9382 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9383 == REFERENCE_TYPE))
9385 pd = &TREE_OPERAND (decl, 0);
9386 decl = TREE_OPERAND (decl, 0);
9388 bool indir_p = false;
9389 tree orig_decl = decl;
9390 tree decl_ref = NULL_TREE;
9391 if ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA)) != 0
9392 && TREE_CODE (*pd) == COMPONENT_REF
9393 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
9394 && code != OACC_UPDATE)
9396 while (TREE_CODE (decl) == COMPONENT_REF)
9398 decl = TREE_OPERAND (decl, 0);
9399 if (((TREE_CODE (decl) == MEM_REF
9400 && integer_zerop (TREE_OPERAND (decl, 1)))
9401 || INDIRECT_REF_P (decl))
9402 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9403 == POINTER_TYPE))
9405 indir_p = true;
9406 decl = TREE_OPERAND (decl, 0);
9408 if (TREE_CODE (decl) == INDIRECT_REF
9409 && DECL_P (TREE_OPERAND (decl, 0))
9410 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9411 == REFERENCE_TYPE))
9413 decl_ref = decl;
9414 decl = TREE_OPERAND (decl, 0);
9418 else if (TREE_CODE (decl) == COMPONENT_REF)
9420 while (TREE_CODE (decl) == COMPONENT_REF)
9421 decl = TREE_OPERAND (decl, 0);
9422 if (TREE_CODE (decl) == INDIRECT_REF
9423 && DECL_P (TREE_OPERAND (decl, 0))
9424 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9425 == REFERENCE_TYPE))
9426 decl = TREE_OPERAND (decl, 0);
9428 if (decl != orig_decl && DECL_P (decl) && indir_p)
9430 gomp_map_kind k
9431 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9432 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9433 /* We have a dereference of a struct member. Make this an
9434 attach/detach operation, and ensure the base pointer is
9435 mapped as a FIRSTPRIVATE_POINTER. */
9436 OMP_CLAUSE_SET_MAP_KIND (c, k);
9437 flags = GOVD_MAP | GOVD_SEEN | GOVD_EXPLICIT;
9438 tree next_clause = OMP_CLAUSE_CHAIN (c);
9439 if (k == GOMP_MAP_ATTACH
9440 && code != OACC_ENTER_DATA
9441 && code != OMP_TARGET_ENTER_DATA
9442 && (!next_clause
9443 || (OMP_CLAUSE_CODE (next_clause) != OMP_CLAUSE_MAP)
9444 || (OMP_CLAUSE_MAP_KIND (next_clause)
9445 != GOMP_MAP_POINTER)
9446 || OMP_CLAUSE_DECL (next_clause) != decl)
9447 && (!struct_deref_set
9448 || !struct_deref_set->contains (decl)))
9450 if (!struct_deref_set)
9451 struct_deref_set = new hash_set<tree> ();
9452 /* As well as the attach, we also need a
9453 FIRSTPRIVATE_POINTER clause to properly map the
9454 pointer to the struct base. */
9455 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9456 OMP_CLAUSE_MAP);
9457 OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALLOC);
9458 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c2)
9459 = 1;
9460 tree charptr_zero
9461 = build_int_cst (build_pointer_type (char_type_node),
9463 OMP_CLAUSE_DECL (c2)
9464 = build2 (MEM_REF, char_type_node,
9465 decl_ref ? decl_ref : decl, charptr_zero);
9466 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9467 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9468 OMP_CLAUSE_MAP);
9469 OMP_CLAUSE_SET_MAP_KIND (c3,
9470 GOMP_MAP_FIRSTPRIVATE_POINTER);
9471 OMP_CLAUSE_DECL (c3) = decl;
9472 OMP_CLAUSE_SIZE (c3) = size_zero_node;
9473 tree mapgrp = *prev_list_p;
9474 *prev_list_p = c2;
9475 OMP_CLAUSE_CHAIN (c3) = mapgrp;
9476 OMP_CLAUSE_CHAIN (c2) = c3;
9478 struct_deref_set->add (decl);
9480 goto do_add_decl;
9482 /* An "attach/detach" operation on an update directive should
9483 behave as a GOMP_MAP_ALWAYS_POINTER. Beware that
9484 unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
9485 depends on the previous mapping. */
9486 if (code == OACC_UPDATE
9487 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9488 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
9489 if (DECL_P (decl)
9490 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
9491 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
9492 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
9493 && code != OACC_UPDATE
9494 && code != OMP_TARGET_UPDATE)
9496 if (error_operand_p (decl))
9498 remove = true;
9499 break;
9502 tree stype = TREE_TYPE (decl);
9503 if (TREE_CODE (stype) == REFERENCE_TYPE)
9504 stype = TREE_TYPE (stype);
9505 if (TYPE_SIZE_UNIT (stype) == NULL
9506 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
9508 error_at (OMP_CLAUSE_LOCATION (c),
9509 "mapping field %qE of variable length "
9510 "structure", OMP_CLAUSE_DECL (c));
9511 remove = true;
9512 break;
9515 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
9516 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9518 /* Error recovery. */
9519 if (prev_list_p == NULL)
9521 remove = true;
9522 break;
9524 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
9526 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
9527 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
9529 remove = true;
9530 break;
9535 poly_offset_int offset1;
9536 poly_int64 bitpos1;
9537 tree base_ref;
9539 tree base
9540 = extract_base_bit_offset (OMP_CLAUSE_DECL (c), &base_ref,
9541 &bitpos1, &offset1);
9543 gcc_assert (base == decl);
9545 splay_tree_node n
9546 = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
9547 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
9548 == GOMP_MAP_ALWAYS_POINTER);
9549 bool attach_detach = (OMP_CLAUSE_MAP_KIND (c)
9550 == GOMP_MAP_ATTACH_DETACH);
9551 bool attach = OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9552 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH;
9553 bool has_attachments = false;
9554 /* For OpenACC, pointers in structs should trigger an
9555 attach action. */
9556 if (attach_detach
9557 && ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA))
9558 || code == OMP_TARGET_ENTER_DATA
9559 || code == OMP_TARGET_EXIT_DATA))
9562 /* Turn a GOMP_MAP_ATTACH_DETACH clause into a
9563 GOMP_MAP_ATTACH or GOMP_MAP_DETACH clause after we
9564 have detected a case that needs a GOMP_MAP_STRUCT
9565 mapping added. */
9566 gomp_map_kind k
9567 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9568 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9569 OMP_CLAUSE_SET_MAP_KIND (c, k);
9570 has_attachments = true;
9572 if (n == NULL || (n->value & GOVD_MAP) == 0)
9574 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9575 OMP_CLAUSE_MAP);
9576 gomp_map_kind k = attach ? GOMP_MAP_FORCE_PRESENT
9577 : GOMP_MAP_STRUCT;
9579 OMP_CLAUSE_SET_MAP_KIND (l, k);
9580 if (base_ref)
9581 OMP_CLAUSE_DECL (l) = unshare_expr (base_ref);
9582 else
9583 OMP_CLAUSE_DECL (l) = decl;
9584 OMP_CLAUSE_SIZE (l)
9585 = (!attach
9586 ? size_int (1)
9587 : DECL_P (OMP_CLAUSE_DECL (l))
9588 ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l))
9589 : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l))));
9590 if (struct_map_to_clause == NULL)
9591 struct_map_to_clause = new hash_map<tree, tree>;
9592 struct_map_to_clause->put (decl, l);
9593 if (ptr || attach_detach)
9595 insert_struct_comp_map (code, c, l, *prev_list_p,
9596 NULL);
9597 *prev_list_p = l;
9598 prev_list_p = NULL;
9600 else
9602 OMP_CLAUSE_CHAIN (l) = c;
9603 *list_p = l;
9604 list_p = &OMP_CLAUSE_CHAIN (l);
9606 if (base_ref && code == OMP_TARGET)
9608 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9609 OMP_CLAUSE_MAP);
9610 enum gomp_map_kind mkind
9611 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
9612 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9613 OMP_CLAUSE_DECL (c2) = decl;
9614 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9615 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
9616 OMP_CLAUSE_CHAIN (l) = c2;
9618 flags = GOVD_MAP | GOVD_EXPLICIT;
9619 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9620 || ptr
9621 || attach_detach)
9622 flags |= GOVD_SEEN;
9623 if (has_attachments)
9624 flags |= GOVD_MAP_HAS_ATTACHMENTS;
9625 goto do_add_decl;
9627 else if (struct_map_to_clause)
9629 tree *osc = struct_map_to_clause->get (decl);
9630 tree *sc = NULL, *scp = NULL;
9631 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9632 || ptr
9633 || attach_detach)
9634 n->value |= GOVD_SEEN;
9635 sc = &OMP_CLAUSE_CHAIN (*osc);
9636 if (*sc != c
9637 && (OMP_CLAUSE_MAP_KIND (*sc)
9638 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9639 sc = &OMP_CLAUSE_CHAIN (*sc);
9640 /* Here "prev_list_p" is the end of the inserted
9641 alloc/release nodes after the struct node, OSC. */
9642 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
9643 if ((ptr || attach_detach) && sc == prev_list_p)
9644 break;
9645 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9646 != COMPONENT_REF
9647 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9648 != INDIRECT_REF)
9649 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9650 != ARRAY_REF))
9651 break;
9652 else
9654 tree sc_decl = OMP_CLAUSE_DECL (*sc);
9655 poly_offset_int offsetn;
9656 poly_int64 bitposn;
9657 tree base
9658 = extract_base_bit_offset (sc_decl, NULL,
9659 &bitposn, &offsetn);
9660 if (base != decl)
9661 break;
9662 if (scp)
9663 continue;
9664 if ((region_type & ORT_ACC) != 0)
9666 /* This duplicate checking code is currently only
9667 enabled for OpenACC. */
9668 tree d1 = OMP_CLAUSE_DECL (*sc);
9669 tree d2 = OMP_CLAUSE_DECL (c);
9670 while (TREE_CODE (d1) == ARRAY_REF)
9671 d1 = TREE_OPERAND (d1, 0);
9672 while (TREE_CODE (d2) == ARRAY_REF)
9673 d2 = TREE_OPERAND (d2, 0);
9674 if (TREE_CODE (d1) == INDIRECT_REF)
9675 d1 = TREE_OPERAND (d1, 0);
9676 if (TREE_CODE (d2) == INDIRECT_REF)
9677 d2 = TREE_OPERAND (d2, 0);
9678 while (TREE_CODE (d1) == COMPONENT_REF)
9679 if (TREE_CODE (d2) == COMPONENT_REF
9680 && TREE_OPERAND (d1, 1)
9681 == TREE_OPERAND (d2, 1))
9683 d1 = TREE_OPERAND (d1, 0);
9684 d2 = TREE_OPERAND (d2, 0);
9686 else
9687 break;
9688 if (d1 == d2)
9690 error_at (OMP_CLAUSE_LOCATION (c),
9691 "%qE appears more than once in map "
9692 "clauses", OMP_CLAUSE_DECL (c));
9693 remove = true;
9694 break;
9697 if (maybe_lt (offset1, offsetn)
9698 || (known_eq (offset1, offsetn)
9699 && maybe_lt (bitpos1, bitposn)))
9701 if (ptr || attach_detach)
9702 scp = sc;
9703 else
9704 break;
9707 if (remove)
9708 break;
9709 if (!attach)
9710 OMP_CLAUSE_SIZE (*osc)
9711 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
9712 size_one_node);
9713 if (ptr || attach_detach)
9715 tree cl = insert_struct_comp_map (code, c, NULL,
9716 *prev_list_p, scp);
9717 if (sc == prev_list_p)
9719 *sc = cl;
9720 prev_list_p = NULL;
9722 else
9724 *prev_list_p = OMP_CLAUSE_CHAIN (c);
9725 list_p = prev_list_p;
9726 prev_list_p = NULL;
9727 OMP_CLAUSE_CHAIN (c) = *sc;
9728 *sc = cl;
9729 continue;
9732 else if (*sc != c)
9734 *list_p = OMP_CLAUSE_CHAIN (c);
9735 OMP_CLAUSE_CHAIN (c) = *sc;
9736 *sc = c;
9737 continue;
9741 else if ((code == OACC_ENTER_DATA
9742 || code == OACC_EXIT_DATA
9743 || code == OACC_DATA
9744 || code == OACC_PARALLEL
9745 || code == OACC_KERNELS
9746 || code == OACC_SERIAL)
9747 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9749 gomp_map_kind k = (code == OACC_EXIT_DATA
9750 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9751 OMP_CLAUSE_SET_MAP_KIND (c, k);
9754 if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
9756 /* Don't gimplify *pd fully at this point, as the base
9757 will need to be adjusted during omp lowering. */
9758 auto_vec<tree, 10> expr_stack;
9759 tree *p = pd;
9760 while (handled_component_p (*p)
9761 || TREE_CODE (*p) == INDIRECT_REF
9762 || TREE_CODE (*p) == ADDR_EXPR
9763 || TREE_CODE (*p) == MEM_REF
9764 || TREE_CODE (*p) == NON_LVALUE_EXPR)
9766 expr_stack.safe_push (*p);
9767 p = &TREE_OPERAND (*p, 0);
9769 for (int i = expr_stack.length () - 1; i >= 0; i--)
9771 tree t = expr_stack[i];
9772 if (TREE_CODE (t) == ARRAY_REF
9773 || TREE_CODE (t) == ARRAY_RANGE_REF)
9775 if (TREE_OPERAND (t, 2) == NULL_TREE)
9777 tree low = unshare_expr (array_ref_low_bound (t));
9778 if (!is_gimple_min_invariant (low))
9780 TREE_OPERAND (t, 2) = low;
9781 if (gimplify_expr (&TREE_OPERAND (t, 2),
9782 pre_p, NULL,
9783 is_gimple_reg,
9784 fb_rvalue) == GS_ERROR)
9785 remove = true;
9788 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
9789 NULL, is_gimple_reg,
9790 fb_rvalue) == GS_ERROR)
9791 remove = true;
9792 if (TREE_OPERAND (t, 3) == NULL_TREE)
9794 tree elmt_size = array_ref_element_size (t);
9795 if (!is_gimple_min_invariant (elmt_size))
9797 elmt_size = unshare_expr (elmt_size);
9798 tree elmt_type
9799 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t,
9800 0)));
9801 tree factor
9802 = size_int (TYPE_ALIGN_UNIT (elmt_type));
9803 elmt_size
9804 = size_binop (EXACT_DIV_EXPR, elmt_size,
9805 factor);
9806 TREE_OPERAND (t, 3) = elmt_size;
9807 if (gimplify_expr (&TREE_OPERAND (t, 3),
9808 pre_p, NULL,
9809 is_gimple_reg,
9810 fb_rvalue) == GS_ERROR)
9811 remove = true;
9814 else if (gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
9815 NULL, is_gimple_reg,
9816 fb_rvalue) == GS_ERROR)
9817 remove = true;
9819 else if (TREE_CODE (t) == COMPONENT_REF)
9821 if (TREE_OPERAND (t, 2) == NULL_TREE)
9823 tree offset = component_ref_field_offset (t);
9824 if (!is_gimple_min_invariant (offset))
9826 offset = unshare_expr (offset);
9827 tree field = TREE_OPERAND (t, 1);
9828 tree factor
9829 = size_int (DECL_OFFSET_ALIGN (field)
9830 / BITS_PER_UNIT);
9831 offset = size_binop (EXACT_DIV_EXPR, offset,
9832 factor);
9833 TREE_OPERAND (t, 2) = offset;
9834 if (gimplify_expr (&TREE_OPERAND (t, 2),
9835 pre_p, NULL,
9836 is_gimple_reg,
9837 fb_rvalue) == GS_ERROR)
9838 remove = true;
9841 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
9842 NULL, is_gimple_reg,
9843 fb_rvalue) == GS_ERROR)
9844 remove = true;
9847 for (; expr_stack.length () > 0; )
9849 tree t = expr_stack.pop ();
9851 if (TREE_CODE (t) == ARRAY_REF
9852 || TREE_CODE (t) == ARRAY_RANGE_REF)
9854 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))
9855 && gimplify_expr (&TREE_OPERAND (t, 1), pre_p,
9856 NULL, is_gimple_val,
9857 fb_rvalue) == GS_ERROR)
9858 remove = true;
9862 else if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
9863 fb_lvalue) == GS_ERROR)
9865 remove = true;
9866 break;
9869 if (!remove
9870 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
9871 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
9872 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
9873 && OMP_CLAUSE_CHAIN (c)
9874 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
9875 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9876 == GOMP_MAP_ALWAYS_POINTER)
9877 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9878 == GOMP_MAP_ATTACH_DETACH)
9879 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9880 == GOMP_MAP_TO_PSET)))
9881 prev_list_p = list_p;
9883 break;
9885 else
9887 /* DECL_P (decl) == true */
9888 tree *sc;
9889 if (struct_map_to_clause
9890 && (sc = struct_map_to_clause->get (decl)) != NULL
9891 && OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_STRUCT
9892 && decl == OMP_CLAUSE_DECL (*sc))
9894 /* We have found a map of the whole structure after a
9895 leading GOMP_MAP_STRUCT has been created, so refill the
9896 leading clause into a map of the whole structure
9897 variable, and remove the current one.
9898 TODO: we should be able to remove some maps of the
9899 following structure element maps if they are of
9900 compatible TO/FROM/ALLOC type. */
9901 OMP_CLAUSE_SET_MAP_KIND (*sc, OMP_CLAUSE_MAP_KIND (c));
9902 OMP_CLAUSE_SIZE (*sc) = unshare_expr (OMP_CLAUSE_SIZE (c));
9903 remove = true;
9904 break;
9907 flags = GOVD_MAP | GOVD_EXPLICIT;
9908 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
9909 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
9910 flags |= GOVD_MAP_ALWAYS_TO;
9912 if ((code == OMP_TARGET
9913 || code == OMP_TARGET_DATA
9914 || code == OMP_TARGET_ENTER_DATA
9915 || code == OMP_TARGET_EXIT_DATA)
9916 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9918 for (struct gimplify_omp_ctx *octx = outer_ctx; octx;
9919 octx = octx->outer_context)
9921 splay_tree_node n
9922 = splay_tree_lookup (octx->variables,
9923 (splay_tree_key) OMP_CLAUSE_DECL (c));
9924 /* If this is contained in an outer OpenMP region as a
9925 firstprivate value, remove the attach/detach. */
9926 if (n && (n->value & GOVD_FIRSTPRIVATE))
9928 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FIRSTPRIVATE_POINTER);
9929 goto do_add;
9933 enum gomp_map_kind map_kind = (code == OMP_TARGET_EXIT_DATA
9934 ? GOMP_MAP_DETACH
9935 : GOMP_MAP_ATTACH);
9936 OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
9939 goto do_add;
9941 case OMP_CLAUSE_AFFINITY:
9942 gimplify_omp_affinity (list_p, pre_p);
9943 remove = true;
9944 break;
9945 case OMP_CLAUSE_DEPEND:
9946 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
9948 tree deps = OMP_CLAUSE_DECL (c);
9949 while (deps && TREE_CODE (deps) == TREE_LIST)
9951 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
9952 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
9953 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
9954 pre_p, NULL, is_gimple_val, fb_rvalue);
9955 deps = TREE_CHAIN (deps);
9957 break;
9959 else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
9960 break;
9961 if (handled_depend_iterators == -1)
9962 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
9963 if (handled_depend_iterators)
9965 if (handled_depend_iterators == 2)
9966 remove = true;
9967 break;
9969 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
9971 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
9972 NULL, is_gimple_val, fb_rvalue);
9973 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
9975 if (error_operand_p (OMP_CLAUSE_DECL (c)))
9977 remove = true;
9978 break;
9980 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
9981 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
9982 is_gimple_val, fb_rvalue) == GS_ERROR)
9984 remove = true;
9985 break;
9987 if (code == OMP_TASK)
9988 ctx->has_depend = true;
9989 break;
9991 case OMP_CLAUSE_TO:
9992 case OMP_CLAUSE_FROM:
9993 case OMP_CLAUSE__CACHE_:
9994 decl = OMP_CLAUSE_DECL (c);
9995 if (error_operand_p (decl))
9997 remove = true;
9998 break;
10000 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10001 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
10002 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
10003 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
10004 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
10006 remove = true;
10007 break;
10009 if (!DECL_P (decl))
10011 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
10012 NULL, is_gimple_lvalue, fb_lvalue)
10013 == GS_ERROR)
10015 remove = true;
10016 break;
10018 break;
10020 goto do_notice;
10022 case OMP_CLAUSE_USE_DEVICE_PTR:
10023 case OMP_CLAUSE_USE_DEVICE_ADDR:
10024 flags = GOVD_EXPLICIT;
10025 goto do_add;
10027 case OMP_CLAUSE_IS_DEVICE_PTR:
10028 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
10029 goto do_add;
10031 do_add:
10032 decl = OMP_CLAUSE_DECL (c);
10033 do_add_decl:
10034 if (error_operand_p (decl))
10036 remove = true;
10037 break;
10039 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
10041 tree t = omp_member_access_dummy_var (decl);
10042 if (t)
10044 tree v = DECL_VALUE_EXPR (decl);
10045 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
10046 if (outer_ctx)
10047 omp_notice_variable (outer_ctx, t, true);
10050 if (code == OACC_DATA
10051 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10052 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
10053 flags |= GOVD_MAP_0LEN_ARRAY;
10054 omp_add_variable (ctx, decl, flags);
10055 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10056 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
10057 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
10058 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
10060 struct gimplify_omp_ctx *pctx
10061 = code == OMP_TARGET ? outer_ctx : ctx;
10062 if (pctx)
10063 omp_add_variable (pctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
10064 GOVD_LOCAL | GOVD_SEEN);
10065 if (pctx
10066 && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
10067 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
10068 find_decl_expr,
10069 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
10070 NULL) == NULL_TREE)
10071 omp_add_variable (pctx,
10072 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
10073 GOVD_LOCAL | GOVD_SEEN);
10074 gimplify_omp_ctxp = pctx;
10075 push_gimplify_context ();
10077 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
10078 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
10080 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
10081 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
10082 pop_gimplify_context
10083 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
10084 push_gimplify_context ();
10085 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
10086 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
10087 pop_gimplify_context
10088 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
10089 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
10090 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
10092 gimplify_omp_ctxp = outer_ctx;
10094 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10095 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
10097 gimplify_omp_ctxp = ctx;
10098 push_gimplify_context ();
10099 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
10101 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
10102 NULL, NULL);
10103 TREE_SIDE_EFFECTS (bind) = 1;
10104 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
10105 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
10107 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
10108 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
10109 pop_gimplify_context
10110 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
10111 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
10113 gimplify_omp_ctxp = outer_ctx;
10115 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10116 && OMP_CLAUSE_LINEAR_STMT (c))
10118 gimplify_omp_ctxp = ctx;
10119 push_gimplify_context ();
10120 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
10122 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
10123 NULL, NULL);
10124 TREE_SIDE_EFFECTS (bind) = 1;
10125 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
10126 OMP_CLAUSE_LINEAR_STMT (c) = bind;
10128 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
10129 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
10130 pop_gimplify_context
10131 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
10132 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
10134 gimplify_omp_ctxp = outer_ctx;
10136 if (notice_outer)
10137 goto do_notice;
10138 break;
10140 case OMP_CLAUSE_COPYIN:
10141 case OMP_CLAUSE_COPYPRIVATE:
10142 decl = OMP_CLAUSE_DECL (c);
10143 if (error_operand_p (decl))
10145 remove = true;
10146 break;
10148 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
10149 && !remove
10150 && !omp_check_private (ctx, decl, true))
10152 remove = true;
10153 if (is_global_var (decl))
10155 if (DECL_THREAD_LOCAL_P (decl))
10156 remove = false;
10157 else if (DECL_HAS_VALUE_EXPR_P (decl))
10159 tree value = get_base_address (DECL_VALUE_EXPR (decl));
10161 if (value
10162 && DECL_P (value)
10163 && DECL_THREAD_LOCAL_P (value))
10164 remove = false;
10167 if (remove)
10168 error_at (OMP_CLAUSE_LOCATION (c),
10169 "copyprivate variable %qE is not threadprivate"
10170 " or private in outer context", DECL_NAME (decl));
10172 do_notice:
10173 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10174 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10175 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
10176 && outer_ctx
10177 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
10178 || (region_type == ORT_WORKSHARE
10179 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10180 && (OMP_CLAUSE_REDUCTION_INSCAN (c)
10181 || code == OMP_LOOP)))
10182 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
10183 || (code == OMP_LOOP
10184 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10185 && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
10186 == ORT_COMBINED_TEAMS))))
10188 splay_tree_node on
10189 = splay_tree_lookup (outer_ctx->variables,
10190 (splay_tree_key)decl);
10191 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
10193 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10194 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10195 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
10196 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
10197 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
10198 == POINTER_TYPE))))
10199 omp_firstprivatize_variable (outer_ctx, decl);
10200 else
10202 omp_add_variable (outer_ctx, decl,
10203 GOVD_SEEN | GOVD_SHARED);
10204 if (outer_ctx->outer_context)
10205 omp_notice_variable (outer_ctx->outer_context, decl,
10206 true);
10210 if (outer_ctx)
10211 omp_notice_variable (outer_ctx, decl, true);
10212 if (check_non_private
10213 && (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
10214 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
10215 || decl == OMP_CLAUSE_DECL (c)
10216 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10217 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10218 == ADDR_EXPR
10219 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10220 == POINTER_PLUS_EXPR
10221 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
10222 (OMP_CLAUSE_DECL (c), 0), 0))
10223 == ADDR_EXPR)))))
10224 && omp_check_private (ctx, decl, false))
10226 error ("%s variable %qE is private in outer context",
10227 check_non_private, DECL_NAME (decl));
10228 remove = true;
10230 break;
10232 case OMP_CLAUSE_DETACH:
10233 flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
10234 goto do_add;
10236 case OMP_CLAUSE_IF:
10237 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
10238 && OMP_CLAUSE_IF_MODIFIER (c) != code)
10240 const char *p[2];
10241 for (int i = 0; i < 2; i++)
10242 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
10244 case VOID_CST: p[i] = "cancel"; break;
10245 case OMP_PARALLEL: p[i] = "parallel"; break;
10246 case OMP_SIMD: p[i] = "simd"; break;
10247 case OMP_TASK: p[i] = "task"; break;
10248 case OMP_TASKLOOP: p[i] = "taskloop"; break;
10249 case OMP_TARGET_DATA: p[i] = "target data"; break;
10250 case OMP_TARGET: p[i] = "target"; break;
10251 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
10252 case OMP_TARGET_ENTER_DATA:
10253 p[i] = "target enter data"; break;
10254 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
10255 default: gcc_unreachable ();
10257 error_at (OMP_CLAUSE_LOCATION (c),
10258 "expected %qs %<if%> clause modifier rather than %qs",
10259 p[0], p[1]);
10260 remove = true;
10262 /* Fall through. */
10264 case OMP_CLAUSE_FINAL:
10265 OMP_CLAUSE_OPERAND (c, 0)
10266 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
10267 /* Fall through. */
10269 case OMP_CLAUSE_NUM_TEAMS:
10270 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
10271 && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
10272 && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
10274 if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
10276 remove = true;
10277 break;
10279 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
10280 = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c),
10281 pre_p, NULL, true);
10283 /* Fall through. */
10285 case OMP_CLAUSE_SCHEDULE:
10286 case OMP_CLAUSE_NUM_THREADS:
10287 case OMP_CLAUSE_THREAD_LIMIT:
10288 case OMP_CLAUSE_DIST_SCHEDULE:
10289 case OMP_CLAUSE_DEVICE:
10290 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE
10291 && OMP_CLAUSE_DEVICE_ANCESTOR (c))
10293 if (code != OMP_TARGET)
10295 error_at (OMP_CLAUSE_LOCATION (c),
10296 "%<device%> clause with %<ancestor%> is only "
10297 "allowed on %<target%> construct");
10298 remove = true;
10299 break;
10302 tree clauses = *orig_list_p;
10303 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
10304 if (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEVICE
10305 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_FIRSTPRIVATE
10306 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_PRIVATE
10307 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEFAULTMAP
10308 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_MAP
10311 error_at (OMP_CLAUSE_LOCATION (c),
10312 "with %<ancestor%>, only the %<device%>, "
10313 "%<firstprivate%>, %<private%>, %<defaultmap%>, "
10314 "and %<map%> clauses may appear on the "
10315 "construct");
10316 remove = true;
10317 break;
10320 /* Fall through. */
10322 case OMP_CLAUSE_PRIORITY:
10323 case OMP_CLAUSE_GRAINSIZE:
10324 case OMP_CLAUSE_NUM_TASKS:
10325 case OMP_CLAUSE_FILTER:
10326 case OMP_CLAUSE_HINT:
10327 case OMP_CLAUSE_ASYNC:
10328 case OMP_CLAUSE_WAIT:
10329 case OMP_CLAUSE_NUM_GANGS:
10330 case OMP_CLAUSE_NUM_WORKERS:
10331 case OMP_CLAUSE_VECTOR_LENGTH:
10332 case OMP_CLAUSE_WORKER:
10333 case OMP_CLAUSE_VECTOR:
10334 if (OMP_CLAUSE_OPERAND (c, 0)
10335 && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0)))
10337 if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0)))
10339 remove = true;
10340 break;
10342 /* All these clauses care about value, not a particular decl,
10343 so try to force it into a SSA_NAME or fresh temporary. */
10344 OMP_CLAUSE_OPERAND (c, 0)
10345 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0),
10346 pre_p, NULL, true);
10348 break;
10350 case OMP_CLAUSE_GANG:
10351 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
10352 is_gimple_val, fb_rvalue) == GS_ERROR)
10353 remove = true;
10354 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
10355 is_gimple_val, fb_rvalue) == GS_ERROR)
10356 remove = true;
10357 break;
10359 case OMP_CLAUSE_NOWAIT:
10360 nowait = 1;
10361 break;
10363 case OMP_CLAUSE_ORDERED:
10364 case OMP_CLAUSE_UNTIED:
10365 case OMP_CLAUSE_COLLAPSE:
10366 case OMP_CLAUSE_TILE:
10367 case OMP_CLAUSE_AUTO:
10368 case OMP_CLAUSE_SEQ:
10369 case OMP_CLAUSE_INDEPENDENT:
10370 case OMP_CLAUSE_MERGEABLE:
10371 case OMP_CLAUSE_PROC_BIND:
10372 case OMP_CLAUSE_SAFELEN:
10373 case OMP_CLAUSE_SIMDLEN:
10374 case OMP_CLAUSE_NOGROUP:
10375 case OMP_CLAUSE_THREADS:
10376 case OMP_CLAUSE_SIMD:
10377 case OMP_CLAUSE_BIND:
10378 case OMP_CLAUSE_IF_PRESENT:
10379 case OMP_CLAUSE_FINALIZE:
10380 break;
10382 case OMP_CLAUSE_ORDER:
10383 ctx->order_concurrent = true;
10384 break;
10386 case OMP_CLAUSE_DEFAULTMAP:
10387 enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
10388 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
10390 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
10391 gdmkmin = GDMK_SCALAR;
10392 gdmkmax = GDMK_POINTER;
10393 break;
10394 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
10395 gdmkmin = GDMK_SCALAR;
10396 gdmkmax = GDMK_SCALAR_TARGET;
10397 break;
10398 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
10399 gdmkmin = gdmkmax = GDMK_AGGREGATE;
10400 break;
10401 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
10402 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
10403 break;
10404 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
10405 gdmkmin = gdmkmax = GDMK_POINTER;
10406 break;
10407 default:
10408 gcc_unreachable ();
10410 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
10411 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
10413 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
10414 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
10415 break;
10416 case OMP_CLAUSE_DEFAULTMAP_TO:
10417 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
10418 break;
10419 case OMP_CLAUSE_DEFAULTMAP_FROM:
10420 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
10421 break;
10422 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
10423 ctx->defaultmap[gdmk] = GOVD_MAP;
10424 break;
10425 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
10426 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10427 break;
10428 case OMP_CLAUSE_DEFAULTMAP_NONE:
10429 ctx->defaultmap[gdmk] = 0;
10430 break;
10431 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
10432 switch (gdmk)
10434 case GDMK_SCALAR:
10435 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10436 break;
10437 case GDMK_SCALAR_TARGET:
10438 ctx->defaultmap[gdmk] = (lang_GNU_Fortran ()
10439 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
10440 break;
10441 case GDMK_AGGREGATE:
10442 case GDMK_ALLOCATABLE:
10443 ctx->defaultmap[gdmk] = GOVD_MAP;
10444 break;
10445 case GDMK_POINTER:
10446 ctx->defaultmap[gdmk] = GOVD_MAP;
10447 if (!lang_GNU_Fortran ())
10448 ctx->defaultmap[gdmk] |= GOVD_MAP_0LEN_ARRAY;
10449 break;
10450 default:
10451 gcc_unreachable ();
10453 break;
10454 default:
10455 gcc_unreachable ();
10457 break;
10459 case OMP_CLAUSE_ALIGNED:
10460 decl = OMP_CLAUSE_DECL (c);
10461 if (error_operand_p (decl))
10463 remove = true;
10464 break;
10466 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
10467 is_gimple_val, fb_rvalue) == GS_ERROR)
10469 remove = true;
10470 break;
10472 if (!is_global_var (decl)
10473 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
10474 omp_add_variable (ctx, decl, GOVD_ALIGNED);
10475 break;
10477 case OMP_CLAUSE_NONTEMPORAL:
10478 decl = OMP_CLAUSE_DECL (c);
10479 if (error_operand_p (decl))
10481 remove = true;
10482 break;
10484 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
10485 break;
10487 case OMP_CLAUSE_ALLOCATE:
10488 decl = OMP_CLAUSE_DECL (c);
10489 if (error_operand_p (decl))
10491 remove = true;
10492 break;
10494 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL,
10495 is_gimple_val, fb_rvalue) == GS_ERROR)
10497 remove = true;
10498 break;
10500 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
10501 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
10502 == INTEGER_CST))
10504 else if (code == OMP_TASKLOOP
10505 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
10506 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
10507 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
10508 pre_p, NULL, false);
10509 break;
10511 case OMP_CLAUSE_DEFAULT:
10512 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
10513 break;
10515 case OMP_CLAUSE_INCLUSIVE:
10516 case OMP_CLAUSE_EXCLUSIVE:
10517 decl = OMP_CLAUSE_DECL (c);
10519 splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
10520 (splay_tree_key) decl);
10521 if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
10523 error_at (OMP_CLAUSE_LOCATION (c),
10524 "%qD specified in %qs clause but not in %<inscan%> "
10525 "%<reduction%> clause on the containing construct",
10526 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10527 remove = true;
10529 else
10531 n->value |= GOVD_REDUCTION_INSCAN;
10532 if (outer_ctx->region_type == ORT_SIMD
10533 && outer_ctx->outer_context
10534 && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
10536 n = splay_tree_lookup (outer_ctx->outer_context->variables,
10537 (splay_tree_key) decl);
10538 if (n && (n->value & GOVD_REDUCTION) != 0)
10539 n->value |= GOVD_REDUCTION_INSCAN;
10543 break;
10545 case OMP_CLAUSE_NOHOST:
10546 default:
10547 gcc_unreachable ();
10550 if (code == OACC_DATA
10551 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10552 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
10553 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
10554 remove = true;
10555 if (remove)
10556 *list_p = OMP_CLAUSE_CHAIN (c);
10557 else
10558 list_p = &OMP_CLAUSE_CHAIN (c);
10561 ctx->clauses = *orig_list_p;
10562 gimplify_omp_ctxp = ctx;
10563 if (struct_map_to_clause)
10564 delete struct_map_to_clause;
10565 if (struct_deref_set)
10566 delete struct_deref_set;
10569 /* Return true if DECL is a candidate for shared to firstprivate
10570 optimization. We only consider non-addressable scalars, not
10571 too big, and not references. */
10573 static bool
10574 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
10576 if (TREE_ADDRESSABLE (decl))
10577 return false;
10578 tree type = TREE_TYPE (decl);
10579 if (!is_gimple_reg_type (type)
10580 || TREE_CODE (type) == REFERENCE_TYPE
10581 || TREE_ADDRESSABLE (type))
10582 return false;
10583 /* Don't optimize too large decls, as each thread/task will have
10584 its own. */
10585 HOST_WIDE_INT len = int_size_in_bytes (type);
10586 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
10587 return false;
10588 if (omp_privatize_by_reference (decl))
10589 return false;
10590 return true;
10593 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
10594 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
10595 GOVD_WRITTEN in outer contexts. */
10597 static void
10598 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
10600 for (; ctx; ctx = ctx->outer_context)
10602 splay_tree_node n = splay_tree_lookup (ctx->variables,
10603 (splay_tree_key) decl);
10604 if (n == NULL)
10605 continue;
10606 else if (n->value & GOVD_SHARED)
10608 n->value |= GOVD_WRITTEN;
10609 return;
10611 else if (n->value & GOVD_DATA_SHARE_CLASS)
10612 return;
10616 /* Helper callback for walk_gimple_seq to discover possible stores
10617 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10618 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10619 for those. */
10621 static tree
10622 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
10624 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
10626 *walk_subtrees = 0;
10627 if (!wi->is_lhs)
10628 return NULL_TREE;
10630 tree op = *tp;
10633 if (handled_component_p (op))
10634 op = TREE_OPERAND (op, 0);
10635 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
10636 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
10637 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
10638 else
10639 break;
10641 while (1);
10642 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
10643 return NULL_TREE;
10645 omp_mark_stores (gimplify_omp_ctxp, op);
10646 return NULL_TREE;
10649 /* Helper callback for walk_gimple_seq to discover possible stores
10650 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10651 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10652 for those. */
10654 static tree
10655 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
10656 bool *handled_ops_p,
10657 struct walk_stmt_info *wi)
10659 gimple *stmt = gsi_stmt (*gsi_p);
10660 switch (gimple_code (stmt))
10662 /* Don't recurse on OpenMP constructs for which
10663 gimplify_adjust_omp_clauses already handled the bodies,
10664 except handle gimple_omp_for_pre_body. */
10665 case GIMPLE_OMP_FOR:
10666 *handled_ops_p = true;
10667 if (gimple_omp_for_pre_body (stmt))
10668 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
10669 omp_find_stores_stmt, omp_find_stores_op, wi);
10670 break;
10671 case GIMPLE_OMP_PARALLEL:
10672 case GIMPLE_OMP_TASK:
10673 case GIMPLE_OMP_SECTIONS:
10674 case GIMPLE_OMP_SINGLE:
10675 case GIMPLE_OMP_SCOPE:
10676 case GIMPLE_OMP_TARGET:
10677 case GIMPLE_OMP_TEAMS:
10678 case GIMPLE_OMP_CRITICAL:
10679 *handled_ops_p = true;
10680 break;
10681 default:
10682 break;
10684 return NULL_TREE;
10687 struct gimplify_adjust_omp_clauses_data
10689 tree *list_p;
10690 gimple_seq *pre_p;
10693 /* For all variables that were not actually used within the context,
10694 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
10696 static int
10697 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
10699 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
10700 gimple_seq *pre_p
10701 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
10702 tree decl = (tree) n->key;
10703 unsigned flags = n->value;
10704 enum omp_clause_code code;
10705 tree clause;
10706 bool private_debug;
10708 if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
10709 && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
10710 flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
10711 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
10712 return 0;
10713 if ((flags & GOVD_SEEN) == 0)
10714 return 0;
10715 if ((flags & GOVD_MAP_HAS_ATTACHMENTS) != 0)
10716 return 0;
10717 if (flags & GOVD_DEBUG_PRIVATE)
10719 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
10720 private_debug = true;
10722 else if (flags & GOVD_MAP)
10723 private_debug = false;
10724 else
10725 private_debug
10726 = lang_hooks.decls.omp_private_debug_clause (decl,
10727 !!(flags & GOVD_SHARED));
10728 if (private_debug)
10729 code = OMP_CLAUSE_PRIVATE;
10730 else if (flags & GOVD_MAP)
10732 code = OMP_CLAUSE_MAP;
10733 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
10734 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
10736 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
10737 return 0;
10739 if (VAR_P (decl)
10740 && DECL_IN_CONSTANT_POOL (decl)
10741 && !lookup_attribute ("omp declare target",
10742 DECL_ATTRIBUTES (decl)))
10744 tree id = get_identifier ("omp declare target");
10745 DECL_ATTRIBUTES (decl)
10746 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
10747 varpool_node *node = varpool_node::get (decl);
10748 if (node)
10750 node->offloadable = 1;
10751 if (ENABLE_OFFLOADING)
10752 g->have_offload = true;
10756 else if (flags & GOVD_SHARED)
10758 if (is_global_var (decl))
10760 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
10761 while (ctx != NULL)
10763 splay_tree_node on
10764 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10765 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
10766 | GOVD_PRIVATE | GOVD_REDUCTION
10767 | GOVD_LINEAR | GOVD_MAP)) != 0)
10768 break;
10769 ctx = ctx->outer_context;
10771 if (ctx == NULL)
10772 return 0;
10774 code = OMP_CLAUSE_SHARED;
10775 /* Don't optimize shared into firstprivate for read-only vars
10776 on tasks with depend clause, we shouldn't try to copy them
10777 until the dependencies are satisfied. */
10778 if (gimplify_omp_ctxp->has_depend)
10779 flags |= GOVD_WRITTEN;
10781 else if (flags & GOVD_PRIVATE)
10782 code = OMP_CLAUSE_PRIVATE;
10783 else if (flags & GOVD_FIRSTPRIVATE)
10785 code = OMP_CLAUSE_FIRSTPRIVATE;
10786 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
10787 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
10788 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
10790 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
10791 "%<target%> construct", decl);
10792 return 0;
10795 else if (flags & GOVD_LASTPRIVATE)
10796 code = OMP_CLAUSE_LASTPRIVATE;
10797 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
10798 return 0;
10799 else if (flags & GOVD_CONDTEMP)
10801 code = OMP_CLAUSE__CONDTEMP_;
10802 gimple_add_tmp_var (decl);
10804 else
10805 gcc_unreachable ();
10807 if (((flags & GOVD_LASTPRIVATE)
10808 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
10809 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10810 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10812 tree chain = *list_p;
10813 clause = build_omp_clause (input_location, code);
10814 OMP_CLAUSE_DECL (clause) = decl;
10815 OMP_CLAUSE_CHAIN (clause) = chain;
10816 if (private_debug)
10817 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
10818 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
10819 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
10820 else if (code == OMP_CLAUSE_SHARED
10821 && (flags & GOVD_WRITTEN) == 0
10822 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10823 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
10824 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
10825 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
10826 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
10828 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
10829 OMP_CLAUSE_DECL (nc) = decl;
10830 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
10831 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
10832 OMP_CLAUSE_DECL (clause)
10833 = build_simple_mem_ref_loc (input_location, decl);
10834 OMP_CLAUSE_DECL (clause)
10835 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
10836 build_int_cst (build_pointer_type (char_type_node), 0));
10837 OMP_CLAUSE_SIZE (clause) = size_zero_node;
10838 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10839 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
10840 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
10841 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
10842 OMP_CLAUSE_CHAIN (nc) = chain;
10843 OMP_CLAUSE_CHAIN (clause) = nc;
10844 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10845 gimplify_omp_ctxp = ctx->outer_context;
10846 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
10847 pre_p, NULL, is_gimple_val, fb_rvalue);
10848 gimplify_omp_ctxp = ctx;
10850 else if (code == OMP_CLAUSE_MAP)
10852 int kind;
10853 /* Not all combinations of these GOVD_MAP flags are actually valid. */
10854 switch (flags & (GOVD_MAP_TO_ONLY
10855 | GOVD_MAP_FORCE
10856 | GOVD_MAP_FORCE_PRESENT
10857 | GOVD_MAP_ALLOC_ONLY
10858 | GOVD_MAP_FROM_ONLY))
10860 case 0:
10861 kind = GOMP_MAP_TOFROM;
10862 break;
10863 case GOVD_MAP_FORCE:
10864 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
10865 break;
10866 case GOVD_MAP_TO_ONLY:
10867 kind = GOMP_MAP_TO;
10868 break;
10869 case GOVD_MAP_FROM_ONLY:
10870 kind = GOMP_MAP_FROM;
10871 break;
10872 case GOVD_MAP_ALLOC_ONLY:
10873 kind = GOMP_MAP_ALLOC;
10874 break;
10875 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
10876 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
10877 break;
10878 case GOVD_MAP_FORCE_PRESENT:
10879 kind = GOMP_MAP_FORCE_PRESENT;
10880 break;
10881 default:
10882 gcc_unreachable ();
10884 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
10885 /* Setting of the implicit flag for the runtime is currently disabled for
10886 OpenACC. */
10887 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
10888 OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
10889 if (DECL_SIZE (decl)
10890 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
10892 tree decl2 = DECL_VALUE_EXPR (decl);
10893 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
10894 decl2 = TREE_OPERAND (decl2, 0);
10895 gcc_assert (DECL_P (decl2));
10896 tree mem = build_simple_mem_ref (decl2);
10897 OMP_CLAUSE_DECL (clause) = mem;
10898 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
10899 if (gimplify_omp_ctxp->outer_context)
10901 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
10902 omp_notice_variable (ctx, decl2, true);
10903 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
10905 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
10906 OMP_CLAUSE_MAP);
10907 OMP_CLAUSE_DECL (nc) = decl;
10908 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10909 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
10910 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
10911 else
10912 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
10913 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
10914 OMP_CLAUSE_CHAIN (clause) = nc;
10916 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
10917 && omp_privatize_by_reference (decl))
10919 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
10920 OMP_CLAUSE_SIZE (clause)
10921 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
10922 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10923 gimplify_omp_ctxp = ctx->outer_context;
10924 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
10925 pre_p, NULL, is_gimple_val, fb_rvalue);
10926 gimplify_omp_ctxp = ctx;
10927 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
10928 OMP_CLAUSE_MAP);
10929 OMP_CLAUSE_DECL (nc) = decl;
10930 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10931 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
10932 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
10933 OMP_CLAUSE_CHAIN (clause) = nc;
10935 else
10936 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
10938 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
10940 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
10941 OMP_CLAUSE_DECL (nc) = decl;
10942 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
10943 OMP_CLAUSE_CHAIN (nc) = chain;
10944 OMP_CLAUSE_CHAIN (clause) = nc;
10945 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10946 gimplify_omp_ctxp = ctx->outer_context;
10947 lang_hooks.decls.omp_finish_clause (nc, pre_p,
10948 (ctx->region_type & ORT_ACC) != 0);
10949 gimplify_omp_ctxp = ctx;
10951 *list_p = clause;
10952 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10953 gimplify_omp_ctxp = ctx->outer_context;
10954 /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
10955 in simd. Those are only added for the local vars inside of simd body
10956 and they don't need to be e.g. default constructible. */
10957 if (code != OMP_CLAUSE_PRIVATE || ctx->region_type != ORT_SIMD)
10958 lang_hooks.decls.omp_finish_clause (clause, pre_p,
10959 (ctx->region_type & ORT_ACC) != 0);
10960 if (gimplify_omp_ctxp)
10961 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
10962 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
10963 && DECL_P (OMP_CLAUSE_SIZE (clause)))
10964 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
10965 true);
10966 gimplify_omp_ctxp = ctx;
10967 return 0;
10970 static void
10971 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
10972 enum tree_code code)
10974 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10975 tree *orig_list_p = list_p;
10976 tree c, decl;
10977 bool has_inscan_reductions = false;
10979 if (body)
10981 struct gimplify_omp_ctx *octx;
10982 for (octx = ctx; octx; octx = octx->outer_context)
10983 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
10984 break;
10985 if (octx)
10987 struct walk_stmt_info wi;
10988 memset (&wi, 0, sizeof (wi));
10989 walk_gimple_seq (body, omp_find_stores_stmt,
10990 omp_find_stores_op, &wi);
10994 if (ctx->add_safelen1)
10996 /* If there are VLAs in the body of simd loop, prevent
10997 vectorization. */
10998 gcc_assert (ctx->region_type == ORT_SIMD);
10999 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
11000 OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
11001 OMP_CLAUSE_CHAIN (c) = *list_p;
11002 *list_p = c;
11003 list_p = &OMP_CLAUSE_CHAIN (c);
11006 if (ctx->region_type == ORT_WORKSHARE
11007 && ctx->outer_context
11008 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
11010 for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
11011 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11012 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
11014 decl = OMP_CLAUSE_DECL (c);
11015 splay_tree_node n
11016 = splay_tree_lookup (ctx->outer_context->variables,
11017 (splay_tree_key) decl);
11018 gcc_checking_assert (!splay_tree_lookup (ctx->variables,
11019 (splay_tree_key) decl));
11020 omp_add_variable (ctx, decl, n->value);
11021 tree c2 = copy_node (c);
11022 OMP_CLAUSE_CHAIN (c2) = *list_p;
11023 *list_p = c2;
11024 if ((n->value & GOVD_FIRSTPRIVATE) == 0)
11025 continue;
11026 c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11027 OMP_CLAUSE_FIRSTPRIVATE);
11028 OMP_CLAUSE_DECL (c2) = decl;
11029 OMP_CLAUSE_CHAIN (c2) = *list_p;
11030 *list_p = c2;
11033 while ((c = *list_p) != NULL)
11035 splay_tree_node n;
11036 bool remove = false;
11038 switch (OMP_CLAUSE_CODE (c))
11040 case OMP_CLAUSE_FIRSTPRIVATE:
11041 if ((ctx->region_type & ORT_TARGET)
11042 && (ctx->region_type & ORT_ACC) == 0
11043 && TYPE_ATOMIC (strip_array_types
11044 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
11046 error_at (OMP_CLAUSE_LOCATION (c),
11047 "%<_Atomic%> %qD in %<firstprivate%> clause on "
11048 "%<target%> construct", OMP_CLAUSE_DECL (c));
11049 remove = true;
11050 break;
11052 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
11054 decl = OMP_CLAUSE_DECL (c);
11055 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11056 if ((n->value & GOVD_MAP) != 0)
11058 remove = true;
11059 break;
11061 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) = 0;
11062 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) = 0;
11064 /* FALLTHRU */
11065 case OMP_CLAUSE_PRIVATE:
11066 case OMP_CLAUSE_SHARED:
11067 case OMP_CLAUSE_LINEAR:
11068 decl = OMP_CLAUSE_DECL (c);
11069 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11070 remove = !(n->value & GOVD_SEEN);
11071 if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
11072 && code == OMP_PARALLEL
11073 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
11074 remove = true;
11075 if (! remove)
11077 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
11078 if ((n->value & GOVD_DEBUG_PRIVATE)
11079 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
11081 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
11082 || ((n->value & GOVD_DATA_SHARE_CLASS)
11083 == GOVD_SHARED));
11084 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
11085 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
11087 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11088 && ctx->has_depend
11089 && DECL_P (decl))
11090 n->value |= GOVD_WRITTEN;
11091 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11092 && (n->value & GOVD_WRITTEN) == 0
11093 && DECL_P (decl)
11094 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11095 OMP_CLAUSE_SHARED_READONLY (c) = 1;
11096 else if (DECL_P (decl)
11097 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11098 && (n->value & GOVD_WRITTEN) != 0)
11099 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11100 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
11101 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11102 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11104 else
11105 n->value &= ~GOVD_EXPLICIT;
11106 break;
11108 case OMP_CLAUSE_LASTPRIVATE:
11109 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
11110 accurately reflect the presence of a FIRSTPRIVATE clause. */
11111 decl = OMP_CLAUSE_DECL (c);
11112 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11113 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
11114 = (n->value & GOVD_FIRSTPRIVATE) != 0;
11115 if (code == OMP_DISTRIBUTE
11116 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
11118 remove = true;
11119 error_at (OMP_CLAUSE_LOCATION (c),
11120 "same variable used in %<firstprivate%> and "
11121 "%<lastprivate%> clauses on %<distribute%> "
11122 "construct");
11124 if (!remove
11125 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11126 && DECL_P (decl)
11127 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11128 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11129 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
11130 remove = true;
11131 break;
11133 case OMP_CLAUSE_ALIGNED:
11134 decl = OMP_CLAUSE_DECL (c);
11135 if (!is_global_var (decl))
11137 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11138 remove = n == NULL || !(n->value & GOVD_SEEN);
11139 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
11141 struct gimplify_omp_ctx *octx;
11142 if (n != NULL
11143 && (n->value & (GOVD_DATA_SHARE_CLASS
11144 & ~GOVD_FIRSTPRIVATE)))
11145 remove = true;
11146 else
11147 for (octx = ctx->outer_context; octx;
11148 octx = octx->outer_context)
11150 n = splay_tree_lookup (octx->variables,
11151 (splay_tree_key) decl);
11152 if (n == NULL)
11153 continue;
11154 if (n->value & GOVD_LOCAL)
11155 break;
11156 /* We have to avoid assigning a shared variable
11157 to itself when trying to add
11158 __builtin_assume_aligned. */
11159 if (n->value & GOVD_SHARED)
11161 remove = true;
11162 break;
11167 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
11169 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11170 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
11171 remove = true;
11173 break;
11175 case OMP_CLAUSE_NONTEMPORAL:
11176 decl = OMP_CLAUSE_DECL (c);
11177 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11178 remove = n == NULL || !(n->value & GOVD_SEEN);
11179 break;
11181 case OMP_CLAUSE_MAP:
11182 if (code == OMP_TARGET_EXIT_DATA
11183 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
11185 remove = true;
11186 break;
11188 decl = OMP_CLAUSE_DECL (c);
11189 /* Data clauses associated with reductions must be
11190 compatible with present_or_copy. Warn and adjust the clause
11191 if that is not the case. */
11192 if (ctx->region_type == ORT_ACC_PARALLEL
11193 || ctx->region_type == ORT_ACC_SERIAL)
11195 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
11196 n = NULL;
11198 if (DECL_P (t))
11199 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
11201 if (n && (n->value & GOVD_REDUCTION))
11203 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
11205 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
11206 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
11207 && kind != GOMP_MAP_FORCE_PRESENT
11208 && kind != GOMP_MAP_POINTER)
11210 warning_at (OMP_CLAUSE_LOCATION (c), 0,
11211 "incompatible data clause with reduction "
11212 "on %qE; promoting to %<present_or_copy%>",
11213 DECL_NAME (t));
11214 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
11218 if (!DECL_P (decl))
11220 if ((ctx->region_type & ORT_TARGET) != 0
11221 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
11223 if (TREE_CODE (decl) == INDIRECT_REF
11224 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
11225 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
11226 == REFERENCE_TYPE))
11227 decl = TREE_OPERAND (decl, 0);
11228 if (TREE_CODE (decl) == COMPONENT_REF)
11230 while (TREE_CODE (decl) == COMPONENT_REF)
11231 decl = TREE_OPERAND (decl, 0);
11232 if (DECL_P (decl))
11234 n = splay_tree_lookup (ctx->variables,
11235 (splay_tree_key) decl);
11236 if (!(n->value & GOVD_SEEN))
11237 remove = true;
11241 break;
11243 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11244 if ((ctx->region_type & ORT_TARGET) != 0
11245 && !(n->value & GOVD_SEEN)
11246 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
11247 && (!is_global_var (decl)
11248 || !lookup_attribute ("omp declare target link",
11249 DECL_ATTRIBUTES (decl))))
11251 remove = true;
11252 /* For struct element mapping, if struct is never referenced
11253 in target block and none of the mapping has always modifier,
11254 remove all the struct element mappings, which immediately
11255 follow the GOMP_MAP_STRUCT map clause. */
11256 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
11258 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
11259 while (cnt--)
11260 OMP_CLAUSE_CHAIN (c)
11261 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
11264 else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
11265 && (code == OMP_TARGET_EXIT_DATA
11266 || code == OACC_EXIT_DATA))
11267 remove = true;
11268 else if (DECL_SIZE (decl)
11269 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
11270 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
11271 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
11272 && (OMP_CLAUSE_MAP_KIND (c)
11273 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
11275 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
11276 for these, TREE_CODE (DECL_SIZE (decl)) will always be
11277 INTEGER_CST. */
11278 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
11280 tree decl2 = DECL_VALUE_EXPR (decl);
11281 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11282 decl2 = TREE_OPERAND (decl2, 0);
11283 gcc_assert (DECL_P (decl2));
11284 tree mem = build_simple_mem_ref (decl2);
11285 OMP_CLAUSE_DECL (c) = mem;
11286 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11287 if (ctx->outer_context)
11289 omp_notice_variable (ctx->outer_context, decl2, true);
11290 omp_notice_variable (ctx->outer_context,
11291 OMP_CLAUSE_SIZE (c), true);
11293 if (((ctx->region_type & ORT_TARGET) != 0
11294 || !ctx->target_firstprivatize_array_bases)
11295 && ((n->value & GOVD_SEEN) == 0
11296 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
11298 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11299 OMP_CLAUSE_MAP);
11300 OMP_CLAUSE_DECL (nc) = decl;
11301 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11302 if (ctx->target_firstprivatize_array_bases)
11303 OMP_CLAUSE_SET_MAP_KIND (nc,
11304 GOMP_MAP_FIRSTPRIVATE_POINTER);
11305 else
11306 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
11307 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
11308 OMP_CLAUSE_CHAIN (c) = nc;
11309 c = nc;
11312 else
11314 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11315 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11316 gcc_assert ((n->value & GOVD_SEEN) == 0
11317 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11318 == 0));
11320 break;
11322 case OMP_CLAUSE_TO:
11323 case OMP_CLAUSE_FROM:
11324 case OMP_CLAUSE__CACHE_:
11325 decl = OMP_CLAUSE_DECL (c);
11326 if (!DECL_P (decl))
11327 break;
11328 if (DECL_SIZE (decl)
11329 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
11331 tree decl2 = DECL_VALUE_EXPR (decl);
11332 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11333 decl2 = TREE_OPERAND (decl2, 0);
11334 gcc_assert (DECL_P (decl2));
11335 tree mem = build_simple_mem_ref (decl2);
11336 OMP_CLAUSE_DECL (c) = mem;
11337 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11338 if (ctx->outer_context)
11340 omp_notice_variable (ctx->outer_context, decl2, true);
11341 omp_notice_variable (ctx->outer_context,
11342 OMP_CLAUSE_SIZE (c), true);
11345 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11346 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11347 break;
11349 case OMP_CLAUSE_REDUCTION:
11350 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
11352 decl = OMP_CLAUSE_DECL (c);
11353 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11354 if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
11356 remove = true;
11357 error_at (OMP_CLAUSE_LOCATION (c),
11358 "%qD specified in %<inscan%> %<reduction%> clause "
11359 "but not in %<scan%> directive clause", decl);
11360 break;
11362 has_inscan_reductions = true;
11364 /* FALLTHRU */
11365 case OMP_CLAUSE_IN_REDUCTION:
11366 case OMP_CLAUSE_TASK_REDUCTION:
11367 decl = OMP_CLAUSE_DECL (c);
11368 /* OpenACC reductions need a present_or_copy data clause.
11369 Add one if necessary. Emit error when the reduction is private. */
11370 if (ctx->region_type == ORT_ACC_PARALLEL
11371 || ctx->region_type == ORT_ACC_SERIAL)
11373 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11374 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11376 remove = true;
11377 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
11378 "reduction on %qE", DECL_NAME (decl));
11380 else if ((n->value & GOVD_MAP) == 0)
11382 tree next = OMP_CLAUSE_CHAIN (c);
11383 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
11384 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
11385 OMP_CLAUSE_DECL (nc) = decl;
11386 OMP_CLAUSE_CHAIN (c) = nc;
11387 lang_hooks.decls.omp_finish_clause (nc, pre_p,
11388 (ctx->region_type
11389 & ORT_ACC) != 0);
11390 while (1)
11392 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
11393 if (OMP_CLAUSE_CHAIN (nc) == NULL)
11394 break;
11395 nc = OMP_CLAUSE_CHAIN (nc);
11397 OMP_CLAUSE_CHAIN (nc) = next;
11398 n->value |= GOVD_MAP;
11401 if (DECL_P (decl)
11402 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11403 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11404 break;
11406 case OMP_CLAUSE_ALLOCATE:
11407 decl = OMP_CLAUSE_DECL (c);
11408 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11409 if (n != NULL && !(n->value & GOVD_SEEN))
11411 if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR))
11412 != 0
11413 && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0)
11414 remove = true;
11416 if (!remove
11417 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
11418 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST
11419 && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0
11420 || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK
11421 || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS))
11423 tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
11424 n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator);
11425 if (n == NULL)
11427 enum omp_clause_default_kind default_kind
11428 = ctx->default_kind;
11429 ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
11430 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11431 true);
11432 ctx->default_kind = default_kind;
11434 else
11435 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11436 true);
11438 break;
11440 case OMP_CLAUSE_COPYIN:
11441 case OMP_CLAUSE_COPYPRIVATE:
11442 case OMP_CLAUSE_IF:
11443 case OMP_CLAUSE_NUM_THREADS:
11444 case OMP_CLAUSE_NUM_TEAMS:
11445 case OMP_CLAUSE_THREAD_LIMIT:
11446 case OMP_CLAUSE_DIST_SCHEDULE:
11447 case OMP_CLAUSE_DEVICE:
11448 case OMP_CLAUSE_SCHEDULE:
11449 case OMP_CLAUSE_NOWAIT:
11450 case OMP_CLAUSE_ORDERED:
11451 case OMP_CLAUSE_DEFAULT:
11452 case OMP_CLAUSE_UNTIED:
11453 case OMP_CLAUSE_COLLAPSE:
11454 case OMP_CLAUSE_FINAL:
11455 case OMP_CLAUSE_MERGEABLE:
11456 case OMP_CLAUSE_PROC_BIND:
11457 case OMP_CLAUSE_SAFELEN:
11458 case OMP_CLAUSE_SIMDLEN:
11459 case OMP_CLAUSE_DEPEND:
11460 case OMP_CLAUSE_PRIORITY:
11461 case OMP_CLAUSE_GRAINSIZE:
11462 case OMP_CLAUSE_NUM_TASKS:
11463 case OMP_CLAUSE_NOGROUP:
11464 case OMP_CLAUSE_THREADS:
11465 case OMP_CLAUSE_SIMD:
11466 case OMP_CLAUSE_FILTER:
11467 case OMP_CLAUSE_HINT:
11468 case OMP_CLAUSE_DEFAULTMAP:
11469 case OMP_CLAUSE_ORDER:
11470 case OMP_CLAUSE_BIND:
11471 case OMP_CLAUSE_DETACH:
11472 case OMP_CLAUSE_USE_DEVICE_PTR:
11473 case OMP_CLAUSE_USE_DEVICE_ADDR:
11474 case OMP_CLAUSE_IS_DEVICE_PTR:
11475 case OMP_CLAUSE_ASYNC:
11476 case OMP_CLAUSE_WAIT:
11477 case OMP_CLAUSE_INDEPENDENT:
11478 case OMP_CLAUSE_NUM_GANGS:
11479 case OMP_CLAUSE_NUM_WORKERS:
11480 case OMP_CLAUSE_VECTOR_LENGTH:
11481 case OMP_CLAUSE_GANG:
11482 case OMP_CLAUSE_WORKER:
11483 case OMP_CLAUSE_VECTOR:
11484 case OMP_CLAUSE_AUTO:
11485 case OMP_CLAUSE_SEQ:
11486 case OMP_CLAUSE_TILE:
11487 case OMP_CLAUSE_IF_PRESENT:
11488 case OMP_CLAUSE_FINALIZE:
11489 case OMP_CLAUSE_INCLUSIVE:
11490 case OMP_CLAUSE_EXCLUSIVE:
11491 break;
11493 case OMP_CLAUSE_NOHOST:
11494 default:
11495 gcc_unreachable ();
11498 if (remove)
11499 *list_p = OMP_CLAUSE_CHAIN (c);
11500 else
11501 list_p = &OMP_CLAUSE_CHAIN (c);
11504 /* Add in any implicit data sharing. Implicit clauses are added at the start
11505 of the clause list, but after any non-map clauses. */
11506 struct gimplify_adjust_omp_clauses_data data;
11507 tree *implicit_add_list_p = orig_list_p;
11508 while (*implicit_add_list_p
11509 && OMP_CLAUSE_CODE (*implicit_add_list_p) != OMP_CLAUSE_MAP)
11510 implicit_add_list_p = &OMP_CLAUSE_CHAIN (*implicit_add_list_p);
11512 data.list_p = implicit_add_list_p;
11513 data.pre_p = pre_p;
11514 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
11516 if (has_inscan_reductions)
11517 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
11518 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11519 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
11521 error_at (OMP_CLAUSE_LOCATION (c),
11522 "%<inscan%> %<reduction%> clause used together with "
11523 "%<linear%> clause for a variable other than loop "
11524 "iterator");
11525 break;
11528 gimplify_omp_ctxp = ctx->outer_context;
11529 delete_omp_context (ctx);
11532 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
11533 -1 if unknown yet (simd is involved, won't be known until vectorization)
11534 and 1 if they do. If SCORES is non-NULL, it should point to an array
11535 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
11536 of the CONSTRUCTS (position -1 if it will never match) followed by
11537 number of constructs in the OpenMP context construct trait. If the
11538 score depends on whether it will be in a declare simd clone or not,
11539 the function returns 2 and there will be two sets of the scores, the first
11540 one for the case that it is not in a declare simd clone, the other
11541 that it is in a declare simd clone. */
11544 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
11545 int *scores)
11547 int matched = 0, cnt = 0;
11548 bool simd_seen = false;
11549 bool target_seen = false;
11550 int declare_simd_cnt = -1;
11551 auto_vec<enum tree_code, 16> codes;
11552 for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
11554 if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
11555 || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
11556 == ORT_TARGET && ctx->code == OMP_TARGET)
11557 || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
11558 || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
11559 || (ctx->region_type == ORT_SIMD
11560 && ctx->code == OMP_SIMD
11561 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
11563 ++cnt;
11564 if (scores)
11565 codes.safe_push (ctx->code);
11566 else if (matched < nconstructs && ctx->code == constructs[matched])
11568 if (ctx->code == OMP_SIMD)
11570 if (matched)
11571 return 0;
11572 simd_seen = true;
11574 ++matched;
11576 if (ctx->code == OMP_TARGET)
11578 if (scores == NULL)
11579 return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
11580 target_seen = true;
11581 break;
11584 else if (ctx->region_type == ORT_WORKSHARE
11585 && ctx->code == OMP_LOOP
11586 && ctx->outer_context
11587 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
11588 && ctx->outer_context->outer_context
11589 && ctx->outer_context->outer_context->code == OMP_LOOP
11590 && ctx->outer_context->outer_context->distribute)
11591 ctx = ctx->outer_context->outer_context;
11592 ctx = ctx->outer_context;
11594 if (!target_seen
11595 && lookup_attribute ("omp declare simd",
11596 DECL_ATTRIBUTES (current_function_decl)))
11598 /* Declare simd is a maybe case, it is supposed to be added only to the
11599 omp-simd-clone.c added clones and not to the base function. */
11600 declare_simd_cnt = cnt++;
11601 if (scores)
11602 codes.safe_push (OMP_SIMD);
11603 else if (cnt == 0
11604 && constructs[0] == OMP_SIMD)
11606 gcc_assert (matched == 0);
11607 simd_seen = true;
11608 if (++matched == nconstructs)
11609 return -1;
11612 if (tree attr = lookup_attribute ("omp declare variant variant",
11613 DECL_ATTRIBUTES (current_function_decl)))
11615 enum tree_code variant_constructs[5];
11616 int variant_nconstructs = 0;
11617 if (!target_seen)
11618 variant_nconstructs
11619 = omp_constructor_traits_to_codes (TREE_VALUE (attr),
11620 variant_constructs);
11621 for (int i = 0; i < variant_nconstructs; i++)
11623 ++cnt;
11624 if (scores)
11625 codes.safe_push (variant_constructs[i]);
11626 else if (matched < nconstructs
11627 && variant_constructs[i] == constructs[matched])
11629 if (variant_constructs[i] == OMP_SIMD)
11631 if (matched)
11632 return 0;
11633 simd_seen = true;
11635 ++matched;
11639 if (!target_seen
11640 && lookup_attribute ("omp declare target block",
11641 DECL_ATTRIBUTES (current_function_decl)))
11643 if (scores)
11644 codes.safe_push (OMP_TARGET);
11645 else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
11646 ++matched;
11648 if (scores)
11650 for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
11652 int j = codes.length () - 1;
11653 for (int i = nconstructs - 1; i >= 0; i--)
11655 while (j >= 0
11656 && (pass != 0 || declare_simd_cnt != j)
11657 && constructs[i] != codes[j])
11658 --j;
11659 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
11660 *scores++ = j - 1;
11661 else
11662 *scores++ = j;
11664 *scores++ = ((pass == 0 && declare_simd_cnt != -1)
11665 ? codes.length () - 1 : codes.length ());
11667 return declare_simd_cnt == -1 ? 1 : 2;
11669 if (matched == nconstructs)
11670 return simd_seen ? -1 : 1;
11671 return 0;
11674 /* Gimplify OACC_CACHE. */
11676 static void
11677 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
11679 tree expr = *expr_p;
11681 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
11682 OACC_CACHE);
11683 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
11684 OACC_CACHE);
11686 /* TODO: Do something sensible with this information. */
11688 *expr_p = NULL_TREE;
11691 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
11692 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
11693 kind. The entry kind will replace the one in CLAUSE, while the exit
11694 kind will be used in a new omp_clause and returned to the caller. */
11696 static tree
11697 gimplify_oacc_declare_1 (tree clause)
11699 HOST_WIDE_INT kind, new_op;
11700 bool ret = false;
11701 tree c = NULL;
11703 kind = OMP_CLAUSE_MAP_KIND (clause);
11705 switch (kind)
11707 case GOMP_MAP_ALLOC:
11708 new_op = GOMP_MAP_RELEASE;
11709 ret = true;
11710 break;
11712 case GOMP_MAP_FROM:
11713 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
11714 new_op = GOMP_MAP_FROM;
11715 ret = true;
11716 break;
11718 case GOMP_MAP_TOFROM:
11719 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
11720 new_op = GOMP_MAP_FROM;
11721 ret = true;
11722 break;
11724 case GOMP_MAP_DEVICE_RESIDENT:
11725 case GOMP_MAP_FORCE_DEVICEPTR:
11726 case GOMP_MAP_FORCE_PRESENT:
11727 case GOMP_MAP_LINK:
11728 case GOMP_MAP_POINTER:
11729 case GOMP_MAP_TO:
11730 break;
11732 default:
11733 gcc_unreachable ();
11734 break;
11737 if (ret)
11739 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
11740 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
11741 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
11744 return c;
11747 /* Gimplify OACC_DECLARE. */
11749 static void
11750 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
11752 tree expr = *expr_p;
11753 gomp_target *stmt;
11754 tree clauses, t, decl;
11756 clauses = OACC_DECLARE_CLAUSES (expr);
11758 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
11759 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
11761 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
11763 decl = OMP_CLAUSE_DECL (t);
11765 if (TREE_CODE (decl) == MEM_REF)
11766 decl = TREE_OPERAND (decl, 0);
11768 if (VAR_P (decl) && !is_oacc_declared (decl))
11770 tree attr = get_identifier ("oacc declare target");
11771 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
11772 DECL_ATTRIBUTES (decl));
11775 if (VAR_P (decl)
11776 && !is_global_var (decl)
11777 && DECL_CONTEXT (decl) == current_function_decl)
11779 tree c = gimplify_oacc_declare_1 (t);
11780 if (c)
11782 if (oacc_declare_returns == NULL)
11783 oacc_declare_returns = new hash_map<tree, tree>;
11785 oacc_declare_returns->put (decl, c);
11789 if (gimplify_omp_ctxp)
11790 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
11793 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
11794 clauses);
11796 gimplify_seq_add_stmt (pre_p, stmt);
11798 *expr_p = NULL_TREE;
11801 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
11802 gimplification of the body, as well as scanning the body for used
11803 variables. We need to do this scan now, because variable-sized
11804 decls will be decomposed during gimplification. */
11806 static void
11807 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
11809 tree expr = *expr_p;
11810 gimple *g;
11811 gimple_seq body = NULL;
11813 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
11814 OMP_PARALLEL_COMBINED (expr)
11815 ? ORT_COMBINED_PARALLEL
11816 : ORT_PARALLEL, OMP_PARALLEL);
11818 push_gimplify_context ();
11820 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
11821 if (gimple_code (g) == GIMPLE_BIND)
11822 pop_gimplify_context (g);
11823 else
11824 pop_gimplify_context (NULL);
11826 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
11827 OMP_PARALLEL);
11829 g = gimple_build_omp_parallel (body,
11830 OMP_PARALLEL_CLAUSES (expr),
11831 NULL_TREE, NULL_TREE);
11832 if (OMP_PARALLEL_COMBINED (expr))
11833 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
11834 gimplify_seq_add_stmt (pre_p, g);
11835 *expr_p = NULL_TREE;
11838 /* Gimplify the contents of an OMP_TASK statement. This involves
11839 gimplification of the body, as well as scanning the body for used
11840 variables. We need to do this scan now, because variable-sized
11841 decls will be decomposed during gimplification. */
11843 static void
11844 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
11846 tree expr = *expr_p;
11847 gimple *g;
11848 gimple_seq body = NULL;
11850 if (OMP_TASK_BODY (expr) == NULL_TREE)
11851 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
11852 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
11853 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
11855 error_at (OMP_CLAUSE_LOCATION (c),
11856 "%<mutexinoutset%> kind in %<depend%> clause on a "
11857 "%<taskwait%> construct");
11858 break;
11861 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
11862 omp_find_clause (OMP_TASK_CLAUSES (expr),
11863 OMP_CLAUSE_UNTIED)
11864 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
11866 if (OMP_TASK_BODY (expr))
11868 push_gimplify_context ();
11870 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
11871 if (gimple_code (g) == GIMPLE_BIND)
11872 pop_gimplify_context (g);
11873 else
11874 pop_gimplify_context (NULL);
11877 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
11878 OMP_TASK);
11880 g = gimple_build_omp_task (body,
11881 OMP_TASK_CLAUSES (expr),
11882 NULL_TREE, NULL_TREE,
11883 NULL_TREE, NULL_TREE, NULL_TREE);
11884 if (OMP_TASK_BODY (expr) == NULL_TREE)
11885 gimple_omp_task_set_taskwait_p (g, true);
11886 gimplify_seq_add_stmt (pre_p, g);
11887 *expr_p = NULL_TREE;
11890 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
11891 force it into a temporary initialized in PRE_P and add firstprivate clause
11892 to ORIG_FOR_STMT. */
11894 static void
11895 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
11896 tree orig_for_stmt)
11898 if (*tp == NULL || is_gimple_constant (*tp))
11899 return;
11901 *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
11902 /* Reference to pointer conversion is considered useless,
11903 but is significant for firstprivate clause. Force it
11904 here. */
11905 if (type
11906 && TREE_CODE (type) == POINTER_TYPE
11907 && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
11909 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
11910 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
11911 gimplify_and_add (m, pre_p);
11912 *tp = v;
11915 tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
11916 OMP_CLAUSE_DECL (c) = *tp;
11917 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
11918 OMP_FOR_CLAUSES (orig_for_stmt) = c;
11921 /* Gimplify the gross structure of an OMP_FOR statement. */
11923 static enum gimplify_status
11924 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
11926 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
11927 enum gimplify_status ret = GS_ALL_DONE;
11928 enum gimplify_status tret;
11929 gomp_for *gfor;
11930 gimple_seq for_body, for_pre_body;
11931 int i;
11932 bitmap has_decl_expr = NULL;
11933 enum omp_region_type ort = ORT_WORKSHARE;
11934 bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
11936 orig_for_stmt = for_stmt = *expr_p;
11938 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
11939 != NULL_TREE);
11940 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
11942 tree *data[4] = { NULL, NULL, NULL, NULL };
11943 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
11944 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
11945 find_combined_omp_for, data, NULL);
11946 if (inner_for_stmt == NULL_TREE)
11948 gcc_assert (seen_error ());
11949 *expr_p = NULL_TREE;
11950 return GS_ERROR;
11952 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
11954 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
11955 &OMP_FOR_PRE_BODY (for_stmt));
11956 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
11958 if (OMP_FOR_PRE_BODY (inner_for_stmt))
11960 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
11961 &OMP_FOR_PRE_BODY (for_stmt));
11962 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
11965 if (data[0])
11967 /* We have some statements or variable declarations in between
11968 the composite construct directives. Move them around the
11969 inner_for_stmt. */
11970 data[0] = expr_p;
11971 for (i = 0; i < 3; i++)
11972 if (data[i])
11974 tree t = *data[i];
11975 if (i < 2 && data[i + 1] == &OMP_BODY (t))
11976 data[i + 1] = data[i];
11977 *data[i] = OMP_BODY (t);
11978 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
11979 NULL_TREE, make_node (BLOCK));
11980 OMP_BODY (t) = body;
11981 append_to_statement_list_force (inner_for_stmt,
11982 &BIND_EXPR_BODY (body));
11983 *data[3] = t;
11984 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
11985 gcc_assert (*data[3] == inner_for_stmt);
11987 return GS_OK;
11990 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
11991 if (!loop_p
11992 && OMP_FOR_ORIG_DECLS (inner_for_stmt)
11993 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11994 i)) == TREE_LIST
11995 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11996 i)))
11998 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
11999 /* Class iterators aren't allowed on OMP_SIMD, so the only
12000 case we need to solve is distribute parallel for. They are
12001 allowed on the loop construct, but that is already handled
12002 in gimplify_omp_loop. */
12003 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
12004 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
12005 && data[1]);
12006 tree orig_decl = TREE_PURPOSE (orig);
12007 tree last = TREE_VALUE (orig);
12008 tree *pc;
12009 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
12010 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
12011 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
12012 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
12013 && OMP_CLAUSE_DECL (*pc) == orig_decl)
12014 break;
12015 if (*pc == NULL_TREE)
12017 tree *spc;
12018 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
12019 *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
12020 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
12021 && OMP_CLAUSE_DECL (*spc) == orig_decl)
12022 break;
12023 if (*spc)
12025 tree c = *spc;
12026 *spc = OMP_CLAUSE_CHAIN (c);
12027 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
12028 *pc = c;
12031 if (*pc == NULL_TREE)
12033 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
12035 /* private clause will appear only on inner_for_stmt.
12036 Change it into firstprivate, and add private clause
12037 on for_stmt. */
12038 tree c = copy_node (*pc);
12039 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12040 OMP_FOR_CLAUSES (for_stmt) = c;
12041 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
12042 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12044 else
12046 /* lastprivate clause will appear on both inner_for_stmt
12047 and for_stmt. Add firstprivate clause to
12048 inner_for_stmt. */
12049 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
12050 OMP_CLAUSE_FIRSTPRIVATE);
12051 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
12052 OMP_CLAUSE_CHAIN (c) = *pc;
12053 *pc = c;
12054 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12056 tree c = build_omp_clause (UNKNOWN_LOCATION,
12057 OMP_CLAUSE_FIRSTPRIVATE);
12058 OMP_CLAUSE_DECL (c) = last;
12059 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12060 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12061 c = build_omp_clause (UNKNOWN_LOCATION,
12062 *pc ? OMP_CLAUSE_SHARED
12063 : OMP_CLAUSE_FIRSTPRIVATE);
12064 OMP_CLAUSE_DECL (c) = orig_decl;
12065 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12066 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12068 /* Similarly, take care of C++ range for temporaries, those should
12069 be firstprivate on OMP_PARALLEL if any. */
12070 if (data[1])
12071 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
12072 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
12073 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12074 i)) == TREE_LIST
12075 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12076 i)))
12078 tree orig
12079 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
12080 tree v = TREE_CHAIN (orig);
12081 tree c = build_omp_clause (UNKNOWN_LOCATION,
12082 OMP_CLAUSE_FIRSTPRIVATE);
12083 /* First add firstprivate clause for the __for_end artificial
12084 decl. */
12085 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
12086 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12087 == REFERENCE_TYPE)
12088 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12089 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12090 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12091 if (TREE_VEC_ELT (v, 0))
12093 /* And now the same for __for_range artificial decl if it
12094 exists. */
12095 c = build_omp_clause (UNKNOWN_LOCATION,
12096 OMP_CLAUSE_FIRSTPRIVATE);
12097 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
12098 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12099 == REFERENCE_TYPE)
12100 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12101 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12102 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12107 switch (TREE_CODE (for_stmt))
12109 case OMP_FOR:
12110 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
12112 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12113 OMP_CLAUSE_SCHEDULE))
12114 error_at (EXPR_LOCATION (for_stmt),
12115 "%qs clause may not appear on non-rectangular %qs",
12116 "schedule", "for");
12117 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
12118 error_at (EXPR_LOCATION (for_stmt),
12119 "%qs clause may not appear on non-rectangular %qs",
12120 "ordered", "for");
12122 break;
12123 case OMP_DISTRIBUTE:
12124 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
12125 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12126 OMP_CLAUSE_DIST_SCHEDULE))
12127 error_at (EXPR_LOCATION (for_stmt),
12128 "%qs clause may not appear on non-rectangular %qs",
12129 "dist_schedule", "distribute");
12130 break;
12131 case OACC_LOOP:
12132 ort = ORT_ACC;
12133 break;
12134 case OMP_TASKLOOP:
12135 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
12136 ort = ORT_UNTIED_TASKLOOP;
12137 else
12138 ort = ORT_TASKLOOP;
12139 break;
12140 case OMP_SIMD:
12141 ort = ORT_SIMD;
12142 break;
12143 default:
12144 gcc_unreachable ();
12147 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
12148 clause for the IV. */
12149 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12151 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
12152 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12153 decl = TREE_OPERAND (t, 0);
12154 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
12155 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12156 && OMP_CLAUSE_DECL (c) == decl)
12158 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12159 break;
12163 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
12164 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
12165 loop_p && TREE_CODE (for_stmt) != OMP_SIMD
12166 ? OMP_LOOP : TREE_CODE (for_stmt));
12168 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
12169 gimplify_omp_ctxp->distribute = true;
12171 /* Handle OMP_FOR_INIT. */
12172 for_pre_body = NULL;
12173 if ((ort == ORT_SIMD
12174 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
12175 && OMP_FOR_PRE_BODY (for_stmt))
12177 has_decl_expr = BITMAP_ALLOC (NULL);
12178 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
12179 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
12180 == VAR_DECL)
12182 t = OMP_FOR_PRE_BODY (for_stmt);
12183 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12185 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
12187 tree_stmt_iterator si;
12188 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
12189 tsi_next (&si))
12191 t = tsi_stmt (si);
12192 if (TREE_CODE (t) == DECL_EXPR
12193 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
12194 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12198 if (OMP_FOR_PRE_BODY (for_stmt))
12200 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
12201 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12202 else
12204 struct gimplify_omp_ctx ctx;
12205 memset (&ctx, 0, sizeof (ctx));
12206 ctx.region_type = ORT_NONE;
12207 gimplify_omp_ctxp = &ctx;
12208 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12209 gimplify_omp_ctxp = NULL;
12212 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
12214 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
12215 for_stmt = inner_for_stmt;
12217 /* For taskloop, need to gimplify the start, end and step before the
12218 taskloop, outside of the taskloop omp context. */
12219 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12221 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12223 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12224 gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
12225 ? pre_p : &for_pre_body);
12226 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
12227 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12229 tree v = TREE_OPERAND (t, 1);
12230 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12231 for_pre_p, orig_for_stmt);
12232 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12233 for_pre_p, orig_for_stmt);
12235 else
12236 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12237 orig_for_stmt);
12239 /* Handle OMP_FOR_COND. */
12240 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12241 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12243 tree v = TREE_OPERAND (t, 1);
12244 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12245 for_pre_p, orig_for_stmt);
12246 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12247 for_pre_p, orig_for_stmt);
12249 else
12250 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12251 orig_for_stmt);
12253 /* Handle OMP_FOR_INCR. */
12254 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12255 if (TREE_CODE (t) == MODIFY_EXPR)
12257 decl = TREE_OPERAND (t, 0);
12258 t = TREE_OPERAND (t, 1);
12259 tree *tp = &TREE_OPERAND (t, 1);
12260 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
12261 tp = &TREE_OPERAND (t, 0);
12263 gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
12264 orig_for_stmt);
12268 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
12269 OMP_TASKLOOP);
12272 if (orig_for_stmt != for_stmt)
12273 gimplify_omp_ctxp->combined_loop = true;
12275 for_body = NULL;
12276 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12277 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
12278 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12279 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
12281 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
12282 bool is_doacross = false;
12283 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
12285 is_doacross = true;
12286 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
12287 (OMP_FOR_INIT (for_stmt))
12288 * 2);
12290 int collapse = 1, tile = 0;
12291 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
12292 if (c)
12293 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
12294 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
12295 if (c)
12296 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
12297 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
12298 hash_set<tree> *allocate_uids = NULL;
12299 if (c)
12301 allocate_uids = new hash_set<tree>;
12302 for (; c; c = OMP_CLAUSE_CHAIN (c))
12303 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
12304 allocate_uids->add (OMP_CLAUSE_DECL (c));
12306 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12308 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12309 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12310 decl = TREE_OPERAND (t, 0);
12311 gcc_assert (DECL_P (decl));
12312 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
12313 || POINTER_TYPE_P (TREE_TYPE (decl)));
12314 if (is_doacross)
12316 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
12318 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12319 if (TREE_CODE (orig_decl) == TREE_LIST)
12321 orig_decl = TREE_PURPOSE (orig_decl);
12322 if (!orig_decl)
12323 orig_decl = decl;
12325 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
12327 else
12328 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12329 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12332 if (for_stmt == orig_for_stmt)
12334 tree orig_decl = decl;
12335 if (OMP_FOR_ORIG_DECLS (for_stmt))
12337 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12338 if (TREE_CODE (orig_decl) == TREE_LIST)
12340 orig_decl = TREE_PURPOSE (orig_decl);
12341 if (!orig_decl)
12342 orig_decl = decl;
12345 if (is_global_var (orig_decl) && DECL_THREAD_LOCAL_P (orig_decl))
12346 error_at (EXPR_LOCATION (for_stmt),
12347 "threadprivate iteration variable %qD", orig_decl);
12350 /* Make sure the iteration variable is private. */
12351 tree c = NULL_TREE;
12352 tree c2 = NULL_TREE;
12353 if (orig_for_stmt != for_stmt)
12355 /* Preserve this information until we gimplify the inner simd. */
12356 if (has_decl_expr
12357 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12358 TREE_PRIVATE (t) = 1;
12360 else if (ort == ORT_SIMD)
12362 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12363 (splay_tree_key) decl);
12364 omp_is_private (gimplify_omp_ctxp, decl,
12365 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12366 != 1));
12367 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
12369 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12370 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
12371 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12372 OMP_CLAUSE_LASTPRIVATE);
12373 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12374 OMP_CLAUSE_LASTPRIVATE))
12375 if (OMP_CLAUSE_DECL (c3) == decl)
12377 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12378 "conditional %<lastprivate%> on loop "
12379 "iterator %qD ignored", decl);
12380 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12381 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12384 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
12386 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12387 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12388 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
12389 if ((has_decl_expr
12390 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12391 || TREE_PRIVATE (t))
12393 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12394 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12396 struct gimplify_omp_ctx *outer
12397 = gimplify_omp_ctxp->outer_context;
12398 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12400 if (outer->region_type == ORT_WORKSHARE
12401 && outer->combined_loop)
12403 n = splay_tree_lookup (outer->variables,
12404 (splay_tree_key)decl);
12405 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12407 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12408 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12410 else
12412 struct gimplify_omp_ctx *octx = outer->outer_context;
12413 if (octx
12414 && octx->region_type == ORT_COMBINED_PARALLEL
12415 && octx->outer_context
12416 && (octx->outer_context->region_type
12417 == ORT_WORKSHARE)
12418 && octx->outer_context->combined_loop)
12420 octx = octx->outer_context;
12421 n = splay_tree_lookup (octx->variables,
12422 (splay_tree_key)decl);
12423 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12425 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12426 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12433 OMP_CLAUSE_DECL (c) = decl;
12434 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12435 OMP_FOR_CLAUSES (for_stmt) = c;
12436 omp_add_variable (gimplify_omp_ctxp, decl, flags);
12437 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12438 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12439 true);
12441 else
12443 bool lastprivate
12444 = (!has_decl_expr
12445 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
12446 if (TREE_PRIVATE (t))
12447 lastprivate = false;
12448 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
12450 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12451 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
12452 lastprivate = false;
12455 struct gimplify_omp_ctx *outer
12456 = gimplify_omp_ctxp->outer_context;
12457 if (outer && lastprivate)
12458 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12459 true);
12461 c = build_omp_clause (input_location,
12462 lastprivate ? OMP_CLAUSE_LASTPRIVATE
12463 : OMP_CLAUSE_PRIVATE);
12464 OMP_CLAUSE_DECL (c) = decl;
12465 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12466 OMP_FOR_CLAUSES (for_stmt) = c;
12467 omp_add_variable (gimplify_omp_ctxp, decl,
12468 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
12469 | GOVD_EXPLICIT | GOVD_SEEN);
12470 c = NULL_TREE;
12473 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
12475 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12476 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12477 (splay_tree_key) decl);
12478 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
12479 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12480 OMP_CLAUSE_LASTPRIVATE);
12481 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12482 OMP_CLAUSE_LASTPRIVATE))
12483 if (OMP_CLAUSE_DECL (c3) == decl)
12485 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12486 "conditional %<lastprivate%> on loop "
12487 "iterator %qD ignored", decl);
12488 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12489 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12492 else
12493 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
12495 /* If DECL is not a gimple register, create a temporary variable to act
12496 as an iteration counter. This is valid, since DECL cannot be
12497 modified in the body of the loop. Similarly for any iteration vars
12498 in simd with collapse > 1 where the iterator vars must be
12499 lastprivate. And similarly for vars mentioned in allocate clauses. */
12500 if (orig_for_stmt != for_stmt)
12501 var = decl;
12502 else if (!is_gimple_reg (decl)
12503 || (ort == ORT_SIMD
12504 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
12505 || (allocate_uids && allocate_uids->contains (decl)))
12507 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12508 /* Make sure omp_add_variable is not called on it prematurely.
12509 We call it ourselves a few lines later. */
12510 gimplify_omp_ctxp = NULL;
12511 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
12512 gimplify_omp_ctxp = ctx;
12513 TREE_OPERAND (t, 0) = var;
12515 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
12517 if (ort == ORT_SIMD
12518 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12520 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12521 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
12522 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
12523 OMP_CLAUSE_DECL (c2) = var;
12524 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
12525 OMP_FOR_CLAUSES (for_stmt) = c2;
12526 omp_add_variable (gimplify_omp_ctxp, var,
12527 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
12528 if (c == NULL_TREE)
12530 c = c2;
12531 c2 = NULL_TREE;
12534 else
12535 omp_add_variable (gimplify_omp_ctxp, var,
12536 GOVD_PRIVATE | GOVD_SEEN);
12538 else
12539 var = decl;
12541 gimplify_omp_ctxp->in_for_exprs = true;
12542 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12544 tree lb = TREE_OPERAND (t, 1);
12545 tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
12546 is_gimple_val, fb_rvalue, false);
12547 ret = MIN (ret, tret);
12548 tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
12549 is_gimple_val, fb_rvalue, false);
12551 else
12552 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12553 is_gimple_val, fb_rvalue, false);
12554 gimplify_omp_ctxp->in_for_exprs = false;
12555 ret = MIN (ret, tret);
12556 if (ret == GS_ERROR)
12557 return ret;
12559 /* Handle OMP_FOR_COND. */
12560 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12561 gcc_assert (COMPARISON_CLASS_P (t));
12562 gcc_assert (TREE_OPERAND (t, 0) == decl);
12564 gimplify_omp_ctxp->in_for_exprs = true;
12565 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12567 tree ub = TREE_OPERAND (t, 1);
12568 tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
12569 is_gimple_val, fb_rvalue, false);
12570 ret = MIN (ret, tret);
12571 tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
12572 is_gimple_val, fb_rvalue, false);
12574 else
12575 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12576 is_gimple_val, fb_rvalue, false);
12577 gimplify_omp_ctxp->in_for_exprs = false;
12578 ret = MIN (ret, tret);
12580 /* Handle OMP_FOR_INCR. */
12581 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12582 switch (TREE_CODE (t))
12584 case PREINCREMENT_EXPR:
12585 case POSTINCREMENT_EXPR:
12587 tree decl = TREE_OPERAND (t, 0);
12588 /* c_omp_for_incr_canonicalize_ptr() should have been
12589 called to massage things appropriately. */
12590 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
12592 if (orig_for_stmt != for_stmt)
12593 break;
12594 t = build_int_cst (TREE_TYPE (decl), 1);
12595 if (c)
12596 OMP_CLAUSE_LINEAR_STEP (c) = t;
12597 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
12598 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
12599 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
12600 break;
12603 case PREDECREMENT_EXPR:
12604 case POSTDECREMENT_EXPR:
12605 /* c_omp_for_incr_canonicalize_ptr() should have been
12606 called to massage things appropriately. */
12607 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
12608 if (orig_for_stmt != for_stmt)
12609 break;
12610 t = build_int_cst (TREE_TYPE (decl), -1);
12611 if (c)
12612 OMP_CLAUSE_LINEAR_STEP (c) = t;
12613 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
12614 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
12615 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
12616 break;
12618 case MODIFY_EXPR:
12619 gcc_assert (TREE_OPERAND (t, 0) == decl);
12620 TREE_OPERAND (t, 0) = var;
12622 t = TREE_OPERAND (t, 1);
12623 switch (TREE_CODE (t))
12625 case PLUS_EXPR:
12626 if (TREE_OPERAND (t, 1) == decl)
12628 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
12629 TREE_OPERAND (t, 0) = var;
12630 break;
12633 /* Fallthru. */
12634 case MINUS_EXPR:
12635 case POINTER_PLUS_EXPR:
12636 gcc_assert (TREE_OPERAND (t, 0) == decl);
12637 TREE_OPERAND (t, 0) = var;
12638 break;
12639 default:
12640 gcc_unreachable ();
12643 gimplify_omp_ctxp->in_for_exprs = true;
12644 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12645 is_gimple_val, fb_rvalue, false);
12646 ret = MIN (ret, tret);
12647 if (c)
12649 tree step = TREE_OPERAND (t, 1);
12650 tree stept = TREE_TYPE (decl);
12651 if (POINTER_TYPE_P (stept))
12652 stept = sizetype;
12653 step = fold_convert (stept, step);
12654 if (TREE_CODE (t) == MINUS_EXPR)
12655 step = fold_build1 (NEGATE_EXPR, stept, step);
12656 OMP_CLAUSE_LINEAR_STEP (c) = step;
12657 if (step != TREE_OPERAND (t, 1))
12659 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
12660 &for_pre_body, NULL,
12661 is_gimple_val, fb_rvalue, false);
12662 ret = MIN (ret, tret);
12665 gimplify_omp_ctxp->in_for_exprs = false;
12666 break;
12668 default:
12669 gcc_unreachable ();
12672 if (c2)
12674 gcc_assert (c);
12675 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
12678 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
12680 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
12681 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12682 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
12683 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12684 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
12685 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
12686 && OMP_CLAUSE_DECL (c) == decl)
12688 if (is_doacross && (collapse == 1 || i >= collapse))
12689 t = var;
12690 else
12692 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12693 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12694 gcc_assert (TREE_OPERAND (t, 0) == var);
12695 t = TREE_OPERAND (t, 1);
12696 gcc_assert (TREE_CODE (t) == PLUS_EXPR
12697 || TREE_CODE (t) == MINUS_EXPR
12698 || TREE_CODE (t) == POINTER_PLUS_EXPR);
12699 gcc_assert (TREE_OPERAND (t, 0) == var);
12700 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
12701 is_doacross ? var : decl,
12702 TREE_OPERAND (t, 1));
12704 gimple_seq *seq;
12705 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
12706 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
12707 else
12708 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
12709 push_gimplify_context ();
12710 gimplify_assign (decl, t, seq);
12711 gimple *bind = NULL;
12712 if (gimplify_ctxp->temps)
12714 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
12715 *seq = NULL;
12716 gimplify_seq_add_stmt (seq, bind);
12718 pop_gimplify_context (bind);
12721 if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
12722 for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
12724 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
12725 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12726 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12727 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12728 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12729 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
12730 gcc_assert (COMPARISON_CLASS_P (t));
12731 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12732 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12733 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12737 BITMAP_FREE (has_decl_expr);
12738 delete allocate_uids;
12740 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
12741 || (loop_p && orig_for_stmt == for_stmt))
12743 push_gimplify_context ();
12744 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
12746 OMP_FOR_BODY (orig_for_stmt)
12747 = build3 (BIND_EXPR, void_type_node, NULL,
12748 OMP_FOR_BODY (orig_for_stmt), NULL);
12749 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
12753 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
12754 &for_body);
12756 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
12757 || (loop_p && orig_for_stmt == for_stmt))
12759 if (gimple_code (g) == GIMPLE_BIND)
12760 pop_gimplify_context (g);
12761 else
12762 pop_gimplify_context (NULL);
12765 if (orig_for_stmt != for_stmt)
12766 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12768 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12769 decl = TREE_OPERAND (t, 0);
12770 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12771 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12772 gimplify_omp_ctxp = ctx->outer_context;
12773 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
12774 gimplify_omp_ctxp = ctx;
12775 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
12776 TREE_OPERAND (t, 0) = var;
12777 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12778 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12779 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
12780 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
12781 for (int j = i + 1;
12782 j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
12784 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
12785 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12786 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12787 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12789 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12790 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12792 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
12793 gcc_assert (COMPARISON_CLASS_P (t));
12794 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12795 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12797 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12798 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12803 gimplify_adjust_omp_clauses (pre_p, for_body,
12804 &OMP_FOR_CLAUSES (orig_for_stmt),
12805 TREE_CODE (orig_for_stmt));
12807 int kind;
12808 switch (TREE_CODE (orig_for_stmt))
12810 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
12811 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
12812 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
12813 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
12814 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
12815 default:
12816 gcc_unreachable ();
12818 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
12820 gimplify_seq_add_seq (pre_p, for_pre_body);
12821 for_pre_body = NULL;
12823 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
12824 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
12825 for_pre_body);
12826 if (orig_for_stmt != for_stmt)
12827 gimple_omp_for_set_combined_p (gfor, true);
12828 if (gimplify_omp_ctxp
12829 && (gimplify_omp_ctxp->combined_loop
12830 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
12831 && gimplify_omp_ctxp->outer_context
12832 && gimplify_omp_ctxp->outer_context->combined_loop)))
12834 gimple_omp_for_set_combined_into_p (gfor, true);
12835 if (gimplify_omp_ctxp->combined_loop)
12836 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
12837 else
12838 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
12841 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12843 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12844 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
12845 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
12846 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12847 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
12848 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
12849 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12850 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
12853 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
12854 constructs with GIMPLE_OMP_TASK sandwiched in between them.
12855 The outer taskloop stands for computing the number of iterations,
12856 counts for collapsed loops and holding taskloop specific clauses.
12857 The task construct stands for the effect of data sharing on the
12858 explicit task it creates and the inner taskloop stands for expansion
12859 of the static loop inside of the explicit task construct. */
12860 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12862 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
12863 tree task_clauses = NULL_TREE;
12864 tree c = *gfor_clauses_ptr;
12865 tree *gtask_clauses_ptr = &task_clauses;
12866 tree outer_for_clauses = NULL_TREE;
12867 tree *gforo_clauses_ptr = &outer_for_clauses;
12868 bitmap lastprivate_uids = NULL;
12869 if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
12871 c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
12872 if (c)
12874 lastprivate_uids = BITMAP_ALLOC (NULL);
12875 for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
12876 OMP_CLAUSE_LASTPRIVATE))
12877 bitmap_set_bit (lastprivate_uids,
12878 DECL_UID (OMP_CLAUSE_DECL (c)));
12880 c = *gfor_clauses_ptr;
12882 for (; c; c = OMP_CLAUSE_CHAIN (c))
12883 switch (OMP_CLAUSE_CODE (c))
12885 /* These clauses are allowed on task, move them there. */
12886 case OMP_CLAUSE_SHARED:
12887 case OMP_CLAUSE_FIRSTPRIVATE:
12888 case OMP_CLAUSE_DEFAULT:
12889 case OMP_CLAUSE_IF:
12890 case OMP_CLAUSE_UNTIED:
12891 case OMP_CLAUSE_FINAL:
12892 case OMP_CLAUSE_MERGEABLE:
12893 case OMP_CLAUSE_PRIORITY:
12894 case OMP_CLAUSE_REDUCTION:
12895 case OMP_CLAUSE_IN_REDUCTION:
12896 *gtask_clauses_ptr = c;
12897 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12898 break;
12899 case OMP_CLAUSE_PRIVATE:
12900 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
12902 /* We want private on outer for and firstprivate
12903 on task. */
12904 *gtask_clauses_ptr
12905 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12906 OMP_CLAUSE_FIRSTPRIVATE);
12907 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12908 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
12909 openacc);
12910 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12911 *gforo_clauses_ptr = c;
12912 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12914 else
12916 *gtask_clauses_ptr = c;
12917 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12919 break;
12920 /* These clauses go into outer taskloop clauses. */
12921 case OMP_CLAUSE_GRAINSIZE:
12922 case OMP_CLAUSE_NUM_TASKS:
12923 case OMP_CLAUSE_NOGROUP:
12924 *gforo_clauses_ptr = c;
12925 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12926 break;
12927 /* Collapse clause we duplicate on both taskloops. */
12928 case OMP_CLAUSE_COLLAPSE:
12929 *gfor_clauses_ptr = c;
12930 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12931 *gforo_clauses_ptr = copy_node (c);
12932 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
12933 break;
12934 /* For lastprivate, keep the clause on inner taskloop, and add
12935 a shared clause on task. If the same decl is also firstprivate,
12936 add also firstprivate clause on the inner taskloop. */
12937 case OMP_CLAUSE_LASTPRIVATE:
12938 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
12940 /* For taskloop C++ lastprivate IVs, we want:
12941 1) private on outer taskloop
12942 2) firstprivate and shared on task
12943 3) lastprivate on inner taskloop */
12944 *gtask_clauses_ptr
12945 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12946 OMP_CLAUSE_FIRSTPRIVATE);
12947 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12948 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
12949 openacc);
12950 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12951 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
12952 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12953 OMP_CLAUSE_PRIVATE);
12954 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
12955 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
12956 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
12957 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
12959 *gfor_clauses_ptr = c;
12960 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12961 *gtask_clauses_ptr
12962 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
12963 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12964 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
12965 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
12966 gtask_clauses_ptr
12967 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12968 break;
12969 /* Allocate clause we duplicate on task and inner taskloop
12970 if the decl is lastprivate, otherwise just put on task. */
12971 case OMP_CLAUSE_ALLOCATE:
12972 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
12973 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
12975 /* Additionally, put firstprivate clause on task
12976 for the allocator if it is not constant. */
12977 *gtask_clauses_ptr
12978 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12979 OMP_CLAUSE_FIRSTPRIVATE);
12980 OMP_CLAUSE_DECL (*gtask_clauses_ptr)
12981 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
12982 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12984 if (lastprivate_uids
12985 && bitmap_bit_p (lastprivate_uids,
12986 DECL_UID (OMP_CLAUSE_DECL (c))))
12988 *gfor_clauses_ptr = c;
12989 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12990 *gtask_clauses_ptr = copy_node (c);
12991 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12993 else
12995 *gtask_clauses_ptr = c;
12996 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12998 break;
12999 default:
13000 gcc_unreachable ();
13002 *gfor_clauses_ptr = NULL_TREE;
13003 *gtask_clauses_ptr = NULL_TREE;
13004 *gforo_clauses_ptr = NULL_TREE;
13005 BITMAP_FREE (lastprivate_uids);
13006 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
13007 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
13008 NULL_TREE, NULL_TREE, NULL_TREE);
13009 gimple_omp_task_set_taskloop_p (g, true);
13010 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
13011 gomp_for *gforo
13012 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
13013 gimple_omp_for_collapse (gfor),
13014 gimple_omp_for_pre_body (gfor));
13015 gimple_omp_for_set_pre_body (gfor, NULL);
13016 gimple_omp_for_set_combined_p (gforo, true);
13017 gimple_omp_for_set_combined_into_p (gfor, true);
13018 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
13020 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
13021 tree v = create_tmp_var (type);
13022 gimple_omp_for_set_index (gforo, i, v);
13023 t = unshare_expr (gimple_omp_for_initial (gfor, i));
13024 gimple_omp_for_set_initial (gforo, i, t);
13025 gimple_omp_for_set_cond (gforo, i,
13026 gimple_omp_for_cond (gfor, i));
13027 t = unshare_expr (gimple_omp_for_final (gfor, i));
13028 gimple_omp_for_set_final (gforo, i, t);
13029 t = unshare_expr (gimple_omp_for_incr (gfor, i));
13030 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
13031 TREE_OPERAND (t, 0) = v;
13032 gimple_omp_for_set_incr (gforo, i, t);
13033 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
13034 OMP_CLAUSE_DECL (t) = v;
13035 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
13036 gimple_omp_for_set_clauses (gforo, t);
13037 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
13039 tree *p1 = NULL, *p2 = NULL;
13040 t = gimple_omp_for_initial (gforo, i);
13041 if (TREE_CODE (t) == TREE_VEC)
13042 p1 = &TREE_VEC_ELT (t, 0);
13043 t = gimple_omp_for_final (gforo, i);
13044 if (TREE_CODE (t) == TREE_VEC)
13046 if (p1)
13047 p2 = &TREE_VEC_ELT (t, 0);
13048 else
13049 p1 = &TREE_VEC_ELT (t, 0);
13051 if (p1)
13053 int j;
13054 for (j = 0; j < i; j++)
13055 if (*p1 == gimple_omp_for_index (gfor, j))
13057 *p1 = gimple_omp_for_index (gforo, j);
13058 if (p2)
13059 *p2 = *p1;
13060 break;
13062 gcc_assert (j < i);
13066 gimplify_seq_add_stmt (pre_p, gforo);
13068 else
13069 gimplify_seq_add_stmt (pre_p, gfor);
13071 if (TREE_CODE (orig_for_stmt) == OMP_FOR)
13073 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13074 unsigned lastprivate_conditional = 0;
13075 while (ctx
13076 && (ctx->region_type == ORT_TARGET_DATA
13077 || ctx->region_type == ORT_TASKGROUP))
13078 ctx = ctx->outer_context;
13079 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
13080 for (tree c = gimple_omp_for_clauses (gfor);
13081 c; c = OMP_CLAUSE_CHAIN (c))
13082 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13083 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13084 ++lastprivate_conditional;
13085 if (lastprivate_conditional)
13087 struct omp_for_data fd;
13088 omp_extract_for_data (gfor, &fd, NULL);
13089 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
13090 lastprivate_conditional);
13091 tree var = create_tmp_var_raw (type);
13092 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
13093 OMP_CLAUSE_DECL (c) = var;
13094 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13095 gimple_omp_for_set_clauses (gfor, c);
13096 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
13099 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
13101 unsigned lastprivate_conditional = 0;
13102 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
13103 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13104 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13105 ++lastprivate_conditional;
13106 if (lastprivate_conditional)
13108 struct omp_for_data fd;
13109 omp_extract_for_data (gfor, &fd, NULL);
13110 tree type = unsigned_type_for (fd.iter_type);
13111 while (lastprivate_conditional--)
13113 tree c = build_omp_clause (UNKNOWN_LOCATION,
13114 OMP_CLAUSE__CONDTEMP_);
13115 OMP_CLAUSE_DECL (c) = create_tmp_var (type);
13116 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13117 gimple_omp_for_set_clauses (gfor, c);
13122 if (ret != GS_ALL_DONE)
13123 return GS_ERROR;
13124 *expr_p = NULL_TREE;
13125 return GS_ALL_DONE;
13128 /* Helper for gimplify_omp_loop, called through walk_tree. */
13130 static tree
13131 note_no_context_vars (tree *tp, int *, void *data)
13133 if (VAR_P (*tp)
13134 && DECL_CONTEXT (*tp) == NULL_TREE
13135 && !is_global_var (*tp))
13137 vec<tree> *d = (vec<tree> *) data;
13138 d->safe_push (*tp);
13139 DECL_CONTEXT (*tp) = current_function_decl;
13141 return NULL_TREE;
13144 /* Gimplify the gross structure of an OMP_LOOP statement. */
13146 static enum gimplify_status
13147 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
13149 tree for_stmt = *expr_p;
13150 tree clauses = OMP_FOR_CLAUSES (for_stmt);
13151 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
13152 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
13153 int i;
13155 /* If order is not present, the behavior is as if order(concurrent)
13156 appeared. */
13157 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
13158 if (order == NULL_TREE)
13160 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
13161 OMP_CLAUSE_CHAIN (order) = clauses;
13162 OMP_FOR_CLAUSES (for_stmt) = clauses = order;
13165 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
13166 if (bind == NULL_TREE)
13168 if (!flag_openmp) /* flag_openmp_simd */
13170 else if (octx && (octx->region_type & ORT_TEAMS) != 0)
13171 kind = OMP_CLAUSE_BIND_TEAMS;
13172 else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
13173 kind = OMP_CLAUSE_BIND_PARALLEL;
13174 else
13176 for (; octx; octx = octx->outer_context)
13178 if ((octx->region_type & ORT_ACC) != 0
13179 || octx->region_type == ORT_NONE
13180 || octx->region_type == ORT_IMPLICIT_TARGET)
13181 continue;
13182 break;
13184 if (octx == NULL && !in_omp_construct)
13185 error_at (EXPR_LOCATION (for_stmt),
13186 "%<bind%> clause not specified on a %<loop%> "
13187 "construct not nested inside another OpenMP construct");
13189 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
13190 OMP_CLAUSE_CHAIN (bind) = clauses;
13191 OMP_CLAUSE_BIND_KIND (bind) = kind;
13192 OMP_FOR_CLAUSES (for_stmt) = bind;
13194 else
13195 switch (OMP_CLAUSE_BIND_KIND (bind))
13197 case OMP_CLAUSE_BIND_THREAD:
13198 break;
13199 case OMP_CLAUSE_BIND_PARALLEL:
13200 if (!flag_openmp) /* flag_openmp_simd */
13202 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13203 break;
13205 for (; octx; octx = octx->outer_context)
13206 if (octx->region_type == ORT_SIMD
13207 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
13209 error_at (EXPR_LOCATION (for_stmt),
13210 "%<bind(parallel)%> on a %<loop%> construct nested "
13211 "inside %<simd%> construct");
13212 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13213 break;
13215 kind = OMP_CLAUSE_BIND_PARALLEL;
13216 break;
13217 case OMP_CLAUSE_BIND_TEAMS:
13218 if (!flag_openmp) /* flag_openmp_simd */
13220 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13221 break;
13223 if ((octx
13224 && octx->region_type != ORT_IMPLICIT_TARGET
13225 && octx->region_type != ORT_NONE
13226 && (octx->region_type & ORT_TEAMS) == 0)
13227 || in_omp_construct)
13229 error_at (EXPR_LOCATION (for_stmt),
13230 "%<bind(teams)%> on a %<loop%> region not strictly "
13231 "nested inside of a %<teams%> region");
13232 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13233 break;
13235 kind = OMP_CLAUSE_BIND_TEAMS;
13236 break;
13237 default:
13238 gcc_unreachable ();
13241 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
13242 switch (OMP_CLAUSE_CODE (*pc))
13244 case OMP_CLAUSE_REDUCTION:
13245 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
13247 error_at (OMP_CLAUSE_LOCATION (*pc),
13248 "%<inscan%> %<reduction%> clause on "
13249 "%qs construct", "loop");
13250 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
13252 if (OMP_CLAUSE_REDUCTION_TASK (*pc))
13254 error_at (OMP_CLAUSE_LOCATION (*pc),
13255 "invalid %<task%> reduction modifier on construct "
13256 "other than %<parallel%>, %qs or %<sections%>",
13257 lang_GNU_Fortran () ? "do" : "for");
13258 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
13260 pc = &OMP_CLAUSE_CHAIN (*pc);
13261 break;
13262 case OMP_CLAUSE_LASTPRIVATE:
13263 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13265 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13266 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13267 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
13268 break;
13269 if (OMP_FOR_ORIG_DECLS (for_stmt)
13270 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13271 i)) == TREE_LIST
13272 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13273 i)))
13275 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13276 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
13277 break;
13280 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
13282 error_at (OMP_CLAUSE_LOCATION (*pc),
13283 "%<lastprivate%> clause on a %<loop%> construct refers "
13284 "to a variable %qD which is not the loop iterator",
13285 OMP_CLAUSE_DECL (*pc));
13286 *pc = OMP_CLAUSE_CHAIN (*pc);
13287 break;
13289 pc = &OMP_CLAUSE_CHAIN (*pc);
13290 break;
13291 default:
13292 pc = &OMP_CLAUSE_CHAIN (*pc);
13293 break;
13296 TREE_SET_CODE (for_stmt, OMP_SIMD);
13298 int last;
13299 switch (kind)
13301 case OMP_CLAUSE_BIND_THREAD: last = 0; break;
13302 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
13303 case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
13305 for (int pass = 1; pass <= last; pass++)
13307 if (pass == 2)
13309 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
13310 make_node (BLOCK));
13311 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
13312 *expr_p = make_node (OMP_PARALLEL);
13313 TREE_TYPE (*expr_p) = void_type_node;
13314 OMP_PARALLEL_BODY (*expr_p) = bind;
13315 OMP_PARALLEL_COMBINED (*expr_p) = 1;
13316 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
13317 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
13318 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13319 if (OMP_FOR_ORIG_DECLS (for_stmt)
13320 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
13321 == TREE_LIST))
13323 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13324 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
13326 *pc = build_omp_clause (UNKNOWN_LOCATION,
13327 OMP_CLAUSE_FIRSTPRIVATE);
13328 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
13329 pc = &OMP_CLAUSE_CHAIN (*pc);
13333 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
13334 tree *pc = &OMP_FOR_CLAUSES (t);
13335 TREE_TYPE (t) = void_type_node;
13336 OMP_FOR_BODY (t) = *expr_p;
13337 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
13338 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
13339 switch (OMP_CLAUSE_CODE (c))
13341 case OMP_CLAUSE_BIND:
13342 case OMP_CLAUSE_ORDER:
13343 case OMP_CLAUSE_COLLAPSE:
13344 *pc = copy_node (c);
13345 pc = &OMP_CLAUSE_CHAIN (*pc);
13346 break;
13347 case OMP_CLAUSE_PRIVATE:
13348 case OMP_CLAUSE_FIRSTPRIVATE:
13349 /* Only needed on innermost. */
13350 break;
13351 case OMP_CLAUSE_LASTPRIVATE:
13352 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
13354 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13355 OMP_CLAUSE_FIRSTPRIVATE);
13356 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
13357 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13358 pc = &OMP_CLAUSE_CHAIN (*pc);
13360 *pc = copy_node (c);
13361 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
13362 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13363 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
13365 if (pass != last)
13366 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
13367 else
13368 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13369 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
13371 pc = &OMP_CLAUSE_CHAIN (*pc);
13372 break;
13373 case OMP_CLAUSE_REDUCTION:
13374 *pc = copy_node (c);
13375 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
13376 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13377 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
13379 auto_vec<tree> no_context_vars;
13380 int walk_subtrees = 0;
13381 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13382 &walk_subtrees, &no_context_vars);
13383 if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c))
13384 note_no_context_vars (&p, &walk_subtrees, &no_context_vars);
13385 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c),
13386 note_no_context_vars,
13387 &no_context_vars);
13388 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c),
13389 note_no_context_vars,
13390 &no_context_vars);
13392 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
13393 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
13394 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13395 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
13396 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
13398 hash_map<tree, tree> decl_map;
13399 decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c));
13400 decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13401 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc));
13402 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13403 decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
13404 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc));
13406 copy_body_data id;
13407 memset (&id, 0, sizeof (id));
13408 id.src_fn = current_function_decl;
13409 id.dst_fn = current_function_decl;
13410 id.src_cfun = cfun;
13411 id.decl_map = &decl_map;
13412 id.copy_decl = copy_decl_no_change;
13413 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
13414 id.transform_new_cfg = true;
13415 id.transform_return_to_modify = false;
13416 id.eh_lp_nr = 0;
13417 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r,
13418 &id, NULL);
13419 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r,
13420 &id, NULL);
13422 for (tree d : no_context_vars)
13424 DECL_CONTEXT (d) = NULL_TREE;
13425 DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE;
13428 else
13430 OMP_CLAUSE_REDUCTION_INIT (*pc)
13431 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
13432 OMP_CLAUSE_REDUCTION_MERGE (*pc)
13433 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
13435 pc = &OMP_CLAUSE_CHAIN (*pc);
13436 break;
13437 default:
13438 gcc_unreachable ();
13440 *pc = NULL_TREE;
13441 *expr_p = t;
13443 return gimplify_omp_for (expr_p, pre_p);
13447 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
13448 of OMP_TARGET's body. */
13450 static tree
13451 find_omp_teams (tree *tp, int *walk_subtrees, void *)
13453 *walk_subtrees = 0;
13454 switch (TREE_CODE (*tp))
13456 case OMP_TEAMS:
13457 return *tp;
13458 case BIND_EXPR:
13459 case STATEMENT_LIST:
13460 *walk_subtrees = 1;
13461 break;
13462 default:
13463 break;
13465 return NULL_TREE;
13468 /* Helper function of optimize_target_teams, determine if the expression
13469 can be computed safely before the target construct on the host. */
13471 static tree
13472 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
13474 splay_tree_node n;
13476 if (TYPE_P (*tp))
13478 *walk_subtrees = 0;
13479 return NULL_TREE;
13481 switch (TREE_CODE (*tp))
13483 case VAR_DECL:
13484 case PARM_DECL:
13485 case RESULT_DECL:
13486 *walk_subtrees = 0;
13487 if (error_operand_p (*tp)
13488 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
13489 || DECL_HAS_VALUE_EXPR_P (*tp)
13490 || DECL_THREAD_LOCAL_P (*tp)
13491 || TREE_SIDE_EFFECTS (*tp)
13492 || TREE_THIS_VOLATILE (*tp))
13493 return *tp;
13494 if (is_global_var (*tp)
13495 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
13496 || lookup_attribute ("omp declare target link",
13497 DECL_ATTRIBUTES (*tp))))
13498 return *tp;
13499 if (VAR_P (*tp)
13500 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
13501 && !is_global_var (*tp)
13502 && decl_function_context (*tp) == current_function_decl)
13503 return *tp;
13504 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
13505 (splay_tree_key) *tp);
13506 if (n == NULL)
13508 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
13509 return NULL_TREE;
13510 return *tp;
13512 else if (n->value & GOVD_LOCAL)
13513 return *tp;
13514 else if (n->value & GOVD_FIRSTPRIVATE)
13515 return NULL_TREE;
13516 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13517 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13518 return NULL_TREE;
13519 return *tp;
13520 case INTEGER_CST:
13521 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13522 return *tp;
13523 return NULL_TREE;
13524 case TARGET_EXPR:
13525 if (TARGET_EXPR_INITIAL (*tp)
13526 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
13527 return *tp;
13528 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
13529 walk_subtrees, NULL);
13530 /* Allow some reasonable subset of integral arithmetics. */
13531 case PLUS_EXPR:
13532 case MINUS_EXPR:
13533 case MULT_EXPR:
13534 case TRUNC_DIV_EXPR:
13535 case CEIL_DIV_EXPR:
13536 case FLOOR_DIV_EXPR:
13537 case ROUND_DIV_EXPR:
13538 case TRUNC_MOD_EXPR:
13539 case CEIL_MOD_EXPR:
13540 case FLOOR_MOD_EXPR:
13541 case ROUND_MOD_EXPR:
13542 case RDIV_EXPR:
13543 case EXACT_DIV_EXPR:
13544 case MIN_EXPR:
13545 case MAX_EXPR:
13546 case LSHIFT_EXPR:
13547 case RSHIFT_EXPR:
13548 case BIT_IOR_EXPR:
13549 case BIT_XOR_EXPR:
13550 case BIT_AND_EXPR:
13551 case NEGATE_EXPR:
13552 case ABS_EXPR:
13553 case BIT_NOT_EXPR:
13554 case NON_LVALUE_EXPR:
13555 CASE_CONVERT:
13556 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13557 return *tp;
13558 return NULL_TREE;
13559 /* And disallow anything else, except for comparisons. */
13560 default:
13561 if (COMPARISON_CLASS_P (*tp))
13562 return NULL_TREE;
13563 return *tp;
13567 /* Try to determine if the num_teams and/or thread_limit expressions
13568 can have their values determined already before entering the
13569 target construct.
13570 INTEGER_CSTs trivially are,
13571 integral decls that are firstprivate (explicitly or implicitly)
13572 or explicitly map(always, to:) or map(always, tofrom:) on the target
13573 region too, and expressions involving simple arithmetics on those
13574 too, function calls are not ok, dereferencing something neither etc.
13575 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
13576 EXPR based on what we find:
13577 0 stands for clause not specified at all, use implementation default
13578 -1 stands for value that can't be determined easily before entering
13579 the target construct.
13580 If teams construct is not present at all, use 1 for num_teams
13581 and 0 for thread_limit (only one team is involved, and the thread
13582 limit is implementation defined. */
13584 static void
13585 optimize_target_teams (tree target, gimple_seq *pre_p)
13587 tree body = OMP_BODY (target);
13588 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
13589 tree num_teams_lower = NULL_TREE;
13590 tree num_teams_upper = integer_zero_node;
13591 tree thread_limit = integer_zero_node;
13592 location_t num_teams_loc = EXPR_LOCATION (target);
13593 location_t thread_limit_loc = EXPR_LOCATION (target);
13594 tree c, *p, expr;
13595 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
13597 if (teams == NULL_TREE)
13598 num_teams_upper = integer_one_node;
13599 else
13600 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
13602 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
13604 p = &num_teams_upper;
13605 num_teams_loc = OMP_CLAUSE_LOCATION (c);
13606 if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))
13608 expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
13609 if (TREE_CODE (expr) == INTEGER_CST)
13610 num_teams_lower = expr;
13611 else if (walk_tree (&expr, computable_teams_clause,
13612 NULL, NULL))
13613 num_teams_lower = integer_minus_one_node;
13614 else
13616 num_teams_lower = expr;
13617 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
13618 if (gimplify_expr (&num_teams_lower, pre_p, NULL,
13619 is_gimple_val, fb_rvalue, false)
13620 == GS_ERROR)
13622 gimplify_omp_ctxp = target_ctx;
13623 num_teams_lower = integer_minus_one_node;
13625 else
13627 gimplify_omp_ctxp = target_ctx;
13628 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
13629 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
13630 = num_teams_lower;
13635 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
13637 p = &thread_limit;
13638 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
13640 else
13641 continue;
13642 expr = OMP_CLAUSE_OPERAND (c, 0);
13643 if (TREE_CODE (expr) == INTEGER_CST)
13645 *p = expr;
13646 continue;
13648 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
13650 *p = integer_minus_one_node;
13651 continue;
13653 *p = expr;
13654 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
13655 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
13656 == GS_ERROR)
13658 gimplify_omp_ctxp = target_ctx;
13659 *p = integer_minus_one_node;
13660 continue;
13662 gimplify_omp_ctxp = target_ctx;
13663 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
13664 OMP_CLAUSE_OPERAND (c, 0) = *p;
13666 if (!omp_find_clause (OMP_TARGET_CLAUSES (target), OMP_CLAUSE_THREAD_LIMIT))
13668 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
13669 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
13670 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
13671 OMP_TARGET_CLAUSES (target) = c;
13673 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
13674 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper;
13675 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower;
13676 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
13677 OMP_TARGET_CLAUSES (target) = c;
13680 /* Gimplify the gross structure of several OMP constructs. */
13682 static void
13683 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
13685 tree expr = *expr_p;
13686 gimple *stmt;
13687 gimple_seq body = NULL;
13688 enum omp_region_type ort;
13690 switch (TREE_CODE (expr))
13692 case OMP_SECTIONS:
13693 case OMP_SINGLE:
13694 ort = ORT_WORKSHARE;
13695 break;
13696 case OMP_SCOPE:
13697 ort = ORT_TASKGROUP;
13698 break;
13699 case OMP_TARGET:
13700 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
13701 break;
13702 case OACC_KERNELS:
13703 ort = ORT_ACC_KERNELS;
13704 break;
13705 case OACC_PARALLEL:
13706 ort = ORT_ACC_PARALLEL;
13707 break;
13708 case OACC_SERIAL:
13709 ort = ORT_ACC_SERIAL;
13710 break;
13711 case OACC_DATA:
13712 ort = ORT_ACC_DATA;
13713 break;
13714 case OMP_TARGET_DATA:
13715 ort = ORT_TARGET_DATA;
13716 break;
13717 case OMP_TEAMS:
13718 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
13719 if (gimplify_omp_ctxp == NULL
13720 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
13721 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
13722 break;
13723 case OACC_HOST_DATA:
13724 ort = ORT_ACC_HOST_DATA;
13725 break;
13726 default:
13727 gcc_unreachable ();
13730 bool save_in_omp_construct = in_omp_construct;
13731 if ((ort & ORT_ACC) == 0)
13732 in_omp_construct = false;
13733 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
13734 TREE_CODE (expr));
13735 if (TREE_CODE (expr) == OMP_TARGET)
13736 optimize_target_teams (expr, pre_p);
13737 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
13738 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
13740 push_gimplify_context ();
13741 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
13742 if (gimple_code (g) == GIMPLE_BIND)
13743 pop_gimplify_context (g);
13744 else
13745 pop_gimplify_context (NULL);
13746 if ((ort & ORT_TARGET_DATA) != 0)
13748 enum built_in_function end_ix;
13749 switch (TREE_CODE (expr))
13751 case OACC_DATA:
13752 case OACC_HOST_DATA:
13753 end_ix = BUILT_IN_GOACC_DATA_END;
13754 break;
13755 case OMP_TARGET_DATA:
13756 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
13757 break;
13758 default:
13759 gcc_unreachable ();
13761 tree fn = builtin_decl_explicit (end_ix);
13762 g = gimple_build_call (fn, 0);
13763 gimple_seq cleanup = NULL;
13764 gimple_seq_add_stmt (&cleanup, g);
13765 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
13766 body = NULL;
13767 gimple_seq_add_stmt (&body, g);
13770 else
13771 gimplify_and_add (OMP_BODY (expr), &body);
13772 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
13773 TREE_CODE (expr));
13774 in_omp_construct = save_in_omp_construct;
13776 switch (TREE_CODE (expr))
13778 case OACC_DATA:
13779 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
13780 OMP_CLAUSES (expr));
13781 break;
13782 case OACC_HOST_DATA:
13783 if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
13785 for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13786 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
13787 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
13790 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
13791 OMP_CLAUSES (expr));
13792 break;
13793 case OACC_KERNELS:
13794 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
13795 OMP_CLAUSES (expr));
13796 break;
13797 case OACC_PARALLEL:
13798 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
13799 OMP_CLAUSES (expr));
13800 break;
13801 case OACC_SERIAL:
13802 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
13803 OMP_CLAUSES (expr));
13804 break;
13805 case OMP_SECTIONS:
13806 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
13807 break;
13808 case OMP_SINGLE:
13809 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
13810 break;
13811 case OMP_SCOPE:
13812 stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr));
13813 break;
13814 case OMP_TARGET:
13815 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
13816 OMP_CLAUSES (expr));
13817 break;
13818 case OMP_TARGET_DATA:
13819 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
13820 to be evaluated before the use_device_{ptr,addr} clauses if they
13821 refer to the same variables. */
13823 tree use_device_clauses;
13824 tree *pc, *uc = &use_device_clauses;
13825 for (pc = &OMP_CLAUSES (expr); *pc; )
13826 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
13827 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
13829 *uc = *pc;
13830 *pc = OMP_CLAUSE_CHAIN (*pc);
13831 uc = &OMP_CLAUSE_CHAIN (*uc);
13833 else
13834 pc = &OMP_CLAUSE_CHAIN (*pc);
13835 *uc = NULL_TREE;
13836 *pc = use_device_clauses;
13837 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
13838 OMP_CLAUSES (expr));
13840 break;
13841 case OMP_TEAMS:
13842 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
13843 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
13844 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
13845 break;
13846 default:
13847 gcc_unreachable ();
13850 gimplify_seq_add_stmt (pre_p, stmt);
13851 *expr_p = NULL_TREE;
13854 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
13855 target update constructs. */
13857 static void
13858 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
13860 tree expr = *expr_p;
13861 int kind;
13862 gomp_target *stmt;
13863 enum omp_region_type ort = ORT_WORKSHARE;
13865 switch (TREE_CODE (expr))
13867 case OACC_ENTER_DATA:
13868 kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA;
13869 ort = ORT_ACC;
13870 break;
13871 case OACC_EXIT_DATA:
13872 kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA;
13873 ort = ORT_ACC;
13874 break;
13875 case OACC_UPDATE:
13876 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
13877 ort = ORT_ACC;
13878 break;
13879 case OMP_TARGET_UPDATE:
13880 kind = GF_OMP_TARGET_KIND_UPDATE;
13881 break;
13882 case OMP_TARGET_ENTER_DATA:
13883 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
13884 break;
13885 case OMP_TARGET_EXIT_DATA:
13886 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
13887 break;
13888 default:
13889 gcc_unreachable ();
13891 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
13892 ort, TREE_CODE (expr));
13893 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
13894 TREE_CODE (expr));
13895 if (TREE_CODE (expr) == OACC_UPDATE
13896 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
13897 OMP_CLAUSE_IF_PRESENT))
13899 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
13900 clause. */
13901 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13902 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
13903 switch (OMP_CLAUSE_MAP_KIND (c))
13905 case GOMP_MAP_FORCE_TO:
13906 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
13907 break;
13908 case GOMP_MAP_FORCE_FROM:
13909 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
13910 break;
13911 default:
13912 break;
13915 else if (TREE_CODE (expr) == OACC_EXIT_DATA
13916 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
13917 OMP_CLAUSE_FINALIZE))
13919 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
13920 semantics. */
13921 bool have_clause = false;
13922 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13923 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
13924 switch (OMP_CLAUSE_MAP_KIND (c))
13926 case GOMP_MAP_FROM:
13927 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
13928 have_clause = true;
13929 break;
13930 case GOMP_MAP_RELEASE:
13931 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
13932 have_clause = true;
13933 break;
13934 case GOMP_MAP_TO_PSET:
13935 /* Fortran arrays with descriptors must map that descriptor when
13936 doing standalone "attach" operations (in OpenACC). In that
13937 case GOMP_MAP_TO_PSET appears by itself with no preceding
13938 clause (see trans-openmp.c:gfc_trans_omp_clauses). */
13939 break;
13940 case GOMP_MAP_POINTER:
13941 /* TODO PR92929: we may see these here, but they'll always follow
13942 one of the clauses above, and will be handled by libgomp as
13943 one group, so no handling required here. */
13944 gcc_assert (have_clause);
13945 break;
13946 case GOMP_MAP_DETACH:
13947 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
13948 have_clause = false;
13949 break;
13950 case GOMP_MAP_STRUCT:
13951 have_clause = false;
13952 break;
13953 default:
13954 gcc_unreachable ();
13957 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
13959 gimplify_seq_add_stmt (pre_p, stmt);
13960 *expr_p = NULL_TREE;
13963 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
13964 stabilized the lhs of the atomic operation as *ADDR. Return true if
13965 EXPR is this stabilized form. */
13967 static bool
13968 goa_lhs_expr_p (tree expr, tree addr)
13970 /* Also include casts to other type variants. The C front end is fond
13971 of adding these for e.g. volatile variables. This is like
13972 STRIP_TYPE_NOPS but includes the main variant lookup. */
13973 STRIP_USELESS_TYPE_CONVERSION (expr);
13975 if (TREE_CODE (expr) == INDIRECT_REF)
13977 expr = TREE_OPERAND (expr, 0);
13978 while (expr != addr
13979 && (CONVERT_EXPR_P (expr)
13980 || TREE_CODE (expr) == NON_LVALUE_EXPR)
13981 && TREE_CODE (expr) == TREE_CODE (addr)
13982 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
13984 expr = TREE_OPERAND (expr, 0);
13985 addr = TREE_OPERAND (addr, 0);
13987 if (expr == addr)
13988 return true;
13989 return (TREE_CODE (addr) == ADDR_EXPR
13990 && TREE_CODE (expr) == ADDR_EXPR
13991 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
13993 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
13994 return true;
13995 return false;
13998 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
13999 expression does not involve the lhs, evaluate it into a temporary.
14000 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
14001 or -1 if an error was encountered. */
14003 static int
14004 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
14005 tree lhs_var, tree &target_expr, bool rhs, int depth)
14007 tree expr = *expr_p;
14008 int saw_lhs = 0;
14010 if (goa_lhs_expr_p (expr, lhs_addr))
14012 if (pre_p)
14013 *expr_p = lhs_var;
14014 return 1;
14016 if (is_gimple_val (expr))
14017 return 0;
14019 /* Maximum depth of lhs in expression is for the
14020 __builtin_clear_padding (...), __builtin_clear_padding (...),
14021 __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs; */
14022 if (++depth > 7)
14023 goto finish;
14025 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
14027 case tcc_binary:
14028 case tcc_comparison:
14029 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
14030 lhs_var, target_expr, true, depth);
14031 /* FALLTHRU */
14032 case tcc_unary:
14033 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
14034 lhs_var, target_expr, true, depth);
14035 break;
14036 case tcc_expression:
14037 switch (TREE_CODE (expr))
14039 case TRUTH_ANDIF_EXPR:
14040 case TRUTH_ORIF_EXPR:
14041 case TRUTH_AND_EXPR:
14042 case TRUTH_OR_EXPR:
14043 case TRUTH_XOR_EXPR:
14044 case BIT_INSERT_EXPR:
14045 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14046 lhs_addr, lhs_var, target_expr, true,
14047 depth);
14048 /* FALLTHRU */
14049 case TRUTH_NOT_EXPR:
14050 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14051 lhs_addr, lhs_var, target_expr, true,
14052 depth);
14053 break;
14054 case MODIFY_EXPR:
14055 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14056 target_expr, true, depth))
14057 break;
14058 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14059 lhs_addr, lhs_var, target_expr, true,
14060 depth);
14061 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14062 lhs_addr, lhs_var, target_expr, false,
14063 depth);
14064 break;
14065 /* FALLTHRU */
14066 case ADDR_EXPR:
14067 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14068 target_expr, true, depth))
14069 break;
14070 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14071 lhs_addr, lhs_var, target_expr, false,
14072 depth);
14073 break;
14074 case COMPOUND_EXPR:
14075 /* Break out any preevaluations from cp_build_modify_expr. */
14076 for (; TREE_CODE (expr) == COMPOUND_EXPR;
14077 expr = TREE_OPERAND (expr, 1))
14079 /* Special-case __builtin_clear_padding call before
14080 __builtin_memcmp. */
14081 if (TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR)
14083 tree fndecl = get_callee_fndecl (TREE_OPERAND (expr, 0));
14084 if (fndecl
14085 && fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14086 && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
14087 && (!pre_p
14088 || goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL,
14089 lhs_addr, lhs_var,
14090 target_expr, true, depth)))
14092 if (pre_p)
14093 *expr_p = expr;
14094 saw_lhs = goa_stabilize_expr (&TREE_OPERAND (expr, 0),
14095 pre_p, lhs_addr, lhs_var,
14096 target_expr, true, depth);
14097 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1),
14098 pre_p, lhs_addr, lhs_var,
14099 target_expr, rhs, depth);
14100 return saw_lhs;
14104 if (pre_p)
14105 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
14107 if (!pre_p)
14108 return goa_stabilize_expr (&expr, pre_p, lhs_addr, lhs_var,
14109 target_expr, rhs, depth);
14110 *expr_p = expr;
14111 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var,
14112 target_expr, rhs, depth);
14113 case COND_EXPR:
14114 if (!goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, lhs_addr,
14115 lhs_var, target_expr, true, depth))
14116 break;
14117 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14118 lhs_addr, lhs_var, target_expr, true,
14119 depth);
14120 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14121 lhs_addr, lhs_var, target_expr, true,
14122 depth);
14123 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 2), pre_p,
14124 lhs_addr, lhs_var, target_expr, true,
14125 depth);
14126 break;
14127 case TARGET_EXPR:
14128 if (TARGET_EXPR_INITIAL (expr))
14130 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr,
14131 lhs_var, target_expr, true,
14132 depth))
14133 break;
14134 if (expr == target_expr)
14135 saw_lhs = 1;
14136 else
14138 saw_lhs = goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr),
14139 pre_p, lhs_addr, lhs_var,
14140 target_expr, true, depth);
14141 if (saw_lhs && target_expr == NULL_TREE && pre_p)
14142 target_expr = expr;
14145 break;
14146 default:
14147 break;
14149 break;
14150 case tcc_reference:
14151 if (TREE_CODE (expr) == BIT_FIELD_REF
14152 || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
14153 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14154 lhs_addr, lhs_var, target_expr, true,
14155 depth);
14156 break;
14157 case tcc_vl_exp:
14158 if (TREE_CODE (expr) == CALL_EXPR)
14160 if (tree fndecl = get_callee_fndecl (expr))
14161 if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14162 || fndecl_built_in_p (fndecl, BUILT_IN_MEMCMP))
14164 int nargs = call_expr_nargs (expr);
14165 for (int i = 0; i < nargs; i++)
14166 saw_lhs |= goa_stabilize_expr (&CALL_EXPR_ARG (expr, i),
14167 pre_p, lhs_addr, lhs_var,
14168 target_expr, true, depth);
14171 break;
14172 default:
14173 break;
14176 finish:
14177 if (saw_lhs == 0 && pre_p)
14179 enum gimplify_status gs;
14180 if (TREE_CODE (expr) == CALL_EXPR && VOID_TYPE_P (TREE_TYPE (expr)))
14182 gimplify_stmt (&expr, pre_p);
14183 return saw_lhs;
14185 else if (rhs)
14186 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
14187 else
14188 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_lvalue, fb_lvalue);
14189 if (gs != GS_ALL_DONE)
14190 saw_lhs = -1;
14193 return saw_lhs;
14196 /* Gimplify an OMP_ATOMIC statement. */
14198 static enum gimplify_status
14199 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
14201 tree addr = TREE_OPERAND (*expr_p, 0);
14202 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
14203 ? NULL : TREE_OPERAND (*expr_p, 1);
14204 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
14205 tree tmp_load;
14206 gomp_atomic_load *loadstmt;
14207 gomp_atomic_store *storestmt;
14208 tree target_expr = NULL_TREE;
14210 tmp_load = create_tmp_reg (type);
14211 if (rhs
14212 && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load, target_expr,
14213 true, 0) < 0)
14214 return GS_ERROR;
14216 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
14217 != GS_ALL_DONE)
14218 return GS_ERROR;
14220 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
14221 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14222 gimplify_seq_add_stmt (pre_p, loadstmt);
14223 if (rhs)
14225 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
14226 representatives. Use BIT_FIELD_REF on the lhs instead. */
14227 tree rhsarg = rhs;
14228 if (TREE_CODE (rhs) == COND_EXPR)
14229 rhsarg = TREE_OPERAND (rhs, 1);
14230 if (TREE_CODE (rhsarg) == BIT_INSERT_EXPR
14231 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
14233 tree bitpos = TREE_OPERAND (rhsarg, 2);
14234 tree op1 = TREE_OPERAND (rhsarg, 1);
14235 tree bitsize;
14236 tree tmp_store = tmp_load;
14237 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
14238 tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
14239 if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
14240 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
14241 else
14242 bitsize = TYPE_SIZE (TREE_TYPE (op1));
14243 gcc_assert (TREE_OPERAND (rhsarg, 0) == tmp_load);
14244 tree t = build2_loc (EXPR_LOCATION (rhsarg),
14245 MODIFY_EXPR, void_type_node,
14246 build3_loc (EXPR_LOCATION (rhsarg),
14247 BIT_FIELD_REF, TREE_TYPE (op1),
14248 tmp_store, bitsize, bitpos), op1);
14249 if (TREE_CODE (rhs) == COND_EXPR)
14250 t = build3_loc (EXPR_LOCATION (rhs), COND_EXPR, void_type_node,
14251 TREE_OPERAND (rhs, 0), t, void_node);
14252 gimplify_and_add (t, pre_p);
14253 rhs = tmp_store;
14255 bool save_allow_rhs_cond_expr = gimplify_ctxp->allow_rhs_cond_expr;
14256 if (TREE_CODE (rhs) == COND_EXPR)
14257 gimplify_ctxp->allow_rhs_cond_expr = true;
14258 enum gimplify_status gs = gimplify_expr (&rhs, pre_p, NULL,
14259 is_gimple_val, fb_rvalue);
14260 gimplify_ctxp->allow_rhs_cond_expr = save_allow_rhs_cond_expr;
14261 if (gs != GS_ALL_DONE)
14262 return GS_ERROR;
14265 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
14266 rhs = tmp_load;
14267 storestmt
14268 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14269 if (TREE_CODE (*expr_p) != OMP_ATOMIC_READ && OMP_ATOMIC_WEAK (*expr_p))
14271 gimple_omp_atomic_set_weak (loadstmt);
14272 gimple_omp_atomic_set_weak (storestmt);
14274 gimplify_seq_add_stmt (pre_p, storestmt);
14275 switch (TREE_CODE (*expr_p))
14277 case OMP_ATOMIC_READ:
14278 case OMP_ATOMIC_CAPTURE_OLD:
14279 *expr_p = tmp_load;
14280 gimple_omp_atomic_set_need_value (loadstmt);
14281 break;
14282 case OMP_ATOMIC_CAPTURE_NEW:
14283 *expr_p = rhs;
14284 gimple_omp_atomic_set_need_value (storestmt);
14285 break;
14286 default:
14287 *expr_p = NULL;
14288 break;
14291 return GS_ALL_DONE;
14294 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
14295 body, and adding some EH bits. */
14297 static enum gimplify_status
14298 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
14300 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
14301 gimple *body_stmt;
14302 gtransaction *trans_stmt;
14303 gimple_seq body = NULL;
14304 int subcode = 0;
14306 /* Wrap the transaction body in a BIND_EXPR so we have a context
14307 where to put decls for OMP. */
14308 if (TREE_CODE (tbody) != BIND_EXPR)
14310 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
14311 TREE_SIDE_EFFECTS (bind) = 1;
14312 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
14313 TRANSACTION_EXPR_BODY (expr) = bind;
14316 push_gimplify_context ();
14317 temp = voidify_wrapper_expr (*expr_p, NULL);
14319 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
14320 pop_gimplify_context (body_stmt);
14322 trans_stmt = gimple_build_transaction (body);
14323 if (TRANSACTION_EXPR_OUTER (expr))
14324 subcode = GTMA_IS_OUTER;
14325 else if (TRANSACTION_EXPR_RELAXED (expr))
14326 subcode = GTMA_IS_RELAXED;
14327 gimple_transaction_set_subcode (trans_stmt, subcode);
14329 gimplify_seq_add_stmt (pre_p, trans_stmt);
14331 if (temp)
14333 *expr_p = temp;
14334 return GS_OK;
14337 *expr_p = NULL_TREE;
14338 return GS_ALL_DONE;
14341 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
14342 is the OMP_BODY of the original EXPR (which has already been
14343 gimplified so it's not present in the EXPR).
14345 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
14347 static gimple *
14348 gimplify_omp_ordered (tree expr, gimple_seq body)
14350 tree c, decls;
14351 int failures = 0;
14352 unsigned int i;
14353 tree source_c = NULL_TREE;
14354 tree sink_c = NULL_TREE;
14356 if (gimplify_omp_ctxp)
14358 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14359 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14360 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
14361 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
14362 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
14364 error_at (OMP_CLAUSE_LOCATION (c),
14365 "%<ordered%> construct with %<depend%> clause must be "
14366 "closely nested inside a loop with %<ordered%> clause "
14367 "with a parameter");
14368 failures++;
14370 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14371 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
14373 bool fail = false;
14374 for (decls = OMP_CLAUSE_DECL (c), i = 0;
14375 decls && TREE_CODE (decls) == TREE_LIST;
14376 decls = TREE_CHAIN (decls), ++i)
14377 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
14378 continue;
14379 else if (TREE_VALUE (decls)
14380 != gimplify_omp_ctxp->loop_iter_var[2 * i])
14382 error_at (OMP_CLAUSE_LOCATION (c),
14383 "variable %qE is not an iteration "
14384 "of outermost loop %d, expected %qE",
14385 TREE_VALUE (decls), i + 1,
14386 gimplify_omp_ctxp->loop_iter_var[2 * i]);
14387 fail = true;
14388 failures++;
14390 else
14391 TREE_VALUE (decls)
14392 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
14393 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
14395 error_at (OMP_CLAUSE_LOCATION (c),
14396 "number of variables in %<depend%> clause with "
14397 "%<sink%> modifier does not match number of "
14398 "iteration variables");
14399 failures++;
14401 sink_c = c;
14403 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14404 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
14406 if (source_c)
14408 error_at (OMP_CLAUSE_LOCATION (c),
14409 "more than one %<depend%> clause with %<source%> "
14410 "modifier on an %<ordered%> construct");
14411 failures++;
14413 else
14414 source_c = c;
14417 if (source_c && sink_c)
14419 error_at (OMP_CLAUSE_LOCATION (source_c),
14420 "%<depend%> clause with %<source%> modifier specified "
14421 "together with %<depend%> clauses with %<sink%> modifier "
14422 "on the same construct");
14423 failures++;
14426 if (failures)
14427 return gimple_build_nop ();
14428 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
14431 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
14432 expression produces a value to be used as an operand inside a GIMPLE
14433 statement, the value will be stored back in *EXPR_P. This value will
14434 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
14435 an SSA_NAME. The corresponding sequence of GIMPLE statements is
14436 emitted in PRE_P and POST_P.
14438 Additionally, this process may overwrite parts of the input
14439 expression during gimplification. Ideally, it should be
14440 possible to do non-destructive gimplification.
14442 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
14443 the expression needs to evaluate to a value to be used as
14444 an operand in a GIMPLE statement, this value will be stored in
14445 *EXPR_P on exit. This happens when the caller specifies one
14446 of fb_lvalue or fb_rvalue fallback flags.
14448 PRE_P will contain the sequence of GIMPLE statements corresponding
14449 to the evaluation of EXPR and all the side-effects that must
14450 be executed before the main expression. On exit, the last
14451 statement of PRE_P is the core statement being gimplified. For
14452 instance, when gimplifying 'if (++a)' the last statement in
14453 PRE_P will be 'if (t.1)' where t.1 is the result of
14454 pre-incrementing 'a'.
14456 POST_P will contain the sequence of GIMPLE statements corresponding
14457 to the evaluation of all the side-effects that must be executed
14458 after the main expression. If this is NULL, the post
14459 side-effects are stored at the end of PRE_P.
14461 The reason why the output is split in two is to handle post
14462 side-effects explicitly. In some cases, an expression may have
14463 inner and outer post side-effects which need to be emitted in
14464 an order different from the one given by the recursive
14465 traversal. For instance, for the expression (*p--)++ the post
14466 side-effects of '--' must actually occur *after* the post
14467 side-effects of '++'. However, gimplification will first visit
14468 the inner expression, so if a separate POST sequence was not
14469 used, the resulting sequence would be:
14471 1 t.1 = *p
14472 2 p = p - 1
14473 3 t.2 = t.1 + 1
14474 4 *p = t.2
14476 However, the post-decrement operation in line #2 must not be
14477 evaluated until after the store to *p at line #4, so the
14478 correct sequence should be:
14480 1 t.1 = *p
14481 2 t.2 = t.1 + 1
14482 3 *p = t.2
14483 4 p = p - 1
14485 So, by specifying a separate post queue, it is possible
14486 to emit the post side-effects in the correct order.
14487 If POST_P is NULL, an internal queue will be used. Before
14488 returning to the caller, the sequence POST_P is appended to
14489 the main output sequence PRE_P.
14491 GIMPLE_TEST_F points to a function that takes a tree T and
14492 returns nonzero if T is in the GIMPLE form requested by the
14493 caller. The GIMPLE predicates are in gimple.c.
14495 FALLBACK tells the function what sort of a temporary we want if
14496 gimplification cannot produce an expression that complies with
14497 GIMPLE_TEST_F.
14499 fb_none means that no temporary should be generated
14500 fb_rvalue means that an rvalue is OK to generate
14501 fb_lvalue means that an lvalue is OK to generate
14502 fb_either means that either is OK, but an lvalue is preferable.
14503 fb_mayfail means that gimplification may fail (in which case
14504 GS_ERROR will be returned)
14506 The return value is either GS_ERROR or GS_ALL_DONE, since this
14507 function iterates until EXPR is completely gimplified or an error
14508 occurs. */
14510 enum gimplify_status
14511 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
14512 bool (*gimple_test_f) (tree), fallback_t fallback)
14514 tree tmp;
14515 gimple_seq internal_pre = NULL;
14516 gimple_seq internal_post = NULL;
14517 tree save_expr;
14518 bool is_statement;
14519 location_t saved_location;
14520 enum gimplify_status ret;
14521 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
14522 tree label;
14524 save_expr = *expr_p;
14525 if (save_expr == NULL_TREE)
14526 return GS_ALL_DONE;
14528 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
14529 is_statement = gimple_test_f == is_gimple_stmt;
14530 if (is_statement)
14531 gcc_assert (pre_p);
14533 /* Consistency checks. */
14534 if (gimple_test_f == is_gimple_reg)
14535 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
14536 else if (gimple_test_f == is_gimple_val
14537 || gimple_test_f == is_gimple_call_addr
14538 || gimple_test_f == is_gimple_condexpr
14539 || gimple_test_f == is_gimple_condexpr_for_cond
14540 || gimple_test_f == is_gimple_mem_rhs
14541 || gimple_test_f == is_gimple_mem_rhs_or_call
14542 || gimple_test_f == is_gimple_reg_rhs
14543 || gimple_test_f == is_gimple_reg_rhs_or_call
14544 || gimple_test_f == is_gimple_asm_val
14545 || gimple_test_f == is_gimple_mem_ref_addr)
14546 gcc_assert (fallback & fb_rvalue);
14547 else if (gimple_test_f == is_gimple_min_lval
14548 || gimple_test_f == is_gimple_lvalue)
14549 gcc_assert (fallback & fb_lvalue);
14550 else if (gimple_test_f == is_gimple_addressable)
14551 gcc_assert (fallback & fb_either);
14552 else if (gimple_test_f == is_gimple_stmt)
14553 gcc_assert (fallback == fb_none);
14554 else
14556 /* We should have recognized the GIMPLE_TEST_F predicate to
14557 know what kind of fallback to use in case a temporary is
14558 needed to hold the value or address of *EXPR_P. */
14559 gcc_unreachable ();
14562 /* We used to check the predicate here and return immediately if it
14563 succeeds. This is wrong; the design is for gimplification to be
14564 idempotent, and for the predicates to only test for valid forms, not
14565 whether they are fully simplified. */
14566 if (pre_p == NULL)
14567 pre_p = &internal_pre;
14569 if (post_p == NULL)
14570 post_p = &internal_post;
14572 /* Remember the last statements added to PRE_P and POST_P. Every
14573 new statement added by the gimplification helpers needs to be
14574 annotated with location information. To centralize the
14575 responsibility, we remember the last statement that had been
14576 added to both queues before gimplifying *EXPR_P. If
14577 gimplification produces new statements in PRE_P and POST_P, those
14578 statements will be annotated with the same location information
14579 as *EXPR_P. */
14580 pre_last_gsi = gsi_last (*pre_p);
14581 post_last_gsi = gsi_last (*post_p);
14583 saved_location = input_location;
14584 if (save_expr != error_mark_node
14585 && EXPR_HAS_LOCATION (*expr_p))
14586 input_location = EXPR_LOCATION (*expr_p);
14588 /* Loop over the specific gimplifiers until the toplevel node
14589 remains the same. */
14592 /* Strip away as many useless type conversions as possible
14593 at the toplevel. */
14594 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
14596 /* Remember the expr. */
14597 save_expr = *expr_p;
14599 /* Die, die, die, my darling. */
14600 if (error_operand_p (save_expr))
14602 ret = GS_ERROR;
14603 break;
14606 /* Do any language-specific gimplification. */
14607 ret = ((enum gimplify_status)
14608 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
14609 if (ret == GS_OK)
14611 if (*expr_p == NULL_TREE)
14612 break;
14613 if (*expr_p != save_expr)
14614 continue;
14616 else if (ret != GS_UNHANDLED)
14617 break;
14619 /* Make sure that all the cases set 'ret' appropriately. */
14620 ret = GS_UNHANDLED;
14621 switch (TREE_CODE (*expr_p))
14623 /* First deal with the special cases. */
14625 case POSTINCREMENT_EXPR:
14626 case POSTDECREMENT_EXPR:
14627 case PREINCREMENT_EXPR:
14628 case PREDECREMENT_EXPR:
14629 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
14630 fallback != fb_none,
14631 TREE_TYPE (*expr_p));
14632 break;
14634 case VIEW_CONVERT_EXPR:
14635 if ((fallback & fb_rvalue)
14636 && is_gimple_reg_type (TREE_TYPE (*expr_p))
14637 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
14639 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14640 post_p, is_gimple_val, fb_rvalue);
14641 recalculate_side_effects (*expr_p);
14642 break;
14644 /* Fallthru. */
14646 case ARRAY_REF:
14647 case ARRAY_RANGE_REF:
14648 case REALPART_EXPR:
14649 case IMAGPART_EXPR:
14650 case COMPONENT_REF:
14651 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
14652 fallback ? fallback : fb_rvalue);
14653 break;
14655 case COND_EXPR:
14656 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
14658 /* C99 code may assign to an array in a structure value of a
14659 conditional expression, and this has undefined behavior
14660 only on execution, so create a temporary if an lvalue is
14661 required. */
14662 if (fallback == fb_lvalue)
14664 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14665 mark_addressable (*expr_p);
14666 ret = GS_OK;
14668 break;
14670 case CALL_EXPR:
14671 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
14673 /* C99 code may assign to an array in a structure returned
14674 from a function, and this has undefined behavior only on
14675 execution, so create a temporary if an lvalue is
14676 required. */
14677 if (fallback == fb_lvalue)
14679 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14680 mark_addressable (*expr_p);
14681 ret = GS_OK;
14683 break;
14685 case TREE_LIST:
14686 gcc_unreachable ();
14688 case COMPOUND_EXPR:
14689 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
14690 break;
14692 case COMPOUND_LITERAL_EXPR:
14693 ret = gimplify_compound_literal_expr (expr_p, pre_p,
14694 gimple_test_f, fallback);
14695 break;
14697 case MODIFY_EXPR:
14698 case INIT_EXPR:
14699 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
14700 fallback != fb_none);
14701 break;
14703 case TRUTH_ANDIF_EXPR:
14704 case TRUTH_ORIF_EXPR:
14706 /* Preserve the original type of the expression and the
14707 source location of the outer expression. */
14708 tree org_type = TREE_TYPE (*expr_p);
14709 *expr_p = gimple_boolify (*expr_p);
14710 *expr_p = build3_loc (input_location, COND_EXPR,
14711 org_type, *expr_p,
14712 fold_convert_loc
14713 (input_location,
14714 org_type, boolean_true_node),
14715 fold_convert_loc
14716 (input_location,
14717 org_type, boolean_false_node));
14718 ret = GS_OK;
14719 break;
14722 case TRUTH_NOT_EXPR:
14724 tree type = TREE_TYPE (*expr_p);
14725 /* The parsers are careful to generate TRUTH_NOT_EXPR
14726 only with operands that are always zero or one.
14727 We do not fold here but handle the only interesting case
14728 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
14729 *expr_p = gimple_boolify (*expr_p);
14730 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
14731 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
14732 TREE_TYPE (*expr_p),
14733 TREE_OPERAND (*expr_p, 0));
14734 else
14735 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
14736 TREE_TYPE (*expr_p),
14737 TREE_OPERAND (*expr_p, 0),
14738 build_int_cst (TREE_TYPE (*expr_p), 1));
14739 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
14740 *expr_p = fold_convert_loc (input_location, type, *expr_p);
14741 ret = GS_OK;
14742 break;
14745 case ADDR_EXPR:
14746 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
14747 break;
14749 case ANNOTATE_EXPR:
14751 tree cond = TREE_OPERAND (*expr_p, 0);
14752 tree kind = TREE_OPERAND (*expr_p, 1);
14753 tree data = TREE_OPERAND (*expr_p, 2);
14754 tree type = TREE_TYPE (cond);
14755 if (!INTEGRAL_TYPE_P (type))
14757 *expr_p = cond;
14758 ret = GS_OK;
14759 break;
14761 tree tmp = create_tmp_var (type);
14762 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
14763 gcall *call
14764 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
14765 gimple_call_set_lhs (call, tmp);
14766 gimplify_seq_add_stmt (pre_p, call);
14767 *expr_p = tmp;
14768 ret = GS_ALL_DONE;
14769 break;
14772 case VA_ARG_EXPR:
14773 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
14774 break;
14776 CASE_CONVERT:
14777 if (IS_EMPTY_STMT (*expr_p))
14779 ret = GS_ALL_DONE;
14780 break;
14783 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
14784 || fallback == fb_none)
14786 /* Just strip a conversion to void (or in void context) and
14787 try again. */
14788 *expr_p = TREE_OPERAND (*expr_p, 0);
14789 ret = GS_OK;
14790 break;
14793 ret = gimplify_conversion (expr_p);
14794 if (ret == GS_ERROR)
14795 break;
14796 if (*expr_p != save_expr)
14797 break;
14798 /* FALLTHRU */
14800 case FIX_TRUNC_EXPR:
14801 /* unary_expr: ... | '(' cast ')' val | ... */
14802 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14803 is_gimple_val, fb_rvalue);
14804 recalculate_side_effects (*expr_p);
14805 break;
14807 case INDIRECT_REF:
14809 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
14810 bool notrap = TREE_THIS_NOTRAP (*expr_p);
14811 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
14813 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
14814 if (*expr_p != save_expr)
14816 ret = GS_OK;
14817 break;
14820 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14821 is_gimple_reg, fb_rvalue);
14822 if (ret == GS_ERROR)
14823 break;
14825 recalculate_side_effects (*expr_p);
14826 *expr_p = fold_build2_loc (input_location, MEM_REF,
14827 TREE_TYPE (*expr_p),
14828 TREE_OPERAND (*expr_p, 0),
14829 build_int_cst (saved_ptr_type, 0));
14830 TREE_THIS_VOLATILE (*expr_p) = volatilep;
14831 TREE_THIS_NOTRAP (*expr_p) = notrap;
14832 ret = GS_OK;
14833 break;
14836 /* We arrive here through the various re-gimplifcation paths. */
14837 case MEM_REF:
14838 /* First try re-folding the whole thing. */
14839 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
14840 TREE_OPERAND (*expr_p, 0),
14841 TREE_OPERAND (*expr_p, 1));
14842 if (tmp)
14844 REF_REVERSE_STORAGE_ORDER (tmp)
14845 = REF_REVERSE_STORAGE_ORDER (*expr_p);
14846 *expr_p = tmp;
14847 recalculate_side_effects (*expr_p);
14848 ret = GS_OK;
14849 break;
14851 /* Avoid re-gimplifying the address operand if it is already
14852 in suitable form. Re-gimplifying would mark the address
14853 operand addressable. Always gimplify when not in SSA form
14854 as we still may have to gimplify decls with value-exprs. */
14855 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
14856 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
14858 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14859 is_gimple_mem_ref_addr, fb_rvalue);
14860 if (ret == GS_ERROR)
14861 break;
14863 recalculate_side_effects (*expr_p);
14864 ret = GS_ALL_DONE;
14865 break;
14867 /* Constants need not be gimplified. */
14868 case INTEGER_CST:
14869 case REAL_CST:
14870 case FIXED_CST:
14871 case STRING_CST:
14872 case COMPLEX_CST:
14873 case VECTOR_CST:
14874 /* Drop the overflow flag on constants, we do not want
14875 that in the GIMPLE IL. */
14876 if (TREE_OVERFLOW_P (*expr_p))
14877 *expr_p = drop_tree_overflow (*expr_p);
14878 ret = GS_ALL_DONE;
14879 break;
14881 case CONST_DECL:
14882 /* If we require an lvalue, such as for ADDR_EXPR, retain the
14883 CONST_DECL node. Otherwise the decl is replaceable by its
14884 value. */
14885 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
14886 if (fallback & fb_lvalue)
14887 ret = GS_ALL_DONE;
14888 else
14890 *expr_p = DECL_INITIAL (*expr_p);
14891 ret = GS_OK;
14893 break;
14895 case DECL_EXPR:
14896 ret = gimplify_decl_expr (expr_p, pre_p);
14897 break;
14899 case BIND_EXPR:
14900 ret = gimplify_bind_expr (expr_p, pre_p);
14901 break;
14903 case LOOP_EXPR:
14904 ret = gimplify_loop_expr (expr_p, pre_p);
14905 break;
14907 case SWITCH_EXPR:
14908 ret = gimplify_switch_expr (expr_p, pre_p);
14909 break;
14911 case EXIT_EXPR:
14912 ret = gimplify_exit_expr (expr_p);
14913 break;
14915 case GOTO_EXPR:
14916 /* If the target is not LABEL, then it is a computed jump
14917 and the target needs to be gimplified. */
14918 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
14920 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
14921 NULL, is_gimple_val, fb_rvalue);
14922 if (ret == GS_ERROR)
14923 break;
14925 gimplify_seq_add_stmt (pre_p,
14926 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
14927 ret = GS_ALL_DONE;
14928 break;
14930 case PREDICT_EXPR:
14931 gimplify_seq_add_stmt (pre_p,
14932 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
14933 PREDICT_EXPR_OUTCOME (*expr_p)));
14934 ret = GS_ALL_DONE;
14935 break;
14937 case LABEL_EXPR:
14938 ret = gimplify_label_expr (expr_p, pre_p);
14939 label = LABEL_EXPR_LABEL (*expr_p);
14940 gcc_assert (decl_function_context (label) == current_function_decl);
14942 /* If the label is used in a goto statement, or address of the label
14943 is taken, we need to unpoison all variables that were seen so far.
14944 Doing so would prevent us from reporting a false positives. */
14945 if (asan_poisoned_variables
14946 && asan_used_labels != NULL
14947 && asan_used_labels->contains (label)
14948 && !gimplify_omp_ctxp)
14949 asan_poison_variables (asan_poisoned_variables, false, pre_p);
14950 break;
14952 case CASE_LABEL_EXPR:
14953 ret = gimplify_case_label_expr (expr_p, pre_p);
14955 if (gimplify_ctxp->live_switch_vars)
14956 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
14957 pre_p);
14958 break;
14960 case RETURN_EXPR:
14961 ret = gimplify_return_expr (*expr_p, pre_p);
14962 break;
14964 case CONSTRUCTOR:
14965 /* Don't reduce this in place; let gimplify_init_constructor work its
14966 magic. Buf if we're just elaborating this for side effects, just
14967 gimplify any element that has side-effects. */
14968 if (fallback == fb_none)
14970 unsigned HOST_WIDE_INT ix;
14971 tree val;
14972 tree temp = NULL_TREE;
14973 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
14974 if (TREE_SIDE_EFFECTS (val))
14975 append_to_statement_list (val, &temp);
14977 *expr_p = temp;
14978 ret = temp ? GS_OK : GS_ALL_DONE;
14980 /* C99 code may assign to an array in a constructed
14981 structure or union, and this has undefined behavior only
14982 on execution, so create a temporary if an lvalue is
14983 required. */
14984 else if (fallback == fb_lvalue)
14986 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14987 mark_addressable (*expr_p);
14988 ret = GS_OK;
14990 else
14991 ret = GS_ALL_DONE;
14992 break;
14994 /* The following are special cases that are not handled by the
14995 original GIMPLE grammar. */
14997 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
14998 eliminated. */
14999 case SAVE_EXPR:
15000 ret = gimplify_save_expr (expr_p, pre_p, post_p);
15001 break;
15003 case BIT_FIELD_REF:
15004 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15005 post_p, is_gimple_lvalue, fb_either);
15006 recalculate_side_effects (*expr_p);
15007 break;
15009 case TARGET_MEM_REF:
15011 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
15013 if (TMR_BASE (*expr_p))
15014 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
15015 post_p, is_gimple_mem_ref_addr, fb_either);
15016 if (TMR_INDEX (*expr_p))
15017 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
15018 post_p, is_gimple_val, fb_rvalue);
15019 if (TMR_INDEX2 (*expr_p))
15020 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
15021 post_p, is_gimple_val, fb_rvalue);
15022 /* TMR_STEP and TMR_OFFSET are always integer constants. */
15023 ret = MIN (r0, r1);
15025 break;
15027 case NON_LVALUE_EXPR:
15028 /* This should have been stripped above. */
15029 gcc_unreachable ();
15031 case ASM_EXPR:
15032 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
15033 break;
15035 case TRY_FINALLY_EXPR:
15036 case TRY_CATCH_EXPR:
15038 gimple_seq eval, cleanup;
15039 gtry *try_;
15041 /* Calls to destructors are generated automatically in FINALLY/CATCH
15042 block. They should have location as UNKNOWN_LOCATION. However,
15043 gimplify_call_expr will reset these call stmts to input_location
15044 if it finds stmt's location is unknown. To prevent resetting for
15045 destructors, we set the input_location to unknown.
15046 Note that this only affects the destructor calls in FINALLY/CATCH
15047 block, and will automatically reset to its original value by the
15048 end of gimplify_expr. */
15049 input_location = UNKNOWN_LOCATION;
15050 eval = cleanup = NULL;
15051 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
15052 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15053 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
15055 gimple_seq n = NULL, e = NULL;
15056 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15057 0), &n);
15058 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15059 1), &e);
15060 if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
15062 geh_else *stmt = gimple_build_eh_else (n, e);
15063 gimple_seq_add_stmt (&cleanup, stmt);
15066 else
15067 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
15068 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
15069 if (gimple_seq_empty_p (cleanup))
15071 gimple_seq_add_seq (pre_p, eval);
15072 ret = GS_ALL_DONE;
15073 break;
15075 try_ = gimple_build_try (eval, cleanup,
15076 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15077 ? GIMPLE_TRY_FINALLY
15078 : GIMPLE_TRY_CATCH);
15079 if (EXPR_HAS_LOCATION (save_expr))
15080 gimple_set_location (try_, EXPR_LOCATION (save_expr));
15081 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
15082 gimple_set_location (try_, saved_location);
15083 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
15084 gimple_try_set_catch_is_cleanup (try_,
15085 TRY_CATCH_IS_CLEANUP (*expr_p));
15086 gimplify_seq_add_stmt (pre_p, try_);
15087 ret = GS_ALL_DONE;
15088 break;
15091 case CLEANUP_POINT_EXPR:
15092 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
15093 break;
15095 case TARGET_EXPR:
15096 ret = gimplify_target_expr (expr_p, pre_p, post_p);
15097 break;
15099 case CATCH_EXPR:
15101 gimple *c;
15102 gimple_seq handler = NULL;
15103 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
15104 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
15105 gimplify_seq_add_stmt (pre_p, c);
15106 ret = GS_ALL_DONE;
15107 break;
15110 case EH_FILTER_EXPR:
15112 gimple *ehf;
15113 gimple_seq failure = NULL;
15115 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
15116 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
15117 copy_warning (ehf, *expr_p);
15118 gimplify_seq_add_stmt (pre_p, ehf);
15119 ret = GS_ALL_DONE;
15120 break;
15123 case OBJ_TYPE_REF:
15125 enum gimplify_status r0, r1;
15126 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
15127 post_p, is_gimple_val, fb_rvalue);
15128 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
15129 post_p, is_gimple_val, fb_rvalue);
15130 TREE_SIDE_EFFECTS (*expr_p) = 0;
15131 ret = MIN (r0, r1);
15133 break;
15135 case LABEL_DECL:
15136 /* We get here when taking the address of a label. We mark
15137 the label as "forced"; meaning it can never be removed and
15138 it is a potential target for any computed goto. */
15139 FORCED_LABEL (*expr_p) = 1;
15140 ret = GS_ALL_DONE;
15141 break;
15143 case STATEMENT_LIST:
15144 ret = gimplify_statement_list (expr_p, pre_p);
15145 break;
15147 case WITH_SIZE_EXPR:
15149 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15150 post_p == &internal_post ? NULL : post_p,
15151 gimple_test_f, fallback);
15152 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15153 is_gimple_val, fb_rvalue);
15154 ret = GS_ALL_DONE;
15156 break;
15158 case VAR_DECL:
15159 case PARM_DECL:
15160 ret = gimplify_var_or_parm_decl (expr_p);
15161 break;
15163 case RESULT_DECL:
15164 /* When within an OMP context, notice uses of variables. */
15165 if (gimplify_omp_ctxp)
15166 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
15167 ret = GS_ALL_DONE;
15168 break;
15170 case DEBUG_EXPR_DECL:
15171 gcc_unreachable ();
15173 case DEBUG_BEGIN_STMT:
15174 gimplify_seq_add_stmt (pre_p,
15175 gimple_build_debug_begin_stmt
15176 (TREE_BLOCK (*expr_p),
15177 EXPR_LOCATION (*expr_p)));
15178 ret = GS_ALL_DONE;
15179 *expr_p = NULL;
15180 break;
15182 case SSA_NAME:
15183 /* Allow callbacks into the gimplifier during optimization. */
15184 ret = GS_ALL_DONE;
15185 break;
15187 case OMP_PARALLEL:
15188 gimplify_omp_parallel (expr_p, pre_p);
15189 ret = GS_ALL_DONE;
15190 break;
15192 case OMP_TASK:
15193 gimplify_omp_task (expr_p, pre_p);
15194 ret = GS_ALL_DONE;
15195 break;
15197 case OMP_FOR:
15198 case OMP_SIMD:
15199 case OMP_DISTRIBUTE:
15200 case OMP_TASKLOOP:
15201 case OACC_LOOP:
15202 ret = gimplify_omp_for (expr_p, pre_p);
15203 break;
15205 case OMP_LOOP:
15206 ret = gimplify_omp_loop (expr_p, pre_p);
15207 break;
15209 case OACC_CACHE:
15210 gimplify_oacc_cache (expr_p, pre_p);
15211 ret = GS_ALL_DONE;
15212 break;
15214 case OACC_DECLARE:
15215 gimplify_oacc_declare (expr_p, pre_p);
15216 ret = GS_ALL_DONE;
15217 break;
15219 case OACC_HOST_DATA:
15220 case OACC_DATA:
15221 case OACC_KERNELS:
15222 case OACC_PARALLEL:
15223 case OACC_SERIAL:
15224 case OMP_SCOPE:
15225 case OMP_SECTIONS:
15226 case OMP_SINGLE:
15227 case OMP_TARGET:
15228 case OMP_TARGET_DATA:
15229 case OMP_TEAMS:
15230 gimplify_omp_workshare (expr_p, pre_p);
15231 ret = GS_ALL_DONE;
15232 break;
15234 case OACC_ENTER_DATA:
15235 case OACC_EXIT_DATA:
15236 case OACC_UPDATE:
15237 case OMP_TARGET_UPDATE:
15238 case OMP_TARGET_ENTER_DATA:
15239 case OMP_TARGET_EXIT_DATA:
15240 gimplify_omp_target_update (expr_p, pre_p);
15241 ret = GS_ALL_DONE;
15242 break;
15244 case OMP_SECTION:
15245 case OMP_MASTER:
15246 case OMP_MASKED:
15247 case OMP_ORDERED:
15248 case OMP_CRITICAL:
15249 case OMP_SCAN:
15251 gimple_seq body = NULL;
15252 gimple *g;
15253 bool saved_in_omp_construct = in_omp_construct;
15255 in_omp_construct = true;
15256 gimplify_and_add (OMP_BODY (*expr_p), &body);
15257 in_omp_construct = saved_in_omp_construct;
15258 switch (TREE_CODE (*expr_p))
15260 case OMP_SECTION:
15261 g = gimple_build_omp_section (body);
15262 break;
15263 case OMP_MASTER:
15264 g = gimple_build_omp_master (body);
15265 break;
15266 case OMP_ORDERED:
15267 g = gimplify_omp_ordered (*expr_p, body);
15268 break;
15269 case OMP_MASKED:
15270 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p),
15271 pre_p, ORT_WORKSHARE, OMP_MASKED);
15272 gimplify_adjust_omp_clauses (pre_p, body,
15273 &OMP_MASKED_CLAUSES (*expr_p),
15274 OMP_MASKED);
15275 g = gimple_build_omp_masked (body,
15276 OMP_MASKED_CLAUSES (*expr_p));
15277 break;
15278 case OMP_CRITICAL:
15279 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
15280 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
15281 gimplify_adjust_omp_clauses (pre_p, body,
15282 &OMP_CRITICAL_CLAUSES (*expr_p),
15283 OMP_CRITICAL);
15284 g = gimple_build_omp_critical (body,
15285 OMP_CRITICAL_NAME (*expr_p),
15286 OMP_CRITICAL_CLAUSES (*expr_p));
15287 break;
15288 case OMP_SCAN:
15289 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
15290 pre_p, ORT_WORKSHARE, OMP_SCAN);
15291 gimplify_adjust_omp_clauses (pre_p, body,
15292 &OMP_SCAN_CLAUSES (*expr_p),
15293 OMP_SCAN);
15294 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
15295 break;
15296 default:
15297 gcc_unreachable ();
15299 gimplify_seq_add_stmt (pre_p, g);
15300 ret = GS_ALL_DONE;
15301 break;
15304 case OMP_TASKGROUP:
15306 gimple_seq body = NULL;
15308 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
15309 bool saved_in_omp_construct = in_omp_construct;
15310 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
15311 OMP_TASKGROUP);
15312 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
15314 in_omp_construct = true;
15315 gimplify_and_add (OMP_BODY (*expr_p), &body);
15316 in_omp_construct = saved_in_omp_construct;
15317 gimple_seq cleanup = NULL;
15318 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
15319 gimple *g = gimple_build_call (fn, 0);
15320 gimple_seq_add_stmt (&cleanup, g);
15321 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
15322 body = NULL;
15323 gimple_seq_add_stmt (&body, g);
15324 g = gimple_build_omp_taskgroup (body, *pclauses);
15325 gimplify_seq_add_stmt (pre_p, g);
15326 ret = GS_ALL_DONE;
15327 break;
15330 case OMP_ATOMIC:
15331 case OMP_ATOMIC_READ:
15332 case OMP_ATOMIC_CAPTURE_OLD:
15333 case OMP_ATOMIC_CAPTURE_NEW:
15334 ret = gimplify_omp_atomic (expr_p, pre_p);
15335 break;
15337 case TRANSACTION_EXPR:
15338 ret = gimplify_transaction (expr_p, pre_p);
15339 break;
15341 case TRUTH_AND_EXPR:
15342 case TRUTH_OR_EXPR:
15343 case TRUTH_XOR_EXPR:
15345 tree orig_type = TREE_TYPE (*expr_p);
15346 tree new_type, xop0, xop1;
15347 *expr_p = gimple_boolify (*expr_p);
15348 new_type = TREE_TYPE (*expr_p);
15349 if (!useless_type_conversion_p (orig_type, new_type))
15351 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
15352 ret = GS_OK;
15353 break;
15356 /* Boolified binary truth expressions are semantically equivalent
15357 to bitwise binary expressions. Canonicalize them to the
15358 bitwise variant. */
15359 switch (TREE_CODE (*expr_p))
15361 case TRUTH_AND_EXPR:
15362 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
15363 break;
15364 case TRUTH_OR_EXPR:
15365 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
15366 break;
15367 case TRUTH_XOR_EXPR:
15368 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
15369 break;
15370 default:
15371 break;
15373 /* Now make sure that operands have compatible type to
15374 expression's new_type. */
15375 xop0 = TREE_OPERAND (*expr_p, 0);
15376 xop1 = TREE_OPERAND (*expr_p, 1);
15377 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
15378 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
15379 new_type,
15380 xop0);
15381 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
15382 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
15383 new_type,
15384 xop1);
15385 /* Continue classified as tcc_binary. */
15386 goto expr_2;
15389 case VEC_COND_EXPR:
15390 goto expr_3;
15392 case VEC_PERM_EXPR:
15393 /* Classified as tcc_expression. */
15394 goto expr_3;
15396 case BIT_INSERT_EXPR:
15397 /* Argument 3 is a constant. */
15398 goto expr_2;
15400 case POINTER_PLUS_EXPR:
15402 enum gimplify_status r0, r1;
15403 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15404 post_p, is_gimple_val, fb_rvalue);
15405 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15406 post_p, is_gimple_val, fb_rvalue);
15407 recalculate_side_effects (*expr_p);
15408 ret = MIN (r0, r1);
15409 break;
15412 default:
15413 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
15415 case tcc_comparison:
15416 /* Handle comparison of objects of non scalar mode aggregates
15417 with a call to memcmp. It would be nice to only have to do
15418 this for variable-sized objects, but then we'd have to allow
15419 the same nest of reference nodes we allow for MODIFY_EXPR and
15420 that's too complex.
15422 Compare scalar mode aggregates as scalar mode values. Using
15423 memcmp for them would be very inefficient at best, and is
15424 plain wrong if bitfields are involved. */
15426 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
15428 /* Vector comparisons need no boolification. */
15429 if (TREE_CODE (type) == VECTOR_TYPE)
15430 goto expr_2;
15431 else if (!AGGREGATE_TYPE_P (type))
15433 tree org_type = TREE_TYPE (*expr_p);
15434 *expr_p = gimple_boolify (*expr_p);
15435 if (!useless_type_conversion_p (org_type,
15436 TREE_TYPE (*expr_p)))
15438 *expr_p = fold_convert_loc (input_location,
15439 org_type, *expr_p);
15440 ret = GS_OK;
15442 else
15443 goto expr_2;
15445 else if (TYPE_MODE (type) != BLKmode)
15446 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
15447 else
15448 ret = gimplify_variable_sized_compare (expr_p);
15450 break;
15453 /* If *EXPR_P does not need to be special-cased, handle it
15454 according to its class. */
15455 case tcc_unary:
15456 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15457 post_p, is_gimple_val, fb_rvalue);
15458 break;
15460 case tcc_binary:
15461 expr_2:
15463 enum gimplify_status r0, r1;
15465 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15466 post_p, is_gimple_val, fb_rvalue);
15467 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15468 post_p, is_gimple_val, fb_rvalue);
15470 ret = MIN (r0, r1);
15471 break;
15474 expr_3:
15476 enum gimplify_status r0, r1, r2;
15478 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15479 post_p, is_gimple_val, fb_rvalue);
15480 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15481 post_p, is_gimple_val, fb_rvalue);
15482 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
15483 post_p, is_gimple_val, fb_rvalue);
15485 ret = MIN (MIN (r0, r1), r2);
15486 break;
15489 case tcc_declaration:
15490 case tcc_constant:
15491 ret = GS_ALL_DONE;
15492 goto dont_recalculate;
15494 default:
15495 gcc_unreachable ();
15498 recalculate_side_effects (*expr_p);
15500 dont_recalculate:
15501 break;
15504 gcc_assert (*expr_p || ret != GS_OK);
15506 while (ret == GS_OK);
15508 /* If we encountered an error_mark somewhere nested inside, either
15509 stub out the statement or propagate the error back out. */
15510 if (ret == GS_ERROR)
15512 if (is_statement)
15513 *expr_p = NULL;
15514 goto out;
15517 /* This was only valid as a return value from the langhook, which
15518 we handled. Make sure it doesn't escape from any other context. */
15519 gcc_assert (ret != GS_UNHANDLED);
15521 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
15523 /* We aren't looking for a value, and we don't have a valid
15524 statement. If it doesn't have side-effects, throw it away.
15525 We can also get here with code such as "*&&L;", where L is
15526 a LABEL_DECL that is marked as FORCED_LABEL. */
15527 if (TREE_CODE (*expr_p) == LABEL_DECL
15528 || !TREE_SIDE_EFFECTS (*expr_p))
15529 *expr_p = NULL;
15530 else if (!TREE_THIS_VOLATILE (*expr_p))
15532 /* This is probably a _REF that contains something nested that
15533 has side effects. Recurse through the operands to find it. */
15534 enum tree_code code = TREE_CODE (*expr_p);
15536 switch (code)
15538 case COMPONENT_REF:
15539 case REALPART_EXPR:
15540 case IMAGPART_EXPR:
15541 case VIEW_CONVERT_EXPR:
15542 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15543 gimple_test_f, fallback);
15544 break;
15546 case ARRAY_REF:
15547 case ARRAY_RANGE_REF:
15548 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15549 gimple_test_f, fallback);
15550 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15551 gimple_test_f, fallback);
15552 break;
15554 default:
15555 /* Anything else with side-effects must be converted to
15556 a valid statement before we get here. */
15557 gcc_unreachable ();
15560 *expr_p = NULL;
15562 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
15563 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode
15564 && !is_empty_type (TREE_TYPE (*expr_p)))
15566 /* Historically, the compiler has treated a bare reference
15567 to a non-BLKmode volatile lvalue as forcing a load. */
15568 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
15570 /* Normally, we do not want to create a temporary for a
15571 TREE_ADDRESSABLE type because such a type should not be
15572 copied by bitwise-assignment. However, we make an
15573 exception here, as all we are doing here is ensuring that
15574 we read the bytes that make up the type. We use
15575 create_tmp_var_raw because create_tmp_var will abort when
15576 given a TREE_ADDRESSABLE type. */
15577 tree tmp = create_tmp_var_raw (type, "vol");
15578 gimple_add_tmp_var (tmp);
15579 gimplify_assign (tmp, *expr_p, pre_p);
15580 *expr_p = NULL;
15582 else
15583 /* We can't do anything useful with a volatile reference to
15584 an incomplete type, so just throw it away. Likewise for
15585 a BLKmode type, since any implicit inner load should
15586 already have been turned into an explicit one by the
15587 gimplification process. */
15588 *expr_p = NULL;
15591 /* If we are gimplifying at the statement level, we're done. Tack
15592 everything together and return. */
15593 if (fallback == fb_none || is_statement)
15595 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
15596 it out for GC to reclaim it. */
15597 *expr_p = NULL_TREE;
15599 if (!gimple_seq_empty_p (internal_pre)
15600 || !gimple_seq_empty_p (internal_post))
15602 gimplify_seq_add_seq (&internal_pre, internal_post);
15603 gimplify_seq_add_seq (pre_p, internal_pre);
15606 /* The result of gimplifying *EXPR_P is going to be the last few
15607 statements in *PRE_P and *POST_P. Add location information
15608 to all the statements that were added by the gimplification
15609 helpers. */
15610 if (!gimple_seq_empty_p (*pre_p))
15611 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
15613 if (!gimple_seq_empty_p (*post_p))
15614 annotate_all_with_location_after (*post_p, post_last_gsi,
15615 input_location);
15617 goto out;
15620 #ifdef ENABLE_GIMPLE_CHECKING
15621 if (*expr_p)
15623 enum tree_code code = TREE_CODE (*expr_p);
15624 /* These expressions should already be in gimple IR form. */
15625 gcc_assert (code != MODIFY_EXPR
15626 && code != ASM_EXPR
15627 && code != BIND_EXPR
15628 && code != CATCH_EXPR
15629 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
15630 && code != EH_FILTER_EXPR
15631 && code != GOTO_EXPR
15632 && code != LABEL_EXPR
15633 && code != LOOP_EXPR
15634 && code != SWITCH_EXPR
15635 && code != TRY_FINALLY_EXPR
15636 && code != EH_ELSE_EXPR
15637 && code != OACC_PARALLEL
15638 && code != OACC_KERNELS
15639 && code != OACC_SERIAL
15640 && code != OACC_DATA
15641 && code != OACC_HOST_DATA
15642 && code != OACC_DECLARE
15643 && code != OACC_UPDATE
15644 && code != OACC_ENTER_DATA
15645 && code != OACC_EXIT_DATA
15646 && code != OACC_CACHE
15647 && code != OMP_CRITICAL
15648 && code != OMP_FOR
15649 && code != OACC_LOOP
15650 && code != OMP_MASTER
15651 && code != OMP_MASKED
15652 && code != OMP_TASKGROUP
15653 && code != OMP_ORDERED
15654 && code != OMP_PARALLEL
15655 && code != OMP_SCAN
15656 && code != OMP_SECTIONS
15657 && code != OMP_SECTION
15658 && code != OMP_SINGLE
15659 && code != OMP_SCOPE);
15661 #endif
15663 /* Otherwise we're gimplifying a subexpression, so the resulting
15664 value is interesting. If it's a valid operand that matches
15665 GIMPLE_TEST_F, we're done. Unless we are handling some
15666 post-effects internally; if that's the case, we need to copy into
15667 a temporary before adding the post-effects to POST_P. */
15668 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
15669 goto out;
15671 /* Otherwise, we need to create a new temporary for the gimplified
15672 expression. */
15674 /* We can't return an lvalue if we have an internal postqueue. The
15675 object the lvalue refers to would (probably) be modified by the
15676 postqueue; we need to copy the value out first, which means an
15677 rvalue. */
15678 if ((fallback & fb_lvalue)
15679 && gimple_seq_empty_p (internal_post)
15680 && is_gimple_addressable (*expr_p))
15682 /* An lvalue will do. Take the address of the expression, store it
15683 in a temporary, and replace the expression with an INDIRECT_REF of
15684 that temporary. */
15685 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
15686 unsigned int ref_align = get_object_alignment (*expr_p);
15687 tree ref_type = TREE_TYPE (*expr_p);
15688 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
15689 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
15690 if (TYPE_ALIGN (ref_type) != ref_align)
15691 ref_type = build_aligned_type (ref_type, ref_align);
15692 *expr_p = build2 (MEM_REF, ref_type,
15693 tmp, build_zero_cst (ref_alias_type));
15695 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
15697 /* An rvalue will do. Assign the gimplified expression into a
15698 new temporary TMP and replace the original expression with
15699 TMP. First, make sure that the expression has a type so that
15700 it can be assigned into a temporary. */
15701 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
15702 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
15704 else
15706 #ifdef ENABLE_GIMPLE_CHECKING
15707 if (!(fallback & fb_mayfail))
15709 fprintf (stderr, "gimplification failed:\n");
15710 print_generic_expr (stderr, *expr_p);
15711 debug_tree (*expr_p);
15712 internal_error ("gimplification failed");
15714 #endif
15715 gcc_assert (fallback & fb_mayfail);
15717 /* If this is an asm statement, and the user asked for the
15718 impossible, don't die. Fail and let gimplify_asm_expr
15719 issue an error. */
15720 ret = GS_ERROR;
15721 goto out;
15724 /* Make sure the temporary matches our predicate. */
15725 gcc_assert ((*gimple_test_f) (*expr_p));
15727 if (!gimple_seq_empty_p (internal_post))
15729 annotate_all_with_location (internal_post, input_location);
15730 gimplify_seq_add_seq (pre_p, internal_post);
15733 out:
15734 input_location = saved_location;
15735 return ret;
15738 /* Like gimplify_expr but make sure the gimplified result is not itself
15739 a SSA name (but a decl if it were). Temporaries required by
15740 evaluating *EXPR_P may be still SSA names. */
15742 static enum gimplify_status
15743 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
15744 bool (*gimple_test_f) (tree), fallback_t fallback,
15745 bool allow_ssa)
15747 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
15748 gimple_test_f, fallback);
15749 if (! allow_ssa
15750 && TREE_CODE (*expr_p) == SSA_NAME)
15751 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
15752 return ret;
15755 /* Look through TYPE for variable-sized objects and gimplify each such
15756 size that we find. Add to LIST_P any statements generated. */
15758 void
15759 gimplify_type_sizes (tree type, gimple_seq *list_p)
15761 if (type == NULL || type == error_mark_node)
15762 return;
15764 const bool ignored_p
15765 = TYPE_NAME (type)
15766 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
15767 && DECL_IGNORED_P (TYPE_NAME (type));
15768 tree t;
15770 /* We first do the main variant, then copy into any other variants. */
15771 type = TYPE_MAIN_VARIANT (type);
15773 /* Avoid infinite recursion. */
15774 if (TYPE_SIZES_GIMPLIFIED (type))
15775 return;
15777 TYPE_SIZES_GIMPLIFIED (type) = 1;
15779 switch (TREE_CODE (type))
15781 case INTEGER_TYPE:
15782 case ENUMERAL_TYPE:
15783 case BOOLEAN_TYPE:
15784 case REAL_TYPE:
15785 case FIXED_POINT_TYPE:
15786 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
15787 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
15789 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
15791 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
15792 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
15794 break;
15796 case ARRAY_TYPE:
15797 /* These types may not have declarations, so handle them here. */
15798 gimplify_type_sizes (TREE_TYPE (type), list_p);
15799 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
15800 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
15801 with assigned stack slots, for -O1+ -g they should be tracked
15802 by VTA. */
15803 if (!ignored_p
15804 && TYPE_DOMAIN (type)
15805 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
15807 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
15808 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
15809 DECL_IGNORED_P (t) = 0;
15810 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
15811 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
15812 DECL_IGNORED_P (t) = 0;
15814 break;
15816 case RECORD_TYPE:
15817 case UNION_TYPE:
15818 case QUAL_UNION_TYPE:
15819 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
15820 if (TREE_CODE (field) == FIELD_DECL)
15822 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
15823 /* Likewise, ensure variable offsets aren't removed. */
15824 if (!ignored_p
15825 && (t = DECL_FIELD_OFFSET (field))
15826 && VAR_P (t)
15827 && DECL_ARTIFICIAL (t))
15828 DECL_IGNORED_P (t) = 0;
15829 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
15830 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
15831 gimplify_type_sizes (TREE_TYPE (field), list_p);
15833 break;
15835 case POINTER_TYPE:
15836 case REFERENCE_TYPE:
15837 /* We used to recurse on the pointed-to type here, which turned out to
15838 be incorrect because its definition might refer to variables not
15839 yet initialized at this point if a forward declaration is involved.
15841 It was actually useful for anonymous pointed-to types to ensure
15842 that the sizes evaluation dominates every possible later use of the
15843 values. Restricting to such types here would be safe since there
15844 is no possible forward declaration around, but would introduce an
15845 undesirable middle-end semantic to anonymity. We then defer to
15846 front-ends the responsibility of ensuring that the sizes are
15847 evaluated both early and late enough, e.g. by attaching artificial
15848 type declarations to the tree. */
15849 break;
15851 default:
15852 break;
15855 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
15856 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
15858 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
15860 TYPE_SIZE (t) = TYPE_SIZE (type);
15861 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
15862 TYPE_SIZES_GIMPLIFIED (t) = 1;
15866 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
15867 a size or position, has had all of its SAVE_EXPRs evaluated.
15868 We add any required statements to *STMT_P. */
15870 void
15871 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
15873 tree expr = *expr_p;
15875 /* We don't do anything if the value isn't there, is constant, or contains
15876 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
15877 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
15878 will want to replace it with a new variable, but that will cause problems
15879 if this type is from outside the function. It's OK to have that here. */
15880 if (expr == NULL_TREE
15881 || is_gimple_constant (expr)
15882 || TREE_CODE (expr) == VAR_DECL
15883 || CONTAINS_PLACEHOLDER_P (expr))
15884 return;
15886 *expr_p = unshare_expr (expr);
15888 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
15889 if the def vanishes. */
15890 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
15892 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
15893 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
15894 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
15895 if (is_gimple_constant (*expr_p))
15896 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
15899 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
15900 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
15901 is true, also gimplify the parameters. */
15903 gbind *
15904 gimplify_body (tree fndecl, bool do_parms)
15906 location_t saved_location = input_location;
15907 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
15908 gimple *outer_stmt;
15909 gbind *outer_bind;
15911 timevar_push (TV_TREE_GIMPLIFY);
15913 init_tree_ssa (cfun);
15915 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
15916 gimplification. */
15917 default_rtl_profile ();
15919 gcc_assert (gimplify_ctxp == NULL);
15920 push_gimplify_context (true);
15922 if (flag_openacc || flag_openmp)
15924 gcc_assert (gimplify_omp_ctxp == NULL);
15925 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
15926 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
15929 /* Unshare most shared trees in the body and in that of any nested functions.
15930 It would seem we don't have to do this for nested functions because
15931 they are supposed to be output and then the outer function gimplified
15932 first, but the g++ front end doesn't always do it that way. */
15933 unshare_body (fndecl);
15934 unvisit_body (fndecl);
15936 /* Make sure input_location isn't set to something weird. */
15937 input_location = DECL_SOURCE_LOCATION (fndecl);
15939 /* Resolve callee-copies. This has to be done before processing
15940 the body so that DECL_VALUE_EXPR gets processed correctly. */
15941 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
15943 /* Gimplify the function's body. */
15944 seq = NULL;
15945 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
15946 outer_stmt = gimple_seq_first_nondebug_stmt (seq);
15947 if (!outer_stmt)
15949 outer_stmt = gimple_build_nop ();
15950 gimplify_seq_add_stmt (&seq, outer_stmt);
15953 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
15954 not the case, wrap everything in a GIMPLE_BIND to make it so. */
15955 if (gimple_code (outer_stmt) == GIMPLE_BIND
15956 && (gimple_seq_first_nondebug_stmt (seq)
15957 == gimple_seq_last_nondebug_stmt (seq)))
15959 outer_bind = as_a <gbind *> (outer_stmt);
15960 if (gimple_seq_first_stmt (seq) != outer_stmt
15961 || gimple_seq_last_stmt (seq) != outer_stmt)
15963 /* If there are debug stmts before or after outer_stmt, move them
15964 inside of outer_bind body. */
15965 gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
15966 gimple_seq second_seq = NULL;
15967 if (gimple_seq_first_stmt (seq) != outer_stmt
15968 && gimple_seq_last_stmt (seq) != outer_stmt)
15970 second_seq = gsi_split_seq_after (gsi);
15971 gsi_remove (&gsi, false);
15973 else if (gimple_seq_first_stmt (seq) != outer_stmt)
15974 gsi_remove (&gsi, false);
15975 else
15977 gsi_remove (&gsi, false);
15978 second_seq = seq;
15979 seq = NULL;
15981 gimple_seq_add_seq_without_update (&seq,
15982 gimple_bind_body (outer_bind));
15983 gimple_seq_add_seq_without_update (&seq, second_seq);
15984 gimple_bind_set_body (outer_bind, seq);
15987 else
15988 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
15990 DECL_SAVED_TREE (fndecl) = NULL_TREE;
15992 /* If we had callee-copies statements, insert them at the beginning
15993 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
15994 if (!gimple_seq_empty_p (parm_stmts))
15996 tree parm;
15998 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
15999 if (parm_cleanup)
16001 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
16002 GIMPLE_TRY_FINALLY);
16003 parm_stmts = NULL;
16004 gimple_seq_add_stmt (&parm_stmts, g);
16006 gimple_bind_set_body (outer_bind, parm_stmts);
16008 for (parm = DECL_ARGUMENTS (current_function_decl);
16009 parm; parm = DECL_CHAIN (parm))
16010 if (DECL_HAS_VALUE_EXPR_P (parm))
16012 DECL_HAS_VALUE_EXPR_P (parm) = 0;
16013 DECL_IGNORED_P (parm) = 0;
16017 if ((flag_openacc || flag_openmp || flag_openmp_simd)
16018 && gimplify_omp_ctxp)
16020 delete_omp_context (gimplify_omp_ctxp);
16021 gimplify_omp_ctxp = NULL;
16024 pop_gimplify_context (outer_bind);
16025 gcc_assert (gimplify_ctxp == NULL);
16027 if (flag_checking && !seen_error ())
16028 verify_gimple_in_seq (gimple_bind_body (outer_bind));
16030 timevar_pop (TV_TREE_GIMPLIFY);
16031 input_location = saved_location;
16033 return outer_bind;
16036 typedef char *char_p; /* For DEF_VEC_P. */
16038 /* Return whether we should exclude FNDECL from instrumentation. */
16040 static bool
16041 flag_instrument_functions_exclude_p (tree fndecl)
16043 vec<char_p> *v;
16045 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
16046 if (v && v->length () > 0)
16048 const char *name;
16049 int i;
16050 char *s;
16052 name = lang_hooks.decl_printable_name (fndecl, 1);
16053 FOR_EACH_VEC_ELT (*v, i, s)
16054 if (strstr (name, s) != NULL)
16055 return true;
16058 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
16059 if (v && v->length () > 0)
16061 const char *name;
16062 int i;
16063 char *s;
16065 name = DECL_SOURCE_FILE (fndecl);
16066 FOR_EACH_VEC_ELT (*v, i, s)
16067 if (strstr (name, s) != NULL)
16068 return true;
16071 return false;
16074 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
16075 node for the function we want to gimplify.
16077 Return the sequence of GIMPLE statements corresponding to the body
16078 of FNDECL. */
16080 void
16081 gimplify_function_tree (tree fndecl)
16083 gimple_seq seq;
16084 gbind *bind;
16086 gcc_assert (!gimple_body (fndecl));
16088 if (DECL_STRUCT_FUNCTION (fndecl))
16089 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
16090 else
16091 push_struct_function (fndecl);
16093 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
16094 if necessary. */
16095 cfun->curr_properties |= PROP_gimple_lva;
16097 if (asan_sanitize_use_after_scope ())
16098 asan_poisoned_variables = new hash_set<tree> ();
16099 bind = gimplify_body (fndecl, true);
16100 if (asan_poisoned_variables)
16102 delete asan_poisoned_variables;
16103 asan_poisoned_variables = NULL;
16106 /* The tree body of the function is no longer needed, replace it
16107 with the new GIMPLE body. */
16108 seq = NULL;
16109 gimple_seq_add_stmt (&seq, bind);
16110 gimple_set_body (fndecl, seq);
16112 /* If we're instrumenting function entry/exit, then prepend the call to
16113 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
16114 catch the exit hook. */
16115 /* ??? Add some way to ignore exceptions for this TFE. */
16116 if (flag_instrument_function_entry_exit
16117 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
16118 /* Do not instrument extern inline functions. */
16119 && !(DECL_DECLARED_INLINE_P (fndecl)
16120 && DECL_EXTERNAL (fndecl)
16121 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
16122 && !flag_instrument_functions_exclude_p (fndecl))
16124 tree x;
16125 gbind *new_bind;
16126 gimple *tf;
16127 gimple_seq cleanup = NULL, body = NULL;
16128 tree tmp_var, this_fn_addr;
16129 gcall *call;
16131 /* The instrumentation hooks aren't going to call the instrumented
16132 function and the address they receive is expected to be matchable
16133 against symbol addresses. Make sure we don't create a trampoline,
16134 in case the current function is nested. */
16135 this_fn_addr = build_fold_addr_expr (current_function_decl);
16136 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
16138 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
16139 call = gimple_build_call (x, 1, integer_zero_node);
16140 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
16141 gimple_call_set_lhs (call, tmp_var);
16142 gimplify_seq_add_stmt (&cleanup, call);
16143 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
16144 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
16145 gimplify_seq_add_stmt (&cleanup, call);
16146 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
16148 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
16149 call = gimple_build_call (x, 1, integer_zero_node);
16150 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
16151 gimple_call_set_lhs (call, tmp_var);
16152 gimplify_seq_add_stmt (&body, call);
16153 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
16154 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
16155 gimplify_seq_add_stmt (&body, call);
16156 gimplify_seq_add_stmt (&body, tf);
16157 new_bind = gimple_build_bind (NULL, body, NULL);
16159 /* Replace the current function body with the body
16160 wrapped in the try/finally TF. */
16161 seq = NULL;
16162 gimple_seq_add_stmt (&seq, new_bind);
16163 gimple_set_body (fndecl, seq);
16164 bind = new_bind;
16167 if (sanitize_flags_p (SANITIZE_THREAD)
16168 && param_tsan_instrument_func_entry_exit)
16170 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
16171 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
16172 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
16173 /* Replace the current function body with the body
16174 wrapped in the try/finally TF. */
16175 seq = NULL;
16176 gimple_seq_add_stmt (&seq, new_bind);
16177 gimple_set_body (fndecl, seq);
16180 DECL_SAVED_TREE (fndecl) = NULL_TREE;
16181 cfun->curr_properties |= PROP_gimple_any;
16183 pop_cfun ();
16185 dump_function (TDI_gimple, fndecl);
16188 /* Return a dummy expression of type TYPE in order to keep going after an
16189 error. */
16191 static tree
16192 dummy_object (tree type)
16194 tree t = build_int_cst (build_pointer_type (type), 0);
16195 return build2 (MEM_REF, type, t, t);
16198 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
16199 builtin function, but a very special sort of operator. */
16201 enum gimplify_status
16202 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
16203 gimple_seq *post_p ATTRIBUTE_UNUSED)
16205 tree promoted_type, have_va_type;
16206 tree valist = TREE_OPERAND (*expr_p, 0);
16207 tree type = TREE_TYPE (*expr_p);
16208 tree t, tag, aptag;
16209 location_t loc = EXPR_LOCATION (*expr_p);
16211 /* Verify that valist is of the proper type. */
16212 have_va_type = TREE_TYPE (valist);
16213 if (have_va_type == error_mark_node)
16214 return GS_ERROR;
16215 have_va_type = targetm.canonical_va_list_type (have_va_type);
16216 if (have_va_type == NULL_TREE
16217 && POINTER_TYPE_P (TREE_TYPE (valist)))
16218 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
16219 have_va_type
16220 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
16221 gcc_assert (have_va_type != NULL_TREE);
16223 /* Generate a diagnostic for requesting data of a type that cannot
16224 be passed through `...' due to type promotion at the call site. */
16225 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
16226 != type)
16228 static bool gave_help;
16229 bool warned;
16230 /* Use the expansion point to handle cases such as passing bool (defined
16231 in a system header) through `...'. */
16232 location_t xloc
16233 = expansion_point_location_if_in_system_header (loc);
16235 /* Unfortunately, this is merely undefined, rather than a constraint
16236 violation, so we cannot make this an error. If this call is never
16237 executed, the program is still strictly conforming. */
16238 auto_diagnostic_group d;
16239 warned = warning_at (xloc, 0,
16240 "%qT is promoted to %qT when passed through %<...%>",
16241 type, promoted_type);
16242 if (!gave_help && warned)
16244 gave_help = true;
16245 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
16246 promoted_type, type);
16249 /* We can, however, treat "undefined" any way we please.
16250 Call abort to encourage the user to fix the program. */
16251 if (warned)
16252 inform (xloc, "if this code is reached, the program will abort");
16253 /* Before the abort, allow the evaluation of the va_list
16254 expression to exit or longjmp. */
16255 gimplify_and_add (valist, pre_p);
16256 t = build_call_expr_loc (loc,
16257 builtin_decl_implicit (BUILT_IN_TRAP), 0);
16258 gimplify_and_add (t, pre_p);
16260 /* This is dead code, but go ahead and finish so that the
16261 mode of the result comes out right. */
16262 *expr_p = dummy_object (type);
16263 return GS_ALL_DONE;
16266 tag = build_int_cst (build_pointer_type (type), 0);
16267 aptag = build_int_cst (TREE_TYPE (valist), 0);
16269 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
16270 valist, tag, aptag);
16272 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
16273 needs to be expanded. */
16274 cfun->curr_properties &= ~PROP_gimple_lva;
16276 return GS_OK;
16279 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
16281 DST/SRC are the destination and source respectively. You can pass
16282 ungimplified trees in DST or SRC, in which case they will be
16283 converted to a gimple operand if necessary.
16285 This function returns the newly created GIMPLE_ASSIGN tuple. */
16287 gimple *
16288 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
16290 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
16291 gimplify_and_add (t, seq_p);
16292 ggc_free (t);
16293 return gimple_seq_last_stmt (*seq_p);
16296 inline hashval_t
16297 gimplify_hasher::hash (const elt_t *p)
16299 tree t = p->val;
16300 return iterative_hash_expr (t, 0);
16303 inline bool
16304 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
16306 tree t1 = p1->val;
16307 tree t2 = p2->val;
16308 enum tree_code code = TREE_CODE (t1);
16310 if (TREE_CODE (t2) != code
16311 || TREE_TYPE (t1) != TREE_TYPE (t2))
16312 return false;
16314 if (!operand_equal_p (t1, t2, 0))
16315 return false;
16317 /* Only allow them to compare equal if they also hash equal; otherwise
16318 results are nondeterminate, and we fail bootstrap comparison. */
16319 gcc_checking_assert (hash (p1) == hash (p2));
16321 return true;