Daily bump.
[official-gcc.git] / gcc / gimplify.c
blob8624f8221fd3b75be097800e33e9433e4a34e186
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. */
11505 struct gimplify_adjust_omp_clauses_data data;
11506 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
11508 /* OpenMP. Implicit clauses are added at the start of the clause list,
11509 but after any non-map clauses. */
11510 tree *implicit_add_list_p = orig_list_p;
11511 while (*implicit_add_list_p
11512 && OMP_CLAUSE_CODE (*implicit_add_list_p) != OMP_CLAUSE_MAP)
11513 implicit_add_list_p = &OMP_CLAUSE_CHAIN (*implicit_add_list_p);
11514 data.list_p = implicit_add_list_p;
11516 else
11517 /* OpenACC. */
11518 data.list_p = list_p;
11519 data.pre_p = pre_p;
11520 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
11522 if (has_inscan_reductions)
11523 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
11524 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11525 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
11527 error_at (OMP_CLAUSE_LOCATION (c),
11528 "%<inscan%> %<reduction%> clause used together with "
11529 "%<linear%> clause for a variable other than loop "
11530 "iterator");
11531 break;
11534 gimplify_omp_ctxp = ctx->outer_context;
11535 delete_omp_context (ctx);
11538 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
11539 -1 if unknown yet (simd is involved, won't be known until vectorization)
11540 and 1 if they do. If SCORES is non-NULL, it should point to an array
11541 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
11542 of the CONSTRUCTS (position -1 if it will never match) followed by
11543 number of constructs in the OpenMP context construct trait. If the
11544 score depends on whether it will be in a declare simd clone or not,
11545 the function returns 2 and there will be two sets of the scores, the first
11546 one for the case that it is not in a declare simd clone, the other
11547 that it is in a declare simd clone. */
11550 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
11551 int *scores)
11553 int matched = 0, cnt = 0;
11554 bool simd_seen = false;
11555 bool target_seen = false;
11556 int declare_simd_cnt = -1;
11557 auto_vec<enum tree_code, 16> codes;
11558 for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
11560 if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
11561 || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
11562 == ORT_TARGET && ctx->code == OMP_TARGET)
11563 || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
11564 || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
11565 || (ctx->region_type == ORT_SIMD
11566 && ctx->code == OMP_SIMD
11567 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
11569 ++cnt;
11570 if (scores)
11571 codes.safe_push (ctx->code);
11572 else if (matched < nconstructs && ctx->code == constructs[matched])
11574 if (ctx->code == OMP_SIMD)
11576 if (matched)
11577 return 0;
11578 simd_seen = true;
11580 ++matched;
11582 if (ctx->code == OMP_TARGET)
11584 if (scores == NULL)
11585 return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
11586 target_seen = true;
11587 break;
11590 else if (ctx->region_type == ORT_WORKSHARE
11591 && ctx->code == OMP_LOOP
11592 && ctx->outer_context
11593 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
11594 && ctx->outer_context->outer_context
11595 && ctx->outer_context->outer_context->code == OMP_LOOP
11596 && ctx->outer_context->outer_context->distribute)
11597 ctx = ctx->outer_context->outer_context;
11598 ctx = ctx->outer_context;
11600 if (!target_seen
11601 && lookup_attribute ("omp declare simd",
11602 DECL_ATTRIBUTES (current_function_decl)))
11604 /* Declare simd is a maybe case, it is supposed to be added only to the
11605 omp-simd-clone.c added clones and not to the base function. */
11606 declare_simd_cnt = cnt++;
11607 if (scores)
11608 codes.safe_push (OMP_SIMD);
11609 else if (cnt == 0
11610 && constructs[0] == OMP_SIMD)
11612 gcc_assert (matched == 0);
11613 simd_seen = true;
11614 if (++matched == nconstructs)
11615 return -1;
11618 if (tree attr = lookup_attribute ("omp declare variant variant",
11619 DECL_ATTRIBUTES (current_function_decl)))
11621 enum tree_code variant_constructs[5];
11622 int variant_nconstructs = 0;
11623 if (!target_seen)
11624 variant_nconstructs
11625 = omp_constructor_traits_to_codes (TREE_VALUE (attr),
11626 variant_constructs);
11627 for (int i = 0; i < variant_nconstructs; i++)
11629 ++cnt;
11630 if (scores)
11631 codes.safe_push (variant_constructs[i]);
11632 else if (matched < nconstructs
11633 && variant_constructs[i] == constructs[matched])
11635 if (variant_constructs[i] == OMP_SIMD)
11637 if (matched)
11638 return 0;
11639 simd_seen = true;
11641 ++matched;
11645 if (!target_seen
11646 && lookup_attribute ("omp declare target block",
11647 DECL_ATTRIBUTES (current_function_decl)))
11649 if (scores)
11650 codes.safe_push (OMP_TARGET);
11651 else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
11652 ++matched;
11654 if (scores)
11656 for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
11658 int j = codes.length () - 1;
11659 for (int i = nconstructs - 1; i >= 0; i--)
11661 while (j >= 0
11662 && (pass != 0 || declare_simd_cnt != j)
11663 && constructs[i] != codes[j])
11664 --j;
11665 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
11666 *scores++ = j - 1;
11667 else
11668 *scores++ = j;
11670 *scores++ = ((pass == 0 && declare_simd_cnt != -1)
11671 ? codes.length () - 1 : codes.length ());
11673 return declare_simd_cnt == -1 ? 1 : 2;
11675 if (matched == nconstructs)
11676 return simd_seen ? -1 : 1;
11677 return 0;
11680 /* Gimplify OACC_CACHE. */
11682 static void
11683 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
11685 tree expr = *expr_p;
11687 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
11688 OACC_CACHE);
11689 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
11690 OACC_CACHE);
11692 /* TODO: Do something sensible with this information. */
11694 *expr_p = NULL_TREE;
11697 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
11698 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
11699 kind. The entry kind will replace the one in CLAUSE, while the exit
11700 kind will be used in a new omp_clause and returned to the caller. */
11702 static tree
11703 gimplify_oacc_declare_1 (tree clause)
11705 HOST_WIDE_INT kind, new_op;
11706 bool ret = false;
11707 tree c = NULL;
11709 kind = OMP_CLAUSE_MAP_KIND (clause);
11711 switch (kind)
11713 case GOMP_MAP_ALLOC:
11714 new_op = GOMP_MAP_RELEASE;
11715 ret = true;
11716 break;
11718 case GOMP_MAP_FROM:
11719 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
11720 new_op = GOMP_MAP_FROM;
11721 ret = true;
11722 break;
11724 case GOMP_MAP_TOFROM:
11725 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
11726 new_op = GOMP_MAP_FROM;
11727 ret = true;
11728 break;
11730 case GOMP_MAP_DEVICE_RESIDENT:
11731 case GOMP_MAP_FORCE_DEVICEPTR:
11732 case GOMP_MAP_FORCE_PRESENT:
11733 case GOMP_MAP_LINK:
11734 case GOMP_MAP_POINTER:
11735 case GOMP_MAP_TO:
11736 break;
11738 default:
11739 gcc_unreachable ();
11740 break;
11743 if (ret)
11745 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
11746 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
11747 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
11750 return c;
11753 /* Gimplify OACC_DECLARE. */
11755 static void
11756 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
11758 tree expr = *expr_p;
11759 gomp_target *stmt;
11760 tree clauses, t, decl;
11762 clauses = OACC_DECLARE_CLAUSES (expr);
11764 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
11765 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
11767 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
11769 decl = OMP_CLAUSE_DECL (t);
11771 if (TREE_CODE (decl) == MEM_REF)
11772 decl = TREE_OPERAND (decl, 0);
11774 if (VAR_P (decl) && !is_oacc_declared (decl))
11776 tree attr = get_identifier ("oacc declare target");
11777 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
11778 DECL_ATTRIBUTES (decl));
11781 if (VAR_P (decl)
11782 && !is_global_var (decl)
11783 && DECL_CONTEXT (decl) == current_function_decl)
11785 tree c = gimplify_oacc_declare_1 (t);
11786 if (c)
11788 if (oacc_declare_returns == NULL)
11789 oacc_declare_returns = new hash_map<tree, tree>;
11791 oacc_declare_returns->put (decl, c);
11795 if (gimplify_omp_ctxp)
11796 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
11799 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
11800 clauses);
11802 gimplify_seq_add_stmt (pre_p, stmt);
11804 *expr_p = NULL_TREE;
11807 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
11808 gimplification of the body, as well as scanning the body for used
11809 variables. We need to do this scan now, because variable-sized
11810 decls will be decomposed during gimplification. */
11812 static void
11813 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
11815 tree expr = *expr_p;
11816 gimple *g;
11817 gimple_seq body = NULL;
11819 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
11820 OMP_PARALLEL_COMBINED (expr)
11821 ? ORT_COMBINED_PARALLEL
11822 : ORT_PARALLEL, OMP_PARALLEL);
11824 push_gimplify_context ();
11826 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
11827 if (gimple_code (g) == GIMPLE_BIND)
11828 pop_gimplify_context (g);
11829 else
11830 pop_gimplify_context (NULL);
11832 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
11833 OMP_PARALLEL);
11835 g = gimple_build_omp_parallel (body,
11836 OMP_PARALLEL_CLAUSES (expr),
11837 NULL_TREE, NULL_TREE);
11838 if (OMP_PARALLEL_COMBINED (expr))
11839 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
11840 gimplify_seq_add_stmt (pre_p, g);
11841 *expr_p = NULL_TREE;
11844 /* Gimplify the contents of an OMP_TASK statement. This involves
11845 gimplification of the body, as well as scanning the body for used
11846 variables. We need to do this scan now, because variable-sized
11847 decls will be decomposed during gimplification. */
11849 static void
11850 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
11852 tree expr = *expr_p;
11853 gimple *g;
11854 gimple_seq body = NULL;
11856 if (OMP_TASK_BODY (expr) == NULL_TREE)
11857 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
11858 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
11859 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
11861 error_at (OMP_CLAUSE_LOCATION (c),
11862 "%<mutexinoutset%> kind in %<depend%> clause on a "
11863 "%<taskwait%> construct");
11864 break;
11867 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
11868 omp_find_clause (OMP_TASK_CLAUSES (expr),
11869 OMP_CLAUSE_UNTIED)
11870 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
11872 if (OMP_TASK_BODY (expr))
11874 push_gimplify_context ();
11876 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
11877 if (gimple_code (g) == GIMPLE_BIND)
11878 pop_gimplify_context (g);
11879 else
11880 pop_gimplify_context (NULL);
11883 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
11884 OMP_TASK);
11886 g = gimple_build_omp_task (body,
11887 OMP_TASK_CLAUSES (expr),
11888 NULL_TREE, NULL_TREE,
11889 NULL_TREE, NULL_TREE, NULL_TREE);
11890 if (OMP_TASK_BODY (expr) == NULL_TREE)
11891 gimple_omp_task_set_taskwait_p (g, true);
11892 gimplify_seq_add_stmt (pre_p, g);
11893 *expr_p = NULL_TREE;
11896 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
11897 force it into a temporary initialized in PRE_P and add firstprivate clause
11898 to ORIG_FOR_STMT. */
11900 static void
11901 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
11902 tree orig_for_stmt)
11904 if (*tp == NULL || is_gimple_constant (*tp))
11905 return;
11907 *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
11908 /* Reference to pointer conversion is considered useless,
11909 but is significant for firstprivate clause. Force it
11910 here. */
11911 if (type
11912 && TREE_CODE (type) == POINTER_TYPE
11913 && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
11915 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
11916 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
11917 gimplify_and_add (m, pre_p);
11918 *tp = v;
11921 tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
11922 OMP_CLAUSE_DECL (c) = *tp;
11923 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
11924 OMP_FOR_CLAUSES (orig_for_stmt) = c;
11927 /* Gimplify the gross structure of an OMP_FOR statement. */
11929 static enum gimplify_status
11930 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
11932 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
11933 enum gimplify_status ret = GS_ALL_DONE;
11934 enum gimplify_status tret;
11935 gomp_for *gfor;
11936 gimple_seq for_body, for_pre_body;
11937 int i;
11938 bitmap has_decl_expr = NULL;
11939 enum omp_region_type ort = ORT_WORKSHARE;
11940 bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
11942 orig_for_stmt = for_stmt = *expr_p;
11944 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
11945 != NULL_TREE);
11946 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
11948 tree *data[4] = { NULL, NULL, NULL, NULL };
11949 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
11950 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
11951 find_combined_omp_for, data, NULL);
11952 if (inner_for_stmt == NULL_TREE)
11954 gcc_assert (seen_error ());
11955 *expr_p = NULL_TREE;
11956 return GS_ERROR;
11958 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
11960 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
11961 &OMP_FOR_PRE_BODY (for_stmt));
11962 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
11964 if (OMP_FOR_PRE_BODY (inner_for_stmt))
11966 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
11967 &OMP_FOR_PRE_BODY (for_stmt));
11968 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
11971 if (data[0])
11973 /* We have some statements or variable declarations in between
11974 the composite construct directives. Move them around the
11975 inner_for_stmt. */
11976 data[0] = expr_p;
11977 for (i = 0; i < 3; i++)
11978 if (data[i])
11980 tree t = *data[i];
11981 if (i < 2 && data[i + 1] == &OMP_BODY (t))
11982 data[i + 1] = data[i];
11983 *data[i] = OMP_BODY (t);
11984 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
11985 NULL_TREE, make_node (BLOCK));
11986 OMP_BODY (t) = body;
11987 append_to_statement_list_force (inner_for_stmt,
11988 &BIND_EXPR_BODY (body));
11989 *data[3] = t;
11990 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
11991 gcc_assert (*data[3] == inner_for_stmt);
11993 return GS_OK;
11996 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
11997 if (!loop_p
11998 && OMP_FOR_ORIG_DECLS (inner_for_stmt)
11999 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12000 i)) == TREE_LIST
12001 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12002 i)))
12004 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
12005 /* Class iterators aren't allowed on OMP_SIMD, so the only
12006 case we need to solve is distribute parallel for. They are
12007 allowed on the loop construct, but that is already handled
12008 in gimplify_omp_loop. */
12009 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
12010 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
12011 && data[1]);
12012 tree orig_decl = TREE_PURPOSE (orig);
12013 tree last = TREE_VALUE (orig);
12014 tree *pc;
12015 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
12016 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
12017 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
12018 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
12019 && OMP_CLAUSE_DECL (*pc) == orig_decl)
12020 break;
12021 if (*pc == NULL_TREE)
12023 tree *spc;
12024 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
12025 *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
12026 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
12027 && OMP_CLAUSE_DECL (*spc) == orig_decl)
12028 break;
12029 if (*spc)
12031 tree c = *spc;
12032 *spc = OMP_CLAUSE_CHAIN (c);
12033 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
12034 *pc = c;
12037 if (*pc == NULL_TREE)
12039 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
12041 /* private clause will appear only on inner_for_stmt.
12042 Change it into firstprivate, and add private clause
12043 on for_stmt. */
12044 tree c = copy_node (*pc);
12045 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12046 OMP_FOR_CLAUSES (for_stmt) = c;
12047 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
12048 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12050 else
12052 /* lastprivate clause will appear on both inner_for_stmt
12053 and for_stmt. Add firstprivate clause to
12054 inner_for_stmt. */
12055 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
12056 OMP_CLAUSE_FIRSTPRIVATE);
12057 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
12058 OMP_CLAUSE_CHAIN (c) = *pc;
12059 *pc = c;
12060 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12062 tree c = build_omp_clause (UNKNOWN_LOCATION,
12063 OMP_CLAUSE_FIRSTPRIVATE);
12064 OMP_CLAUSE_DECL (c) = last;
12065 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12066 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12067 c = build_omp_clause (UNKNOWN_LOCATION,
12068 *pc ? OMP_CLAUSE_SHARED
12069 : OMP_CLAUSE_FIRSTPRIVATE);
12070 OMP_CLAUSE_DECL (c) = orig_decl;
12071 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12072 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12074 /* Similarly, take care of C++ range for temporaries, those should
12075 be firstprivate on OMP_PARALLEL if any. */
12076 if (data[1])
12077 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
12078 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
12079 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12080 i)) == TREE_LIST
12081 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12082 i)))
12084 tree orig
12085 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
12086 tree v = TREE_CHAIN (orig);
12087 tree c = build_omp_clause (UNKNOWN_LOCATION,
12088 OMP_CLAUSE_FIRSTPRIVATE);
12089 /* First add firstprivate clause for the __for_end artificial
12090 decl. */
12091 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
12092 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12093 == REFERENCE_TYPE)
12094 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12095 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12096 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12097 if (TREE_VEC_ELT (v, 0))
12099 /* And now the same for __for_range artificial decl if it
12100 exists. */
12101 c = build_omp_clause (UNKNOWN_LOCATION,
12102 OMP_CLAUSE_FIRSTPRIVATE);
12103 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
12104 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12105 == REFERENCE_TYPE)
12106 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12107 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12108 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12113 switch (TREE_CODE (for_stmt))
12115 case OMP_FOR:
12116 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
12118 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12119 OMP_CLAUSE_SCHEDULE))
12120 error_at (EXPR_LOCATION (for_stmt),
12121 "%qs clause may not appear on non-rectangular %qs",
12122 "schedule", "for");
12123 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
12124 error_at (EXPR_LOCATION (for_stmt),
12125 "%qs clause may not appear on non-rectangular %qs",
12126 "ordered", "for");
12128 break;
12129 case OMP_DISTRIBUTE:
12130 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
12131 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12132 OMP_CLAUSE_DIST_SCHEDULE))
12133 error_at (EXPR_LOCATION (for_stmt),
12134 "%qs clause may not appear on non-rectangular %qs",
12135 "dist_schedule", "distribute");
12136 break;
12137 case OACC_LOOP:
12138 ort = ORT_ACC;
12139 break;
12140 case OMP_TASKLOOP:
12141 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
12142 ort = ORT_UNTIED_TASKLOOP;
12143 else
12144 ort = ORT_TASKLOOP;
12145 break;
12146 case OMP_SIMD:
12147 ort = ORT_SIMD;
12148 break;
12149 default:
12150 gcc_unreachable ();
12153 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
12154 clause for the IV. */
12155 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12157 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
12158 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12159 decl = TREE_OPERAND (t, 0);
12160 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
12161 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12162 && OMP_CLAUSE_DECL (c) == decl)
12164 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12165 break;
12169 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
12170 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
12171 loop_p && TREE_CODE (for_stmt) != OMP_SIMD
12172 ? OMP_LOOP : TREE_CODE (for_stmt));
12174 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
12175 gimplify_omp_ctxp->distribute = true;
12177 /* Handle OMP_FOR_INIT. */
12178 for_pre_body = NULL;
12179 if ((ort == ORT_SIMD
12180 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
12181 && OMP_FOR_PRE_BODY (for_stmt))
12183 has_decl_expr = BITMAP_ALLOC (NULL);
12184 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
12185 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
12186 == VAR_DECL)
12188 t = OMP_FOR_PRE_BODY (for_stmt);
12189 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12191 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
12193 tree_stmt_iterator si;
12194 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
12195 tsi_next (&si))
12197 t = tsi_stmt (si);
12198 if (TREE_CODE (t) == DECL_EXPR
12199 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
12200 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12204 if (OMP_FOR_PRE_BODY (for_stmt))
12206 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
12207 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12208 else
12210 struct gimplify_omp_ctx ctx;
12211 memset (&ctx, 0, sizeof (ctx));
12212 ctx.region_type = ORT_NONE;
12213 gimplify_omp_ctxp = &ctx;
12214 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12215 gimplify_omp_ctxp = NULL;
12218 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
12220 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
12221 for_stmt = inner_for_stmt;
12223 /* For taskloop, need to gimplify the start, end and step before the
12224 taskloop, outside of the taskloop omp context. */
12225 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12227 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12229 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12230 gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
12231 ? pre_p : &for_pre_body);
12232 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
12233 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12235 tree v = TREE_OPERAND (t, 1);
12236 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12237 for_pre_p, orig_for_stmt);
12238 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12239 for_pre_p, orig_for_stmt);
12241 else
12242 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12243 orig_for_stmt);
12245 /* Handle OMP_FOR_COND. */
12246 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12247 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12249 tree v = TREE_OPERAND (t, 1);
12250 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12251 for_pre_p, orig_for_stmt);
12252 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12253 for_pre_p, orig_for_stmt);
12255 else
12256 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12257 orig_for_stmt);
12259 /* Handle OMP_FOR_INCR. */
12260 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12261 if (TREE_CODE (t) == MODIFY_EXPR)
12263 decl = TREE_OPERAND (t, 0);
12264 t = TREE_OPERAND (t, 1);
12265 tree *tp = &TREE_OPERAND (t, 1);
12266 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
12267 tp = &TREE_OPERAND (t, 0);
12269 gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
12270 orig_for_stmt);
12274 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
12275 OMP_TASKLOOP);
12278 if (orig_for_stmt != for_stmt)
12279 gimplify_omp_ctxp->combined_loop = true;
12281 for_body = NULL;
12282 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12283 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
12284 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12285 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
12287 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
12288 bool is_doacross = false;
12289 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
12291 is_doacross = true;
12292 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
12293 (OMP_FOR_INIT (for_stmt))
12294 * 2);
12296 int collapse = 1, tile = 0;
12297 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
12298 if (c)
12299 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
12300 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
12301 if (c)
12302 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
12303 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
12304 hash_set<tree> *allocate_uids = NULL;
12305 if (c)
12307 allocate_uids = new hash_set<tree>;
12308 for (; c; c = OMP_CLAUSE_CHAIN (c))
12309 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
12310 allocate_uids->add (OMP_CLAUSE_DECL (c));
12312 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12314 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12315 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12316 decl = TREE_OPERAND (t, 0);
12317 gcc_assert (DECL_P (decl));
12318 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
12319 || POINTER_TYPE_P (TREE_TYPE (decl)));
12320 if (is_doacross)
12322 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
12324 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12325 if (TREE_CODE (orig_decl) == TREE_LIST)
12327 orig_decl = TREE_PURPOSE (orig_decl);
12328 if (!orig_decl)
12329 orig_decl = decl;
12331 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
12333 else
12334 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12335 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12338 if (for_stmt == orig_for_stmt)
12340 tree orig_decl = decl;
12341 if (OMP_FOR_ORIG_DECLS (for_stmt))
12343 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12344 if (TREE_CODE (orig_decl) == TREE_LIST)
12346 orig_decl = TREE_PURPOSE (orig_decl);
12347 if (!orig_decl)
12348 orig_decl = decl;
12351 if (is_global_var (orig_decl) && DECL_THREAD_LOCAL_P (orig_decl))
12352 error_at (EXPR_LOCATION (for_stmt),
12353 "threadprivate iteration variable %qD", orig_decl);
12356 /* Make sure the iteration variable is private. */
12357 tree c = NULL_TREE;
12358 tree c2 = NULL_TREE;
12359 if (orig_for_stmt != for_stmt)
12361 /* Preserve this information until we gimplify the inner simd. */
12362 if (has_decl_expr
12363 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12364 TREE_PRIVATE (t) = 1;
12366 else if (ort == ORT_SIMD)
12368 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12369 (splay_tree_key) decl);
12370 omp_is_private (gimplify_omp_ctxp, decl,
12371 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12372 != 1));
12373 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
12375 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12376 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
12377 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12378 OMP_CLAUSE_LASTPRIVATE);
12379 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12380 OMP_CLAUSE_LASTPRIVATE))
12381 if (OMP_CLAUSE_DECL (c3) == decl)
12383 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12384 "conditional %<lastprivate%> on loop "
12385 "iterator %qD ignored", decl);
12386 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12387 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12390 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
12392 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12393 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12394 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
12395 if ((has_decl_expr
12396 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12397 || TREE_PRIVATE (t))
12399 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12400 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12402 struct gimplify_omp_ctx *outer
12403 = gimplify_omp_ctxp->outer_context;
12404 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12406 if (outer->region_type == ORT_WORKSHARE
12407 && outer->combined_loop)
12409 n = splay_tree_lookup (outer->variables,
12410 (splay_tree_key)decl);
12411 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12413 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12414 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12416 else
12418 struct gimplify_omp_ctx *octx = outer->outer_context;
12419 if (octx
12420 && octx->region_type == ORT_COMBINED_PARALLEL
12421 && octx->outer_context
12422 && (octx->outer_context->region_type
12423 == ORT_WORKSHARE)
12424 && octx->outer_context->combined_loop)
12426 octx = octx->outer_context;
12427 n = splay_tree_lookup (octx->variables,
12428 (splay_tree_key)decl);
12429 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12431 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12432 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12439 OMP_CLAUSE_DECL (c) = decl;
12440 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12441 OMP_FOR_CLAUSES (for_stmt) = c;
12442 omp_add_variable (gimplify_omp_ctxp, decl, flags);
12443 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12444 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12445 true);
12447 else
12449 bool lastprivate
12450 = (!has_decl_expr
12451 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
12452 if (TREE_PRIVATE (t))
12453 lastprivate = false;
12454 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
12456 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12457 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
12458 lastprivate = false;
12461 struct gimplify_omp_ctx *outer
12462 = gimplify_omp_ctxp->outer_context;
12463 if (outer && lastprivate)
12464 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12465 true);
12467 c = build_omp_clause (input_location,
12468 lastprivate ? OMP_CLAUSE_LASTPRIVATE
12469 : OMP_CLAUSE_PRIVATE);
12470 OMP_CLAUSE_DECL (c) = decl;
12471 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12472 OMP_FOR_CLAUSES (for_stmt) = c;
12473 omp_add_variable (gimplify_omp_ctxp, decl,
12474 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
12475 | GOVD_EXPLICIT | GOVD_SEEN);
12476 c = NULL_TREE;
12479 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
12481 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12482 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12483 (splay_tree_key) decl);
12484 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
12485 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12486 OMP_CLAUSE_LASTPRIVATE);
12487 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12488 OMP_CLAUSE_LASTPRIVATE))
12489 if (OMP_CLAUSE_DECL (c3) == decl)
12491 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12492 "conditional %<lastprivate%> on loop "
12493 "iterator %qD ignored", decl);
12494 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12495 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12498 else
12499 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
12501 /* If DECL is not a gimple register, create a temporary variable to act
12502 as an iteration counter. This is valid, since DECL cannot be
12503 modified in the body of the loop. Similarly for any iteration vars
12504 in simd with collapse > 1 where the iterator vars must be
12505 lastprivate. And similarly for vars mentioned in allocate clauses. */
12506 if (orig_for_stmt != for_stmt)
12507 var = decl;
12508 else if (!is_gimple_reg (decl)
12509 || (ort == ORT_SIMD
12510 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
12511 || (allocate_uids && allocate_uids->contains (decl)))
12513 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12514 /* Make sure omp_add_variable is not called on it prematurely.
12515 We call it ourselves a few lines later. */
12516 gimplify_omp_ctxp = NULL;
12517 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
12518 gimplify_omp_ctxp = ctx;
12519 TREE_OPERAND (t, 0) = var;
12521 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
12523 if (ort == ORT_SIMD
12524 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12526 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12527 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
12528 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
12529 OMP_CLAUSE_DECL (c2) = var;
12530 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
12531 OMP_FOR_CLAUSES (for_stmt) = c2;
12532 omp_add_variable (gimplify_omp_ctxp, var,
12533 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
12534 if (c == NULL_TREE)
12536 c = c2;
12537 c2 = NULL_TREE;
12540 else
12541 omp_add_variable (gimplify_omp_ctxp, var,
12542 GOVD_PRIVATE | GOVD_SEEN);
12544 else
12545 var = decl;
12547 gimplify_omp_ctxp->in_for_exprs = true;
12548 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12550 tree lb = TREE_OPERAND (t, 1);
12551 tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
12552 is_gimple_val, fb_rvalue, false);
12553 ret = MIN (ret, tret);
12554 tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
12555 is_gimple_val, fb_rvalue, false);
12557 else
12558 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12559 is_gimple_val, fb_rvalue, false);
12560 gimplify_omp_ctxp->in_for_exprs = false;
12561 ret = MIN (ret, tret);
12562 if (ret == GS_ERROR)
12563 return ret;
12565 /* Handle OMP_FOR_COND. */
12566 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12567 gcc_assert (COMPARISON_CLASS_P (t));
12568 gcc_assert (TREE_OPERAND (t, 0) == decl);
12570 gimplify_omp_ctxp->in_for_exprs = true;
12571 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12573 tree ub = TREE_OPERAND (t, 1);
12574 tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
12575 is_gimple_val, fb_rvalue, false);
12576 ret = MIN (ret, tret);
12577 tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
12578 is_gimple_val, fb_rvalue, false);
12580 else
12581 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12582 is_gimple_val, fb_rvalue, false);
12583 gimplify_omp_ctxp->in_for_exprs = false;
12584 ret = MIN (ret, tret);
12586 /* Handle OMP_FOR_INCR. */
12587 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12588 switch (TREE_CODE (t))
12590 case PREINCREMENT_EXPR:
12591 case POSTINCREMENT_EXPR:
12593 tree decl = TREE_OPERAND (t, 0);
12594 /* c_omp_for_incr_canonicalize_ptr() should have been
12595 called to massage things appropriately. */
12596 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
12598 if (orig_for_stmt != for_stmt)
12599 break;
12600 t = build_int_cst (TREE_TYPE (decl), 1);
12601 if (c)
12602 OMP_CLAUSE_LINEAR_STEP (c) = t;
12603 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
12604 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
12605 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
12606 break;
12609 case PREDECREMENT_EXPR:
12610 case POSTDECREMENT_EXPR:
12611 /* c_omp_for_incr_canonicalize_ptr() should have been
12612 called to massage things appropriately. */
12613 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
12614 if (orig_for_stmt != for_stmt)
12615 break;
12616 t = build_int_cst (TREE_TYPE (decl), -1);
12617 if (c)
12618 OMP_CLAUSE_LINEAR_STEP (c) = t;
12619 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
12620 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
12621 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
12622 break;
12624 case MODIFY_EXPR:
12625 gcc_assert (TREE_OPERAND (t, 0) == decl);
12626 TREE_OPERAND (t, 0) = var;
12628 t = TREE_OPERAND (t, 1);
12629 switch (TREE_CODE (t))
12631 case PLUS_EXPR:
12632 if (TREE_OPERAND (t, 1) == decl)
12634 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
12635 TREE_OPERAND (t, 0) = var;
12636 break;
12639 /* Fallthru. */
12640 case MINUS_EXPR:
12641 case POINTER_PLUS_EXPR:
12642 gcc_assert (TREE_OPERAND (t, 0) == decl);
12643 TREE_OPERAND (t, 0) = var;
12644 break;
12645 default:
12646 gcc_unreachable ();
12649 gimplify_omp_ctxp->in_for_exprs = true;
12650 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12651 is_gimple_val, fb_rvalue, false);
12652 ret = MIN (ret, tret);
12653 if (c)
12655 tree step = TREE_OPERAND (t, 1);
12656 tree stept = TREE_TYPE (decl);
12657 if (POINTER_TYPE_P (stept))
12658 stept = sizetype;
12659 step = fold_convert (stept, step);
12660 if (TREE_CODE (t) == MINUS_EXPR)
12661 step = fold_build1 (NEGATE_EXPR, stept, step);
12662 OMP_CLAUSE_LINEAR_STEP (c) = step;
12663 if (step != TREE_OPERAND (t, 1))
12665 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
12666 &for_pre_body, NULL,
12667 is_gimple_val, fb_rvalue, false);
12668 ret = MIN (ret, tret);
12671 gimplify_omp_ctxp->in_for_exprs = false;
12672 break;
12674 default:
12675 gcc_unreachable ();
12678 if (c2)
12680 gcc_assert (c);
12681 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
12684 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
12686 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
12687 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12688 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
12689 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12690 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
12691 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
12692 && OMP_CLAUSE_DECL (c) == decl)
12694 if (is_doacross && (collapse == 1 || i >= collapse))
12695 t = var;
12696 else
12698 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12699 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12700 gcc_assert (TREE_OPERAND (t, 0) == var);
12701 t = TREE_OPERAND (t, 1);
12702 gcc_assert (TREE_CODE (t) == PLUS_EXPR
12703 || TREE_CODE (t) == MINUS_EXPR
12704 || TREE_CODE (t) == POINTER_PLUS_EXPR);
12705 gcc_assert (TREE_OPERAND (t, 0) == var);
12706 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
12707 is_doacross ? var : decl,
12708 TREE_OPERAND (t, 1));
12710 gimple_seq *seq;
12711 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
12712 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
12713 else
12714 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
12715 push_gimplify_context ();
12716 gimplify_assign (decl, t, seq);
12717 gimple *bind = NULL;
12718 if (gimplify_ctxp->temps)
12720 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
12721 *seq = NULL;
12722 gimplify_seq_add_stmt (seq, bind);
12724 pop_gimplify_context (bind);
12727 if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
12728 for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
12730 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
12731 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12732 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12733 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12734 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12735 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
12736 gcc_assert (COMPARISON_CLASS_P (t));
12737 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12738 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12739 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12743 BITMAP_FREE (has_decl_expr);
12744 delete allocate_uids;
12746 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
12747 || (loop_p && orig_for_stmt == for_stmt))
12749 push_gimplify_context ();
12750 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
12752 OMP_FOR_BODY (orig_for_stmt)
12753 = build3 (BIND_EXPR, void_type_node, NULL,
12754 OMP_FOR_BODY (orig_for_stmt), NULL);
12755 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
12759 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
12760 &for_body);
12762 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
12763 || (loop_p && orig_for_stmt == for_stmt))
12765 if (gimple_code (g) == GIMPLE_BIND)
12766 pop_gimplify_context (g);
12767 else
12768 pop_gimplify_context (NULL);
12771 if (orig_for_stmt != for_stmt)
12772 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12774 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12775 decl = TREE_OPERAND (t, 0);
12776 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12777 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12778 gimplify_omp_ctxp = ctx->outer_context;
12779 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
12780 gimplify_omp_ctxp = ctx;
12781 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
12782 TREE_OPERAND (t, 0) = var;
12783 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12784 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12785 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
12786 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
12787 for (int j = i + 1;
12788 j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
12790 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
12791 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12792 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12793 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12795 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12796 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12798 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
12799 gcc_assert (COMPARISON_CLASS_P (t));
12800 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12801 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12803 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12804 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12809 gimplify_adjust_omp_clauses (pre_p, for_body,
12810 &OMP_FOR_CLAUSES (orig_for_stmt),
12811 TREE_CODE (orig_for_stmt));
12813 int kind;
12814 switch (TREE_CODE (orig_for_stmt))
12816 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
12817 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
12818 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
12819 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
12820 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
12821 default:
12822 gcc_unreachable ();
12824 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
12826 gimplify_seq_add_seq (pre_p, for_pre_body);
12827 for_pre_body = NULL;
12829 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
12830 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
12831 for_pre_body);
12832 if (orig_for_stmt != for_stmt)
12833 gimple_omp_for_set_combined_p (gfor, true);
12834 if (gimplify_omp_ctxp
12835 && (gimplify_omp_ctxp->combined_loop
12836 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
12837 && gimplify_omp_ctxp->outer_context
12838 && gimplify_omp_ctxp->outer_context->combined_loop)))
12840 gimple_omp_for_set_combined_into_p (gfor, true);
12841 if (gimplify_omp_ctxp->combined_loop)
12842 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
12843 else
12844 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
12847 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12849 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12850 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
12851 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
12852 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12853 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
12854 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
12855 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12856 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
12859 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
12860 constructs with GIMPLE_OMP_TASK sandwiched in between them.
12861 The outer taskloop stands for computing the number of iterations,
12862 counts for collapsed loops and holding taskloop specific clauses.
12863 The task construct stands for the effect of data sharing on the
12864 explicit task it creates and the inner taskloop stands for expansion
12865 of the static loop inside of the explicit task construct. */
12866 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12868 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
12869 tree task_clauses = NULL_TREE;
12870 tree c = *gfor_clauses_ptr;
12871 tree *gtask_clauses_ptr = &task_clauses;
12872 tree outer_for_clauses = NULL_TREE;
12873 tree *gforo_clauses_ptr = &outer_for_clauses;
12874 bitmap lastprivate_uids = NULL;
12875 if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
12877 c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
12878 if (c)
12880 lastprivate_uids = BITMAP_ALLOC (NULL);
12881 for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
12882 OMP_CLAUSE_LASTPRIVATE))
12883 bitmap_set_bit (lastprivate_uids,
12884 DECL_UID (OMP_CLAUSE_DECL (c)));
12886 c = *gfor_clauses_ptr;
12888 for (; c; c = OMP_CLAUSE_CHAIN (c))
12889 switch (OMP_CLAUSE_CODE (c))
12891 /* These clauses are allowed on task, move them there. */
12892 case OMP_CLAUSE_SHARED:
12893 case OMP_CLAUSE_FIRSTPRIVATE:
12894 case OMP_CLAUSE_DEFAULT:
12895 case OMP_CLAUSE_IF:
12896 case OMP_CLAUSE_UNTIED:
12897 case OMP_CLAUSE_FINAL:
12898 case OMP_CLAUSE_MERGEABLE:
12899 case OMP_CLAUSE_PRIORITY:
12900 case OMP_CLAUSE_REDUCTION:
12901 case OMP_CLAUSE_IN_REDUCTION:
12902 *gtask_clauses_ptr = c;
12903 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12904 break;
12905 case OMP_CLAUSE_PRIVATE:
12906 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
12908 /* We want private on outer for and firstprivate
12909 on task. */
12910 *gtask_clauses_ptr
12911 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12912 OMP_CLAUSE_FIRSTPRIVATE);
12913 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12914 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
12915 openacc);
12916 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12917 *gforo_clauses_ptr = c;
12918 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12920 else
12922 *gtask_clauses_ptr = c;
12923 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12925 break;
12926 /* These clauses go into outer taskloop clauses. */
12927 case OMP_CLAUSE_GRAINSIZE:
12928 case OMP_CLAUSE_NUM_TASKS:
12929 case OMP_CLAUSE_NOGROUP:
12930 *gforo_clauses_ptr = c;
12931 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12932 break;
12933 /* Collapse clause we duplicate on both taskloops. */
12934 case OMP_CLAUSE_COLLAPSE:
12935 *gfor_clauses_ptr = c;
12936 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12937 *gforo_clauses_ptr = copy_node (c);
12938 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
12939 break;
12940 /* For lastprivate, keep the clause on inner taskloop, and add
12941 a shared clause on task. If the same decl is also firstprivate,
12942 add also firstprivate clause on the inner taskloop. */
12943 case OMP_CLAUSE_LASTPRIVATE:
12944 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
12946 /* For taskloop C++ lastprivate IVs, we want:
12947 1) private on outer taskloop
12948 2) firstprivate and shared on task
12949 3) lastprivate on inner taskloop */
12950 *gtask_clauses_ptr
12951 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12952 OMP_CLAUSE_FIRSTPRIVATE);
12953 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12954 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
12955 openacc);
12956 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12957 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
12958 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12959 OMP_CLAUSE_PRIVATE);
12960 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
12961 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
12962 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
12963 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
12965 *gfor_clauses_ptr = c;
12966 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12967 *gtask_clauses_ptr
12968 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
12969 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12970 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
12971 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
12972 gtask_clauses_ptr
12973 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12974 break;
12975 /* Allocate clause we duplicate on task and inner taskloop
12976 if the decl is lastprivate, otherwise just put on task. */
12977 case OMP_CLAUSE_ALLOCATE:
12978 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
12979 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
12981 /* Additionally, put firstprivate clause on task
12982 for the allocator if it is not constant. */
12983 *gtask_clauses_ptr
12984 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12985 OMP_CLAUSE_FIRSTPRIVATE);
12986 OMP_CLAUSE_DECL (*gtask_clauses_ptr)
12987 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
12988 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12990 if (lastprivate_uids
12991 && bitmap_bit_p (lastprivate_uids,
12992 DECL_UID (OMP_CLAUSE_DECL (c))))
12994 *gfor_clauses_ptr = c;
12995 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12996 *gtask_clauses_ptr = copy_node (c);
12997 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12999 else
13001 *gtask_clauses_ptr = c;
13002 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13004 break;
13005 default:
13006 gcc_unreachable ();
13008 *gfor_clauses_ptr = NULL_TREE;
13009 *gtask_clauses_ptr = NULL_TREE;
13010 *gforo_clauses_ptr = NULL_TREE;
13011 BITMAP_FREE (lastprivate_uids);
13012 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
13013 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
13014 NULL_TREE, NULL_TREE, NULL_TREE);
13015 gimple_omp_task_set_taskloop_p (g, true);
13016 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
13017 gomp_for *gforo
13018 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
13019 gimple_omp_for_collapse (gfor),
13020 gimple_omp_for_pre_body (gfor));
13021 gimple_omp_for_set_pre_body (gfor, NULL);
13022 gimple_omp_for_set_combined_p (gforo, true);
13023 gimple_omp_for_set_combined_into_p (gfor, true);
13024 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
13026 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
13027 tree v = create_tmp_var (type);
13028 gimple_omp_for_set_index (gforo, i, v);
13029 t = unshare_expr (gimple_omp_for_initial (gfor, i));
13030 gimple_omp_for_set_initial (gforo, i, t);
13031 gimple_omp_for_set_cond (gforo, i,
13032 gimple_omp_for_cond (gfor, i));
13033 t = unshare_expr (gimple_omp_for_final (gfor, i));
13034 gimple_omp_for_set_final (gforo, i, t);
13035 t = unshare_expr (gimple_omp_for_incr (gfor, i));
13036 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
13037 TREE_OPERAND (t, 0) = v;
13038 gimple_omp_for_set_incr (gforo, i, t);
13039 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
13040 OMP_CLAUSE_DECL (t) = v;
13041 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
13042 gimple_omp_for_set_clauses (gforo, t);
13043 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
13045 tree *p1 = NULL, *p2 = NULL;
13046 t = gimple_omp_for_initial (gforo, i);
13047 if (TREE_CODE (t) == TREE_VEC)
13048 p1 = &TREE_VEC_ELT (t, 0);
13049 t = gimple_omp_for_final (gforo, i);
13050 if (TREE_CODE (t) == TREE_VEC)
13052 if (p1)
13053 p2 = &TREE_VEC_ELT (t, 0);
13054 else
13055 p1 = &TREE_VEC_ELT (t, 0);
13057 if (p1)
13059 int j;
13060 for (j = 0; j < i; j++)
13061 if (*p1 == gimple_omp_for_index (gfor, j))
13063 *p1 = gimple_omp_for_index (gforo, j);
13064 if (p2)
13065 *p2 = *p1;
13066 break;
13068 gcc_assert (j < i);
13072 gimplify_seq_add_stmt (pre_p, gforo);
13074 else
13075 gimplify_seq_add_stmt (pre_p, gfor);
13077 if (TREE_CODE (orig_for_stmt) == OMP_FOR)
13079 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13080 unsigned lastprivate_conditional = 0;
13081 while (ctx
13082 && (ctx->region_type == ORT_TARGET_DATA
13083 || ctx->region_type == ORT_TASKGROUP))
13084 ctx = ctx->outer_context;
13085 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
13086 for (tree c = gimple_omp_for_clauses (gfor);
13087 c; c = OMP_CLAUSE_CHAIN (c))
13088 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13089 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13090 ++lastprivate_conditional;
13091 if (lastprivate_conditional)
13093 struct omp_for_data fd;
13094 omp_extract_for_data (gfor, &fd, NULL);
13095 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
13096 lastprivate_conditional);
13097 tree var = create_tmp_var_raw (type);
13098 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
13099 OMP_CLAUSE_DECL (c) = var;
13100 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13101 gimple_omp_for_set_clauses (gfor, c);
13102 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
13105 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
13107 unsigned lastprivate_conditional = 0;
13108 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
13109 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13110 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13111 ++lastprivate_conditional;
13112 if (lastprivate_conditional)
13114 struct omp_for_data fd;
13115 omp_extract_for_data (gfor, &fd, NULL);
13116 tree type = unsigned_type_for (fd.iter_type);
13117 while (lastprivate_conditional--)
13119 tree c = build_omp_clause (UNKNOWN_LOCATION,
13120 OMP_CLAUSE__CONDTEMP_);
13121 OMP_CLAUSE_DECL (c) = create_tmp_var (type);
13122 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13123 gimple_omp_for_set_clauses (gfor, c);
13128 if (ret != GS_ALL_DONE)
13129 return GS_ERROR;
13130 *expr_p = NULL_TREE;
13131 return GS_ALL_DONE;
13134 /* Helper for gimplify_omp_loop, called through walk_tree. */
13136 static tree
13137 note_no_context_vars (tree *tp, int *, void *data)
13139 if (VAR_P (*tp)
13140 && DECL_CONTEXT (*tp) == NULL_TREE
13141 && !is_global_var (*tp))
13143 vec<tree> *d = (vec<tree> *) data;
13144 d->safe_push (*tp);
13145 DECL_CONTEXT (*tp) = current_function_decl;
13147 return NULL_TREE;
13150 /* Gimplify the gross structure of an OMP_LOOP statement. */
13152 static enum gimplify_status
13153 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
13155 tree for_stmt = *expr_p;
13156 tree clauses = OMP_FOR_CLAUSES (for_stmt);
13157 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
13158 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
13159 int i;
13161 /* If order is not present, the behavior is as if order(concurrent)
13162 appeared. */
13163 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
13164 if (order == NULL_TREE)
13166 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
13167 OMP_CLAUSE_CHAIN (order) = clauses;
13168 OMP_FOR_CLAUSES (for_stmt) = clauses = order;
13171 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
13172 if (bind == NULL_TREE)
13174 if (!flag_openmp) /* flag_openmp_simd */
13176 else if (octx && (octx->region_type & ORT_TEAMS) != 0)
13177 kind = OMP_CLAUSE_BIND_TEAMS;
13178 else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
13179 kind = OMP_CLAUSE_BIND_PARALLEL;
13180 else
13182 for (; octx; octx = octx->outer_context)
13184 if ((octx->region_type & ORT_ACC) != 0
13185 || octx->region_type == ORT_NONE
13186 || octx->region_type == ORT_IMPLICIT_TARGET)
13187 continue;
13188 break;
13190 if (octx == NULL && !in_omp_construct)
13191 error_at (EXPR_LOCATION (for_stmt),
13192 "%<bind%> clause not specified on a %<loop%> "
13193 "construct not nested inside another OpenMP construct");
13195 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
13196 OMP_CLAUSE_CHAIN (bind) = clauses;
13197 OMP_CLAUSE_BIND_KIND (bind) = kind;
13198 OMP_FOR_CLAUSES (for_stmt) = bind;
13200 else
13201 switch (OMP_CLAUSE_BIND_KIND (bind))
13203 case OMP_CLAUSE_BIND_THREAD:
13204 break;
13205 case OMP_CLAUSE_BIND_PARALLEL:
13206 if (!flag_openmp) /* flag_openmp_simd */
13208 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13209 break;
13211 for (; octx; octx = octx->outer_context)
13212 if (octx->region_type == ORT_SIMD
13213 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
13215 error_at (EXPR_LOCATION (for_stmt),
13216 "%<bind(parallel)%> on a %<loop%> construct nested "
13217 "inside %<simd%> construct");
13218 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13219 break;
13221 kind = OMP_CLAUSE_BIND_PARALLEL;
13222 break;
13223 case OMP_CLAUSE_BIND_TEAMS:
13224 if (!flag_openmp) /* flag_openmp_simd */
13226 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13227 break;
13229 if ((octx
13230 && octx->region_type != ORT_IMPLICIT_TARGET
13231 && octx->region_type != ORT_NONE
13232 && (octx->region_type & ORT_TEAMS) == 0)
13233 || in_omp_construct)
13235 error_at (EXPR_LOCATION (for_stmt),
13236 "%<bind(teams)%> on a %<loop%> region not strictly "
13237 "nested inside of a %<teams%> region");
13238 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13239 break;
13241 kind = OMP_CLAUSE_BIND_TEAMS;
13242 break;
13243 default:
13244 gcc_unreachable ();
13247 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
13248 switch (OMP_CLAUSE_CODE (*pc))
13250 case OMP_CLAUSE_REDUCTION:
13251 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
13253 error_at (OMP_CLAUSE_LOCATION (*pc),
13254 "%<inscan%> %<reduction%> clause on "
13255 "%qs construct", "loop");
13256 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
13258 if (OMP_CLAUSE_REDUCTION_TASK (*pc))
13260 error_at (OMP_CLAUSE_LOCATION (*pc),
13261 "invalid %<task%> reduction modifier on construct "
13262 "other than %<parallel%>, %qs or %<sections%>",
13263 lang_GNU_Fortran () ? "do" : "for");
13264 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
13266 pc = &OMP_CLAUSE_CHAIN (*pc);
13267 break;
13268 case OMP_CLAUSE_LASTPRIVATE:
13269 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13271 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13272 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13273 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
13274 break;
13275 if (OMP_FOR_ORIG_DECLS (for_stmt)
13276 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13277 i)) == TREE_LIST
13278 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13279 i)))
13281 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13282 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
13283 break;
13286 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
13288 error_at (OMP_CLAUSE_LOCATION (*pc),
13289 "%<lastprivate%> clause on a %<loop%> construct refers "
13290 "to a variable %qD which is not the loop iterator",
13291 OMP_CLAUSE_DECL (*pc));
13292 *pc = OMP_CLAUSE_CHAIN (*pc);
13293 break;
13295 pc = &OMP_CLAUSE_CHAIN (*pc);
13296 break;
13297 default:
13298 pc = &OMP_CLAUSE_CHAIN (*pc);
13299 break;
13302 TREE_SET_CODE (for_stmt, OMP_SIMD);
13304 int last;
13305 switch (kind)
13307 case OMP_CLAUSE_BIND_THREAD: last = 0; break;
13308 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
13309 case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
13311 for (int pass = 1; pass <= last; pass++)
13313 if (pass == 2)
13315 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
13316 make_node (BLOCK));
13317 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
13318 *expr_p = make_node (OMP_PARALLEL);
13319 TREE_TYPE (*expr_p) = void_type_node;
13320 OMP_PARALLEL_BODY (*expr_p) = bind;
13321 OMP_PARALLEL_COMBINED (*expr_p) = 1;
13322 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
13323 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
13324 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13325 if (OMP_FOR_ORIG_DECLS (for_stmt)
13326 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
13327 == TREE_LIST))
13329 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13330 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
13332 *pc = build_omp_clause (UNKNOWN_LOCATION,
13333 OMP_CLAUSE_FIRSTPRIVATE);
13334 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
13335 pc = &OMP_CLAUSE_CHAIN (*pc);
13339 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
13340 tree *pc = &OMP_FOR_CLAUSES (t);
13341 TREE_TYPE (t) = void_type_node;
13342 OMP_FOR_BODY (t) = *expr_p;
13343 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
13344 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
13345 switch (OMP_CLAUSE_CODE (c))
13347 case OMP_CLAUSE_BIND:
13348 case OMP_CLAUSE_ORDER:
13349 case OMP_CLAUSE_COLLAPSE:
13350 *pc = copy_node (c);
13351 pc = &OMP_CLAUSE_CHAIN (*pc);
13352 break;
13353 case OMP_CLAUSE_PRIVATE:
13354 case OMP_CLAUSE_FIRSTPRIVATE:
13355 /* Only needed on innermost. */
13356 break;
13357 case OMP_CLAUSE_LASTPRIVATE:
13358 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
13360 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13361 OMP_CLAUSE_FIRSTPRIVATE);
13362 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
13363 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13364 pc = &OMP_CLAUSE_CHAIN (*pc);
13366 *pc = copy_node (c);
13367 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
13368 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13369 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
13371 if (pass != last)
13372 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
13373 else
13374 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13375 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
13377 pc = &OMP_CLAUSE_CHAIN (*pc);
13378 break;
13379 case OMP_CLAUSE_REDUCTION:
13380 *pc = copy_node (c);
13381 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
13382 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13383 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
13385 auto_vec<tree> no_context_vars;
13386 int walk_subtrees = 0;
13387 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13388 &walk_subtrees, &no_context_vars);
13389 if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c))
13390 note_no_context_vars (&p, &walk_subtrees, &no_context_vars);
13391 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c),
13392 note_no_context_vars,
13393 &no_context_vars);
13394 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c),
13395 note_no_context_vars,
13396 &no_context_vars);
13398 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
13399 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
13400 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13401 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
13402 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
13404 hash_map<tree, tree> decl_map;
13405 decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c));
13406 decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13407 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc));
13408 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13409 decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
13410 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc));
13412 copy_body_data id;
13413 memset (&id, 0, sizeof (id));
13414 id.src_fn = current_function_decl;
13415 id.dst_fn = current_function_decl;
13416 id.src_cfun = cfun;
13417 id.decl_map = &decl_map;
13418 id.copy_decl = copy_decl_no_change;
13419 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
13420 id.transform_new_cfg = true;
13421 id.transform_return_to_modify = false;
13422 id.eh_lp_nr = 0;
13423 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r,
13424 &id, NULL);
13425 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r,
13426 &id, NULL);
13428 for (tree d : no_context_vars)
13430 DECL_CONTEXT (d) = NULL_TREE;
13431 DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE;
13434 else
13436 OMP_CLAUSE_REDUCTION_INIT (*pc)
13437 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
13438 OMP_CLAUSE_REDUCTION_MERGE (*pc)
13439 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
13441 pc = &OMP_CLAUSE_CHAIN (*pc);
13442 break;
13443 default:
13444 gcc_unreachable ();
13446 *pc = NULL_TREE;
13447 *expr_p = t;
13449 return gimplify_omp_for (expr_p, pre_p);
13453 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
13454 of OMP_TARGET's body. */
13456 static tree
13457 find_omp_teams (tree *tp, int *walk_subtrees, void *)
13459 *walk_subtrees = 0;
13460 switch (TREE_CODE (*tp))
13462 case OMP_TEAMS:
13463 return *tp;
13464 case BIND_EXPR:
13465 case STATEMENT_LIST:
13466 *walk_subtrees = 1;
13467 break;
13468 default:
13469 break;
13471 return NULL_TREE;
13474 /* Helper function of optimize_target_teams, determine if the expression
13475 can be computed safely before the target construct on the host. */
13477 static tree
13478 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
13480 splay_tree_node n;
13482 if (TYPE_P (*tp))
13484 *walk_subtrees = 0;
13485 return NULL_TREE;
13487 switch (TREE_CODE (*tp))
13489 case VAR_DECL:
13490 case PARM_DECL:
13491 case RESULT_DECL:
13492 *walk_subtrees = 0;
13493 if (error_operand_p (*tp)
13494 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
13495 || DECL_HAS_VALUE_EXPR_P (*tp)
13496 || DECL_THREAD_LOCAL_P (*tp)
13497 || TREE_SIDE_EFFECTS (*tp)
13498 || TREE_THIS_VOLATILE (*tp))
13499 return *tp;
13500 if (is_global_var (*tp)
13501 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
13502 || lookup_attribute ("omp declare target link",
13503 DECL_ATTRIBUTES (*tp))))
13504 return *tp;
13505 if (VAR_P (*tp)
13506 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
13507 && !is_global_var (*tp)
13508 && decl_function_context (*tp) == current_function_decl)
13509 return *tp;
13510 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
13511 (splay_tree_key) *tp);
13512 if (n == NULL)
13514 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
13515 return NULL_TREE;
13516 return *tp;
13518 else if (n->value & GOVD_LOCAL)
13519 return *tp;
13520 else if (n->value & GOVD_FIRSTPRIVATE)
13521 return NULL_TREE;
13522 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13523 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13524 return NULL_TREE;
13525 return *tp;
13526 case INTEGER_CST:
13527 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13528 return *tp;
13529 return NULL_TREE;
13530 case TARGET_EXPR:
13531 if (TARGET_EXPR_INITIAL (*tp)
13532 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
13533 return *tp;
13534 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
13535 walk_subtrees, NULL);
13536 /* Allow some reasonable subset of integral arithmetics. */
13537 case PLUS_EXPR:
13538 case MINUS_EXPR:
13539 case MULT_EXPR:
13540 case TRUNC_DIV_EXPR:
13541 case CEIL_DIV_EXPR:
13542 case FLOOR_DIV_EXPR:
13543 case ROUND_DIV_EXPR:
13544 case TRUNC_MOD_EXPR:
13545 case CEIL_MOD_EXPR:
13546 case FLOOR_MOD_EXPR:
13547 case ROUND_MOD_EXPR:
13548 case RDIV_EXPR:
13549 case EXACT_DIV_EXPR:
13550 case MIN_EXPR:
13551 case MAX_EXPR:
13552 case LSHIFT_EXPR:
13553 case RSHIFT_EXPR:
13554 case BIT_IOR_EXPR:
13555 case BIT_XOR_EXPR:
13556 case BIT_AND_EXPR:
13557 case NEGATE_EXPR:
13558 case ABS_EXPR:
13559 case BIT_NOT_EXPR:
13560 case NON_LVALUE_EXPR:
13561 CASE_CONVERT:
13562 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13563 return *tp;
13564 return NULL_TREE;
13565 /* And disallow anything else, except for comparisons. */
13566 default:
13567 if (COMPARISON_CLASS_P (*tp))
13568 return NULL_TREE;
13569 return *tp;
13573 /* Try to determine if the num_teams and/or thread_limit expressions
13574 can have their values determined already before entering the
13575 target construct.
13576 INTEGER_CSTs trivially are,
13577 integral decls that are firstprivate (explicitly or implicitly)
13578 or explicitly map(always, to:) or map(always, tofrom:) on the target
13579 region too, and expressions involving simple arithmetics on those
13580 too, function calls are not ok, dereferencing something neither etc.
13581 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
13582 EXPR based on what we find:
13583 0 stands for clause not specified at all, use implementation default
13584 -1 stands for value that can't be determined easily before entering
13585 the target construct.
13586 If teams construct is not present at all, use 1 for num_teams
13587 and 0 for thread_limit (only one team is involved, and the thread
13588 limit is implementation defined. */
13590 static void
13591 optimize_target_teams (tree target, gimple_seq *pre_p)
13593 tree body = OMP_BODY (target);
13594 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
13595 tree num_teams_lower = NULL_TREE;
13596 tree num_teams_upper = integer_zero_node;
13597 tree thread_limit = integer_zero_node;
13598 location_t num_teams_loc = EXPR_LOCATION (target);
13599 location_t thread_limit_loc = EXPR_LOCATION (target);
13600 tree c, *p, expr;
13601 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
13603 if (teams == NULL_TREE)
13604 num_teams_upper = integer_one_node;
13605 else
13606 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
13608 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
13610 p = &num_teams_upper;
13611 num_teams_loc = OMP_CLAUSE_LOCATION (c);
13612 if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))
13614 expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
13615 if (TREE_CODE (expr) == INTEGER_CST)
13616 num_teams_lower = expr;
13617 else if (walk_tree (&expr, computable_teams_clause,
13618 NULL, NULL))
13619 num_teams_lower = integer_minus_one_node;
13620 else
13622 num_teams_lower = expr;
13623 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
13624 if (gimplify_expr (&num_teams_lower, pre_p, NULL,
13625 is_gimple_val, fb_rvalue, false)
13626 == GS_ERROR)
13628 gimplify_omp_ctxp = target_ctx;
13629 num_teams_lower = integer_minus_one_node;
13631 else
13633 gimplify_omp_ctxp = target_ctx;
13634 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
13635 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
13636 = num_teams_lower;
13641 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
13643 p = &thread_limit;
13644 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
13646 else
13647 continue;
13648 expr = OMP_CLAUSE_OPERAND (c, 0);
13649 if (TREE_CODE (expr) == INTEGER_CST)
13651 *p = expr;
13652 continue;
13654 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
13656 *p = integer_minus_one_node;
13657 continue;
13659 *p = expr;
13660 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
13661 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
13662 == GS_ERROR)
13664 gimplify_omp_ctxp = target_ctx;
13665 *p = integer_minus_one_node;
13666 continue;
13668 gimplify_omp_ctxp = target_ctx;
13669 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
13670 OMP_CLAUSE_OPERAND (c, 0) = *p;
13672 if (!omp_find_clause (OMP_TARGET_CLAUSES (target), OMP_CLAUSE_THREAD_LIMIT))
13674 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
13675 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
13676 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
13677 OMP_TARGET_CLAUSES (target) = c;
13679 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
13680 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper;
13681 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower;
13682 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
13683 OMP_TARGET_CLAUSES (target) = c;
13686 /* Gimplify the gross structure of several OMP constructs. */
13688 static void
13689 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
13691 tree expr = *expr_p;
13692 gimple *stmt;
13693 gimple_seq body = NULL;
13694 enum omp_region_type ort;
13696 switch (TREE_CODE (expr))
13698 case OMP_SECTIONS:
13699 case OMP_SINGLE:
13700 ort = ORT_WORKSHARE;
13701 break;
13702 case OMP_SCOPE:
13703 ort = ORT_TASKGROUP;
13704 break;
13705 case OMP_TARGET:
13706 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
13707 break;
13708 case OACC_KERNELS:
13709 ort = ORT_ACC_KERNELS;
13710 break;
13711 case OACC_PARALLEL:
13712 ort = ORT_ACC_PARALLEL;
13713 break;
13714 case OACC_SERIAL:
13715 ort = ORT_ACC_SERIAL;
13716 break;
13717 case OACC_DATA:
13718 ort = ORT_ACC_DATA;
13719 break;
13720 case OMP_TARGET_DATA:
13721 ort = ORT_TARGET_DATA;
13722 break;
13723 case OMP_TEAMS:
13724 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
13725 if (gimplify_omp_ctxp == NULL
13726 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
13727 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
13728 break;
13729 case OACC_HOST_DATA:
13730 ort = ORT_ACC_HOST_DATA;
13731 break;
13732 default:
13733 gcc_unreachable ();
13736 bool save_in_omp_construct = in_omp_construct;
13737 if ((ort & ORT_ACC) == 0)
13738 in_omp_construct = false;
13739 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
13740 TREE_CODE (expr));
13741 if (TREE_CODE (expr) == OMP_TARGET)
13742 optimize_target_teams (expr, pre_p);
13743 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
13744 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
13746 push_gimplify_context ();
13747 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
13748 if (gimple_code (g) == GIMPLE_BIND)
13749 pop_gimplify_context (g);
13750 else
13751 pop_gimplify_context (NULL);
13752 if ((ort & ORT_TARGET_DATA) != 0)
13754 enum built_in_function end_ix;
13755 switch (TREE_CODE (expr))
13757 case OACC_DATA:
13758 case OACC_HOST_DATA:
13759 end_ix = BUILT_IN_GOACC_DATA_END;
13760 break;
13761 case OMP_TARGET_DATA:
13762 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
13763 break;
13764 default:
13765 gcc_unreachable ();
13767 tree fn = builtin_decl_explicit (end_ix);
13768 g = gimple_build_call (fn, 0);
13769 gimple_seq cleanup = NULL;
13770 gimple_seq_add_stmt (&cleanup, g);
13771 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
13772 body = NULL;
13773 gimple_seq_add_stmt (&body, g);
13776 else
13777 gimplify_and_add (OMP_BODY (expr), &body);
13778 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
13779 TREE_CODE (expr));
13780 in_omp_construct = save_in_omp_construct;
13782 switch (TREE_CODE (expr))
13784 case OACC_DATA:
13785 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
13786 OMP_CLAUSES (expr));
13787 break;
13788 case OACC_HOST_DATA:
13789 if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
13791 for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13792 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
13793 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
13796 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
13797 OMP_CLAUSES (expr));
13798 break;
13799 case OACC_KERNELS:
13800 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
13801 OMP_CLAUSES (expr));
13802 break;
13803 case OACC_PARALLEL:
13804 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
13805 OMP_CLAUSES (expr));
13806 break;
13807 case OACC_SERIAL:
13808 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
13809 OMP_CLAUSES (expr));
13810 break;
13811 case OMP_SECTIONS:
13812 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
13813 break;
13814 case OMP_SINGLE:
13815 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
13816 break;
13817 case OMP_SCOPE:
13818 stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr));
13819 break;
13820 case OMP_TARGET:
13821 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
13822 OMP_CLAUSES (expr));
13823 break;
13824 case OMP_TARGET_DATA:
13825 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
13826 to be evaluated before the use_device_{ptr,addr} clauses if they
13827 refer to the same variables. */
13829 tree use_device_clauses;
13830 tree *pc, *uc = &use_device_clauses;
13831 for (pc = &OMP_CLAUSES (expr); *pc; )
13832 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
13833 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
13835 *uc = *pc;
13836 *pc = OMP_CLAUSE_CHAIN (*pc);
13837 uc = &OMP_CLAUSE_CHAIN (*uc);
13839 else
13840 pc = &OMP_CLAUSE_CHAIN (*pc);
13841 *uc = NULL_TREE;
13842 *pc = use_device_clauses;
13843 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
13844 OMP_CLAUSES (expr));
13846 break;
13847 case OMP_TEAMS:
13848 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
13849 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
13850 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
13851 break;
13852 default:
13853 gcc_unreachable ();
13856 gimplify_seq_add_stmt (pre_p, stmt);
13857 *expr_p = NULL_TREE;
13860 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
13861 target update constructs. */
13863 static void
13864 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
13866 tree expr = *expr_p;
13867 int kind;
13868 gomp_target *stmt;
13869 enum omp_region_type ort = ORT_WORKSHARE;
13871 switch (TREE_CODE (expr))
13873 case OACC_ENTER_DATA:
13874 kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA;
13875 ort = ORT_ACC;
13876 break;
13877 case OACC_EXIT_DATA:
13878 kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA;
13879 ort = ORT_ACC;
13880 break;
13881 case OACC_UPDATE:
13882 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
13883 ort = ORT_ACC;
13884 break;
13885 case OMP_TARGET_UPDATE:
13886 kind = GF_OMP_TARGET_KIND_UPDATE;
13887 break;
13888 case OMP_TARGET_ENTER_DATA:
13889 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
13890 break;
13891 case OMP_TARGET_EXIT_DATA:
13892 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
13893 break;
13894 default:
13895 gcc_unreachable ();
13897 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
13898 ort, TREE_CODE (expr));
13899 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
13900 TREE_CODE (expr));
13901 if (TREE_CODE (expr) == OACC_UPDATE
13902 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
13903 OMP_CLAUSE_IF_PRESENT))
13905 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
13906 clause. */
13907 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13908 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
13909 switch (OMP_CLAUSE_MAP_KIND (c))
13911 case GOMP_MAP_FORCE_TO:
13912 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
13913 break;
13914 case GOMP_MAP_FORCE_FROM:
13915 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
13916 break;
13917 default:
13918 break;
13921 else if (TREE_CODE (expr) == OACC_EXIT_DATA
13922 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
13923 OMP_CLAUSE_FINALIZE))
13925 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
13926 semantics. */
13927 bool have_clause = false;
13928 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13929 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
13930 switch (OMP_CLAUSE_MAP_KIND (c))
13932 case GOMP_MAP_FROM:
13933 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
13934 have_clause = true;
13935 break;
13936 case GOMP_MAP_RELEASE:
13937 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
13938 have_clause = true;
13939 break;
13940 case GOMP_MAP_TO_PSET:
13941 /* Fortran arrays with descriptors must map that descriptor when
13942 doing standalone "attach" operations (in OpenACC). In that
13943 case GOMP_MAP_TO_PSET appears by itself with no preceding
13944 clause (see trans-openmp.c:gfc_trans_omp_clauses). */
13945 break;
13946 case GOMP_MAP_POINTER:
13947 /* TODO PR92929: we may see these here, but they'll always follow
13948 one of the clauses above, and will be handled by libgomp as
13949 one group, so no handling required here. */
13950 gcc_assert (have_clause);
13951 break;
13952 case GOMP_MAP_DETACH:
13953 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
13954 have_clause = false;
13955 break;
13956 case GOMP_MAP_STRUCT:
13957 have_clause = false;
13958 break;
13959 default:
13960 gcc_unreachable ();
13963 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
13965 gimplify_seq_add_stmt (pre_p, stmt);
13966 *expr_p = NULL_TREE;
13969 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
13970 stabilized the lhs of the atomic operation as *ADDR. Return true if
13971 EXPR is this stabilized form. */
13973 static bool
13974 goa_lhs_expr_p (tree expr, tree addr)
13976 /* Also include casts to other type variants. The C front end is fond
13977 of adding these for e.g. volatile variables. This is like
13978 STRIP_TYPE_NOPS but includes the main variant lookup. */
13979 STRIP_USELESS_TYPE_CONVERSION (expr);
13981 if (TREE_CODE (expr) == INDIRECT_REF)
13983 expr = TREE_OPERAND (expr, 0);
13984 while (expr != addr
13985 && (CONVERT_EXPR_P (expr)
13986 || TREE_CODE (expr) == NON_LVALUE_EXPR)
13987 && TREE_CODE (expr) == TREE_CODE (addr)
13988 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
13990 expr = TREE_OPERAND (expr, 0);
13991 addr = TREE_OPERAND (addr, 0);
13993 if (expr == addr)
13994 return true;
13995 return (TREE_CODE (addr) == ADDR_EXPR
13996 && TREE_CODE (expr) == ADDR_EXPR
13997 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
13999 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
14000 return true;
14001 return false;
14004 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
14005 expression does not involve the lhs, evaluate it into a temporary.
14006 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
14007 or -1 if an error was encountered. */
14009 static int
14010 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
14011 tree lhs_var, tree &target_expr, bool rhs, int depth)
14013 tree expr = *expr_p;
14014 int saw_lhs = 0;
14016 if (goa_lhs_expr_p (expr, lhs_addr))
14018 if (pre_p)
14019 *expr_p = lhs_var;
14020 return 1;
14022 if (is_gimple_val (expr))
14023 return 0;
14025 /* Maximum depth of lhs in expression is for the
14026 __builtin_clear_padding (...), __builtin_clear_padding (...),
14027 __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs; */
14028 if (++depth > 7)
14029 goto finish;
14031 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
14033 case tcc_binary:
14034 case tcc_comparison:
14035 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
14036 lhs_var, target_expr, true, depth);
14037 /* FALLTHRU */
14038 case tcc_unary:
14039 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
14040 lhs_var, target_expr, true, depth);
14041 break;
14042 case tcc_expression:
14043 switch (TREE_CODE (expr))
14045 case TRUTH_ANDIF_EXPR:
14046 case TRUTH_ORIF_EXPR:
14047 case TRUTH_AND_EXPR:
14048 case TRUTH_OR_EXPR:
14049 case TRUTH_XOR_EXPR:
14050 case BIT_INSERT_EXPR:
14051 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14052 lhs_addr, lhs_var, target_expr, true,
14053 depth);
14054 /* FALLTHRU */
14055 case TRUTH_NOT_EXPR:
14056 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14057 lhs_addr, lhs_var, target_expr, true,
14058 depth);
14059 break;
14060 case MODIFY_EXPR:
14061 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14062 target_expr, true, depth))
14063 break;
14064 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14065 lhs_addr, lhs_var, target_expr, true,
14066 depth);
14067 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14068 lhs_addr, lhs_var, target_expr, false,
14069 depth);
14070 break;
14071 /* FALLTHRU */
14072 case ADDR_EXPR:
14073 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14074 target_expr, true, depth))
14075 break;
14076 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14077 lhs_addr, lhs_var, target_expr, false,
14078 depth);
14079 break;
14080 case COMPOUND_EXPR:
14081 /* Break out any preevaluations from cp_build_modify_expr. */
14082 for (; TREE_CODE (expr) == COMPOUND_EXPR;
14083 expr = TREE_OPERAND (expr, 1))
14085 /* Special-case __builtin_clear_padding call before
14086 __builtin_memcmp. */
14087 if (TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR)
14089 tree fndecl = get_callee_fndecl (TREE_OPERAND (expr, 0));
14090 if (fndecl
14091 && fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14092 && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
14093 && (!pre_p
14094 || goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL,
14095 lhs_addr, lhs_var,
14096 target_expr, true, depth)))
14098 if (pre_p)
14099 *expr_p = expr;
14100 saw_lhs = goa_stabilize_expr (&TREE_OPERAND (expr, 0),
14101 pre_p, lhs_addr, lhs_var,
14102 target_expr, true, depth);
14103 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1),
14104 pre_p, lhs_addr, lhs_var,
14105 target_expr, rhs, depth);
14106 return saw_lhs;
14110 if (pre_p)
14111 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
14113 if (!pre_p)
14114 return goa_stabilize_expr (&expr, pre_p, lhs_addr, lhs_var,
14115 target_expr, rhs, depth);
14116 *expr_p = expr;
14117 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var,
14118 target_expr, rhs, depth);
14119 case COND_EXPR:
14120 if (!goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, lhs_addr,
14121 lhs_var, target_expr, true, depth))
14122 break;
14123 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14124 lhs_addr, lhs_var, target_expr, true,
14125 depth);
14126 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14127 lhs_addr, lhs_var, target_expr, true,
14128 depth);
14129 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 2), pre_p,
14130 lhs_addr, lhs_var, target_expr, true,
14131 depth);
14132 break;
14133 case TARGET_EXPR:
14134 if (TARGET_EXPR_INITIAL (expr))
14136 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr,
14137 lhs_var, target_expr, true,
14138 depth))
14139 break;
14140 if (expr == target_expr)
14141 saw_lhs = 1;
14142 else
14144 saw_lhs = goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr),
14145 pre_p, lhs_addr, lhs_var,
14146 target_expr, true, depth);
14147 if (saw_lhs && target_expr == NULL_TREE && pre_p)
14148 target_expr = expr;
14151 break;
14152 default:
14153 break;
14155 break;
14156 case tcc_reference:
14157 if (TREE_CODE (expr) == BIT_FIELD_REF
14158 || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
14159 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14160 lhs_addr, lhs_var, target_expr, true,
14161 depth);
14162 break;
14163 case tcc_vl_exp:
14164 if (TREE_CODE (expr) == CALL_EXPR)
14166 if (tree fndecl = get_callee_fndecl (expr))
14167 if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14168 || fndecl_built_in_p (fndecl, BUILT_IN_MEMCMP))
14170 int nargs = call_expr_nargs (expr);
14171 for (int i = 0; i < nargs; i++)
14172 saw_lhs |= goa_stabilize_expr (&CALL_EXPR_ARG (expr, i),
14173 pre_p, lhs_addr, lhs_var,
14174 target_expr, true, depth);
14177 break;
14178 default:
14179 break;
14182 finish:
14183 if (saw_lhs == 0 && pre_p)
14185 enum gimplify_status gs;
14186 if (TREE_CODE (expr) == CALL_EXPR && VOID_TYPE_P (TREE_TYPE (expr)))
14188 gimplify_stmt (&expr, pre_p);
14189 return saw_lhs;
14191 else if (rhs)
14192 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
14193 else
14194 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_lvalue, fb_lvalue);
14195 if (gs != GS_ALL_DONE)
14196 saw_lhs = -1;
14199 return saw_lhs;
14202 /* Gimplify an OMP_ATOMIC statement. */
14204 static enum gimplify_status
14205 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
14207 tree addr = TREE_OPERAND (*expr_p, 0);
14208 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
14209 ? NULL : TREE_OPERAND (*expr_p, 1);
14210 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
14211 tree tmp_load;
14212 gomp_atomic_load *loadstmt;
14213 gomp_atomic_store *storestmt;
14214 tree target_expr = NULL_TREE;
14216 tmp_load = create_tmp_reg (type);
14217 if (rhs
14218 && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load, target_expr,
14219 true, 0) < 0)
14220 return GS_ERROR;
14222 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
14223 != GS_ALL_DONE)
14224 return GS_ERROR;
14226 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
14227 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14228 gimplify_seq_add_stmt (pre_p, loadstmt);
14229 if (rhs)
14231 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
14232 representatives. Use BIT_FIELD_REF on the lhs instead. */
14233 tree rhsarg = rhs;
14234 if (TREE_CODE (rhs) == COND_EXPR)
14235 rhsarg = TREE_OPERAND (rhs, 1);
14236 if (TREE_CODE (rhsarg) == BIT_INSERT_EXPR
14237 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
14239 tree bitpos = TREE_OPERAND (rhsarg, 2);
14240 tree op1 = TREE_OPERAND (rhsarg, 1);
14241 tree bitsize;
14242 tree tmp_store = tmp_load;
14243 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
14244 tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
14245 if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
14246 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
14247 else
14248 bitsize = TYPE_SIZE (TREE_TYPE (op1));
14249 gcc_assert (TREE_OPERAND (rhsarg, 0) == tmp_load);
14250 tree t = build2_loc (EXPR_LOCATION (rhsarg),
14251 MODIFY_EXPR, void_type_node,
14252 build3_loc (EXPR_LOCATION (rhsarg),
14253 BIT_FIELD_REF, TREE_TYPE (op1),
14254 tmp_store, bitsize, bitpos), op1);
14255 if (TREE_CODE (rhs) == COND_EXPR)
14256 t = build3_loc (EXPR_LOCATION (rhs), COND_EXPR, void_type_node,
14257 TREE_OPERAND (rhs, 0), t, void_node);
14258 gimplify_and_add (t, pre_p);
14259 rhs = tmp_store;
14261 bool save_allow_rhs_cond_expr = gimplify_ctxp->allow_rhs_cond_expr;
14262 if (TREE_CODE (rhs) == COND_EXPR)
14263 gimplify_ctxp->allow_rhs_cond_expr = true;
14264 enum gimplify_status gs = gimplify_expr (&rhs, pre_p, NULL,
14265 is_gimple_val, fb_rvalue);
14266 gimplify_ctxp->allow_rhs_cond_expr = save_allow_rhs_cond_expr;
14267 if (gs != GS_ALL_DONE)
14268 return GS_ERROR;
14271 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
14272 rhs = tmp_load;
14273 storestmt
14274 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14275 if (TREE_CODE (*expr_p) != OMP_ATOMIC_READ && OMP_ATOMIC_WEAK (*expr_p))
14277 gimple_omp_atomic_set_weak (loadstmt);
14278 gimple_omp_atomic_set_weak (storestmt);
14280 gimplify_seq_add_stmt (pre_p, storestmt);
14281 switch (TREE_CODE (*expr_p))
14283 case OMP_ATOMIC_READ:
14284 case OMP_ATOMIC_CAPTURE_OLD:
14285 *expr_p = tmp_load;
14286 gimple_omp_atomic_set_need_value (loadstmt);
14287 break;
14288 case OMP_ATOMIC_CAPTURE_NEW:
14289 *expr_p = rhs;
14290 gimple_omp_atomic_set_need_value (storestmt);
14291 break;
14292 default:
14293 *expr_p = NULL;
14294 break;
14297 return GS_ALL_DONE;
14300 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
14301 body, and adding some EH bits. */
14303 static enum gimplify_status
14304 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
14306 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
14307 gimple *body_stmt;
14308 gtransaction *trans_stmt;
14309 gimple_seq body = NULL;
14310 int subcode = 0;
14312 /* Wrap the transaction body in a BIND_EXPR so we have a context
14313 where to put decls for OMP. */
14314 if (TREE_CODE (tbody) != BIND_EXPR)
14316 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
14317 TREE_SIDE_EFFECTS (bind) = 1;
14318 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
14319 TRANSACTION_EXPR_BODY (expr) = bind;
14322 push_gimplify_context ();
14323 temp = voidify_wrapper_expr (*expr_p, NULL);
14325 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
14326 pop_gimplify_context (body_stmt);
14328 trans_stmt = gimple_build_transaction (body);
14329 if (TRANSACTION_EXPR_OUTER (expr))
14330 subcode = GTMA_IS_OUTER;
14331 else if (TRANSACTION_EXPR_RELAXED (expr))
14332 subcode = GTMA_IS_RELAXED;
14333 gimple_transaction_set_subcode (trans_stmt, subcode);
14335 gimplify_seq_add_stmt (pre_p, trans_stmt);
14337 if (temp)
14339 *expr_p = temp;
14340 return GS_OK;
14343 *expr_p = NULL_TREE;
14344 return GS_ALL_DONE;
14347 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
14348 is the OMP_BODY of the original EXPR (which has already been
14349 gimplified so it's not present in the EXPR).
14351 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
14353 static gimple *
14354 gimplify_omp_ordered (tree expr, gimple_seq body)
14356 tree c, decls;
14357 int failures = 0;
14358 unsigned int i;
14359 tree source_c = NULL_TREE;
14360 tree sink_c = NULL_TREE;
14362 if (gimplify_omp_ctxp)
14364 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14365 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14366 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
14367 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
14368 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
14370 error_at (OMP_CLAUSE_LOCATION (c),
14371 "%<ordered%> construct with %<depend%> clause must be "
14372 "closely nested inside a loop with %<ordered%> clause "
14373 "with a parameter");
14374 failures++;
14376 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14377 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
14379 bool fail = false;
14380 for (decls = OMP_CLAUSE_DECL (c), i = 0;
14381 decls && TREE_CODE (decls) == TREE_LIST;
14382 decls = TREE_CHAIN (decls), ++i)
14383 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
14384 continue;
14385 else if (TREE_VALUE (decls)
14386 != gimplify_omp_ctxp->loop_iter_var[2 * i])
14388 error_at (OMP_CLAUSE_LOCATION (c),
14389 "variable %qE is not an iteration "
14390 "of outermost loop %d, expected %qE",
14391 TREE_VALUE (decls), i + 1,
14392 gimplify_omp_ctxp->loop_iter_var[2 * i]);
14393 fail = true;
14394 failures++;
14396 else
14397 TREE_VALUE (decls)
14398 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
14399 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
14401 error_at (OMP_CLAUSE_LOCATION (c),
14402 "number of variables in %<depend%> clause with "
14403 "%<sink%> modifier does not match number of "
14404 "iteration variables");
14405 failures++;
14407 sink_c = c;
14409 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14410 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
14412 if (source_c)
14414 error_at (OMP_CLAUSE_LOCATION (c),
14415 "more than one %<depend%> clause with %<source%> "
14416 "modifier on an %<ordered%> construct");
14417 failures++;
14419 else
14420 source_c = c;
14423 if (source_c && sink_c)
14425 error_at (OMP_CLAUSE_LOCATION (source_c),
14426 "%<depend%> clause with %<source%> modifier specified "
14427 "together with %<depend%> clauses with %<sink%> modifier "
14428 "on the same construct");
14429 failures++;
14432 if (failures)
14433 return gimple_build_nop ();
14434 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
14437 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
14438 expression produces a value to be used as an operand inside a GIMPLE
14439 statement, the value will be stored back in *EXPR_P. This value will
14440 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
14441 an SSA_NAME. The corresponding sequence of GIMPLE statements is
14442 emitted in PRE_P and POST_P.
14444 Additionally, this process may overwrite parts of the input
14445 expression during gimplification. Ideally, it should be
14446 possible to do non-destructive gimplification.
14448 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
14449 the expression needs to evaluate to a value to be used as
14450 an operand in a GIMPLE statement, this value will be stored in
14451 *EXPR_P on exit. This happens when the caller specifies one
14452 of fb_lvalue or fb_rvalue fallback flags.
14454 PRE_P will contain the sequence of GIMPLE statements corresponding
14455 to the evaluation of EXPR and all the side-effects that must
14456 be executed before the main expression. On exit, the last
14457 statement of PRE_P is the core statement being gimplified. For
14458 instance, when gimplifying 'if (++a)' the last statement in
14459 PRE_P will be 'if (t.1)' where t.1 is the result of
14460 pre-incrementing 'a'.
14462 POST_P will contain the sequence of GIMPLE statements corresponding
14463 to the evaluation of all the side-effects that must be executed
14464 after the main expression. If this is NULL, the post
14465 side-effects are stored at the end of PRE_P.
14467 The reason why the output is split in two is to handle post
14468 side-effects explicitly. In some cases, an expression may have
14469 inner and outer post side-effects which need to be emitted in
14470 an order different from the one given by the recursive
14471 traversal. For instance, for the expression (*p--)++ the post
14472 side-effects of '--' must actually occur *after* the post
14473 side-effects of '++'. However, gimplification will first visit
14474 the inner expression, so if a separate POST sequence was not
14475 used, the resulting sequence would be:
14477 1 t.1 = *p
14478 2 p = p - 1
14479 3 t.2 = t.1 + 1
14480 4 *p = t.2
14482 However, the post-decrement operation in line #2 must not be
14483 evaluated until after the store to *p at line #4, so the
14484 correct sequence should be:
14486 1 t.1 = *p
14487 2 t.2 = t.1 + 1
14488 3 *p = t.2
14489 4 p = p - 1
14491 So, by specifying a separate post queue, it is possible
14492 to emit the post side-effects in the correct order.
14493 If POST_P is NULL, an internal queue will be used. Before
14494 returning to the caller, the sequence POST_P is appended to
14495 the main output sequence PRE_P.
14497 GIMPLE_TEST_F points to a function that takes a tree T and
14498 returns nonzero if T is in the GIMPLE form requested by the
14499 caller. The GIMPLE predicates are in gimple.c.
14501 FALLBACK tells the function what sort of a temporary we want if
14502 gimplification cannot produce an expression that complies with
14503 GIMPLE_TEST_F.
14505 fb_none means that no temporary should be generated
14506 fb_rvalue means that an rvalue is OK to generate
14507 fb_lvalue means that an lvalue is OK to generate
14508 fb_either means that either is OK, but an lvalue is preferable.
14509 fb_mayfail means that gimplification may fail (in which case
14510 GS_ERROR will be returned)
14512 The return value is either GS_ERROR or GS_ALL_DONE, since this
14513 function iterates until EXPR is completely gimplified or an error
14514 occurs. */
14516 enum gimplify_status
14517 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
14518 bool (*gimple_test_f) (tree), fallback_t fallback)
14520 tree tmp;
14521 gimple_seq internal_pre = NULL;
14522 gimple_seq internal_post = NULL;
14523 tree save_expr;
14524 bool is_statement;
14525 location_t saved_location;
14526 enum gimplify_status ret;
14527 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
14528 tree label;
14530 save_expr = *expr_p;
14531 if (save_expr == NULL_TREE)
14532 return GS_ALL_DONE;
14534 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
14535 is_statement = gimple_test_f == is_gimple_stmt;
14536 if (is_statement)
14537 gcc_assert (pre_p);
14539 /* Consistency checks. */
14540 if (gimple_test_f == is_gimple_reg)
14541 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
14542 else if (gimple_test_f == is_gimple_val
14543 || gimple_test_f == is_gimple_call_addr
14544 || gimple_test_f == is_gimple_condexpr
14545 || gimple_test_f == is_gimple_condexpr_for_cond
14546 || gimple_test_f == is_gimple_mem_rhs
14547 || gimple_test_f == is_gimple_mem_rhs_or_call
14548 || gimple_test_f == is_gimple_reg_rhs
14549 || gimple_test_f == is_gimple_reg_rhs_or_call
14550 || gimple_test_f == is_gimple_asm_val
14551 || gimple_test_f == is_gimple_mem_ref_addr)
14552 gcc_assert (fallback & fb_rvalue);
14553 else if (gimple_test_f == is_gimple_min_lval
14554 || gimple_test_f == is_gimple_lvalue)
14555 gcc_assert (fallback & fb_lvalue);
14556 else if (gimple_test_f == is_gimple_addressable)
14557 gcc_assert (fallback & fb_either);
14558 else if (gimple_test_f == is_gimple_stmt)
14559 gcc_assert (fallback == fb_none);
14560 else
14562 /* We should have recognized the GIMPLE_TEST_F predicate to
14563 know what kind of fallback to use in case a temporary is
14564 needed to hold the value or address of *EXPR_P. */
14565 gcc_unreachable ();
14568 /* We used to check the predicate here and return immediately if it
14569 succeeds. This is wrong; the design is for gimplification to be
14570 idempotent, and for the predicates to only test for valid forms, not
14571 whether they are fully simplified. */
14572 if (pre_p == NULL)
14573 pre_p = &internal_pre;
14575 if (post_p == NULL)
14576 post_p = &internal_post;
14578 /* Remember the last statements added to PRE_P and POST_P. Every
14579 new statement added by the gimplification helpers needs to be
14580 annotated with location information. To centralize the
14581 responsibility, we remember the last statement that had been
14582 added to both queues before gimplifying *EXPR_P. If
14583 gimplification produces new statements in PRE_P and POST_P, those
14584 statements will be annotated with the same location information
14585 as *EXPR_P. */
14586 pre_last_gsi = gsi_last (*pre_p);
14587 post_last_gsi = gsi_last (*post_p);
14589 saved_location = input_location;
14590 if (save_expr != error_mark_node
14591 && EXPR_HAS_LOCATION (*expr_p))
14592 input_location = EXPR_LOCATION (*expr_p);
14594 /* Loop over the specific gimplifiers until the toplevel node
14595 remains the same. */
14598 /* Strip away as many useless type conversions as possible
14599 at the toplevel. */
14600 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
14602 /* Remember the expr. */
14603 save_expr = *expr_p;
14605 /* Die, die, die, my darling. */
14606 if (error_operand_p (save_expr))
14608 ret = GS_ERROR;
14609 break;
14612 /* Do any language-specific gimplification. */
14613 ret = ((enum gimplify_status)
14614 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
14615 if (ret == GS_OK)
14617 if (*expr_p == NULL_TREE)
14618 break;
14619 if (*expr_p != save_expr)
14620 continue;
14622 else if (ret != GS_UNHANDLED)
14623 break;
14625 /* Make sure that all the cases set 'ret' appropriately. */
14626 ret = GS_UNHANDLED;
14627 switch (TREE_CODE (*expr_p))
14629 /* First deal with the special cases. */
14631 case POSTINCREMENT_EXPR:
14632 case POSTDECREMENT_EXPR:
14633 case PREINCREMENT_EXPR:
14634 case PREDECREMENT_EXPR:
14635 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
14636 fallback != fb_none,
14637 TREE_TYPE (*expr_p));
14638 break;
14640 case VIEW_CONVERT_EXPR:
14641 if ((fallback & fb_rvalue)
14642 && is_gimple_reg_type (TREE_TYPE (*expr_p))
14643 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
14645 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14646 post_p, is_gimple_val, fb_rvalue);
14647 recalculate_side_effects (*expr_p);
14648 break;
14650 /* Fallthru. */
14652 case ARRAY_REF:
14653 case ARRAY_RANGE_REF:
14654 case REALPART_EXPR:
14655 case IMAGPART_EXPR:
14656 case COMPONENT_REF:
14657 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
14658 fallback ? fallback : fb_rvalue);
14659 break;
14661 case COND_EXPR:
14662 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
14664 /* C99 code may assign to an array in a structure value of a
14665 conditional expression, and this has undefined behavior
14666 only on execution, so create a temporary if an lvalue is
14667 required. */
14668 if (fallback == fb_lvalue)
14670 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14671 mark_addressable (*expr_p);
14672 ret = GS_OK;
14674 break;
14676 case CALL_EXPR:
14677 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
14679 /* C99 code may assign to an array in a structure returned
14680 from a function, and this has undefined behavior only on
14681 execution, so create a temporary if an lvalue is
14682 required. */
14683 if (fallback == fb_lvalue)
14685 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14686 mark_addressable (*expr_p);
14687 ret = GS_OK;
14689 break;
14691 case TREE_LIST:
14692 gcc_unreachable ();
14694 case COMPOUND_EXPR:
14695 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
14696 break;
14698 case COMPOUND_LITERAL_EXPR:
14699 ret = gimplify_compound_literal_expr (expr_p, pre_p,
14700 gimple_test_f, fallback);
14701 break;
14703 case MODIFY_EXPR:
14704 case INIT_EXPR:
14705 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
14706 fallback != fb_none);
14707 break;
14709 case TRUTH_ANDIF_EXPR:
14710 case TRUTH_ORIF_EXPR:
14712 /* Preserve the original type of the expression and the
14713 source location of the outer expression. */
14714 tree org_type = TREE_TYPE (*expr_p);
14715 *expr_p = gimple_boolify (*expr_p);
14716 *expr_p = build3_loc (input_location, COND_EXPR,
14717 org_type, *expr_p,
14718 fold_convert_loc
14719 (input_location,
14720 org_type, boolean_true_node),
14721 fold_convert_loc
14722 (input_location,
14723 org_type, boolean_false_node));
14724 ret = GS_OK;
14725 break;
14728 case TRUTH_NOT_EXPR:
14730 tree type = TREE_TYPE (*expr_p);
14731 /* The parsers are careful to generate TRUTH_NOT_EXPR
14732 only with operands that are always zero or one.
14733 We do not fold here but handle the only interesting case
14734 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
14735 *expr_p = gimple_boolify (*expr_p);
14736 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
14737 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
14738 TREE_TYPE (*expr_p),
14739 TREE_OPERAND (*expr_p, 0));
14740 else
14741 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
14742 TREE_TYPE (*expr_p),
14743 TREE_OPERAND (*expr_p, 0),
14744 build_int_cst (TREE_TYPE (*expr_p), 1));
14745 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
14746 *expr_p = fold_convert_loc (input_location, type, *expr_p);
14747 ret = GS_OK;
14748 break;
14751 case ADDR_EXPR:
14752 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
14753 break;
14755 case ANNOTATE_EXPR:
14757 tree cond = TREE_OPERAND (*expr_p, 0);
14758 tree kind = TREE_OPERAND (*expr_p, 1);
14759 tree data = TREE_OPERAND (*expr_p, 2);
14760 tree type = TREE_TYPE (cond);
14761 if (!INTEGRAL_TYPE_P (type))
14763 *expr_p = cond;
14764 ret = GS_OK;
14765 break;
14767 tree tmp = create_tmp_var (type);
14768 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
14769 gcall *call
14770 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
14771 gimple_call_set_lhs (call, tmp);
14772 gimplify_seq_add_stmt (pre_p, call);
14773 *expr_p = tmp;
14774 ret = GS_ALL_DONE;
14775 break;
14778 case VA_ARG_EXPR:
14779 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
14780 break;
14782 CASE_CONVERT:
14783 if (IS_EMPTY_STMT (*expr_p))
14785 ret = GS_ALL_DONE;
14786 break;
14789 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
14790 || fallback == fb_none)
14792 /* Just strip a conversion to void (or in void context) and
14793 try again. */
14794 *expr_p = TREE_OPERAND (*expr_p, 0);
14795 ret = GS_OK;
14796 break;
14799 ret = gimplify_conversion (expr_p);
14800 if (ret == GS_ERROR)
14801 break;
14802 if (*expr_p != save_expr)
14803 break;
14804 /* FALLTHRU */
14806 case FIX_TRUNC_EXPR:
14807 /* unary_expr: ... | '(' cast ')' val | ... */
14808 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14809 is_gimple_val, fb_rvalue);
14810 recalculate_side_effects (*expr_p);
14811 break;
14813 case INDIRECT_REF:
14815 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
14816 bool notrap = TREE_THIS_NOTRAP (*expr_p);
14817 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
14819 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
14820 if (*expr_p != save_expr)
14822 ret = GS_OK;
14823 break;
14826 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14827 is_gimple_reg, fb_rvalue);
14828 if (ret == GS_ERROR)
14829 break;
14831 recalculate_side_effects (*expr_p);
14832 *expr_p = fold_build2_loc (input_location, MEM_REF,
14833 TREE_TYPE (*expr_p),
14834 TREE_OPERAND (*expr_p, 0),
14835 build_int_cst (saved_ptr_type, 0));
14836 TREE_THIS_VOLATILE (*expr_p) = volatilep;
14837 TREE_THIS_NOTRAP (*expr_p) = notrap;
14838 ret = GS_OK;
14839 break;
14842 /* We arrive here through the various re-gimplifcation paths. */
14843 case MEM_REF:
14844 /* First try re-folding the whole thing. */
14845 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
14846 TREE_OPERAND (*expr_p, 0),
14847 TREE_OPERAND (*expr_p, 1));
14848 if (tmp)
14850 REF_REVERSE_STORAGE_ORDER (tmp)
14851 = REF_REVERSE_STORAGE_ORDER (*expr_p);
14852 *expr_p = tmp;
14853 recalculate_side_effects (*expr_p);
14854 ret = GS_OK;
14855 break;
14857 /* Avoid re-gimplifying the address operand if it is already
14858 in suitable form. Re-gimplifying would mark the address
14859 operand addressable. Always gimplify when not in SSA form
14860 as we still may have to gimplify decls with value-exprs. */
14861 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
14862 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
14864 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14865 is_gimple_mem_ref_addr, fb_rvalue);
14866 if (ret == GS_ERROR)
14867 break;
14869 recalculate_side_effects (*expr_p);
14870 ret = GS_ALL_DONE;
14871 break;
14873 /* Constants need not be gimplified. */
14874 case INTEGER_CST:
14875 case REAL_CST:
14876 case FIXED_CST:
14877 case STRING_CST:
14878 case COMPLEX_CST:
14879 case VECTOR_CST:
14880 /* Drop the overflow flag on constants, we do not want
14881 that in the GIMPLE IL. */
14882 if (TREE_OVERFLOW_P (*expr_p))
14883 *expr_p = drop_tree_overflow (*expr_p);
14884 ret = GS_ALL_DONE;
14885 break;
14887 case CONST_DECL:
14888 /* If we require an lvalue, such as for ADDR_EXPR, retain the
14889 CONST_DECL node. Otherwise the decl is replaceable by its
14890 value. */
14891 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
14892 if (fallback & fb_lvalue)
14893 ret = GS_ALL_DONE;
14894 else
14896 *expr_p = DECL_INITIAL (*expr_p);
14897 ret = GS_OK;
14899 break;
14901 case DECL_EXPR:
14902 ret = gimplify_decl_expr (expr_p, pre_p);
14903 break;
14905 case BIND_EXPR:
14906 ret = gimplify_bind_expr (expr_p, pre_p);
14907 break;
14909 case LOOP_EXPR:
14910 ret = gimplify_loop_expr (expr_p, pre_p);
14911 break;
14913 case SWITCH_EXPR:
14914 ret = gimplify_switch_expr (expr_p, pre_p);
14915 break;
14917 case EXIT_EXPR:
14918 ret = gimplify_exit_expr (expr_p);
14919 break;
14921 case GOTO_EXPR:
14922 /* If the target is not LABEL, then it is a computed jump
14923 and the target needs to be gimplified. */
14924 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
14926 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
14927 NULL, is_gimple_val, fb_rvalue);
14928 if (ret == GS_ERROR)
14929 break;
14931 gimplify_seq_add_stmt (pre_p,
14932 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
14933 ret = GS_ALL_DONE;
14934 break;
14936 case PREDICT_EXPR:
14937 gimplify_seq_add_stmt (pre_p,
14938 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
14939 PREDICT_EXPR_OUTCOME (*expr_p)));
14940 ret = GS_ALL_DONE;
14941 break;
14943 case LABEL_EXPR:
14944 ret = gimplify_label_expr (expr_p, pre_p);
14945 label = LABEL_EXPR_LABEL (*expr_p);
14946 gcc_assert (decl_function_context (label) == current_function_decl);
14948 /* If the label is used in a goto statement, or address of the label
14949 is taken, we need to unpoison all variables that were seen so far.
14950 Doing so would prevent us from reporting a false positives. */
14951 if (asan_poisoned_variables
14952 && asan_used_labels != NULL
14953 && asan_used_labels->contains (label)
14954 && !gimplify_omp_ctxp)
14955 asan_poison_variables (asan_poisoned_variables, false, pre_p);
14956 break;
14958 case CASE_LABEL_EXPR:
14959 ret = gimplify_case_label_expr (expr_p, pre_p);
14961 if (gimplify_ctxp->live_switch_vars)
14962 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
14963 pre_p);
14964 break;
14966 case RETURN_EXPR:
14967 ret = gimplify_return_expr (*expr_p, pre_p);
14968 break;
14970 case CONSTRUCTOR:
14971 /* Don't reduce this in place; let gimplify_init_constructor work its
14972 magic. Buf if we're just elaborating this for side effects, just
14973 gimplify any element that has side-effects. */
14974 if (fallback == fb_none)
14976 unsigned HOST_WIDE_INT ix;
14977 tree val;
14978 tree temp = NULL_TREE;
14979 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
14980 if (TREE_SIDE_EFFECTS (val))
14981 append_to_statement_list (val, &temp);
14983 *expr_p = temp;
14984 ret = temp ? GS_OK : GS_ALL_DONE;
14986 /* C99 code may assign to an array in a constructed
14987 structure or union, and this has undefined behavior only
14988 on execution, so create a temporary if an lvalue is
14989 required. */
14990 else if (fallback == fb_lvalue)
14992 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14993 mark_addressable (*expr_p);
14994 ret = GS_OK;
14996 else
14997 ret = GS_ALL_DONE;
14998 break;
15000 /* The following are special cases that are not handled by the
15001 original GIMPLE grammar. */
15003 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
15004 eliminated. */
15005 case SAVE_EXPR:
15006 ret = gimplify_save_expr (expr_p, pre_p, post_p);
15007 break;
15009 case BIT_FIELD_REF:
15010 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15011 post_p, is_gimple_lvalue, fb_either);
15012 recalculate_side_effects (*expr_p);
15013 break;
15015 case TARGET_MEM_REF:
15017 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
15019 if (TMR_BASE (*expr_p))
15020 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
15021 post_p, is_gimple_mem_ref_addr, fb_either);
15022 if (TMR_INDEX (*expr_p))
15023 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
15024 post_p, is_gimple_val, fb_rvalue);
15025 if (TMR_INDEX2 (*expr_p))
15026 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
15027 post_p, is_gimple_val, fb_rvalue);
15028 /* TMR_STEP and TMR_OFFSET are always integer constants. */
15029 ret = MIN (r0, r1);
15031 break;
15033 case NON_LVALUE_EXPR:
15034 /* This should have been stripped above. */
15035 gcc_unreachable ();
15037 case ASM_EXPR:
15038 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
15039 break;
15041 case TRY_FINALLY_EXPR:
15042 case TRY_CATCH_EXPR:
15044 gimple_seq eval, cleanup;
15045 gtry *try_;
15047 /* Calls to destructors are generated automatically in FINALLY/CATCH
15048 block. They should have location as UNKNOWN_LOCATION. However,
15049 gimplify_call_expr will reset these call stmts to input_location
15050 if it finds stmt's location is unknown. To prevent resetting for
15051 destructors, we set the input_location to unknown.
15052 Note that this only affects the destructor calls in FINALLY/CATCH
15053 block, and will automatically reset to its original value by the
15054 end of gimplify_expr. */
15055 input_location = UNKNOWN_LOCATION;
15056 eval = cleanup = NULL;
15057 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
15058 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15059 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
15061 gimple_seq n = NULL, e = NULL;
15062 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15063 0), &n);
15064 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15065 1), &e);
15066 if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
15068 geh_else *stmt = gimple_build_eh_else (n, e);
15069 gimple_seq_add_stmt (&cleanup, stmt);
15072 else
15073 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
15074 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
15075 if (gimple_seq_empty_p (cleanup))
15077 gimple_seq_add_seq (pre_p, eval);
15078 ret = GS_ALL_DONE;
15079 break;
15081 try_ = gimple_build_try (eval, cleanup,
15082 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15083 ? GIMPLE_TRY_FINALLY
15084 : GIMPLE_TRY_CATCH);
15085 if (EXPR_HAS_LOCATION (save_expr))
15086 gimple_set_location (try_, EXPR_LOCATION (save_expr));
15087 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
15088 gimple_set_location (try_, saved_location);
15089 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
15090 gimple_try_set_catch_is_cleanup (try_,
15091 TRY_CATCH_IS_CLEANUP (*expr_p));
15092 gimplify_seq_add_stmt (pre_p, try_);
15093 ret = GS_ALL_DONE;
15094 break;
15097 case CLEANUP_POINT_EXPR:
15098 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
15099 break;
15101 case TARGET_EXPR:
15102 ret = gimplify_target_expr (expr_p, pre_p, post_p);
15103 break;
15105 case CATCH_EXPR:
15107 gimple *c;
15108 gimple_seq handler = NULL;
15109 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
15110 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
15111 gimplify_seq_add_stmt (pre_p, c);
15112 ret = GS_ALL_DONE;
15113 break;
15116 case EH_FILTER_EXPR:
15118 gimple *ehf;
15119 gimple_seq failure = NULL;
15121 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
15122 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
15123 copy_warning (ehf, *expr_p);
15124 gimplify_seq_add_stmt (pre_p, ehf);
15125 ret = GS_ALL_DONE;
15126 break;
15129 case OBJ_TYPE_REF:
15131 enum gimplify_status r0, r1;
15132 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
15133 post_p, is_gimple_val, fb_rvalue);
15134 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
15135 post_p, is_gimple_val, fb_rvalue);
15136 TREE_SIDE_EFFECTS (*expr_p) = 0;
15137 ret = MIN (r0, r1);
15139 break;
15141 case LABEL_DECL:
15142 /* We get here when taking the address of a label. We mark
15143 the label as "forced"; meaning it can never be removed and
15144 it is a potential target for any computed goto. */
15145 FORCED_LABEL (*expr_p) = 1;
15146 ret = GS_ALL_DONE;
15147 break;
15149 case STATEMENT_LIST:
15150 ret = gimplify_statement_list (expr_p, pre_p);
15151 break;
15153 case WITH_SIZE_EXPR:
15155 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15156 post_p == &internal_post ? NULL : post_p,
15157 gimple_test_f, fallback);
15158 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15159 is_gimple_val, fb_rvalue);
15160 ret = GS_ALL_DONE;
15162 break;
15164 case VAR_DECL:
15165 case PARM_DECL:
15166 ret = gimplify_var_or_parm_decl (expr_p);
15167 break;
15169 case RESULT_DECL:
15170 /* When within an OMP context, notice uses of variables. */
15171 if (gimplify_omp_ctxp)
15172 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
15173 ret = GS_ALL_DONE;
15174 break;
15176 case DEBUG_EXPR_DECL:
15177 gcc_unreachable ();
15179 case DEBUG_BEGIN_STMT:
15180 gimplify_seq_add_stmt (pre_p,
15181 gimple_build_debug_begin_stmt
15182 (TREE_BLOCK (*expr_p),
15183 EXPR_LOCATION (*expr_p)));
15184 ret = GS_ALL_DONE;
15185 *expr_p = NULL;
15186 break;
15188 case SSA_NAME:
15189 /* Allow callbacks into the gimplifier during optimization. */
15190 ret = GS_ALL_DONE;
15191 break;
15193 case OMP_PARALLEL:
15194 gimplify_omp_parallel (expr_p, pre_p);
15195 ret = GS_ALL_DONE;
15196 break;
15198 case OMP_TASK:
15199 gimplify_omp_task (expr_p, pre_p);
15200 ret = GS_ALL_DONE;
15201 break;
15203 case OMP_FOR:
15204 case OMP_SIMD:
15205 case OMP_DISTRIBUTE:
15206 case OMP_TASKLOOP:
15207 case OACC_LOOP:
15208 ret = gimplify_omp_for (expr_p, pre_p);
15209 break;
15211 case OMP_LOOP:
15212 ret = gimplify_omp_loop (expr_p, pre_p);
15213 break;
15215 case OACC_CACHE:
15216 gimplify_oacc_cache (expr_p, pre_p);
15217 ret = GS_ALL_DONE;
15218 break;
15220 case OACC_DECLARE:
15221 gimplify_oacc_declare (expr_p, pre_p);
15222 ret = GS_ALL_DONE;
15223 break;
15225 case OACC_HOST_DATA:
15226 case OACC_DATA:
15227 case OACC_KERNELS:
15228 case OACC_PARALLEL:
15229 case OACC_SERIAL:
15230 case OMP_SCOPE:
15231 case OMP_SECTIONS:
15232 case OMP_SINGLE:
15233 case OMP_TARGET:
15234 case OMP_TARGET_DATA:
15235 case OMP_TEAMS:
15236 gimplify_omp_workshare (expr_p, pre_p);
15237 ret = GS_ALL_DONE;
15238 break;
15240 case OACC_ENTER_DATA:
15241 case OACC_EXIT_DATA:
15242 case OACC_UPDATE:
15243 case OMP_TARGET_UPDATE:
15244 case OMP_TARGET_ENTER_DATA:
15245 case OMP_TARGET_EXIT_DATA:
15246 gimplify_omp_target_update (expr_p, pre_p);
15247 ret = GS_ALL_DONE;
15248 break;
15250 case OMP_SECTION:
15251 case OMP_MASTER:
15252 case OMP_MASKED:
15253 case OMP_ORDERED:
15254 case OMP_CRITICAL:
15255 case OMP_SCAN:
15257 gimple_seq body = NULL;
15258 gimple *g;
15259 bool saved_in_omp_construct = in_omp_construct;
15261 in_omp_construct = true;
15262 gimplify_and_add (OMP_BODY (*expr_p), &body);
15263 in_omp_construct = saved_in_omp_construct;
15264 switch (TREE_CODE (*expr_p))
15266 case OMP_SECTION:
15267 g = gimple_build_omp_section (body);
15268 break;
15269 case OMP_MASTER:
15270 g = gimple_build_omp_master (body);
15271 break;
15272 case OMP_ORDERED:
15273 g = gimplify_omp_ordered (*expr_p, body);
15274 break;
15275 case OMP_MASKED:
15276 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p),
15277 pre_p, ORT_WORKSHARE, OMP_MASKED);
15278 gimplify_adjust_omp_clauses (pre_p, body,
15279 &OMP_MASKED_CLAUSES (*expr_p),
15280 OMP_MASKED);
15281 g = gimple_build_omp_masked (body,
15282 OMP_MASKED_CLAUSES (*expr_p));
15283 break;
15284 case OMP_CRITICAL:
15285 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
15286 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
15287 gimplify_adjust_omp_clauses (pre_p, body,
15288 &OMP_CRITICAL_CLAUSES (*expr_p),
15289 OMP_CRITICAL);
15290 g = gimple_build_omp_critical (body,
15291 OMP_CRITICAL_NAME (*expr_p),
15292 OMP_CRITICAL_CLAUSES (*expr_p));
15293 break;
15294 case OMP_SCAN:
15295 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
15296 pre_p, ORT_WORKSHARE, OMP_SCAN);
15297 gimplify_adjust_omp_clauses (pre_p, body,
15298 &OMP_SCAN_CLAUSES (*expr_p),
15299 OMP_SCAN);
15300 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
15301 break;
15302 default:
15303 gcc_unreachable ();
15305 gimplify_seq_add_stmt (pre_p, g);
15306 ret = GS_ALL_DONE;
15307 break;
15310 case OMP_TASKGROUP:
15312 gimple_seq body = NULL;
15314 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
15315 bool saved_in_omp_construct = in_omp_construct;
15316 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
15317 OMP_TASKGROUP);
15318 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
15320 in_omp_construct = true;
15321 gimplify_and_add (OMP_BODY (*expr_p), &body);
15322 in_omp_construct = saved_in_omp_construct;
15323 gimple_seq cleanup = NULL;
15324 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
15325 gimple *g = gimple_build_call (fn, 0);
15326 gimple_seq_add_stmt (&cleanup, g);
15327 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
15328 body = NULL;
15329 gimple_seq_add_stmt (&body, g);
15330 g = gimple_build_omp_taskgroup (body, *pclauses);
15331 gimplify_seq_add_stmt (pre_p, g);
15332 ret = GS_ALL_DONE;
15333 break;
15336 case OMP_ATOMIC:
15337 case OMP_ATOMIC_READ:
15338 case OMP_ATOMIC_CAPTURE_OLD:
15339 case OMP_ATOMIC_CAPTURE_NEW:
15340 ret = gimplify_omp_atomic (expr_p, pre_p);
15341 break;
15343 case TRANSACTION_EXPR:
15344 ret = gimplify_transaction (expr_p, pre_p);
15345 break;
15347 case TRUTH_AND_EXPR:
15348 case TRUTH_OR_EXPR:
15349 case TRUTH_XOR_EXPR:
15351 tree orig_type = TREE_TYPE (*expr_p);
15352 tree new_type, xop0, xop1;
15353 *expr_p = gimple_boolify (*expr_p);
15354 new_type = TREE_TYPE (*expr_p);
15355 if (!useless_type_conversion_p (orig_type, new_type))
15357 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
15358 ret = GS_OK;
15359 break;
15362 /* Boolified binary truth expressions are semantically equivalent
15363 to bitwise binary expressions. Canonicalize them to the
15364 bitwise variant. */
15365 switch (TREE_CODE (*expr_p))
15367 case TRUTH_AND_EXPR:
15368 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
15369 break;
15370 case TRUTH_OR_EXPR:
15371 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
15372 break;
15373 case TRUTH_XOR_EXPR:
15374 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
15375 break;
15376 default:
15377 break;
15379 /* Now make sure that operands have compatible type to
15380 expression's new_type. */
15381 xop0 = TREE_OPERAND (*expr_p, 0);
15382 xop1 = TREE_OPERAND (*expr_p, 1);
15383 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
15384 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
15385 new_type,
15386 xop0);
15387 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
15388 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
15389 new_type,
15390 xop1);
15391 /* Continue classified as tcc_binary. */
15392 goto expr_2;
15395 case VEC_COND_EXPR:
15396 goto expr_3;
15398 case VEC_PERM_EXPR:
15399 /* Classified as tcc_expression. */
15400 goto expr_3;
15402 case BIT_INSERT_EXPR:
15403 /* Argument 3 is a constant. */
15404 goto expr_2;
15406 case POINTER_PLUS_EXPR:
15408 enum gimplify_status r0, r1;
15409 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15410 post_p, is_gimple_val, fb_rvalue);
15411 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15412 post_p, is_gimple_val, fb_rvalue);
15413 recalculate_side_effects (*expr_p);
15414 ret = MIN (r0, r1);
15415 break;
15418 default:
15419 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
15421 case tcc_comparison:
15422 /* Handle comparison of objects of non scalar mode aggregates
15423 with a call to memcmp. It would be nice to only have to do
15424 this for variable-sized objects, but then we'd have to allow
15425 the same nest of reference nodes we allow for MODIFY_EXPR and
15426 that's too complex.
15428 Compare scalar mode aggregates as scalar mode values. Using
15429 memcmp for them would be very inefficient at best, and is
15430 plain wrong if bitfields are involved. */
15432 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
15434 /* Vector comparisons need no boolification. */
15435 if (TREE_CODE (type) == VECTOR_TYPE)
15436 goto expr_2;
15437 else if (!AGGREGATE_TYPE_P (type))
15439 tree org_type = TREE_TYPE (*expr_p);
15440 *expr_p = gimple_boolify (*expr_p);
15441 if (!useless_type_conversion_p (org_type,
15442 TREE_TYPE (*expr_p)))
15444 *expr_p = fold_convert_loc (input_location,
15445 org_type, *expr_p);
15446 ret = GS_OK;
15448 else
15449 goto expr_2;
15451 else if (TYPE_MODE (type) != BLKmode)
15452 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
15453 else
15454 ret = gimplify_variable_sized_compare (expr_p);
15456 break;
15459 /* If *EXPR_P does not need to be special-cased, handle it
15460 according to its class. */
15461 case tcc_unary:
15462 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15463 post_p, is_gimple_val, fb_rvalue);
15464 break;
15466 case tcc_binary:
15467 expr_2:
15469 enum gimplify_status r0, r1;
15471 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15472 post_p, is_gimple_val, fb_rvalue);
15473 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15474 post_p, is_gimple_val, fb_rvalue);
15476 ret = MIN (r0, r1);
15477 break;
15480 expr_3:
15482 enum gimplify_status r0, r1, r2;
15484 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15485 post_p, is_gimple_val, fb_rvalue);
15486 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15487 post_p, is_gimple_val, fb_rvalue);
15488 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
15489 post_p, is_gimple_val, fb_rvalue);
15491 ret = MIN (MIN (r0, r1), r2);
15492 break;
15495 case tcc_declaration:
15496 case tcc_constant:
15497 ret = GS_ALL_DONE;
15498 goto dont_recalculate;
15500 default:
15501 gcc_unreachable ();
15504 recalculate_side_effects (*expr_p);
15506 dont_recalculate:
15507 break;
15510 gcc_assert (*expr_p || ret != GS_OK);
15512 while (ret == GS_OK);
15514 /* If we encountered an error_mark somewhere nested inside, either
15515 stub out the statement or propagate the error back out. */
15516 if (ret == GS_ERROR)
15518 if (is_statement)
15519 *expr_p = NULL;
15520 goto out;
15523 /* This was only valid as a return value from the langhook, which
15524 we handled. Make sure it doesn't escape from any other context. */
15525 gcc_assert (ret != GS_UNHANDLED);
15527 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
15529 /* We aren't looking for a value, and we don't have a valid
15530 statement. If it doesn't have side-effects, throw it away.
15531 We can also get here with code such as "*&&L;", where L is
15532 a LABEL_DECL that is marked as FORCED_LABEL. */
15533 if (TREE_CODE (*expr_p) == LABEL_DECL
15534 || !TREE_SIDE_EFFECTS (*expr_p))
15535 *expr_p = NULL;
15536 else if (!TREE_THIS_VOLATILE (*expr_p))
15538 /* This is probably a _REF that contains something nested that
15539 has side effects. Recurse through the operands to find it. */
15540 enum tree_code code = TREE_CODE (*expr_p);
15542 switch (code)
15544 case COMPONENT_REF:
15545 case REALPART_EXPR:
15546 case IMAGPART_EXPR:
15547 case VIEW_CONVERT_EXPR:
15548 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15549 gimple_test_f, fallback);
15550 break;
15552 case ARRAY_REF:
15553 case ARRAY_RANGE_REF:
15554 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15555 gimple_test_f, fallback);
15556 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15557 gimple_test_f, fallback);
15558 break;
15560 default:
15561 /* Anything else with side-effects must be converted to
15562 a valid statement before we get here. */
15563 gcc_unreachable ();
15566 *expr_p = NULL;
15568 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
15569 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode
15570 && !is_empty_type (TREE_TYPE (*expr_p)))
15572 /* Historically, the compiler has treated a bare reference
15573 to a non-BLKmode volatile lvalue as forcing a load. */
15574 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
15576 /* Normally, we do not want to create a temporary for a
15577 TREE_ADDRESSABLE type because such a type should not be
15578 copied by bitwise-assignment. However, we make an
15579 exception here, as all we are doing here is ensuring that
15580 we read the bytes that make up the type. We use
15581 create_tmp_var_raw because create_tmp_var will abort when
15582 given a TREE_ADDRESSABLE type. */
15583 tree tmp = create_tmp_var_raw (type, "vol");
15584 gimple_add_tmp_var (tmp);
15585 gimplify_assign (tmp, *expr_p, pre_p);
15586 *expr_p = NULL;
15588 else
15589 /* We can't do anything useful with a volatile reference to
15590 an incomplete type, so just throw it away. Likewise for
15591 a BLKmode type, since any implicit inner load should
15592 already have been turned into an explicit one by the
15593 gimplification process. */
15594 *expr_p = NULL;
15597 /* If we are gimplifying at the statement level, we're done. Tack
15598 everything together and return. */
15599 if (fallback == fb_none || is_statement)
15601 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
15602 it out for GC to reclaim it. */
15603 *expr_p = NULL_TREE;
15605 if (!gimple_seq_empty_p (internal_pre)
15606 || !gimple_seq_empty_p (internal_post))
15608 gimplify_seq_add_seq (&internal_pre, internal_post);
15609 gimplify_seq_add_seq (pre_p, internal_pre);
15612 /* The result of gimplifying *EXPR_P is going to be the last few
15613 statements in *PRE_P and *POST_P. Add location information
15614 to all the statements that were added by the gimplification
15615 helpers. */
15616 if (!gimple_seq_empty_p (*pre_p))
15617 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
15619 if (!gimple_seq_empty_p (*post_p))
15620 annotate_all_with_location_after (*post_p, post_last_gsi,
15621 input_location);
15623 goto out;
15626 #ifdef ENABLE_GIMPLE_CHECKING
15627 if (*expr_p)
15629 enum tree_code code = TREE_CODE (*expr_p);
15630 /* These expressions should already be in gimple IR form. */
15631 gcc_assert (code != MODIFY_EXPR
15632 && code != ASM_EXPR
15633 && code != BIND_EXPR
15634 && code != CATCH_EXPR
15635 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
15636 && code != EH_FILTER_EXPR
15637 && code != GOTO_EXPR
15638 && code != LABEL_EXPR
15639 && code != LOOP_EXPR
15640 && code != SWITCH_EXPR
15641 && code != TRY_FINALLY_EXPR
15642 && code != EH_ELSE_EXPR
15643 && code != OACC_PARALLEL
15644 && code != OACC_KERNELS
15645 && code != OACC_SERIAL
15646 && code != OACC_DATA
15647 && code != OACC_HOST_DATA
15648 && code != OACC_DECLARE
15649 && code != OACC_UPDATE
15650 && code != OACC_ENTER_DATA
15651 && code != OACC_EXIT_DATA
15652 && code != OACC_CACHE
15653 && code != OMP_CRITICAL
15654 && code != OMP_FOR
15655 && code != OACC_LOOP
15656 && code != OMP_MASTER
15657 && code != OMP_MASKED
15658 && code != OMP_TASKGROUP
15659 && code != OMP_ORDERED
15660 && code != OMP_PARALLEL
15661 && code != OMP_SCAN
15662 && code != OMP_SECTIONS
15663 && code != OMP_SECTION
15664 && code != OMP_SINGLE
15665 && code != OMP_SCOPE);
15667 #endif
15669 /* Otherwise we're gimplifying a subexpression, so the resulting
15670 value is interesting. If it's a valid operand that matches
15671 GIMPLE_TEST_F, we're done. Unless we are handling some
15672 post-effects internally; if that's the case, we need to copy into
15673 a temporary before adding the post-effects to POST_P. */
15674 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
15675 goto out;
15677 /* Otherwise, we need to create a new temporary for the gimplified
15678 expression. */
15680 /* We can't return an lvalue if we have an internal postqueue. The
15681 object the lvalue refers to would (probably) be modified by the
15682 postqueue; we need to copy the value out first, which means an
15683 rvalue. */
15684 if ((fallback & fb_lvalue)
15685 && gimple_seq_empty_p (internal_post)
15686 && is_gimple_addressable (*expr_p))
15688 /* An lvalue will do. Take the address of the expression, store it
15689 in a temporary, and replace the expression with an INDIRECT_REF of
15690 that temporary. */
15691 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
15692 unsigned int ref_align = get_object_alignment (*expr_p);
15693 tree ref_type = TREE_TYPE (*expr_p);
15694 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
15695 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
15696 if (TYPE_ALIGN (ref_type) != ref_align)
15697 ref_type = build_aligned_type (ref_type, ref_align);
15698 *expr_p = build2 (MEM_REF, ref_type,
15699 tmp, build_zero_cst (ref_alias_type));
15701 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
15703 /* An rvalue will do. Assign the gimplified expression into a
15704 new temporary TMP and replace the original expression with
15705 TMP. First, make sure that the expression has a type so that
15706 it can be assigned into a temporary. */
15707 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
15708 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
15710 else
15712 #ifdef ENABLE_GIMPLE_CHECKING
15713 if (!(fallback & fb_mayfail))
15715 fprintf (stderr, "gimplification failed:\n");
15716 print_generic_expr (stderr, *expr_p);
15717 debug_tree (*expr_p);
15718 internal_error ("gimplification failed");
15720 #endif
15721 gcc_assert (fallback & fb_mayfail);
15723 /* If this is an asm statement, and the user asked for the
15724 impossible, don't die. Fail and let gimplify_asm_expr
15725 issue an error. */
15726 ret = GS_ERROR;
15727 goto out;
15730 /* Make sure the temporary matches our predicate. */
15731 gcc_assert ((*gimple_test_f) (*expr_p));
15733 if (!gimple_seq_empty_p (internal_post))
15735 annotate_all_with_location (internal_post, input_location);
15736 gimplify_seq_add_seq (pre_p, internal_post);
15739 out:
15740 input_location = saved_location;
15741 return ret;
15744 /* Like gimplify_expr but make sure the gimplified result is not itself
15745 a SSA name (but a decl if it were). Temporaries required by
15746 evaluating *EXPR_P may be still SSA names. */
15748 static enum gimplify_status
15749 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
15750 bool (*gimple_test_f) (tree), fallback_t fallback,
15751 bool allow_ssa)
15753 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
15754 gimple_test_f, fallback);
15755 if (! allow_ssa
15756 && TREE_CODE (*expr_p) == SSA_NAME)
15757 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
15758 return ret;
15761 /* Look through TYPE for variable-sized objects and gimplify each such
15762 size that we find. Add to LIST_P any statements generated. */
15764 void
15765 gimplify_type_sizes (tree type, gimple_seq *list_p)
15767 if (type == NULL || type == error_mark_node)
15768 return;
15770 const bool ignored_p
15771 = TYPE_NAME (type)
15772 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
15773 && DECL_IGNORED_P (TYPE_NAME (type));
15774 tree t;
15776 /* We first do the main variant, then copy into any other variants. */
15777 type = TYPE_MAIN_VARIANT (type);
15779 /* Avoid infinite recursion. */
15780 if (TYPE_SIZES_GIMPLIFIED (type))
15781 return;
15783 TYPE_SIZES_GIMPLIFIED (type) = 1;
15785 switch (TREE_CODE (type))
15787 case INTEGER_TYPE:
15788 case ENUMERAL_TYPE:
15789 case BOOLEAN_TYPE:
15790 case REAL_TYPE:
15791 case FIXED_POINT_TYPE:
15792 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
15793 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
15795 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
15797 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
15798 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
15800 break;
15802 case ARRAY_TYPE:
15803 /* These types may not have declarations, so handle them here. */
15804 gimplify_type_sizes (TREE_TYPE (type), list_p);
15805 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
15806 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
15807 with assigned stack slots, for -O1+ -g they should be tracked
15808 by VTA. */
15809 if (!ignored_p
15810 && TYPE_DOMAIN (type)
15811 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
15813 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
15814 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
15815 DECL_IGNORED_P (t) = 0;
15816 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
15817 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
15818 DECL_IGNORED_P (t) = 0;
15820 break;
15822 case RECORD_TYPE:
15823 case UNION_TYPE:
15824 case QUAL_UNION_TYPE:
15825 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
15826 if (TREE_CODE (field) == FIELD_DECL)
15828 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
15829 /* Likewise, ensure variable offsets aren't removed. */
15830 if (!ignored_p
15831 && (t = DECL_FIELD_OFFSET (field))
15832 && VAR_P (t)
15833 && DECL_ARTIFICIAL (t))
15834 DECL_IGNORED_P (t) = 0;
15835 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
15836 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
15837 gimplify_type_sizes (TREE_TYPE (field), list_p);
15839 break;
15841 case POINTER_TYPE:
15842 case REFERENCE_TYPE:
15843 /* We used to recurse on the pointed-to type here, which turned out to
15844 be incorrect because its definition might refer to variables not
15845 yet initialized at this point if a forward declaration is involved.
15847 It was actually useful for anonymous pointed-to types to ensure
15848 that the sizes evaluation dominates every possible later use of the
15849 values. Restricting to such types here would be safe since there
15850 is no possible forward declaration around, but would introduce an
15851 undesirable middle-end semantic to anonymity. We then defer to
15852 front-ends the responsibility of ensuring that the sizes are
15853 evaluated both early and late enough, e.g. by attaching artificial
15854 type declarations to the tree. */
15855 break;
15857 default:
15858 break;
15861 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
15862 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
15864 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
15866 TYPE_SIZE (t) = TYPE_SIZE (type);
15867 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
15868 TYPE_SIZES_GIMPLIFIED (t) = 1;
15872 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
15873 a size or position, has had all of its SAVE_EXPRs evaluated.
15874 We add any required statements to *STMT_P. */
15876 void
15877 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
15879 tree expr = *expr_p;
15881 /* We don't do anything if the value isn't there, is constant, or contains
15882 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
15883 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
15884 will want to replace it with a new variable, but that will cause problems
15885 if this type is from outside the function. It's OK to have that here. */
15886 if (expr == NULL_TREE
15887 || is_gimple_constant (expr)
15888 || TREE_CODE (expr) == VAR_DECL
15889 || CONTAINS_PLACEHOLDER_P (expr))
15890 return;
15892 *expr_p = unshare_expr (expr);
15894 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
15895 if the def vanishes. */
15896 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
15898 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
15899 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
15900 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
15901 if (is_gimple_constant (*expr_p))
15902 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
15905 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
15906 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
15907 is true, also gimplify the parameters. */
15909 gbind *
15910 gimplify_body (tree fndecl, bool do_parms)
15912 location_t saved_location = input_location;
15913 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
15914 gimple *outer_stmt;
15915 gbind *outer_bind;
15917 timevar_push (TV_TREE_GIMPLIFY);
15919 init_tree_ssa (cfun);
15921 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
15922 gimplification. */
15923 default_rtl_profile ();
15925 gcc_assert (gimplify_ctxp == NULL);
15926 push_gimplify_context (true);
15928 if (flag_openacc || flag_openmp)
15930 gcc_assert (gimplify_omp_ctxp == NULL);
15931 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
15932 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
15935 /* Unshare most shared trees in the body and in that of any nested functions.
15936 It would seem we don't have to do this for nested functions because
15937 they are supposed to be output and then the outer function gimplified
15938 first, but the g++ front end doesn't always do it that way. */
15939 unshare_body (fndecl);
15940 unvisit_body (fndecl);
15942 /* Make sure input_location isn't set to something weird. */
15943 input_location = DECL_SOURCE_LOCATION (fndecl);
15945 /* Resolve callee-copies. This has to be done before processing
15946 the body so that DECL_VALUE_EXPR gets processed correctly. */
15947 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
15949 /* Gimplify the function's body. */
15950 seq = NULL;
15951 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
15952 outer_stmt = gimple_seq_first_nondebug_stmt (seq);
15953 if (!outer_stmt)
15955 outer_stmt = gimple_build_nop ();
15956 gimplify_seq_add_stmt (&seq, outer_stmt);
15959 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
15960 not the case, wrap everything in a GIMPLE_BIND to make it so. */
15961 if (gimple_code (outer_stmt) == GIMPLE_BIND
15962 && (gimple_seq_first_nondebug_stmt (seq)
15963 == gimple_seq_last_nondebug_stmt (seq)))
15965 outer_bind = as_a <gbind *> (outer_stmt);
15966 if (gimple_seq_first_stmt (seq) != outer_stmt
15967 || gimple_seq_last_stmt (seq) != outer_stmt)
15969 /* If there are debug stmts before or after outer_stmt, move them
15970 inside of outer_bind body. */
15971 gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
15972 gimple_seq second_seq = NULL;
15973 if (gimple_seq_first_stmt (seq) != outer_stmt
15974 && gimple_seq_last_stmt (seq) != outer_stmt)
15976 second_seq = gsi_split_seq_after (gsi);
15977 gsi_remove (&gsi, false);
15979 else if (gimple_seq_first_stmt (seq) != outer_stmt)
15980 gsi_remove (&gsi, false);
15981 else
15983 gsi_remove (&gsi, false);
15984 second_seq = seq;
15985 seq = NULL;
15987 gimple_seq_add_seq_without_update (&seq,
15988 gimple_bind_body (outer_bind));
15989 gimple_seq_add_seq_without_update (&seq, second_seq);
15990 gimple_bind_set_body (outer_bind, seq);
15993 else
15994 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
15996 DECL_SAVED_TREE (fndecl) = NULL_TREE;
15998 /* If we had callee-copies statements, insert them at the beginning
15999 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
16000 if (!gimple_seq_empty_p (parm_stmts))
16002 tree parm;
16004 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
16005 if (parm_cleanup)
16007 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
16008 GIMPLE_TRY_FINALLY);
16009 parm_stmts = NULL;
16010 gimple_seq_add_stmt (&parm_stmts, g);
16012 gimple_bind_set_body (outer_bind, parm_stmts);
16014 for (parm = DECL_ARGUMENTS (current_function_decl);
16015 parm; parm = DECL_CHAIN (parm))
16016 if (DECL_HAS_VALUE_EXPR_P (parm))
16018 DECL_HAS_VALUE_EXPR_P (parm) = 0;
16019 DECL_IGNORED_P (parm) = 0;
16023 if ((flag_openacc || flag_openmp || flag_openmp_simd)
16024 && gimplify_omp_ctxp)
16026 delete_omp_context (gimplify_omp_ctxp);
16027 gimplify_omp_ctxp = NULL;
16030 pop_gimplify_context (outer_bind);
16031 gcc_assert (gimplify_ctxp == NULL);
16033 if (flag_checking && !seen_error ())
16034 verify_gimple_in_seq (gimple_bind_body (outer_bind));
16036 timevar_pop (TV_TREE_GIMPLIFY);
16037 input_location = saved_location;
16039 return outer_bind;
16042 typedef char *char_p; /* For DEF_VEC_P. */
16044 /* Return whether we should exclude FNDECL from instrumentation. */
16046 static bool
16047 flag_instrument_functions_exclude_p (tree fndecl)
16049 vec<char_p> *v;
16051 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
16052 if (v && v->length () > 0)
16054 const char *name;
16055 int i;
16056 char *s;
16058 name = lang_hooks.decl_printable_name (fndecl, 1);
16059 FOR_EACH_VEC_ELT (*v, i, s)
16060 if (strstr (name, s) != NULL)
16061 return true;
16064 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
16065 if (v && v->length () > 0)
16067 const char *name;
16068 int i;
16069 char *s;
16071 name = DECL_SOURCE_FILE (fndecl);
16072 FOR_EACH_VEC_ELT (*v, i, s)
16073 if (strstr (name, s) != NULL)
16074 return true;
16077 return false;
16080 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
16081 node for the function we want to gimplify.
16083 Return the sequence of GIMPLE statements corresponding to the body
16084 of FNDECL. */
16086 void
16087 gimplify_function_tree (tree fndecl)
16089 gimple_seq seq;
16090 gbind *bind;
16092 gcc_assert (!gimple_body (fndecl));
16094 if (DECL_STRUCT_FUNCTION (fndecl))
16095 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
16096 else
16097 push_struct_function (fndecl);
16099 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
16100 if necessary. */
16101 cfun->curr_properties |= PROP_gimple_lva;
16103 if (asan_sanitize_use_after_scope ())
16104 asan_poisoned_variables = new hash_set<tree> ();
16105 bind = gimplify_body (fndecl, true);
16106 if (asan_poisoned_variables)
16108 delete asan_poisoned_variables;
16109 asan_poisoned_variables = NULL;
16112 /* The tree body of the function is no longer needed, replace it
16113 with the new GIMPLE body. */
16114 seq = NULL;
16115 gimple_seq_add_stmt (&seq, bind);
16116 gimple_set_body (fndecl, seq);
16118 /* If we're instrumenting function entry/exit, then prepend the call to
16119 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
16120 catch the exit hook. */
16121 /* ??? Add some way to ignore exceptions for this TFE. */
16122 if (flag_instrument_function_entry_exit
16123 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
16124 /* Do not instrument extern inline functions. */
16125 && !(DECL_DECLARED_INLINE_P (fndecl)
16126 && DECL_EXTERNAL (fndecl)
16127 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
16128 && !flag_instrument_functions_exclude_p (fndecl))
16130 tree x;
16131 gbind *new_bind;
16132 gimple *tf;
16133 gimple_seq cleanup = NULL, body = NULL;
16134 tree tmp_var, this_fn_addr;
16135 gcall *call;
16137 /* The instrumentation hooks aren't going to call the instrumented
16138 function and the address they receive is expected to be matchable
16139 against symbol addresses. Make sure we don't create a trampoline,
16140 in case the current function is nested. */
16141 this_fn_addr = build_fold_addr_expr (current_function_decl);
16142 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
16144 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
16145 call = gimple_build_call (x, 1, integer_zero_node);
16146 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
16147 gimple_call_set_lhs (call, tmp_var);
16148 gimplify_seq_add_stmt (&cleanup, call);
16149 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
16150 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
16151 gimplify_seq_add_stmt (&cleanup, call);
16152 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
16154 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
16155 call = gimple_build_call (x, 1, integer_zero_node);
16156 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
16157 gimple_call_set_lhs (call, tmp_var);
16158 gimplify_seq_add_stmt (&body, call);
16159 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
16160 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
16161 gimplify_seq_add_stmt (&body, call);
16162 gimplify_seq_add_stmt (&body, tf);
16163 new_bind = gimple_build_bind (NULL, body, NULL);
16165 /* Replace the current function body with the body
16166 wrapped in the try/finally TF. */
16167 seq = NULL;
16168 gimple_seq_add_stmt (&seq, new_bind);
16169 gimple_set_body (fndecl, seq);
16170 bind = new_bind;
16173 if (sanitize_flags_p (SANITIZE_THREAD)
16174 && param_tsan_instrument_func_entry_exit)
16176 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
16177 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
16178 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
16179 /* Replace the current function body with the body
16180 wrapped in the try/finally TF. */
16181 seq = NULL;
16182 gimple_seq_add_stmt (&seq, new_bind);
16183 gimple_set_body (fndecl, seq);
16186 DECL_SAVED_TREE (fndecl) = NULL_TREE;
16187 cfun->curr_properties |= PROP_gimple_any;
16189 pop_cfun ();
16191 dump_function (TDI_gimple, fndecl);
16194 /* Return a dummy expression of type TYPE in order to keep going after an
16195 error. */
16197 static tree
16198 dummy_object (tree type)
16200 tree t = build_int_cst (build_pointer_type (type), 0);
16201 return build2 (MEM_REF, type, t, t);
16204 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
16205 builtin function, but a very special sort of operator. */
16207 enum gimplify_status
16208 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
16209 gimple_seq *post_p ATTRIBUTE_UNUSED)
16211 tree promoted_type, have_va_type;
16212 tree valist = TREE_OPERAND (*expr_p, 0);
16213 tree type = TREE_TYPE (*expr_p);
16214 tree t, tag, aptag;
16215 location_t loc = EXPR_LOCATION (*expr_p);
16217 /* Verify that valist is of the proper type. */
16218 have_va_type = TREE_TYPE (valist);
16219 if (have_va_type == error_mark_node)
16220 return GS_ERROR;
16221 have_va_type = targetm.canonical_va_list_type (have_va_type);
16222 if (have_va_type == NULL_TREE
16223 && POINTER_TYPE_P (TREE_TYPE (valist)))
16224 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
16225 have_va_type
16226 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
16227 gcc_assert (have_va_type != NULL_TREE);
16229 /* Generate a diagnostic for requesting data of a type that cannot
16230 be passed through `...' due to type promotion at the call site. */
16231 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
16232 != type)
16234 static bool gave_help;
16235 bool warned;
16236 /* Use the expansion point to handle cases such as passing bool (defined
16237 in a system header) through `...'. */
16238 location_t xloc
16239 = expansion_point_location_if_in_system_header (loc);
16241 /* Unfortunately, this is merely undefined, rather than a constraint
16242 violation, so we cannot make this an error. If this call is never
16243 executed, the program is still strictly conforming. */
16244 auto_diagnostic_group d;
16245 warned = warning_at (xloc, 0,
16246 "%qT is promoted to %qT when passed through %<...%>",
16247 type, promoted_type);
16248 if (!gave_help && warned)
16250 gave_help = true;
16251 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
16252 promoted_type, type);
16255 /* We can, however, treat "undefined" any way we please.
16256 Call abort to encourage the user to fix the program. */
16257 if (warned)
16258 inform (xloc, "if this code is reached, the program will abort");
16259 /* Before the abort, allow the evaluation of the va_list
16260 expression to exit or longjmp. */
16261 gimplify_and_add (valist, pre_p);
16262 t = build_call_expr_loc (loc,
16263 builtin_decl_implicit (BUILT_IN_TRAP), 0);
16264 gimplify_and_add (t, pre_p);
16266 /* This is dead code, but go ahead and finish so that the
16267 mode of the result comes out right. */
16268 *expr_p = dummy_object (type);
16269 return GS_ALL_DONE;
16272 tag = build_int_cst (build_pointer_type (type), 0);
16273 aptag = build_int_cst (TREE_TYPE (valist), 0);
16275 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
16276 valist, tag, aptag);
16278 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
16279 needs to be expanded. */
16280 cfun->curr_properties &= ~PROP_gimple_lva;
16282 return GS_OK;
16285 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
16287 DST/SRC are the destination and source respectively. You can pass
16288 ungimplified trees in DST or SRC, in which case they will be
16289 converted to a gimple operand if necessary.
16291 This function returns the newly created GIMPLE_ASSIGN tuple. */
16293 gimple *
16294 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
16296 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
16297 gimplify_and_add (t, seq_p);
16298 ggc_free (t);
16299 return gimple_seq_last_stmt (*seq_p);
16302 inline hashval_t
16303 gimplify_hasher::hash (const elt_t *p)
16305 tree t = p->val;
16306 return iterative_hash_expr (t, 0);
16309 inline bool
16310 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
16312 tree t1 = p1->val;
16313 tree t2 = p2->val;
16314 enum tree_code code = TREE_CODE (t1);
16316 if (TREE_CODE (t2) != code
16317 || TREE_TYPE (t1) != TREE_TYPE (t2))
16318 return false;
16320 if (!operand_equal_p (t1, t2, 0))
16321 return false;
16323 /* Only allow them to compare equal if they also hash equal; otherwise
16324 results are nondeterminate, and we fail bootstrap comparison. */
16325 gcc_checking_assert (hash (p1) == hash (p2));
16327 return true;