Daily bump.
[official-gcc.git] / gcc / gimplify.c
blob326476f02388016d835c284c15c19bebdec83b92
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 && !OPAQUE_TYPE_P (TREE_TYPE (decl))
1833 && !is_empty_type (TREE_TYPE (decl)))
1834 return true;
1835 return false;
1838 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1839 and initialization explicit. */
1841 static enum gimplify_status
1842 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1844 tree stmt = *stmt_p;
1845 tree decl = DECL_EXPR_DECL (stmt);
1847 *stmt_p = NULL_TREE;
1849 if (TREE_TYPE (decl) == error_mark_node)
1850 return GS_ERROR;
1852 if ((TREE_CODE (decl) == TYPE_DECL
1853 || VAR_P (decl))
1854 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1856 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1857 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1858 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1861 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1862 in case its size expressions contain problematic nodes like CALL_EXPR. */
1863 if (TREE_CODE (decl) == TYPE_DECL
1864 && DECL_ORIGINAL_TYPE (decl)
1865 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1867 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1868 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1869 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1872 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1874 tree init = DECL_INITIAL (decl);
1875 bool is_vla = false;
1876 /* Check whether a decl has FE created VALUE_EXPR here BEFORE
1877 gimplify_vla_decl creates VALUE_EXPR for a vla decl.
1878 If the decl has VALUE_EXPR that was created by FE (usually
1879 C++FE), it's a proxy varaible, and FE already initialized
1880 the VALUE_EXPR of it, we should not initialize it anymore. */
1881 bool decl_had_value_expr_p = DECL_HAS_VALUE_EXPR_P (decl);
1883 poly_uint64 size;
1884 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
1885 || (!TREE_STATIC (decl)
1886 && flag_stack_check == GENERIC_STACK_CHECK
1887 && maybe_gt (size,
1888 (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
1890 gimplify_vla_decl (decl, seq_p);
1891 is_vla = true;
1894 if (asan_poisoned_variables
1895 && !is_vla
1896 && TREE_ADDRESSABLE (decl)
1897 && !TREE_STATIC (decl)
1898 && !DECL_HAS_VALUE_EXPR_P (decl)
1899 && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
1900 && dbg_cnt (asan_use_after_scope)
1901 && !gimplify_omp_ctxp
1902 /* GNAT introduces temporaries to hold return values of calls in
1903 initializers of variables defined in other units, so the
1904 declaration of the variable is discarded completely. We do not
1905 want to issue poison calls for such dropped variables. */
1906 && (DECL_SEEN_IN_BIND_EXPR_P (decl)
1907 || (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)))
1909 asan_poisoned_variables->add (decl);
1910 asan_poison_variable (decl, false, seq_p);
1911 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
1912 gimplify_ctxp->live_switch_vars->add (decl);
1915 /* Some front ends do not explicitly declare all anonymous
1916 artificial variables. We compensate here by declaring the
1917 variables, though it would be better if the front ends would
1918 explicitly declare them. */
1919 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1920 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1921 gimple_add_tmp_var (decl);
1923 if (init && init != error_mark_node)
1925 if (!TREE_STATIC (decl))
1927 DECL_INITIAL (decl) = NULL_TREE;
1928 init = build2 (INIT_EXPR, void_type_node, decl, init);
1929 gimplify_and_add (init, seq_p);
1930 ggc_free (init);
1931 /* Clear TREE_READONLY if we really have an initialization. */
1932 if (!DECL_INITIAL (decl)
1933 && !omp_privatize_by_reference (decl))
1934 TREE_READONLY (decl) = 0;
1936 else
1937 /* We must still examine initializers for static variables
1938 as they may contain a label address. */
1939 walk_tree (&init, force_labels_r, NULL, NULL);
1941 /* When there is no explicit initializer, if the user requested,
1942 We should insert an artifical initializer for this automatic
1943 variable. */
1944 else if (is_var_need_auto_init (decl)
1945 && !decl_had_value_expr_p)
1947 gimple_add_init_for_auto_var (decl,
1948 flag_auto_var_init,
1949 is_vla,
1950 seq_p);
1951 /* The expanding of a call to the above .DEFERRED_INIT will apply
1952 block initialization to the whole space covered by this variable.
1953 As a result, all the paddings will be initialized to zeroes
1954 for zero initialization and 0xFE byte-repeatable patterns for
1955 pattern initialization.
1956 In order to make the paddings as zeroes for pattern init, We
1957 should add a call to __builtin_clear_padding to clear the
1958 paddings to zero in compatiple with CLANG.
1959 We cannot insert this call if the variable is a gimple register
1960 since __builtin_clear_padding will take the address of the
1961 variable. As a result, if a long double/_Complex long double
1962 variable will spilled into stack later, its padding is 0XFE. */
1963 if (flag_auto_var_init == AUTO_INIT_PATTERN
1964 && !is_gimple_reg (decl)
1965 && clear_padding_type_may_have_padding_p (TREE_TYPE (decl)))
1966 gimple_add_padding_init_for_auto_var (decl, is_vla, seq_p);
1970 return GS_ALL_DONE;
1973 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1974 and replacing the LOOP_EXPR with goto, but if the loop contains an
1975 EXIT_EXPR, we need to append a label for it to jump to. */
1977 static enum gimplify_status
1978 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1980 tree saved_label = gimplify_ctxp->exit_label;
1981 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1983 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1985 gimplify_ctxp->exit_label = NULL_TREE;
1987 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1989 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
1991 if (gimplify_ctxp->exit_label)
1992 gimplify_seq_add_stmt (pre_p,
1993 gimple_build_label (gimplify_ctxp->exit_label));
1995 gimplify_ctxp->exit_label = saved_label;
1997 *expr_p = NULL;
1998 return GS_ALL_DONE;
2001 /* Gimplify a statement list onto a sequence. These may be created either
2002 by an enlightened front-end, or by shortcut_cond_expr. */
2004 static enum gimplify_status
2005 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
2007 tree temp = voidify_wrapper_expr (*expr_p, NULL);
2009 tree_stmt_iterator i = tsi_start (*expr_p);
2011 while (!tsi_end_p (i))
2013 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
2014 tsi_delink (&i);
2017 if (temp)
2019 *expr_p = temp;
2020 return GS_OK;
2023 return GS_ALL_DONE;
2026 /* Callback for walk_gimple_seq. */
2028 static tree
2029 warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2030 struct walk_stmt_info *wi)
2032 gimple *stmt = gsi_stmt (*gsi_p);
2034 *handled_ops_p = true;
2035 switch (gimple_code (stmt))
2037 case GIMPLE_TRY:
2038 /* A compiler-generated cleanup or a user-written try block.
2039 If it's empty, don't dive into it--that would result in
2040 worse location info. */
2041 if (gimple_try_eval (stmt) == NULL)
2043 wi->info = stmt;
2044 return integer_zero_node;
2046 /* Fall through. */
2047 case GIMPLE_BIND:
2048 case GIMPLE_CATCH:
2049 case GIMPLE_EH_FILTER:
2050 case GIMPLE_TRANSACTION:
2051 /* Walk the sub-statements. */
2052 *handled_ops_p = false;
2053 break;
2055 case GIMPLE_DEBUG:
2056 /* Ignore these. We may generate them before declarations that
2057 are never executed. If there's something to warn about,
2058 there will be non-debug stmts too, and we'll catch those. */
2059 break;
2061 case GIMPLE_CALL:
2062 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2064 *handled_ops_p = false;
2065 break;
2067 /* Fall through. */
2068 default:
2069 /* Save the first "real" statement (not a decl/lexical scope/...). */
2070 wi->info = stmt;
2071 return integer_zero_node;
2073 return NULL_TREE;
2076 /* Possibly warn about unreachable statements between switch's controlling
2077 expression and the first case. SEQ is the body of a switch expression. */
2079 static void
2080 maybe_warn_switch_unreachable (gimple_seq seq)
2082 if (!warn_switch_unreachable
2083 /* This warning doesn't play well with Fortran when optimizations
2084 are on. */
2085 || lang_GNU_Fortran ()
2086 || seq == NULL)
2087 return;
2089 struct walk_stmt_info wi;
2090 memset (&wi, 0, sizeof (wi));
2091 walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi);
2092 gimple *stmt = (gimple *) wi.info;
2094 if (stmt && gimple_code (stmt) != GIMPLE_LABEL)
2096 if (gimple_code (stmt) == GIMPLE_GOTO
2097 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
2098 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
2099 /* Don't warn for compiler-generated gotos. These occur
2100 in Duff's devices, for example. */;
2101 else
2102 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
2103 "statement will never be executed");
2108 /* A label entry that pairs label and a location. */
2109 struct label_entry
2111 tree label;
2112 location_t loc;
2115 /* Find LABEL in vector of label entries VEC. */
2117 static struct label_entry *
2118 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
2120 unsigned int i;
2121 struct label_entry *l;
2123 FOR_EACH_VEC_ELT (*vec, i, l)
2124 if (l->label == label)
2125 return l;
2126 return NULL;
2129 /* Return true if LABEL, a LABEL_DECL, represents a case label
2130 in a vector of labels CASES. */
2132 static bool
2133 case_label_p (const vec<tree> *cases, tree label)
2135 unsigned int i;
2136 tree l;
2138 FOR_EACH_VEC_ELT (*cases, i, l)
2139 if (CASE_LABEL (l) == label)
2140 return true;
2141 return false;
2144 /* Find the last nondebug statement in a scope STMT. */
2146 static gimple *
2147 last_stmt_in_scope (gimple *stmt)
2149 if (!stmt)
2150 return NULL;
2152 switch (gimple_code (stmt))
2154 case GIMPLE_BIND:
2156 gbind *bind = as_a <gbind *> (stmt);
2157 stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
2158 return last_stmt_in_scope (stmt);
2161 case GIMPLE_TRY:
2163 gtry *try_stmt = as_a <gtry *> (stmt);
2164 stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
2165 gimple *last_eval = last_stmt_in_scope (stmt);
2166 if (gimple_stmt_may_fallthru (last_eval)
2167 && (last_eval == NULL
2168 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
2169 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
2171 stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
2172 return last_stmt_in_scope (stmt);
2174 else
2175 return last_eval;
2178 case GIMPLE_DEBUG:
2179 gcc_unreachable ();
2181 default:
2182 return stmt;
2186 /* Collect interesting labels in LABELS and return the statement preceding
2187 another case label, or a user-defined label. Store a location useful
2188 to give warnings at *PREVLOC (usually the location of the returned
2189 statement or of its surrounding scope). */
2191 static gimple *
2192 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
2193 auto_vec <struct label_entry> *labels,
2194 location_t *prevloc)
2196 gimple *prev = NULL;
2198 *prevloc = UNKNOWN_LOCATION;
2201 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
2203 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2204 which starts on a GIMPLE_SWITCH and ends with a break label.
2205 Handle that as a single statement that can fall through. */
2206 gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
2207 gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
2208 gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
2209 if (last
2210 && gimple_code (first) == GIMPLE_SWITCH
2211 && gimple_code (last) == GIMPLE_LABEL)
2213 tree label = gimple_label_label (as_a <glabel *> (last));
2214 if (SWITCH_BREAK_LABEL_P (label))
2216 prev = bind;
2217 gsi_next (gsi_p);
2218 continue;
2222 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
2223 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
2225 /* Nested scope. Only look at the last statement of
2226 the innermost scope. */
2227 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
2228 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
2229 if (last)
2231 prev = last;
2232 /* It might be a label without a location. Use the
2233 location of the scope then. */
2234 if (!gimple_has_location (prev))
2235 *prevloc = bind_loc;
2237 gsi_next (gsi_p);
2238 continue;
2241 /* Ifs are tricky. */
2242 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
2244 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
2245 tree false_lab = gimple_cond_false_label (cond_stmt);
2246 location_t if_loc = gimple_location (cond_stmt);
2248 /* If we have e.g.
2249 if (i > 1) goto <D.2259>; else goto D;
2250 we can't do much with the else-branch. */
2251 if (!DECL_ARTIFICIAL (false_lab))
2252 break;
2254 /* Go on until the false label, then one step back. */
2255 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
2257 gimple *stmt = gsi_stmt (*gsi_p);
2258 if (gimple_code (stmt) == GIMPLE_LABEL
2259 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
2260 break;
2263 /* Not found? Oops. */
2264 if (gsi_end_p (*gsi_p))
2265 break;
2267 struct label_entry l = { false_lab, if_loc };
2268 labels->safe_push (l);
2270 /* Go to the last statement of the then branch. */
2271 gsi_prev (gsi_p);
2273 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2274 <D.1759>:
2275 <stmt>;
2276 goto <D.1761>;
2277 <D.1760>:
2279 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2280 && !gimple_has_location (gsi_stmt (*gsi_p)))
2282 /* Look at the statement before, it might be
2283 attribute fallthrough, in which case don't warn. */
2284 gsi_prev (gsi_p);
2285 bool fallthru_before_dest
2286 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2287 gsi_next (gsi_p);
2288 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2289 if (!fallthru_before_dest)
2291 struct label_entry l = { goto_dest, if_loc };
2292 labels->safe_push (l);
2295 /* And move back. */
2296 gsi_next (gsi_p);
2299 /* Remember the last statement. Skip labels that are of no interest
2300 to us. */
2301 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2303 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2304 if (find_label_entry (labels, label))
2305 prev = gsi_stmt (*gsi_p);
2307 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2309 else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
2311 else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2312 prev = gsi_stmt (*gsi_p);
2313 gsi_next (gsi_p);
2315 while (!gsi_end_p (*gsi_p)
2316 /* Stop if we find a case or a user-defined label. */
2317 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2318 || !gimple_has_location (gsi_stmt (*gsi_p))));
2320 if (prev && gimple_has_location (prev))
2321 *prevloc = gimple_location (prev);
2322 return prev;
2325 /* Return true if the switch fallthough warning should occur. LABEL is
2326 the label statement that we're falling through to. */
2328 static bool
2329 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2331 gimple_stmt_iterator gsi = *gsi_p;
2333 /* Don't warn if the label is marked with a "falls through" comment. */
2334 if (FALLTHROUGH_LABEL_P (label))
2335 return false;
2337 /* Don't warn for non-case labels followed by a statement:
2338 case 0:
2339 foo ();
2340 label:
2341 bar ();
2342 as these are likely intentional. */
2343 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2345 tree l;
2346 while (!gsi_end_p (gsi)
2347 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2348 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2349 && !case_label_p (&gimplify_ctxp->case_labels, l))
2350 gsi_next_nondebug (&gsi);
2351 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2352 return false;
2355 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2356 immediately breaks. */
2357 gsi = *gsi_p;
2359 /* Skip all immediately following labels. */
2360 while (!gsi_end_p (gsi)
2361 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2362 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2363 gsi_next_nondebug (&gsi);
2365 /* { ... something; default:; } */
2366 if (gsi_end_p (gsi)
2367 /* { ... something; default: break; } or
2368 { ... something; default: goto L; } */
2369 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2370 /* { ... something; default: return; } */
2371 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2372 return false;
2374 return true;
2377 /* Callback for walk_gimple_seq. */
2379 static tree
2380 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2381 struct walk_stmt_info *)
2383 gimple *stmt = gsi_stmt (*gsi_p);
2385 *handled_ops_p = true;
2386 switch (gimple_code (stmt))
2388 case GIMPLE_TRY:
2389 case GIMPLE_BIND:
2390 case GIMPLE_CATCH:
2391 case GIMPLE_EH_FILTER:
2392 case GIMPLE_TRANSACTION:
2393 /* Walk the sub-statements. */
2394 *handled_ops_p = false;
2395 break;
2397 /* Find a sequence of form:
2399 GIMPLE_LABEL
2400 [...]
2401 <may fallthru stmt>
2402 GIMPLE_LABEL
2404 and possibly warn. */
2405 case GIMPLE_LABEL:
2407 /* Found a label. Skip all immediately following labels. */
2408 while (!gsi_end_p (*gsi_p)
2409 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2410 gsi_next_nondebug (gsi_p);
2412 /* There might be no more statements. */
2413 if (gsi_end_p (*gsi_p))
2414 return integer_zero_node;
2416 /* Vector of labels that fall through. */
2417 auto_vec <struct label_entry> labels;
2418 location_t prevloc;
2419 gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
2421 /* There might be no more statements. */
2422 if (gsi_end_p (*gsi_p))
2423 return integer_zero_node;
2425 gimple *next = gsi_stmt (*gsi_p);
2426 tree label;
2427 /* If what follows is a label, then we may have a fallthrough. */
2428 if (gimple_code (next) == GIMPLE_LABEL
2429 && gimple_has_location (next)
2430 && (label = gimple_label_label (as_a <glabel *> (next)))
2431 && prev != NULL)
2433 struct label_entry *l;
2434 bool warned_p = false;
2435 auto_diagnostic_group d;
2436 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2437 /* Quiet. */;
2438 else if (gimple_code (prev) == GIMPLE_LABEL
2439 && (label = gimple_label_label (as_a <glabel *> (prev)))
2440 && (l = find_label_entry (&labels, label)))
2441 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2442 "this statement may fall through");
2443 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2444 /* Try to be clever and don't warn when the statement
2445 can't actually fall through. */
2446 && gimple_stmt_may_fallthru (prev)
2447 && prevloc != UNKNOWN_LOCATION)
2448 warned_p = warning_at (prevloc,
2449 OPT_Wimplicit_fallthrough_,
2450 "this statement may fall through");
2451 if (warned_p)
2452 inform (gimple_location (next), "here");
2454 /* Mark this label as processed so as to prevent multiple
2455 warnings in nested switches. */
2456 FALLTHROUGH_LABEL_P (label) = true;
2458 /* So that next warn_implicit_fallthrough_r will start looking for
2459 a new sequence starting with this label. */
2460 gsi_prev (gsi_p);
2463 break;
2464 default:
2465 break;
2467 return NULL_TREE;
2470 /* Warn when a switch case falls through. */
2472 static void
2473 maybe_warn_implicit_fallthrough (gimple_seq seq)
2475 if (!warn_implicit_fallthrough)
2476 return;
2478 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2479 if (!(lang_GNU_C ()
2480 || lang_GNU_CXX ()
2481 || lang_GNU_OBJC ()))
2482 return;
2484 struct walk_stmt_info wi;
2485 memset (&wi, 0, sizeof (wi));
2486 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2489 /* Callback for walk_gimple_seq. */
2491 static tree
2492 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2493 struct walk_stmt_info *wi)
2495 gimple *stmt = gsi_stmt (*gsi_p);
2497 *handled_ops_p = true;
2498 switch (gimple_code (stmt))
2500 case GIMPLE_TRY:
2501 case GIMPLE_BIND:
2502 case GIMPLE_CATCH:
2503 case GIMPLE_EH_FILTER:
2504 case GIMPLE_TRANSACTION:
2505 /* Walk the sub-statements. */
2506 *handled_ops_p = false;
2507 break;
2508 case GIMPLE_CALL:
2509 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2511 gsi_remove (gsi_p, true);
2512 if (gsi_end_p (*gsi_p))
2514 *static_cast<location_t *>(wi->info) = gimple_location (stmt);
2515 return integer_zero_node;
2518 bool found = false;
2519 location_t loc = gimple_location (stmt);
2521 gimple_stmt_iterator gsi2 = *gsi_p;
2522 stmt = gsi_stmt (gsi2);
2523 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2525 /* Go on until the artificial label. */
2526 tree goto_dest = gimple_goto_dest (stmt);
2527 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2529 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2530 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2531 == goto_dest)
2532 break;
2535 /* Not found? Stop. */
2536 if (gsi_end_p (gsi2))
2537 break;
2539 /* Look one past it. */
2540 gsi_next (&gsi2);
2543 /* We're looking for a case label or default label here. */
2544 while (!gsi_end_p (gsi2))
2546 stmt = gsi_stmt (gsi2);
2547 if (gimple_code (stmt) == GIMPLE_LABEL)
2549 tree label = gimple_label_label (as_a <glabel *> (stmt));
2550 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2552 found = true;
2553 break;
2556 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2558 else if (!is_gimple_debug (stmt))
2559 /* Anything else is not expected. */
2560 break;
2561 gsi_next (&gsi2);
2563 if (!found)
2564 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2565 "a case label or default label");
2567 break;
2568 default:
2569 break;
2571 return NULL_TREE;
2574 /* Expand all FALLTHROUGH () calls in SEQ. */
2576 static void
2577 expand_FALLTHROUGH (gimple_seq *seq_p)
2579 struct walk_stmt_info wi;
2580 location_t loc;
2581 memset (&wi, 0, sizeof (wi));
2582 wi.info = (void *) &loc;
2583 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2584 if (wi.callback_result == integer_zero_node)
2585 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2586 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2587 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2588 "a case label or default label");
2592 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2593 branch to. */
2595 static enum gimplify_status
2596 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2598 tree switch_expr = *expr_p;
2599 gimple_seq switch_body_seq = NULL;
2600 enum gimplify_status ret;
2601 tree index_type = TREE_TYPE (switch_expr);
2602 if (index_type == NULL_TREE)
2603 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2605 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2606 fb_rvalue);
2607 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2608 return ret;
2610 if (SWITCH_BODY (switch_expr))
2612 vec<tree> labels;
2613 vec<tree> saved_labels;
2614 hash_set<tree> *saved_live_switch_vars = NULL;
2615 tree default_case = NULL_TREE;
2616 gswitch *switch_stmt;
2618 /* Save old labels, get new ones from body, then restore the old
2619 labels. Save all the things from the switch body to append after. */
2620 saved_labels = gimplify_ctxp->case_labels;
2621 gimplify_ctxp->case_labels.create (8);
2623 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2624 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2625 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2626 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2627 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2628 else
2629 gimplify_ctxp->live_switch_vars = NULL;
2631 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2632 gimplify_ctxp->in_switch_expr = true;
2634 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2636 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2637 maybe_warn_switch_unreachable (switch_body_seq);
2638 maybe_warn_implicit_fallthrough (switch_body_seq);
2639 /* Only do this for the outermost GIMPLE_SWITCH. */
2640 if (!gimplify_ctxp->in_switch_expr)
2641 expand_FALLTHROUGH (&switch_body_seq);
2643 labels = gimplify_ctxp->case_labels;
2644 gimplify_ctxp->case_labels = saved_labels;
2646 if (gimplify_ctxp->live_switch_vars)
2648 gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
2649 delete gimplify_ctxp->live_switch_vars;
2651 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2653 preprocess_case_label_vec_for_gimple (labels, index_type,
2654 &default_case);
2656 bool add_bind = false;
2657 if (!default_case)
2659 glabel *new_default;
2661 default_case
2662 = build_case_label (NULL_TREE, NULL_TREE,
2663 create_artificial_label (UNKNOWN_LOCATION));
2664 if (old_in_switch_expr)
2666 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2667 add_bind = true;
2669 new_default = gimple_build_label (CASE_LABEL (default_case));
2670 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2672 else if (old_in_switch_expr)
2674 gimple *last = gimple_seq_last_stmt (switch_body_seq);
2675 if (last && gimple_code (last) == GIMPLE_LABEL)
2677 tree label = gimple_label_label (as_a <glabel *> (last));
2678 if (SWITCH_BREAK_LABEL_P (label))
2679 add_bind = true;
2683 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2684 default_case, labels);
2685 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2686 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2687 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2688 so that we can easily find the start and end of the switch
2689 statement. */
2690 if (add_bind)
2692 gimple_seq bind_body = NULL;
2693 gimplify_seq_add_stmt (&bind_body, switch_stmt);
2694 gimple_seq_add_seq (&bind_body, switch_body_seq);
2695 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
2696 gimple_set_location (bind, EXPR_LOCATION (switch_expr));
2697 gimplify_seq_add_stmt (pre_p, bind);
2699 else
2701 gimplify_seq_add_stmt (pre_p, switch_stmt);
2702 gimplify_seq_add_seq (pre_p, switch_body_seq);
2704 labels.release ();
2706 else
2707 gcc_unreachable ();
2709 return GS_ALL_DONE;
2712 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2714 static enum gimplify_status
2715 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2717 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2718 == current_function_decl);
2720 tree label = LABEL_EXPR_LABEL (*expr_p);
2721 glabel *label_stmt = gimple_build_label (label);
2722 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2723 gimplify_seq_add_stmt (pre_p, label_stmt);
2725 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2726 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2727 NOT_TAKEN));
2728 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2729 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2730 TAKEN));
2732 return GS_ALL_DONE;
2735 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2737 static enum gimplify_status
2738 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2740 struct gimplify_ctx *ctxp;
2741 glabel *label_stmt;
2743 /* Invalid programs can play Duff's Device type games with, for example,
2744 #pragma omp parallel. At least in the C front end, we don't
2745 detect such invalid branches until after gimplification, in the
2746 diagnose_omp_blocks pass. */
2747 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2748 if (ctxp->case_labels.exists ())
2749 break;
2751 tree label = CASE_LABEL (*expr_p);
2752 label_stmt = gimple_build_label (label);
2753 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2754 ctxp->case_labels.safe_push (*expr_p);
2755 gimplify_seq_add_stmt (pre_p, label_stmt);
2757 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2758 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2759 NOT_TAKEN));
2760 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2761 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2762 TAKEN));
2764 return GS_ALL_DONE;
2767 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2768 if necessary. */
2770 tree
2771 build_and_jump (tree *label_p)
2773 if (label_p == NULL)
2774 /* If there's nowhere to jump, just fall through. */
2775 return NULL_TREE;
2777 if (*label_p == NULL_TREE)
2779 tree label = create_artificial_label (UNKNOWN_LOCATION);
2780 *label_p = label;
2783 return build1 (GOTO_EXPR, void_type_node, *label_p);
2786 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2787 This also involves building a label to jump to and communicating it to
2788 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2790 static enum gimplify_status
2791 gimplify_exit_expr (tree *expr_p)
2793 tree cond = TREE_OPERAND (*expr_p, 0);
2794 tree expr;
2796 expr = build_and_jump (&gimplify_ctxp->exit_label);
2797 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2798 *expr_p = expr;
2800 return GS_OK;
2803 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2804 different from its canonical type, wrap the whole thing inside a
2805 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2806 type.
2808 The canonical type of a COMPONENT_REF is the type of the field being
2809 referenced--unless the field is a bit-field which can be read directly
2810 in a smaller mode, in which case the canonical type is the
2811 sign-appropriate type corresponding to that mode. */
2813 static void
2814 canonicalize_component_ref (tree *expr_p)
2816 tree expr = *expr_p;
2817 tree type;
2819 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2821 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2822 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2823 else
2824 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2826 /* One could argue that all the stuff below is not necessary for
2827 the non-bitfield case and declare it a FE error if type
2828 adjustment would be needed. */
2829 if (TREE_TYPE (expr) != type)
2831 #ifdef ENABLE_TYPES_CHECKING
2832 tree old_type = TREE_TYPE (expr);
2833 #endif
2834 int type_quals;
2836 /* We need to preserve qualifiers and propagate them from
2837 operand 0. */
2838 type_quals = TYPE_QUALS (type)
2839 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2840 if (TYPE_QUALS (type) != type_quals)
2841 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2843 /* Set the type of the COMPONENT_REF to the underlying type. */
2844 TREE_TYPE (expr) = type;
2846 #ifdef ENABLE_TYPES_CHECKING
2847 /* It is now a FE error, if the conversion from the canonical
2848 type to the original expression type is not useless. */
2849 gcc_assert (useless_type_conversion_p (old_type, type));
2850 #endif
2854 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2855 to foo, embed that change in the ADDR_EXPR by converting
2856 T array[U];
2857 (T *)&array
2859 &array[L]
2860 where L is the lower bound. For simplicity, only do this for constant
2861 lower bound.
2862 The constraint is that the type of &array[L] is trivially convertible
2863 to T *. */
2865 static void
2866 canonicalize_addr_expr (tree *expr_p)
2868 tree expr = *expr_p;
2869 tree addr_expr = TREE_OPERAND (expr, 0);
2870 tree datype, ddatype, pddatype;
2872 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2873 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2874 || TREE_CODE (addr_expr) != ADDR_EXPR)
2875 return;
2877 /* The addr_expr type should be a pointer to an array. */
2878 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2879 if (TREE_CODE (datype) != ARRAY_TYPE)
2880 return;
2882 /* The pointer to element type shall be trivially convertible to
2883 the expression pointer type. */
2884 ddatype = TREE_TYPE (datype);
2885 pddatype = build_pointer_type (ddatype);
2886 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2887 pddatype))
2888 return;
2890 /* The lower bound and element sizes must be constant. */
2891 if (!TYPE_SIZE_UNIT (ddatype)
2892 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2893 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2894 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2895 return;
2897 /* All checks succeeded. Build a new node to merge the cast. */
2898 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2899 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2900 NULL_TREE, NULL_TREE);
2901 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2903 /* We can have stripped a required restrict qualifier above. */
2904 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2905 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2908 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2909 underneath as appropriate. */
2911 static enum gimplify_status
2912 gimplify_conversion (tree *expr_p)
2914 location_t loc = EXPR_LOCATION (*expr_p);
2915 gcc_assert (CONVERT_EXPR_P (*expr_p));
2917 /* Then strip away all but the outermost conversion. */
2918 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
2920 /* And remove the outermost conversion if it's useless. */
2921 if (tree_ssa_useless_type_conversion (*expr_p))
2922 *expr_p = TREE_OPERAND (*expr_p, 0);
2924 /* If we still have a conversion at the toplevel,
2925 then canonicalize some constructs. */
2926 if (CONVERT_EXPR_P (*expr_p))
2928 tree sub = TREE_OPERAND (*expr_p, 0);
2930 /* If a NOP conversion is changing the type of a COMPONENT_REF
2931 expression, then canonicalize its type now in order to expose more
2932 redundant conversions. */
2933 if (TREE_CODE (sub) == COMPONENT_REF)
2934 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
2936 /* If a NOP conversion is changing a pointer to array of foo
2937 to a pointer to foo, embed that change in the ADDR_EXPR. */
2938 else if (TREE_CODE (sub) == ADDR_EXPR)
2939 canonicalize_addr_expr (expr_p);
2942 /* If we have a conversion to a non-register type force the
2943 use of a VIEW_CONVERT_EXPR instead. */
2944 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
2945 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
2946 TREE_OPERAND (*expr_p, 0));
2948 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2949 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
2950 TREE_SET_CODE (*expr_p, NOP_EXPR);
2952 return GS_OK;
2955 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2956 DECL_VALUE_EXPR, and it's worth re-examining things. */
2958 static enum gimplify_status
2959 gimplify_var_or_parm_decl (tree *expr_p)
2961 tree decl = *expr_p;
2963 /* ??? If this is a local variable, and it has not been seen in any
2964 outer BIND_EXPR, then it's probably the result of a duplicate
2965 declaration, for which we've already issued an error. It would
2966 be really nice if the front end wouldn't leak these at all.
2967 Currently the only known culprit is C++ destructors, as seen
2968 in g++.old-deja/g++.jason/binding.C.
2969 Another possible culpit are size expressions for variably modified
2970 types which are lost in the FE or not gimplified correctly. */
2971 if (VAR_P (decl)
2972 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
2973 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
2974 && decl_function_context (decl) == current_function_decl)
2976 gcc_assert (seen_error ());
2977 return GS_ERROR;
2980 /* When within an OMP context, notice uses of variables. */
2981 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
2982 return GS_ALL_DONE;
2984 /* If the decl is an alias for another expression, substitute it now. */
2985 if (DECL_HAS_VALUE_EXPR_P (decl))
2987 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
2988 return GS_OK;
2991 return GS_ALL_DONE;
2994 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2996 static void
2997 recalculate_side_effects (tree t)
2999 enum tree_code code = TREE_CODE (t);
3000 int len = TREE_OPERAND_LENGTH (t);
3001 int i;
3003 switch (TREE_CODE_CLASS (code))
3005 case tcc_expression:
3006 switch (code)
3008 case INIT_EXPR:
3009 case MODIFY_EXPR:
3010 case VA_ARG_EXPR:
3011 case PREDECREMENT_EXPR:
3012 case PREINCREMENT_EXPR:
3013 case POSTDECREMENT_EXPR:
3014 case POSTINCREMENT_EXPR:
3015 /* All of these have side-effects, no matter what their
3016 operands are. */
3017 return;
3019 default:
3020 break;
3022 /* Fall through. */
3024 case tcc_comparison: /* a comparison expression */
3025 case tcc_unary: /* a unary arithmetic expression */
3026 case tcc_binary: /* a binary arithmetic expression */
3027 case tcc_reference: /* a reference */
3028 case tcc_vl_exp: /* a function call */
3029 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
3030 for (i = 0; i < len; ++i)
3032 tree op = TREE_OPERAND (t, i);
3033 if (op && TREE_SIDE_EFFECTS (op))
3034 TREE_SIDE_EFFECTS (t) = 1;
3036 break;
3038 case tcc_constant:
3039 /* No side-effects. */
3040 return;
3042 default:
3043 gcc_unreachable ();
3047 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
3048 node *EXPR_P.
3050 compound_lval
3051 : min_lval '[' val ']'
3052 | min_lval '.' ID
3053 | compound_lval '[' val ']'
3054 | compound_lval '.' ID
3056 This is not part of the original SIMPLE definition, which separates
3057 array and member references, but it seems reasonable to handle them
3058 together. Also, this way we don't run into problems with union
3059 aliasing; gcc requires that for accesses through a union to alias, the
3060 union reference must be explicit, which was not always the case when we
3061 were splitting up array and member refs.
3063 PRE_P points to the sequence where side effects that must happen before
3064 *EXPR_P should be stored.
3066 POST_P points to the sequence where side effects that must happen after
3067 *EXPR_P should be stored. */
3069 static enum gimplify_status
3070 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3071 fallback_t fallback)
3073 tree *p;
3074 enum gimplify_status ret = GS_ALL_DONE, tret;
3075 int i;
3076 location_t loc = EXPR_LOCATION (*expr_p);
3077 tree expr = *expr_p;
3079 /* Create a stack of the subexpressions so later we can walk them in
3080 order from inner to outer. */
3081 auto_vec<tree, 10> expr_stack;
3083 /* We can handle anything that get_inner_reference can deal with. */
3084 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
3086 restart:
3087 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
3088 if (TREE_CODE (*p) == INDIRECT_REF)
3089 *p = fold_indirect_ref_loc (loc, *p);
3091 if (handled_component_p (*p))
3093 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
3094 additional COMPONENT_REFs. */
3095 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
3096 && gimplify_var_or_parm_decl (p) == GS_OK)
3097 goto restart;
3098 else
3099 break;
3101 expr_stack.safe_push (*p);
3104 gcc_assert (expr_stack.length ());
3106 /* Now EXPR_STACK is a stack of pointers to all the refs we've
3107 walked through and P points to the innermost expression.
3109 Java requires that we elaborated nodes in source order. That
3110 means we must gimplify the inner expression followed by each of
3111 the indices, in order. But we can't gimplify the inner
3112 expression until we deal with any variable bounds, sizes, or
3113 positions in order to deal with PLACEHOLDER_EXPRs.
3115 The base expression may contain a statement expression that
3116 has declarations used in size expressions, so has to be
3117 gimplified before gimplifying the size expressions.
3119 So we do this in three steps. First we deal with variable
3120 bounds, sizes, and positions, then we gimplify the base,
3121 then we deal with the annotations for any variables in the
3122 components and any indices, from left to right. */
3124 for (i = expr_stack.length () - 1; i >= 0; i--)
3126 tree t = expr_stack[i];
3128 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3130 /* Deal with the low bound and element type size and put them into
3131 the ARRAY_REF. If these values are set, they have already been
3132 gimplified. */
3133 if (TREE_OPERAND (t, 2) == NULL_TREE)
3135 tree low = unshare_expr (array_ref_low_bound (t));
3136 if (!is_gimple_min_invariant (low))
3138 TREE_OPERAND (t, 2) = low;
3142 if (TREE_OPERAND (t, 3) == NULL_TREE)
3144 tree elmt_size = array_ref_element_size (t);
3145 if (!is_gimple_min_invariant (elmt_size))
3147 elmt_size = unshare_expr (elmt_size);
3148 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
3149 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
3151 /* Divide the element size by the alignment of the element
3152 type (above). */
3153 elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR,
3154 elmt_size, factor);
3156 TREE_OPERAND (t, 3) = elmt_size;
3160 else if (TREE_CODE (t) == COMPONENT_REF)
3162 /* Set the field offset into T and gimplify it. */
3163 if (TREE_OPERAND (t, 2) == NULL_TREE)
3165 tree offset = component_ref_field_offset (t);
3166 if (!is_gimple_min_invariant (offset))
3168 offset = unshare_expr (offset);
3169 tree field = TREE_OPERAND (t, 1);
3170 tree factor
3171 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
3173 /* Divide the offset by its alignment. */
3174 offset = size_binop_loc (loc, EXACT_DIV_EXPR,
3175 offset, factor);
3177 TREE_OPERAND (t, 2) = offset;
3183 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3184 so as to match the min_lval predicate. Failure to do so may result
3185 in the creation of large aggregate temporaries. */
3186 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
3187 fallback | fb_lvalue);
3188 ret = MIN (ret, tret);
3190 /* Step 3: gimplify size expressions and the indices and operands of
3191 ARRAY_REF. During this loop we also remove any useless conversions. */
3193 for (; expr_stack.length () > 0; )
3195 tree t = expr_stack.pop ();
3197 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3199 /* Gimplify the low bound and element type size. */
3200 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3201 is_gimple_reg, fb_rvalue);
3202 ret = MIN (ret, tret);
3204 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
3205 is_gimple_reg, fb_rvalue);
3206 ret = MIN (ret, tret);
3208 /* Gimplify the dimension. */
3209 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
3210 is_gimple_val, fb_rvalue);
3211 ret = MIN (ret, tret);
3213 else if (TREE_CODE (t) == COMPONENT_REF)
3215 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3216 is_gimple_reg, fb_rvalue);
3217 ret = MIN (ret, tret);
3220 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
3222 /* The innermost expression P may have originally had
3223 TREE_SIDE_EFFECTS set which would have caused all the outer
3224 expressions in *EXPR_P leading to P to also have had
3225 TREE_SIDE_EFFECTS set. */
3226 recalculate_side_effects (t);
3229 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3230 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
3232 canonicalize_component_ref (expr_p);
3235 expr_stack.release ();
3237 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
3239 return ret;
3242 /* Gimplify the self modifying expression pointed to by EXPR_P
3243 (++, --, +=, -=).
3245 PRE_P points to the list where side effects that must happen before
3246 *EXPR_P should be stored.
3248 POST_P points to the list where side effects that must happen after
3249 *EXPR_P should be stored.
3251 WANT_VALUE is nonzero iff we want to use the value of this expression
3252 in another expression.
3254 ARITH_TYPE is the type the computation should be performed in. */
3256 enum gimplify_status
3257 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3258 bool want_value, tree arith_type)
3260 enum tree_code code;
3261 tree lhs, lvalue, rhs, t1;
3262 gimple_seq post = NULL, *orig_post_p = post_p;
3263 bool postfix;
3264 enum tree_code arith_code;
3265 enum gimplify_status ret;
3266 location_t loc = EXPR_LOCATION (*expr_p);
3268 code = TREE_CODE (*expr_p);
3270 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3271 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3273 /* Prefix or postfix? */
3274 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3275 /* Faster to treat as prefix if result is not used. */
3276 postfix = want_value;
3277 else
3278 postfix = false;
3280 /* For postfix, make sure the inner expression's post side effects
3281 are executed after side effects from this expression. */
3282 if (postfix)
3283 post_p = &post;
3285 /* Add or subtract? */
3286 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3287 arith_code = PLUS_EXPR;
3288 else
3289 arith_code = MINUS_EXPR;
3291 /* Gimplify the LHS into a GIMPLE lvalue. */
3292 lvalue = TREE_OPERAND (*expr_p, 0);
3293 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3294 if (ret == GS_ERROR)
3295 return ret;
3297 /* Extract the operands to the arithmetic operation. */
3298 lhs = lvalue;
3299 rhs = TREE_OPERAND (*expr_p, 1);
3301 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3302 that as the result value and in the postqueue operation. */
3303 if (postfix)
3305 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3306 if (ret == GS_ERROR)
3307 return ret;
3309 lhs = get_initialized_tmp_var (lhs, pre_p);
3312 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3313 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3315 rhs = convert_to_ptrofftype_loc (loc, rhs);
3316 if (arith_code == MINUS_EXPR)
3317 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3318 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3320 else
3321 t1 = fold_convert (TREE_TYPE (*expr_p),
3322 fold_build2 (arith_code, arith_type,
3323 fold_convert (arith_type, lhs),
3324 fold_convert (arith_type, rhs)));
3326 if (postfix)
3328 gimplify_assign (lvalue, t1, pre_p);
3329 gimplify_seq_add_seq (orig_post_p, post);
3330 *expr_p = lhs;
3331 return GS_ALL_DONE;
3333 else
3335 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3336 return GS_OK;
3340 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3342 static void
3343 maybe_with_size_expr (tree *expr_p)
3345 tree expr = *expr_p;
3346 tree type = TREE_TYPE (expr);
3347 tree size;
3349 /* If we've already wrapped this or the type is error_mark_node, we can't do
3350 anything. */
3351 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3352 || type == error_mark_node)
3353 return;
3355 /* If the size isn't known or is a constant, we have nothing to do. */
3356 size = TYPE_SIZE_UNIT (type);
3357 if (!size || poly_int_tree_p (size))
3358 return;
3360 /* Otherwise, make a WITH_SIZE_EXPR. */
3361 size = unshare_expr (size);
3362 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3363 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3366 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3367 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3368 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3369 gimplified to an SSA name. */
3371 enum gimplify_status
3372 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3373 bool allow_ssa)
3375 bool (*test) (tree);
3376 fallback_t fb;
3378 /* In general, we allow lvalues for function arguments to avoid
3379 extra overhead of copying large aggregates out of even larger
3380 aggregates into temporaries only to copy the temporaries to
3381 the argument list. Make optimizers happy by pulling out to
3382 temporaries those types that fit in registers. */
3383 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3384 test = is_gimple_val, fb = fb_rvalue;
3385 else
3387 test = is_gimple_lvalue, fb = fb_either;
3388 /* Also strip a TARGET_EXPR that would force an extra copy. */
3389 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3391 tree init = TARGET_EXPR_INITIAL (*arg_p);
3392 if (init
3393 && !VOID_TYPE_P (TREE_TYPE (init)))
3394 *arg_p = init;
3398 /* If this is a variable sized type, we must remember the size. */
3399 maybe_with_size_expr (arg_p);
3401 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3402 /* Make sure arguments have the same location as the function call
3403 itself. */
3404 protected_set_expr_location (*arg_p, call_location);
3406 /* There is a sequence point before a function call. Side effects in
3407 the argument list must occur before the actual call. So, when
3408 gimplifying arguments, force gimplify_expr to use an internal
3409 post queue which is then appended to the end of PRE_P. */
3410 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3413 /* Don't fold inside offloading or taskreg regions: it can break code by
3414 adding decl references that weren't in the source. We'll do it during
3415 omplower pass instead. */
3417 static bool
3418 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3420 struct gimplify_omp_ctx *ctx;
3421 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3422 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3423 return false;
3424 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3425 return false;
3426 /* Delay folding of builtins until the IL is in consistent state
3427 so the diagnostic machinery can do a better job. */
3428 if (gimple_call_builtin_p (gsi_stmt (*gsi)))
3429 return false;
3430 return fold_stmt (gsi);
3433 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3434 WANT_VALUE is true if the result of the call is desired. */
3436 static enum gimplify_status
3437 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3439 tree fndecl, parms, p, fnptrtype;
3440 enum gimplify_status ret;
3441 int i, nargs;
3442 gcall *call;
3443 bool builtin_va_start_p = false;
3444 location_t loc = EXPR_LOCATION (*expr_p);
3446 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3448 /* For reliable diagnostics during inlining, it is necessary that
3449 every call_expr be annotated with file and line. */
3450 if (! EXPR_HAS_LOCATION (*expr_p))
3451 SET_EXPR_LOCATION (*expr_p, input_location);
3453 /* Gimplify internal functions created in the FEs. */
3454 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3456 if (want_value)
3457 return GS_ALL_DONE;
3459 nargs = call_expr_nargs (*expr_p);
3460 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3461 auto_vec<tree> vargs (nargs);
3463 for (i = 0; i < nargs; i++)
3465 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3466 EXPR_LOCATION (*expr_p));
3467 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3470 gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3471 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3472 gimplify_seq_add_stmt (pre_p, call);
3473 return GS_ALL_DONE;
3476 /* This may be a call to a builtin function.
3478 Builtin function calls may be transformed into different
3479 (and more efficient) builtin function calls under certain
3480 circumstances. Unfortunately, gimplification can muck things
3481 up enough that the builtin expanders are not aware that certain
3482 transformations are still valid.
3484 So we attempt transformation/gimplification of the call before
3485 we gimplify the CALL_EXPR. At this time we do not manage to
3486 transform all calls in the same manner as the expanders do, but
3487 we do transform most of them. */
3488 fndecl = get_callee_fndecl (*expr_p);
3489 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3490 switch (DECL_FUNCTION_CODE (fndecl))
3492 CASE_BUILT_IN_ALLOCA:
3493 /* If the call has been built for a variable-sized object, then we
3494 want to restore the stack level when the enclosing BIND_EXPR is
3495 exited to reclaim the allocated space; otherwise, we precisely
3496 need to do the opposite and preserve the latest stack level. */
3497 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3498 gimplify_ctxp->save_stack = true;
3499 else
3500 gimplify_ctxp->keep_stack = true;
3501 break;
3503 case BUILT_IN_VA_START:
3505 builtin_va_start_p = TRUE;
3506 if (call_expr_nargs (*expr_p) < 2)
3508 error ("too few arguments to function %<va_start%>");
3509 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3510 return GS_OK;
3513 if (fold_builtin_next_arg (*expr_p, true))
3515 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3516 return GS_OK;
3518 break;
3521 case BUILT_IN_EH_RETURN:
3522 cfun->calls_eh_return = true;
3523 break;
3525 case BUILT_IN_CLEAR_PADDING:
3526 if (call_expr_nargs (*expr_p) == 1)
3528 /* Remember the original type of the argument in an internal
3529 dummy second argument, as in GIMPLE pointer conversions are
3530 useless. also mark this call as not for automatic initialization
3531 in the internal dummy third argument. */
3532 p = CALL_EXPR_ARG (*expr_p, 0);
3533 bool for_auto_init = false;
3534 *expr_p
3535 = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 3, p,
3536 build_zero_cst (TREE_TYPE (p)),
3537 build_int_cst (integer_type_node,
3538 (int) for_auto_init));
3539 return GS_OK;
3541 break;
3543 default:
3546 if (fndecl && fndecl_built_in_p (fndecl))
3548 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3549 if (new_tree && new_tree != *expr_p)
3551 /* There was a transformation of this call which computes the
3552 same value, but in a more efficient way. Return and try
3553 again. */
3554 *expr_p = new_tree;
3555 return GS_OK;
3559 /* Remember the original function pointer type. */
3560 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3562 if (flag_openmp
3563 && fndecl
3564 && cfun
3565 && (cfun->curr_properties & PROP_gimple_any) == 0)
3567 tree variant = omp_resolve_declare_variant (fndecl);
3568 if (variant != fndecl)
3569 CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
3572 /* There is a sequence point before the call, so any side effects in
3573 the calling expression must occur before the actual call. Force
3574 gimplify_expr to use an internal post queue. */
3575 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3576 is_gimple_call_addr, fb_rvalue);
3578 nargs = call_expr_nargs (*expr_p);
3580 /* Get argument types for verification. */
3581 fndecl = get_callee_fndecl (*expr_p);
3582 parms = NULL_TREE;
3583 if (fndecl)
3584 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3585 else
3586 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3588 if (fndecl && DECL_ARGUMENTS (fndecl))
3589 p = DECL_ARGUMENTS (fndecl);
3590 else if (parms)
3591 p = parms;
3592 else
3593 p = NULL_TREE;
3594 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3597 /* If the last argument is __builtin_va_arg_pack () and it is not
3598 passed as a named argument, decrease the number of CALL_EXPR
3599 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3600 if (!p
3601 && i < nargs
3602 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3604 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3605 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3607 if (last_arg_fndecl
3608 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3610 tree call = *expr_p;
3612 --nargs;
3613 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3614 CALL_EXPR_FN (call),
3615 nargs, CALL_EXPR_ARGP (call));
3617 /* Copy all CALL_EXPR flags, location and block, except
3618 CALL_EXPR_VA_ARG_PACK flag. */
3619 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3620 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3621 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3622 = CALL_EXPR_RETURN_SLOT_OPT (call);
3623 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3624 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3626 /* Set CALL_EXPR_VA_ARG_PACK. */
3627 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3631 /* If the call returns twice then after building the CFG the call
3632 argument computations will no longer dominate the call because
3633 we add an abnormal incoming edge to the call. So do not use SSA
3634 vars there. */
3635 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3637 /* Gimplify the function arguments. */
3638 if (nargs > 0)
3640 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3641 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3642 PUSH_ARGS_REVERSED ? i-- : i++)
3644 enum gimplify_status t;
3646 /* Avoid gimplifying the second argument to va_start, which needs to
3647 be the plain PARM_DECL. */
3648 if ((i != 1) || !builtin_va_start_p)
3650 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3651 EXPR_LOCATION (*expr_p), ! returns_twice);
3653 if (t == GS_ERROR)
3654 ret = GS_ERROR;
3659 /* Gimplify the static chain. */
3660 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3662 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3663 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3664 else
3666 enum gimplify_status t;
3667 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3668 EXPR_LOCATION (*expr_p), ! returns_twice);
3669 if (t == GS_ERROR)
3670 ret = GS_ERROR;
3674 /* Verify the function result. */
3675 if (want_value && fndecl
3676 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3678 error_at (loc, "using result of function returning %<void%>");
3679 ret = GS_ERROR;
3682 /* Try this again in case gimplification exposed something. */
3683 if (ret != GS_ERROR)
3685 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3687 if (new_tree && new_tree != *expr_p)
3689 /* There was a transformation of this call which computes the
3690 same value, but in a more efficient way. Return and try
3691 again. */
3692 *expr_p = new_tree;
3693 return GS_OK;
3696 else
3698 *expr_p = error_mark_node;
3699 return GS_ERROR;
3702 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3703 decl. This allows us to eliminate redundant or useless
3704 calls to "const" functions. */
3705 if (TREE_CODE (*expr_p) == CALL_EXPR)
3707 int flags = call_expr_flags (*expr_p);
3708 if (flags & (ECF_CONST | ECF_PURE)
3709 /* An infinite loop is considered a side effect. */
3710 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3711 TREE_SIDE_EFFECTS (*expr_p) = 0;
3714 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3715 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3716 form and delegate the creation of a GIMPLE_CALL to
3717 gimplify_modify_expr. This is always possible because when
3718 WANT_VALUE is true, the caller wants the result of this call into
3719 a temporary, which means that we will emit an INIT_EXPR in
3720 internal_get_tmp_var which will then be handled by
3721 gimplify_modify_expr. */
3722 if (!want_value)
3724 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3725 have to do is replicate it as a GIMPLE_CALL tuple. */
3726 gimple_stmt_iterator gsi;
3727 call = gimple_build_call_from_tree (*expr_p, fnptrtype);
3728 notice_special_calls (call);
3729 gimplify_seq_add_stmt (pre_p, call);
3730 gsi = gsi_last (*pre_p);
3731 maybe_fold_stmt (&gsi);
3732 *expr_p = NULL_TREE;
3734 else
3735 /* Remember the original function type. */
3736 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3737 CALL_EXPR_FN (*expr_p));
3739 return ret;
3742 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3743 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3745 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3746 condition is true or false, respectively. If null, we should generate
3747 our own to skip over the evaluation of this specific expression.
3749 LOCUS is the source location of the COND_EXPR.
3751 This function is the tree equivalent of do_jump.
3753 shortcut_cond_r should only be called by shortcut_cond_expr. */
3755 static tree
3756 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3757 location_t locus)
3759 tree local_label = NULL_TREE;
3760 tree t, expr = NULL;
3762 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3763 retain the shortcut semantics. Just insert the gotos here;
3764 shortcut_cond_expr will append the real blocks later. */
3765 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3767 location_t new_locus;
3769 /* Turn if (a && b) into
3771 if (a); else goto no;
3772 if (b) goto yes; else goto no;
3773 (no:) */
3775 if (false_label_p == NULL)
3776 false_label_p = &local_label;
3778 /* Keep the original source location on the first 'if'. */
3779 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3780 append_to_statement_list (t, &expr);
3782 /* Set the source location of the && on the second 'if'. */
3783 new_locus = rexpr_location (pred, locus);
3784 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3785 new_locus);
3786 append_to_statement_list (t, &expr);
3788 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3790 location_t new_locus;
3792 /* Turn if (a || b) into
3794 if (a) goto yes;
3795 if (b) goto yes; else goto no;
3796 (yes:) */
3798 if (true_label_p == NULL)
3799 true_label_p = &local_label;
3801 /* Keep the original source location on the first 'if'. */
3802 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3803 append_to_statement_list (t, &expr);
3805 /* Set the source location of the || on the second 'if'. */
3806 new_locus = rexpr_location (pred, locus);
3807 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3808 new_locus);
3809 append_to_statement_list (t, &expr);
3811 else if (TREE_CODE (pred) == COND_EXPR
3812 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3813 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3815 location_t new_locus;
3817 /* As long as we're messing with gotos, turn if (a ? b : c) into
3818 if (a)
3819 if (b) goto yes; else goto no;
3820 else
3821 if (c) goto yes; else goto no;
3823 Don't do this if one of the arms has void type, which can happen
3824 in C++ when the arm is throw. */
3826 /* Keep the original source location on the first 'if'. Set the source
3827 location of the ? on the second 'if'. */
3828 new_locus = rexpr_location (pred, locus);
3829 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3830 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3831 false_label_p, locus),
3832 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3833 false_label_p, new_locus));
3835 else
3837 expr = build3 (COND_EXPR, void_type_node, pred,
3838 build_and_jump (true_label_p),
3839 build_and_jump (false_label_p));
3840 SET_EXPR_LOCATION (expr, locus);
3843 if (local_label)
3845 t = build1 (LABEL_EXPR, void_type_node, local_label);
3846 append_to_statement_list (t, &expr);
3849 return expr;
3852 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3853 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3854 statement, if it is the last one. Otherwise, return NULL. */
3856 static tree
3857 find_goto (tree expr)
3859 if (!expr)
3860 return NULL_TREE;
3862 if (TREE_CODE (expr) == GOTO_EXPR)
3863 return expr;
3865 if (TREE_CODE (expr) != STATEMENT_LIST)
3866 return NULL_TREE;
3868 tree_stmt_iterator i = tsi_start (expr);
3870 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
3871 tsi_next (&i);
3873 if (!tsi_one_before_end_p (i))
3874 return NULL_TREE;
3876 return find_goto (tsi_stmt (i));
3879 /* Same as find_goto, except that it returns NULL if the destination
3880 is not a LABEL_DECL. */
3882 static inline tree
3883 find_goto_label (tree expr)
3885 tree dest = find_goto (expr);
3886 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
3887 return dest;
3888 return NULL_TREE;
3891 /* Given a conditional expression EXPR with short-circuit boolean
3892 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3893 predicate apart into the equivalent sequence of conditionals. */
3895 static tree
3896 shortcut_cond_expr (tree expr)
3898 tree pred = TREE_OPERAND (expr, 0);
3899 tree then_ = TREE_OPERAND (expr, 1);
3900 tree else_ = TREE_OPERAND (expr, 2);
3901 tree true_label, false_label, end_label, t;
3902 tree *true_label_p;
3903 tree *false_label_p;
3904 bool emit_end, emit_false, jump_over_else;
3905 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3906 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3908 /* First do simple transformations. */
3909 if (!else_se)
3911 /* If there is no 'else', turn
3912 if (a && b) then c
3913 into
3914 if (a) if (b) then c. */
3915 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3917 /* Keep the original source location on the first 'if'. */
3918 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3919 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3920 /* Set the source location of the && on the second 'if'. */
3921 if (rexpr_has_location (pred))
3922 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3923 then_ = shortcut_cond_expr (expr);
3924 then_se = then_ && TREE_SIDE_EFFECTS (then_);
3925 pred = TREE_OPERAND (pred, 0);
3926 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
3927 SET_EXPR_LOCATION (expr, locus);
3931 if (!then_se)
3933 /* If there is no 'then', turn
3934 if (a || b); else d
3935 into
3936 if (a); else if (b); else d. */
3937 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3939 /* Keep the original source location on the first 'if'. */
3940 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3941 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3942 /* Set the source location of the || on the second 'if'. */
3943 if (rexpr_has_location (pred))
3944 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3945 else_ = shortcut_cond_expr (expr);
3946 else_se = else_ && TREE_SIDE_EFFECTS (else_);
3947 pred = TREE_OPERAND (pred, 0);
3948 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
3949 SET_EXPR_LOCATION (expr, locus);
3953 /* If we're done, great. */
3954 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
3955 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
3956 return expr;
3958 /* Otherwise we need to mess with gotos. Change
3959 if (a) c; else d;
3961 if (a); else goto no;
3962 c; goto end;
3963 no: d; end:
3964 and recursively gimplify the condition. */
3966 true_label = false_label = end_label = NULL_TREE;
3968 /* If our arms just jump somewhere, hijack those labels so we don't
3969 generate jumps to jumps. */
3971 if (tree then_goto = find_goto_label (then_))
3973 true_label = GOTO_DESTINATION (then_goto);
3974 then_ = NULL;
3975 then_se = false;
3978 if (tree else_goto = find_goto_label (else_))
3980 false_label = GOTO_DESTINATION (else_goto);
3981 else_ = NULL;
3982 else_se = false;
3985 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3986 if (true_label)
3987 true_label_p = &true_label;
3988 else
3989 true_label_p = NULL;
3991 /* The 'else' branch also needs a label if it contains interesting code. */
3992 if (false_label || else_se)
3993 false_label_p = &false_label;
3994 else
3995 false_label_p = NULL;
3997 /* If there was nothing else in our arms, just forward the label(s). */
3998 if (!then_se && !else_se)
3999 return shortcut_cond_r (pred, true_label_p, false_label_p,
4000 EXPR_LOC_OR_LOC (expr, input_location));
4002 /* If our last subexpression already has a terminal label, reuse it. */
4003 if (else_se)
4004 t = expr_last (else_);
4005 else if (then_se)
4006 t = expr_last (then_);
4007 else
4008 t = NULL;
4009 if (t && TREE_CODE (t) == LABEL_EXPR)
4010 end_label = LABEL_EXPR_LABEL (t);
4012 /* If we don't care about jumping to the 'else' branch, jump to the end
4013 if the condition is false. */
4014 if (!false_label_p)
4015 false_label_p = &end_label;
4017 /* We only want to emit these labels if we aren't hijacking them. */
4018 emit_end = (end_label == NULL_TREE);
4019 emit_false = (false_label == NULL_TREE);
4021 /* We only emit the jump over the else clause if we have to--if the
4022 then clause may fall through. Otherwise we can wind up with a
4023 useless jump and a useless label at the end of gimplified code,
4024 which will cause us to think that this conditional as a whole
4025 falls through even if it doesn't. If we then inline a function
4026 which ends with such a condition, that can cause us to issue an
4027 inappropriate warning about control reaching the end of a
4028 non-void function. */
4029 jump_over_else = block_may_fallthru (then_);
4031 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
4032 EXPR_LOC_OR_LOC (expr, input_location));
4034 expr = NULL;
4035 append_to_statement_list (pred, &expr);
4037 append_to_statement_list (then_, &expr);
4038 if (else_se)
4040 if (jump_over_else)
4042 tree last = expr_last (expr);
4043 t = build_and_jump (&end_label);
4044 if (rexpr_has_location (last))
4045 SET_EXPR_LOCATION (t, rexpr_location (last));
4046 append_to_statement_list (t, &expr);
4048 if (emit_false)
4050 t = build1 (LABEL_EXPR, void_type_node, false_label);
4051 append_to_statement_list (t, &expr);
4053 append_to_statement_list (else_, &expr);
4055 if (emit_end && end_label)
4057 t = build1 (LABEL_EXPR, void_type_node, end_label);
4058 append_to_statement_list (t, &expr);
4061 return expr;
4064 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
4066 tree
4067 gimple_boolify (tree expr)
4069 tree type = TREE_TYPE (expr);
4070 location_t loc = EXPR_LOCATION (expr);
4072 if (TREE_CODE (expr) == NE_EXPR
4073 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
4074 && integer_zerop (TREE_OPERAND (expr, 1)))
4076 tree call = TREE_OPERAND (expr, 0);
4077 tree fn = get_callee_fndecl (call);
4079 /* For __builtin_expect ((long) (x), y) recurse into x as well
4080 if x is truth_value_p. */
4081 if (fn
4082 && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
4083 && call_expr_nargs (call) == 2)
4085 tree arg = CALL_EXPR_ARG (call, 0);
4086 if (arg)
4088 if (TREE_CODE (arg) == NOP_EXPR
4089 && TREE_TYPE (arg) == TREE_TYPE (call))
4090 arg = TREE_OPERAND (arg, 0);
4091 if (truth_value_p (TREE_CODE (arg)))
4093 arg = gimple_boolify (arg);
4094 CALL_EXPR_ARG (call, 0)
4095 = fold_convert_loc (loc, TREE_TYPE (call), arg);
4101 switch (TREE_CODE (expr))
4103 case TRUTH_AND_EXPR:
4104 case TRUTH_OR_EXPR:
4105 case TRUTH_XOR_EXPR:
4106 case TRUTH_ANDIF_EXPR:
4107 case TRUTH_ORIF_EXPR:
4108 /* Also boolify the arguments of truth exprs. */
4109 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
4110 /* FALLTHRU */
4112 case TRUTH_NOT_EXPR:
4113 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4115 /* These expressions always produce boolean results. */
4116 if (TREE_CODE (type) != BOOLEAN_TYPE)
4117 TREE_TYPE (expr) = boolean_type_node;
4118 return expr;
4120 case ANNOTATE_EXPR:
4121 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
4123 case annot_expr_ivdep_kind:
4124 case annot_expr_unroll_kind:
4125 case annot_expr_no_vector_kind:
4126 case annot_expr_vector_kind:
4127 case annot_expr_parallel_kind:
4128 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4129 if (TREE_CODE (type) != BOOLEAN_TYPE)
4130 TREE_TYPE (expr) = boolean_type_node;
4131 return expr;
4132 default:
4133 gcc_unreachable ();
4136 default:
4137 if (COMPARISON_CLASS_P (expr))
4139 /* There expressions always prduce boolean results. */
4140 if (TREE_CODE (type) != BOOLEAN_TYPE)
4141 TREE_TYPE (expr) = boolean_type_node;
4142 return expr;
4144 /* Other expressions that get here must have boolean values, but
4145 might need to be converted to the appropriate mode. */
4146 if (TREE_CODE (type) == BOOLEAN_TYPE)
4147 return expr;
4148 return fold_convert_loc (loc, boolean_type_node, expr);
4152 /* Given a conditional expression *EXPR_P without side effects, gimplify
4153 its operands. New statements are inserted to PRE_P. */
4155 static enum gimplify_status
4156 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
4158 tree expr = *expr_p, cond;
4159 enum gimplify_status ret, tret;
4160 enum tree_code code;
4162 cond = gimple_boolify (COND_EXPR_COND (expr));
4164 /* We need to handle && and || specially, as their gimplification
4165 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4166 code = TREE_CODE (cond);
4167 if (code == TRUTH_ANDIF_EXPR)
4168 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
4169 else if (code == TRUTH_ORIF_EXPR)
4170 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
4171 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
4172 COND_EXPR_COND (*expr_p) = cond;
4174 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
4175 is_gimple_val, fb_rvalue);
4176 ret = MIN (ret, tret);
4177 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
4178 is_gimple_val, fb_rvalue);
4180 return MIN (ret, tret);
4183 /* Return true if evaluating EXPR could trap.
4184 EXPR is GENERIC, while tree_could_trap_p can be called
4185 only on GIMPLE. */
4187 bool
4188 generic_expr_could_trap_p (tree expr)
4190 unsigned i, n;
4192 if (!expr || is_gimple_val (expr))
4193 return false;
4195 if (!EXPR_P (expr) || tree_could_trap_p (expr))
4196 return true;
4198 n = TREE_OPERAND_LENGTH (expr);
4199 for (i = 0; i < n; i++)
4200 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
4201 return true;
4203 return false;
4206 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4207 into
4209 if (p) if (p)
4210 t1 = a; a;
4211 else or else
4212 t1 = b; b;
4215 The second form is used when *EXPR_P is of type void.
4217 PRE_P points to the list where side effects that must happen before
4218 *EXPR_P should be stored. */
4220 static enum gimplify_status
4221 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
4223 tree expr = *expr_p;
4224 tree type = TREE_TYPE (expr);
4225 location_t loc = EXPR_LOCATION (expr);
4226 tree tmp, arm1, arm2;
4227 enum gimplify_status ret;
4228 tree label_true, label_false, label_cont;
4229 bool have_then_clause_p, have_else_clause_p;
4230 gcond *cond_stmt;
4231 enum tree_code pred_code;
4232 gimple_seq seq = NULL;
4234 /* If this COND_EXPR has a value, copy the values into a temporary within
4235 the arms. */
4236 if (!VOID_TYPE_P (type))
4238 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
4239 tree result;
4241 /* If either an rvalue is ok or we do not require an lvalue, create the
4242 temporary. But we cannot do that if the type is addressable. */
4243 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
4244 && !TREE_ADDRESSABLE (type))
4246 if (gimplify_ctxp->allow_rhs_cond_expr
4247 /* If either branch has side effects or could trap, it can't be
4248 evaluated unconditionally. */
4249 && !TREE_SIDE_EFFECTS (then_)
4250 && !generic_expr_could_trap_p (then_)
4251 && !TREE_SIDE_EFFECTS (else_)
4252 && !generic_expr_could_trap_p (else_))
4253 return gimplify_pure_cond_expr (expr_p, pre_p);
4255 tmp = create_tmp_var (type, "iftmp");
4256 result = tmp;
4259 /* Otherwise, only create and copy references to the values. */
4260 else
4262 type = build_pointer_type (type);
4264 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4265 then_ = build_fold_addr_expr_loc (loc, then_);
4267 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4268 else_ = build_fold_addr_expr_loc (loc, else_);
4270 expr
4271 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
4273 tmp = create_tmp_var (type, "iftmp");
4274 result = build_simple_mem_ref_loc (loc, tmp);
4277 /* Build the new then clause, `tmp = then_;'. But don't build the
4278 assignment if the value is void; in C++ it can be if it's a throw. */
4279 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4280 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
4282 /* Similarly, build the new else clause, `tmp = else_;'. */
4283 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4284 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
4286 TREE_TYPE (expr) = void_type_node;
4287 recalculate_side_effects (expr);
4289 /* Move the COND_EXPR to the prequeue. */
4290 gimplify_stmt (&expr, pre_p);
4292 *expr_p = result;
4293 return GS_ALL_DONE;
4296 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4297 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4298 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4299 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4301 /* Make sure the condition has BOOLEAN_TYPE. */
4302 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4304 /* Break apart && and || conditions. */
4305 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4306 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4308 expr = shortcut_cond_expr (expr);
4310 if (expr != *expr_p)
4312 *expr_p = expr;
4314 /* We can't rely on gimplify_expr to re-gimplify the expanded
4315 form properly, as cleanups might cause the target labels to be
4316 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4317 set up a conditional context. */
4318 gimple_push_condition ();
4319 gimplify_stmt (expr_p, &seq);
4320 gimple_pop_condition (pre_p);
4321 gimple_seq_add_seq (pre_p, seq);
4323 return GS_ALL_DONE;
4327 /* Now do the normal gimplification. */
4329 /* Gimplify condition. */
4330 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
4331 is_gimple_condexpr_for_cond, fb_rvalue);
4332 if (ret == GS_ERROR)
4333 return GS_ERROR;
4334 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4336 gimple_push_condition ();
4338 have_then_clause_p = have_else_clause_p = false;
4339 label_true = find_goto_label (TREE_OPERAND (expr, 1));
4340 if (label_true
4341 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4342 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4343 have different locations, otherwise we end up with incorrect
4344 location information on the branches. */
4345 && (optimize
4346 || !EXPR_HAS_LOCATION (expr)
4347 || !rexpr_has_location (label_true)
4348 || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4350 have_then_clause_p = true;
4351 label_true = GOTO_DESTINATION (label_true);
4353 else
4354 label_true = create_artificial_label (UNKNOWN_LOCATION);
4355 label_false = find_goto_label (TREE_OPERAND (expr, 2));
4356 if (label_false
4357 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4358 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4359 have different locations, otherwise we end up with incorrect
4360 location information on the branches. */
4361 && (optimize
4362 || !EXPR_HAS_LOCATION (expr)
4363 || !rexpr_has_location (label_false)
4364 || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4366 have_else_clause_p = true;
4367 label_false = GOTO_DESTINATION (label_false);
4369 else
4370 label_false = create_artificial_label (UNKNOWN_LOCATION);
4372 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4373 &arm2);
4374 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4375 label_false);
4376 gimple_set_location (cond_stmt, EXPR_LOCATION (expr));
4377 copy_warning (cond_stmt, COND_EXPR_COND (expr));
4378 gimplify_seq_add_stmt (&seq, cond_stmt);
4379 gimple_stmt_iterator gsi = gsi_last (seq);
4380 maybe_fold_stmt (&gsi);
4382 label_cont = NULL_TREE;
4383 if (!have_then_clause_p)
4385 /* For if (...) {} else { code; } put label_true after
4386 the else block. */
4387 if (TREE_OPERAND (expr, 1) == NULL_TREE
4388 && !have_else_clause_p
4389 && TREE_OPERAND (expr, 2) != NULL_TREE)
4390 label_cont = label_true;
4391 else
4393 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4394 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4395 /* For if (...) { code; } else {} or
4396 if (...) { code; } else goto label; or
4397 if (...) { code; return; } else { ... }
4398 label_cont isn't needed. */
4399 if (!have_else_clause_p
4400 && TREE_OPERAND (expr, 2) != NULL_TREE
4401 && gimple_seq_may_fallthru (seq))
4403 gimple *g;
4404 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4406 g = gimple_build_goto (label_cont);
4408 /* GIMPLE_COND's are very low level; they have embedded
4409 gotos. This particular embedded goto should not be marked
4410 with the location of the original COND_EXPR, as it would
4411 correspond to the COND_EXPR's condition, not the ELSE or the
4412 THEN arms. To avoid marking it with the wrong location, flag
4413 it as "no location". */
4414 gimple_set_do_not_emit_location (g);
4416 gimplify_seq_add_stmt (&seq, g);
4420 if (!have_else_clause_p)
4422 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4423 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4425 if (label_cont)
4426 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4428 gimple_pop_condition (pre_p);
4429 gimple_seq_add_seq (pre_p, seq);
4431 if (ret == GS_ERROR)
4432 ; /* Do nothing. */
4433 else if (have_then_clause_p || have_else_clause_p)
4434 ret = GS_ALL_DONE;
4435 else
4437 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4438 expr = TREE_OPERAND (expr, 0);
4439 gimplify_stmt (&expr, pre_p);
4442 *expr_p = NULL;
4443 return ret;
4446 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4447 to be marked addressable.
4449 We cannot rely on such an expression being directly markable if a temporary
4450 has been created by the gimplification. In this case, we create another
4451 temporary and initialize it with a copy, which will become a store after we
4452 mark it addressable. This can happen if the front-end passed us something
4453 that it could not mark addressable yet, like a Fortran pass-by-reference
4454 parameter (int) floatvar. */
4456 static void
4457 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4459 while (handled_component_p (*expr_p))
4460 expr_p = &TREE_OPERAND (*expr_p, 0);
4461 if (is_gimple_reg (*expr_p))
4463 /* Do not allow an SSA name as the temporary. */
4464 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
4465 DECL_NOT_GIMPLE_REG_P (var) = 1;
4466 *expr_p = var;
4470 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4471 a call to __builtin_memcpy. */
4473 static enum gimplify_status
4474 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4475 gimple_seq *seq_p)
4477 tree t, to, to_ptr, from, from_ptr;
4478 gcall *gs;
4479 location_t loc = EXPR_LOCATION (*expr_p);
4481 to = TREE_OPERAND (*expr_p, 0);
4482 from = TREE_OPERAND (*expr_p, 1);
4484 /* Mark the RHS addressable. Beware that it may not be possible to do so
4485 directly if a temporary has been created by the gimplification. */
4486 prepare_gimple_addressable (&from, seq_p);
4488 mark_addressable (from);
4489 from_ptr = build_fold_addr_expr_loc (loc, from);
4490 gimplify_arg (&from_ptr, seq_p, loc);
4492 mark_addressable (to);
4493 to_ptr = build_fold_addr_expr_loc (loc, to);
4494 gimplify_arg (&to_ptr, seq_p, loc);
4496 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4498 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4499 gimple_call_set_alloca_for_var (gs, true);
4501 if (want_value)
4503 /* tmp = memcpy() */
4504 t = create_tmp_var (TREE_TYPE (to_ptr));
4505 gimple_call_set_lhs (gs, t);
4506 gimplify_seq_add_stmt (seq_p, gs);
4508 *expr_p = build_simple_mem_ref (t);
4509 return GS_ALL_DONE;
4512 gimplify_seq_add_stmt (seq_p, gs);
4513 *expr_p = NULL;
4514 return GS_ALL_DONE;
4517 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4518 a call to __builtin_memset. In this case we know that the RHS is
4519 a CONSTRUCTOR with an empty element list. */
4521 static enum gimplify_status
4522 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4523 gimple_seq *seq_p)
4525 tree t, from, to, to_ptr;
4526 gcall *gs;
4527 location_t loc = EXPR_LOCATION (*expr_p);
4529 /* Assert our assumptions, to abort instead of producing wrong code
4530 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4531 not be immediately exposed. */
4532 from = TREE_OPERAND (*expr_p, 1);
4533 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4534 from = TREE_OPERAND (from, 0);
4536 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4537 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4539 /* Now proceed. */
4540 to = TREE_OPERAND (*expr_p, 0);
4542 to_ptr = build_fold_addr_expr_loc (loc, to);
4543 gimplify_arg (&to_ptr, seq_p, loc);
4544 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4546 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4548 if (want_value)
4550 /* tmp = memset() */
4551 t = create_tmp_var (TREE_TYPE (to_ptr));
4552 gimple_call_set_lhs (gs, t);
4553 gimplify_seq_add_stmt (seq_p, gs);
4555 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4556 return GS_ALL_DONE;
4559 gimplify_seq_add_stmt (seq_p, gs);
4560 *expr_p = NULL;
4561 return GS_ALL_DONE;
4564 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4565 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4566 assignment. Return non-null if we detect a potential overlap. */
4568 struct gimplify_init_ctor_preeval_data
4570 /* The base decl of the lhs object. May be NULL, in which case we
4571 have to assume the lhs is indirect. */
4572 tree lhs_base_decl;
4574 /* The alias set of the lhs object. */
4575 alias_set_type lhs_alias_set;
4578 static tree
4579 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4581 struct gimplify_init_ctor_preeval_data *data
4582 = (struct gimplify_init_ctor_preeval_data *) xdata;
4583 tree t = *tp;
4585 /* If we find the base object, obviously we have overlap. */
4586 if (data->lhs_base_decl == t)
4587 return t;
4589 /* If the constructor component is indirect, determine if we have a
4590 potential overlap with the lhs. The only bits of information we
4591 have to go on at this point are addressability and alias sets. */
4592 if ((INDIRECT_REF_P (t)
4593 || TREE_CODE (t) == MEM_REF)
4594 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4595 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4596 return t;
4598 /* If the constructor component is a call, determine if it can hide a
4599 potential overlap with the lhs through an INDIRECT_REF like above.
4600 ??? Ugh - this is completely broken. In fact this whole analysis
4601 doesn't look conservative. */
4602 if (TREE_CODE (t) == CALL_EXPR)
4604 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4606 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4607 if (POINTER_TYPE_P (TREE_VALUE (type))
4608 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4609 && alias_sets_conflict_p (data->lhs_alias_set,
4610 get_alias_set
4611 (TREE_TYPE (TREE_VALUE (type)))))
4612 return t;
4615 if (IS_TYPE_OR_DECL_P (t))
4616 *walk_subtrees = 0;
4617 return NULL;
4620 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4621 force values that overlap with the lhs (as described by *DATA)
4622 into temporaries. */
4624 static void
4625 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4626 struct gimplify_init_ctor_preeval_data *data)
4628 enum gimplify_status one;
4630 /* If the value is constant, then there's nothing to pre-evaluate. */
4631 if (TREE_CONSTANT (*expr_p))
4633 /* Ensure it does not have side effects, it might contain a reference to
4634 the object we're initializing. */
4635 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4636 return;
4639 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4640 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4641 return;
4643 /* Recurse for nested constructors. */
4644 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4646 unsigned HOST_WIDE_INT ix;
4647 constructor_elt *ce;
4648 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4650 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4651 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4653 return;
4656 /* If this is a variable sized type, we must remember the size. */
4657 maybe_with_size_expr (expr_p);
4659 /* Gimplify the constructor element to something appropriate for the rhs
4660 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4661 the gimplifier will consider this a store to memory. Doing this
4662 gimplification now means that we won't have to deal with complicated
4663 language-specific trees, nor trees like SAVE_EXPR that can induce
4664 exponential search behavior. */
4665 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4666 if (one == GS_ERROR)
4668 *expr_p = NULL;
4669 return;
4672 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4673 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4674 always be true for all scalars, since is_gimple_mem_rhs insists on a
4675 temporary variable for them. */
4676 if (DECL_P (*expr_p))
4677 return;
4679 /* If this is of variable size, we have no choice but to assume it doesn't
4680 overlap since we can't make a temporary for it. */
4681 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4682 return;
4684 /* Otherwise, we must search for overlap ... */
4685 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4686 return;
4688 /* ... and if found, force the value into a temporary. */
4689 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4692 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4693 a RANGE_EXPR in a CONSTRUCTOR for an array.
4695 var = lower;
4696 loop_entry:
4697 object[var] = value;
4698 if (var == upper)
4699 goto loop_exit;
4700 var = var + 1;
4701 goto loop_entry;
4702 loop_exit:
4704 We increment var _after_ the loop exit check because we might otherwise
4705 fail if upper == TYPE_MAX_VALUE (type for upper).
4707 Note that we never have to deal with SAVE_EXPRs here, because this has
4708 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4710 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4711 gimple_seq *, bool);
4713 static void
4714 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4715 tree value, tree array_elt_type,
4716 gimple_seq *pre_p, bool cleared)
4718 tree loop_entry_label, loop_exit_label, fall_thru_label;
4719 tree var, var_type, cref, tmp;
4721 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4722 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4723 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4725 /* Create and initialize the index variable. */
4726 var_type = TREE_TYPE (upper);
4727 var = create_tmp_var (var_type);
4728 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4730 /* Add the loop entry label. */
4731 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4733 /* Build the reference. */
4734 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4735 var, NULL_TREE, NULL_TREE);
4737 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4738 the store. Otherwise just assign value to the reference. */
4740 if (TREE_CODE (value) == CONSTRUCTOR)
4741 /* NB we might have to call ourself recursively through
4742 gimplify_init_ctor_eval if the value is a constructor. */
4743 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4744 pre_p, cleared);
4745 else
4747 if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue)
4748 != GS_ERROR)
4749 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4752 /* We exit the loop when the index var is equal to the upper bound. */
4753 gimplify_seq_add_stmt (pre_p,
4754 gimple_build_cond (EQ_EXPR, var, upper,
4755 loop_exit_label, fall_thru_label));
4757 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4759 /* Otherwise, increment the index var... */
4760 tmp = build2 (PLUS_EXPR, var_type, var,
4761 fold_convert (var_type, integer_one_node));
4762 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4764 /* ...and jump back to the loop entry. */
4765 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4767 /* Add the loop exit label. */
4768 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4771 /* A subroutine of gimplify_init_constructor. Generate individual
4772 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4773 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4774 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4775 zeroed first. */
4777 static void
4778 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4779 gimple_seq *pre_p, bool cleared)
4781 tree array_elt_type = NULL;
4782 unsigned HOST_WIDE_INT ix;
4783 tree purpose, value;
4785 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4786 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4788 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4790 tree cref;
4792 /* NULL values are created above for gimplification errors. */
4793 if (value == NULL)
4794 continue;
4796 if (cleared && initializer_zerop (value))
4797 continue;
4799 /* ??? Here's to hoping the front end fills in all of the indices,
4800 so we don't have to figure out what's missing ourselves. */
4801 gcc_assert (purpose);
4803 /* Skip zero-sized fields, unless value has side-effects. This can
4804 happen with calls to functions returning a empty type, which
4805 we shouldn't discard. As a number of downstream passes don't
4806 expect sets of empty type fields, we rely on the gimplification of
4807 the MODIFY_EXPR we make below to drop the assignment statement. */
4808 if (!TREE_SIDE_EFFECTS (value)
4809 && TREE_CODE (purpose) == FIELD_DECL
4810 && is_empty_type (TREE_TYPE (purpose)))
4811 continue;
4813 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4814 whole range. */
4815 if (TREE_CODE (purpose) == RANGE_EXPR)
4817 tree lower = TREE_OPERAND (purpose, 0);
4818 tree upper = TREE_OPERAND (purpose, 1);
4820 /* If the lower bound is equal to upper, just treat it as if
4821 upper was the index. */
4822 if (simple_cst_equal (lower, upper))
4823 purpose = upper;
4824 else
4826 gimplify_init_ctor_eval_range (object, lower, upper, value,
4827 array_elt_type, pre_p, cleared);
4828 continue;
4832 if (array_elt_type)
4834 /* Do not use bitsizetype for ARRAY_REF indices. */
4835 if (TYPE_DOMAIN (TREE_TYPE (object)))
4836 purpose
4837 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4838 purpose);
4839 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4840 purpose, NULL_TREE, NULL_TREE);
4842 else
4844 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4845 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4846 unshare_expr (object), purpose, NULL_TREE);
4849 if (TREE_CODE (value) == CONSTRUCTOR
4850 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4851 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4852 pre_p, cleared);
4853 else
4855 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4856 gimplify_and_add (init, pre_p);
4857 ggc_free (init);
4862 /* Return the appropriate RHS predicate for this LHS. */
4864 gimple_predicate
4865 rhs_predicate_for (tree lhs)
4867 if (is_gimple_reg (lhs))
4868 return is_gimple_reg_rhs_or_call;
4869 else
4870 return is_gimple_mem_rhs_or_call;
4873 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4874 before the LHS has been gimplified. */
4876 static gimple_predicate
4877 initial_rhs_predicate_for (tree lhs)
4879 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4880 return is_gimple_reg_rhs_or_call;
4881 else
4882 return is_gimple_mem_rhs_or_call;
4885 /* Gimplify a C99 compound literal expression. This just means adding
4886 the DECL_EXPR before the current statement and using its anonymous
4887 decl instead. */
4889 static enum gimplify_status
4890 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
4891 bool (*gimple_test_f) (tree),
4892 fallback_t fallback)
4894 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
4895 tree decl = DECL_EXPR_DECL (decl_s);
4896 tree init = DECL_INITIAL (decl);
4897 /* Mark the decl as addressable if the compound literal
4898 expression is addressable now, otherwise it is marked too late
4899 after we gimplify the initialization expression. */
4900 if (TREE_ADDRESSABLE (*expr_p))
4901 TREE_ADDRESSABLE (decl) = 1;
4902 /* Otherwise, if we don't need an lvalue and have a literal directly
4903 substitute it. Check if it matches the gimple predicate, as
4904 otherwise we'd generate a new temporary, and we can as well just
4905 use the decl we already have. */
4906 else if (!TREE_ADDRESSABLE (decl)
4907 && !TREE_THIS_VOLATILE (decl)
4908 && init
4909 && (fallback & fb_lvalue) == 0
4910 && gimple_test_f (init))
4912 *expr_p = init;
4913 return GS_OK;
4916 /* If the decl is not addressable, then it is being used in some
4917 expression or on the right hand side of a statement, and it can
4918 be put into a readonly data section. */
4919 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
4920 TREE_READONLY (decl) = 1;
4922 /* This decl isn't mentioned in the enclosing block, so add it to the
4923 list of temps. FIXME it seems a bit of a kludge to say that
4924 anonymous artificial vars aren't pushed, but everything else is. */
4925 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
4926 gimple_add_tmp_var (decl);
4928 gimplify_and_add (decl_s, pre_p);
4929 *expr_p = decl;
4930 return GS_OK;
4933 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4934 return a new CONSTRUCTOR if something changed. */
4936 static tree
4937 optimize_compound_literals_in_ctor (tree orig_ctor)
4939 tree ctor = orig_ctor;
4940 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
4941 unsigned int idx, num = vec_safe_length (elts);
4943 for (idx = 0; idx < num; idx++)
4945 tree value = (*elts)[idx].value;
4946 tree newval = value;
4947 if (TREE_CODE (value) == CONSTRUCTOR)
4948 newval = optimize_compound_literals_in_ctor (value);
4949 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
4951 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
4952 tree decl = DECL_EXPR_DECL (decl_s);
4953 tree init = DECL_INITIAL (decl);
4955 if (!TREE_ADDRESSABLE (value)
4956 && !TREE_ADDRESSABLE (decl)
4957 && init
4958 && TREE_CODE (init) == CONSTRUCTOR)
4959 newval = optimize_compound_literals_in_ctor (init);
4961 if (newval == value)
4962 continue;
4964 if (ctor == orig_ctor)
4966 ctor = copy_node (orig_ctor);
4967 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
4968 elts = CONSTRUCTOR_ELTS (ctor);
4970 (*elts)[idx].value = newval;
4972 return ctor;
4975 /* A subroutine of gimplify_modify_expr. Break out elements of a
4976 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4978 Note that we still need to clear any elements that don't have explicit
4979 initializers, so if not all elements are initialized we keep the
4980 original MODIFY_EXPR, we just remove all of the constructor elements.
4982 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4983 GS_ERROR if we would have to create a temporary when gimplifying
4984 this constructor. Otherwise, return GS_OK.
4986 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4988 static enum gimplify_status
4989 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4990 bool want_value, bool notify_temp_creation)
4992 tree object, ctor, type;
4993 enum gimplify_status ret;
4994 vec<constructor_elt, va_gc> *elts;
4995 bool cleared = false;
4996 bool is_empty_ctor = false;
4997 bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR);
4999 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
5001 if (!notify_temp_creation)
5003 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5004 is_gimple_lvalue, fb_lvalue);
5005 if (ret == GS_ERROR)
5006 return ret;
5009 object = TREE_OPERAND (*expr_p, 0);
5010 ctor = TREE_OPERAND (*expr_p, 1)
5011 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
5012 type = TREE_TYPE (ctor);
5013 elts = CONSTRUCTOR_ELTS (ctor);
5014 ret = GS_ALL_DONE;
5016 switch (TREE_CODE (type))
5018 case RECORD_TYPE:
5019 case UNION_TYPE:
5020 case QUAL_UNION_TYPE:
5021 case ARRAY_TYPE:
5023 /* Use readonly data for initializers of this or smaller size
5024 regardless of the num_nonzero_elements / num_unique_nonzero_elements
5025 ratio. */
5026 const HOST_WIDE_INT min_unique_size = 64;
5027 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
5028 is smaller than this, use readonly data. */
5029 const int unique_nonzero_ratio = 8;
5030 /* True if a single access of the object must be ensured. This is the
5031 case if the target is volatile, the type is non-addressable and more
5032 than one field need to be assigned. */
5033 const bool ensure_single_access
5034 = TREE_THIS_VOLATILE (object)
5035 && !TREE_ADDRESSABLE (type)
5036 && vec_safe_length (elts) > 1;
5037 struct gimplify_init_ctor_preeval_data preeval_data;
5038 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
5039 HOST_WIDE_INT num_unique_nonzero_elements;
5040 bool complete_p, valid_const_initializer;
5042 /* Aggregate types must lower constructors to initialization of
5043 individual elements. The exception is that a CONSTRUCTOR node
5044 with no elements indicates zero-initialization of the whole. */
5045 if (vec_safe_is_empty (elts))
5047 if (notify_temp_creation)
5048 return GS_OK;
5049 is_empty_ctor = true;
5050 break;
5053 /* Fetch information about the constructor to direct later processing.
5054 We might want to make static versions of it in various cases, and
5055 can only do so if it known to be a valid constant initializer. */
5056 valid_const_initializer
5057 = categorize_ctor_elements (ctor, &num_nonzero_elements,
5058 &num_unique_nonzero_elements,
5059 &num_ctor_elements, &complete_p);
5061 /* If a const aggregate variable is being initialized, then it
5062 should never be a lose to promote the variable to be static. */
5063 if (valid_const_initializer
5064 && num_nonzero_elements > 1
5065 && TREE_READONLY (object)
5066 && VAR_P (object)
5067 && !DECL_REGISTER (object)
5068 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))
5069 /* For ctors that have many repeated nonzero elements
5070 represented through RANGE_EXPRs, prefer initializing
5071 those through runtime loops over copies of large amounts
5072 of data from readonly data section. */
5073 && (num_unique_nonzero_elements
5074 > num_nonzero_elements / unique_nonzero_ratio
5075 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
5076 <= (unsigned HOST_WIDE_INT) min_unique_size)))
5078 if (notify_temp_creation)
5079 return GS_ERROR;
5081 DECL_INITIAL (object) = ctor;
5082 TREE_STATIC (object) = 1;
5083 if (!DECL_NAME (object))
5084 DECL_NAME (object) = create_tmp_var_name ("C");
5085 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
5087 /* ??? C++ doesn't automatically append a .<number> to the
5088 assembler name, and even when it does, it looks at FE private
5089 data structures to figure out what that number should be,
5090 which are not set for this variable. I suppose this is
5091 important for local statics for inline functions, which aren't
5092 "local" in the object file sense. So in order to get a unique
5093 TU-local symbol, we must invoke the lhd version now. */
5094 lhd_set_decl_assembler_name (object);
5096 *expr_p = NULL_TREE;
5097 break;
5100 /* If there are "lots" of initialized elements, even discounting
5101 those that are not address constants (and thus *must* be
5102 computed at runtime), then partition the constructor into
5103 constant and non-constant parts. Block copy the constant
5104 parts in, then generate code for the non-constant parts. */
5105 /* TODO. There's code in cp/typeck.c to do this. */
5107 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
5108 /* store_constructor will ignore the clearing of variable-sized
5109 objects. Initializers for such objects must explicitly set
5110 every field that needs to be set. */
5111 cleared = false;
5112 else if (!complete_p)
5113 /* If the constructor isn't complete, clear the whole object
5114 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
5116 ??? This ought not to be needed. For any element not present
5117 in the initializer, we should simply set them to zero. Except
5118 we'd need to *find* the elements that are not present, and that
5119 requires trickery to avoid quadratic compile-time behavior in
5120 large cases or excessive memory use in small cases. */
5121 cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
5122 else if (num_ctor_elements - num_nonzero_elements
5123 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
5124 && num_nonzero_elements < num_ctor_elements / 4)
5125 /* If there are "lots" of zeros, it's more efficient to clear
5126 the memory and then set the nonzero elements. */
5127 cleared = true;
5128 else if (ensure_single_access && num_nonzero_elements == 0)
5129 /* If a single access to the target must be ensured and all elements
5130 are zero, then it's optimal to clear whatever their number. */
5131 cleared = true;
5132 else
5133 cleared = false;
5135 /* If there are "lots" of initialized elements, and all of them
5136 are valid address constants, then the entire initializer can
5137 be dropped to memory, and then memcpy'd out. Don't do this
5138 for sparse arrays, though, as it's more efficient to follow
5139 the standard CONSTRUCTOR behavior of memset followed by
5140 individual element initialization. Also don't do this for small
5141 all-zero initializers (which aren't big enough to merit
5142 clearing), and don't try to make bitwise copies of
5143 TREE_ADDRESSABLE types. */
5144 if (valid_const_initializer
5145 && complete_p
5146 && !(cleared || num_nonzero_elements == 0)
5147 && !TREE_ADDRESSABLE (type))
5149 HOST_WIDE_INT size = int_size_in_bytes (type);
5150 unsigned int align;
5152 /* ??? We can still get unbounded array types, at least
5153 from the C++ front end. This seems wrong, but attempt
5154 to work around it for now. */
5155 if (size < 0)
5157 size = int_size_in_bytes (TREE_TYPE (object));
5158 if (size >= 0)
5159 TREE_TYPE (ctor) = type = TREE_TYPE (object);
5162 /* Find the maximum alignment we can assume for the object. */
5163 /* ??? Make use of DECL_OFFSET_ALIGN. */
5164 if (DECL_P (object))
5165 align = DECL_ALIGN (object);
5166 else
5167 align = TYPE_ALIGN (type);
5169 /* Do a block move either if the size is so small as to make
5170 each individual move a sub-unit move on average, or if it
5171 is so large as to make individual moves inefficient. */
5172 if (size > 0
5173 && num_nonzero_elements > 1
5174 /* For ctors that have many repeated nonzero elements
5175 represented through RANGE_EXPRs, prefer initializing
5176 those through runtime loops over copies of large amounts
5177 of data from readonly data section. */
5178 && (num_unique_nonzero_elements
5179 > num_nonzero_elements / unique_nonzero_ratio
5180 || size <= min_unique_size)
5181 && (size < num_nonzero_elements
5182 || !can_move_by_pieces (size, align)))
5184 if (notify_temp_creation)
5185 return GS_ERROR;
5187 walk_tree (&ctor, force_labels_r, NULL, NULL);
5188 ctor = tree_output_constant_def (ctor);
5189 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
5190 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
5191 TREE_OPERAND (*expr_p, 1) = ctor;
5193 /* This is no longer an assignment of a CONSTRUCTOR, but
5194 we still may have processing to do on the LHS. So
5195 pretend we didn't do anything here to let that happen. */
5196 return GS_UNHANDLED;
5200 /* If a single access to the target must be ensured and there are
5201 nonzero elements or the zero elements are not assigned en masse,
5202 initialize the target from a temporary. */
5203 if (ensure_single_access && (num_nonzero_elements > 0 || !cleared))
5205 if (notify_temp_creation)
5206 return GS_ERROR;
5208 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
5209 TREE_OPERAND (*expr_p, 0) = temp;
5210 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
5211 *expr_p,
5212 build2 (MODIFY_EXPR, void_type_node,
5213 object, temp));
5214 return GS_OK;
5217 if (notify_temp_creation)
5218 return GS_OK;
5220 /* If there are nonzero elements and if needed, pre-evaluate to capture
5221 elements overlapping with the lhs into temporaries. We must do this
5222 before clearing to fetch the values before they are zeroed-out. */
5223 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
5225 preeval_data.lhs_base_decl = get_base_address (object);
5226 if (!DECL_P (preeval_data.lhs_base_decl))
5227 preeval_data.lhs_base_decl = NULL;
5228 preeval_data.lhs_alias_set = get_alias_set (object);
5230 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
5231 pre_p, post_p, &preeval_data);
5234 bool ctor_has_side_effects_p
5235 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
5237 if (cleared)
5239 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5240 Note that we still have to gimplify, in order to handle the
5241 case of variable sized types. Avoid shared tree structures. */
5242 CONSTRUCTOR_ELTS (ctor) = NULL;
5243 TREE_SIDE_EFFECTS (ctor) = 0;
5244 object = unshare_expr (object);
5245 gimplify_stmt (expr_p, pre_p);
5248 /* If we have not block cleared the object, or if there are nonzero
5249 elements in the constructor, or if the constructor has side effects,
5250 add assignments to the individual scalar fields of the object. */
5251 if (!cleared
5252 || num_nonzero_elements > 0
5253 || ctor_has_side_effects_p)
5254 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
5256 *expr_p = NULL_TREE;
5258 break;
5260 case COMPLEX_TYPE:
5262 tree r, i;
5264 if (notify_temp_creation)
5265 return GS_OK;
5267 /* Extract the real and imaginary parts out of the ctor. */
5268 gcc_assert (elts->length () == 2);
5269 r = (*elts)[0].value;
5270 i = (*elts)[1].value;
5271 if (r == NULL || i == NULL)
5273 tree zero = build_zero_cst (TREE_TYPE (type));
5274 if (r == NULL)
5275 r = zero;
5276 if (i == NULL)
5277 i = zero;
5280 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5281 represent creation of a complex value. */
5282 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
5284 ctor = build_complex (type, r, i);
5285 TREE_OPERAND (*expr_p, 1) = ctor;
5287 else
5289 ctor = build2 (COMPLEX_EXPR, type, r, i);
5290 TREE_OPERAND (*expr_p, 1) = ctor;
5291 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
5292 pre_p,
5293 post_p,
5294 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
5295 fb_rvalue);
5298 break;
5300 case VECTOR_TYPE:
5302 unsigned HOST_WIDE_INT ix;
5303 constructor_elt *ce;
5305 if (notify_temp_creation)
5306 return GS_OK;
5308 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5309 if (TREE_CONSTANT (ctor))
5311 bool constant_p = true;
5312 tree value;
5314 /* Even when ctor is constant, it might contain non-*_CST
5315 elements, such as addresses or trapping values like
5316 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5317 in VECTOR_CST nodes. */
5318 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5319 if (!CONSTANT_CLASS_P (value))
5321 constant_p = false;
5322 break;
5325 if (constant_p)
5327 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5328 break;
5331 TREE_CONSTANT (ctor) = 0;
5334 /* Vector types use CONSTRUCTOR all the way through gimple
5335 compilation as a general initializer. */
5336 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5338 enum gimplify_status tret;
5339 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5340 fb_rvalue);
5341 if (tret == GS_ERROR)
5342 ret = GS_ERROR;
5343 else if (TREE_STATIC (ctor)
5344 && !initializer_constant_valid_p (ce->value,
5345 TREE_TYPE (ce->value)))
5346 TREE_STATIC (ctor) = 0;
5348 recompute_constructor_flags (ctor);
5349 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5350 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5352 break;
5354 default:
5355 /* So how did we get a CONSTRUCTOR for a scalar type? */
5356 gcc_unreachable ();
5359 if (ret == GS_ERROR)
5360 return GS_ERROR;
5361 /* If we have gimplified both sides of the initializer but have
5362 not emitted an assignment, do so now. */
5363 if (*expr_p)
5365 tree lhs = TREE_OPERAND (*expr_p, 0);
5366 tree rhs = TREE_OPERAND (*expr_p, 1);
5367 if (want_value && object == lhs)
5368 lhs = unshare_expr (lhs);
5369 gassign *init = gimple_build_assign (lhs, rhs);
5370 gimplify_seq_add_stmt (pre_p, init);
5372 if (want_value)
5374 *expr_p = object;
5375 ret = GS_OK;
5377 else
5379 *expr_p = NULL;
5380 ret = GS_ALL_DONE;
5383 /* If the user requests to initialize automatic variables, we
5384 should initialize paddings inside the variable. Add a call to
5385 __builtin_clear_pading (&object, 0, for_auto_init = true) to
5386 initialize paddings of object always to zero regardless of
5387 INIT_TYPE. Note, we will not insert this call if the aggregate
5388 variable has be completely cleared already or it's initialized
5389 with an empty constructor. We cannot insert this call if the
5390 variable is a gimple register since __builtin_clear_padding will take
5391 the address of the variable. As a result, if a long double/_Complex long
5392 double variable will be spilled into stack later, its padding cannot
5393 be cleared with __builtin_clear_padding. We should clear its padding
5394 when it is spilled into memory. */
5395 if (is_init_expr
5396 && !is_gimple_reg (object)
5397 && clear_padding_type_may_have_padding_p (type)
5398 && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor)
5399 || !AGGREGATE_TYPE_P (type))
5400 && is_var_need_auto_init (object))
5401 gimple_add_padding_init_for_auto_var (object, false, pre_p);
5403 return ret;
5406 /* Given a pointer value OP0, return a simplified version of an
5407 indirection through OP0, or NULL_TREE if no simplification is
5408 possible. This may only be applied to a rhs of an expression.
5409 Note that the resulting type may be different from the type pointed
5410 to in the sense that it is still compatible from the langhooks
5411 point of view. */
5413 static tree
5414 gimple_fold_indirect_ref_rhs (tree t)
5416 return gimple_fold_indirect_ref (t);
5419 /* Subroutine of gimplify_modify_expr to do simplifications of
5420 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5421 something changes. */
5423 static enum gimplify_status
5424 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5425 gimple_seq *pre_p, gimple_seq *post_p,
5426 bool want_value)
5428 enum gimplify_status ret = GS_UNHANDLED;
5429 bool changed;
5433 changed = false;
5434 switch (TREE_CODE (*from_p))
5436 case VAR_DECL:
5437 /* If we're assigning from a read-only variable initialized with
5438 a constructor and not volatile, do the direct assignment from
5439 the constructor, but only if the target is not volatile either
5440 since this latter assignment might end up being done on a per
5441 field basis. However, if the target is volatile and the type
5442 is aggregate and non-addressable, gimplify_init_constructor
5443 knows that it needs to ensure a single access to the target
5444 and it will return GS_OK only in this case. */
5445 if (TREE_READONLY (*from_p)
5446 && DECL_INITIAL (*from_p)
5447 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR
5448 && !TREE_THIS_VOLATILE (*from_p)
5449 && (!TREE_THIS_VOLATILE (*to_p)
5450 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p))
5451 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p)))))
5453 tree old_from = *from_p;
5454 enum gimplify_status subret;
5456 /* Move the constructor into the RHS. */
5457 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5459 /* Let's see if gimplify_init_constructor will need to put
5460 it in memory. */
5461 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5462 false, true);
5463 if (subret == GS_ERROR)
5465 /* If so, revert the change. */
5466 *from_p = old_from;
5468 else
5470 ret = GS_OK;
5471 changed = true;
5474 break;
5475 case INDIRECT_REF:
5477 /* If we have code like
5479 *(const A*)(A*)&x
5481 where the type of "x" is a (possibly cv-qualified variant
5482 of "A"), treat the entire expression as identical to "x".
5483 This kind of code arises in C++ when an object is bound
5484 to a const reference, and if "x" is a TARGET_EXPR we want
5485 to take advantage of the optimization below. */
5486 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5487 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5488 if (t)
5490 if (TREE_THIS_VOLATILE (t) != volatile_p)
5492 if (DECL_P (t))
5493 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5494 build_fold_addr_expr (t));
5495 if (REFERENCE_CLASS_P (t))
5496 TREE_THIS_VOLATILE (t) = volatile_p;
5498 *from_p = t;
5499 ret = GS_OK;
5500 changed = true;
5502 break;
5505 case TARGET_EXPR:
5507 /* If we are initializing something from a TARGET_EXPR, strip the
5508 TARGET_EXPR and initialize it directly, if possible. This can't
5509 be done if the initializer is void, since that implies that the
5510 temporary is set in some non-trivial way.
5512 ??? What about code that pulls out the temp and uses it
5513 elsewhere? I think that such code never uses the TARGET_EXPR as
5514 an initializer. If I'm wrong, we'll die because the temp won't
5515 have any RTL. In that case, I guess we'll need to replace
5516 references somehow. */
5517 tree init = TARGET_EXPR_INITIAL (*from_p);
5519 if (init
5520 && (TREE_CODE (*expr_p) != MODIFY_EXPR
5521 || !TARGET_EXPR_NO_ELIDE (*from_p))
5522 && !VOID_TYPE_P (TREE_TYPE (init)))
5524 *from_p = init;
5525 ret = GS_OK;
5526 changed = true;
5529 break;
5531 case COMPOUND_EXPR:
5532 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5533 caught. */
5534 gimplify_compound_expr (from_p, pre_p, true);
5535 ret = GS_OK;
5536 changed = true;
5537 break;
5539 case CONSTRUCTOR:
5540 /* If we already made some changes, let the front end have a
5541 crack at this before we break it down. */
5542 if (ret != GS_UNHANDLED)
5543 break;
5545 /* If we're initializing from a CONSTRUCTOR, break this into
5546 individual MODIFY_EXPRs. */
5547 ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5548 false);
5549 return ret;
5551 case COND_EXPR:
5552 /* If we're assigning to a non-register type, push the assignment
5553 down into the branches. This is mandatory for ADDRESSABLE types,
5554 since we cannot generate temporaries for such, but it saves a
5555 copy in other cases as well. */
5556 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5558 /* This code should mirror the code in gimplify_cond_expr. */
5559 enum tree_code code = TREE_CODE (*expr_p);
5560 tree cond = *from_p;
5561 tree result = *to_p;
5563 ret = gimplify_expr (&result, pre_p, post_p,
5564 is_gimple_lvalue, fb_lvalue);
5565 if (ret != GS_ERROR)
5566 ret = GS_OK;
5568 /* If we are going to write RESULT more than once, clear
5569 TREE_READONLY flag, otherwise we might incorrectly promote
5570 the variable to static const and initialize it at compile
5571 time in one of the branches. */
5572 if (VAR_P (result)
5573 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5574 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5575 TREE_READONLY (result) = 0;
5576 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5577 TREE_OPERAND (cond, 1)
5578 = build2 (code, void_type_node, result,
5579 TREE_OPERAND (cond, 1));
5580 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5581 TREE_OPERAND (cond, 2)
5582 = build2 (code, void_type_node, unshare_expr (result),
5583 TREE_OPERAND (cond, 2));
5585 TREE_TYPE (cond) = void_type_node;
5586 recalculate_side_effects (cond);
5588 if (want_value)
5590 gimplify_and_add (cond, pre_p);
5591 *expr_p = unshare_expr (result);
5593 else
5594 *expr_p = cond;
5595 return ret;
5597 break;
5599 case CALL_EXPR:
5600 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5601 return slot so that we don't generate a temporary. */
5602 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5603 && aggregate_value_p (*from_p, *from_p))
5605 bool use_target;
5607 if (!(rhs_predicate_for (*to_p))(*from_p))
5608 /* If we need a temporary, *to_p isn't accurate. */
5609 use_target = false;
5610 /* It's OK to use the return slot directly unless it's an NRV. */
5611 else if (TREE_CODE (*to_p) == RESULT_DECL
5612 && DECL_NAME (*to_p) == NULL_TREE
5613 && needs_to_live_in_memory (*to_p))
5614 use_target = true;
5615 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5616 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5617 /* Don't force regs into memory. */
5618 use_target = false;
5619 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5620 /* It's OK to use the target directly if it's being
5621 initialized. */
5622 use_target = true;
5623 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5624 != INTEGER_CST)
5625 /* Always use the target and thus RSO for variable-sized types.
5626 GIMPLE cannot deal with a variable-sized assignment
5627 embedded in a call statement. */
5628 use_target = true;
5629 else if (TREE_CODE (*to_p) != SSA_NAME
5630 && (!is_gimple_variable (*to_p)
5631 || needs_to_live_in_memory (*to_p)))
5632 /* Don't use the original target if it's already addressable;
5633 if its address escapes, and the called function uses the
5634 NRV optimization, a conforming program could see *to_p
5635 change before the called function returns; see c++/19317.
5636 When optimizing, the return_slot pass marks more functions
5637 as safe after we have escape info. */
5638 use_target = false;
5639 else
5640 use_target = true;
5642 if (use_target)
5644 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5645 mark_addressable (*to_p);
5648 break;
5650 case WITH_SIZE_EXPR:
5651 /* Likewise for calls that return an aggregate of non-constant size,
5652 since we would not be able to generate a temporary at all. */
5653 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5655 *from_p = TREE_OPERAND (*from_p, 0);
5656 /* We don't change ret in this case because the
5657 WITH_SIZE_EXPR might have been added in
5658 gimplify_modify_expr, so returning GS_OK would lead to an
5659 infinite loop. */
5660 changed = true;
5662 break;
5664 /* If we're initializing from a container, push the initialization
5665 inside it. */
5666 case CLEANUP_POINT_EXPR:
5667 case BIND_EXPR:
5668 case STATEMENT_LIST:
5670 tree wrap = *from_p;
5671 tree t;
5673 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5674 fb_lvalue);
5675 if (ret != GS_ERROR)
5676 ret = GS_OK;
5678 t = voidify_wrapper_expr (wrap, *expr_p);
5679 gcc_assert (t == *expr_p);
5681 if (want_value)
5683 gimplify_and_add (wrap, pre_p);
5684 *expr_p = unshare_expr (*to_p);
5686 else
5687 *expr_p = wrap;
5688 return GS_OK;
5691 case NOP_EXPR:
5692 /* Pull out compound literal expressions from a NOP_EXPR.
5693 Those are created in the C FE to drop qualifiers during
5694 lvalue conversion. */
5695 if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
5696 && tree_ssa_useless_type_conversion (*from_p))
5698 *from_p = TREE_OPERAND (*from_p, 0);
5699 ret = GS_OK;
5700 changed = true;
5702 break;
5704 case COMPOUND_LITERAL_EXPR:
5706 tree complit = TREE_OPERAND (*expr_p, 1);
5707 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5708 tree decl = DECL_EXPR_DECL (decl_s);
5709 tree init = DECL_INITIAL (decl);
5711 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5712 into struct T x = { 0, 1, 2 } if the address of the
5713 compound literal has never been taken. */
5714 if (!TREE_ADDRESSABLE (complit)
5715 && !TREE_ADDRESSABLE (decl)
5716 && init)
5718 *expr_p = copy_node (*expr_p);
5719 TREE_OPERAND (*expr_p, 1) = init;
5720 return GS_OK;
5724 default:
5725 break;
5728 while (changed);
5730 return ret;
5734 /* Return true if T looks like a valid GIMPLE statement. */
5736 static bool
5737 is_gimple_stmt (tree t)
5739 const enum tree_code code = TREE_CODE (t);
5741 switch (code)
5743 case NOP_EXPR:
5744 /* The only valid NOP_EXPR is the empty statement. */
5745 return IS_EMPTY_STMT (t);
5747 case BIND_EXPR:
5748 case COND_EXPR:
5749 /* These are only valid if they're void. */
5750 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5752 case SWITCH_EXPR:
5753 case GOTO_EXPR:
5754 case RETURN_EXPR:
5755 case LABEL_EXPR:
5756 case CASE_LABEL_EXPR:
5757 case TRY_CATCH_EXPR:
5758 case TRY_FINALLY_EXPR:
5759 case EH_FILTER_EXPR:
5760 case CATCH_EXPR:
5761 case ASM_EXPR:
5762 case STATEMENT_LIST:
5763 case OACC_PARALLEL:
5764 case OACC_KERNELS:
5765 case OACC_SERIAL:
5766 case OACC_DATA:
5767 case OACC_HOST_DATA:
5768 case OACC_DECLARE:
5769 case OACC_UPDATE:
5770 case OACC_ENTER_DATA:
5771 case OACC_EXIT_DATA:
5772 case OACC_CACHE:
5773 case OMP_PARALLEL:
5774 case OMP_FOR:
5775 case OMP_SIMD:
5776 case OMP_DISTRIBUTE:
5777 case OMP_LOOP:
5778 case OACC_LOOP:
5779 case OMP_SCAN:
5780 case OMP_SCOPE:
5781 case OMP_SECTIONS:
5782 case OMP_SECTION:
5783 case OMP_SINGLE:
5784 case OMP_MASTER:
5785 case OMP_MASKED:
5786 case OMP_TASKGROUP:
5787 case OMP_ORDERED:
5788 case OMP_CRITICAL:
5789 case OMP_TASK:
5790 case OMP_TARGET:
5791 case OMP_TARGET_DATA:
5792 case OMP_TARGET_UPDATE:
5793 case OMP_TARGET_ENTER_DATA:
5794 case OMP_TARGET_EXIT_DATA:
5795 case OMP_TASKLOOP:
5796 case OMP_TEAMS:
5797 /* These are always void. */
5798 return true;
5800 case CALL_EXPR:
5801 case MODIFY_EXPR:
5802 case PREDICT_EXPR:
5803 /* These are valid regardless of their type. */
5804 return true;
5806 default:
5807 return false;
5812 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5813 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
5815 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5816 other, unmodified part of the complex object just before the total store.
5817 As a consequence, if the object is still uninitialized, an undefined value
5818 will be loaded into a register, which may result in a spurious exception
5819 if the register is floating-point and the value happens to be a signaling
5820 NaN for example. Then the fully-fledged complex operations lowering pass
5821 followed by a DCE pass are necessary in order to fix things up. */
5823 static enum gimplify_status
5824 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5825 bool want_value)
5827 enum tree_code code, ocode;
5828 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5830 lhs = TREE_OPERAND (*expr_p, 0);
5831 rhs = TREE_OPERAND (*expr_p, 1);
5832 code = TREE_CODE (lhs);
5833 lhs = TREE_OPERAND (lhs, 0);
5835 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5836 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5837 suppress_warning (other);
5838 other = get_formal_tmp_var (other, pre_p);
5840 realpart = code == REALPART_EXPR ? rhs : other;
5841 imagpart = code == REALPART_EXPR ? other : rhs;
5843 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5844 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5845 else
5846 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5848 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5849 *expr_p = (want_value) ? rhs : NULL_TREE;
5851 return GS_ALL_DONE;
5854 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5856 modify_expr
5857 : varname '=' rhs
5858 | '*' ID '=' rhs
5860 PRE_P points to the list where side effects that must happen before
5861 *EXPR_P should be stored.
5863 POST_P points to the list where side effects that must happen after
5864 *EXPR_P should be stored.
5866 WANT_VALUE is nonzero iff we want to use the value of this expression
5867 in another expression. */
5869 static enum gimplify_status
5870 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5871 bool want_value)
5873 tree *from_p = &TREE_OPERAND (*expr_p, 1);
5874 tree *to_p = &TREE_OPERAND (*expr_p, 0);
5875 enum gimplify_status ret = GS_UNHANDLED;
5876 gimple *assign;
5877 location_t loc = EXPR_LOCATION (*expr_p);
5878 gimple_stmt_iterator gsi;
5880 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
5881 || TREE_CODE (*expr_p) == INIT_EXPR);
5883 /* Trying to simplify a clobber using normal logic doesn't work,
5884 so handle it here. */
5885 if (TREE_CLOBBER_P (*from_p))
5887 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5888 if (ret == GS_ERROR)
5889 return ret;
5890 gcc_assert (!want_value);
5891 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
5893 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
5894 pre_p, post_p);
5895 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
5897 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
5898 *expr_p = NULL;
5899 return GS_ALL_DONE;
5902 /* Insert pointer conversions required by the middle-end that are not
5903 required by the frontend. This fixes middle-end type checking for
5904 for example gcc.dg/redecl-6.c. */
5905 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
5907 STRIP_USELESS_TYPE_CONVERSION (*from_p);
5908 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
5909 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
5912 /* See if any simplifications can be done based on what the RHS is. */
5913 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5914 want_value);
5915 if (ret != GS_UNHANDLED)
5916 return ret;
5918 /* For empty types only gimplify the left hand side and right hand
5919 side as statements and throw away the assignment. Do this after
5920 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5921 types properly. */
5922 if (is_empty_type (TREE_TYPE (*from_p))
5923 && !want_value
5924 /* Don't do this for calls that return addressable types, expand_call
5925 relies on those having a lhs. */
5926 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
5927 && TREE_CODE (*from_p) == CALL_EXPR))
5929 gimplify_stmt (from_p, pre_p);
5930 gimplify_stmt (to_p, pre_p);
5931 *expr_p = NULL_TREE;
5932 return GS_ALL_DONE;
5935 /* If the value being copied is of variable width, compute the length
5936 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5937 before gimplifying any of the operands so that we can resolve any
5938 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5939 the size of the expression to be copied, not of the destination, so
5940 that is what we must do here. */
5941 maybe_with_size_expr (from_p);
5943 /* As a special case, we have to temporarily allow for assignments
5944 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5945 a toplevel statement, when gimplifying the GENERIC expression
5946 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5947 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5949 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5950 prevent gimplify_expr from trying to create a new temporary for
5951 foo's LHS, we tell it that it should only gimplify until it
5952 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5953 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5954 and all we need to do here is set 'a' to be its LHS. */
5956 /* Gimplify the RHS first for C++17 and bug 71104. */
5957 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
5958 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
5959 if (ret == GS_ERROR)
5960 return ret;
5962 /* Then gimplify the LHS. */
5963 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5964 twice we have to make sure to gimplify into non-SSA as otherwise
5965 the abnormal edge added later will make those defs not dominate
5966 their uses.
5967 ??? Technically this applies only to the registers used in the
5968 resulting non-register *TO_P. */
5969 bool saved_into_ssa = gimplify_ctxp->into_ssa;
5970 if (saved_into_ssa
5971 && TREE_CODE (*from_p) == CALL_EXPR
5972 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
5973 gimplify_ctxp->into_ssa = false;
5974 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5975 gimplify_ctxp->into_ssa = saved_into_ssa;
5976 if (ret == GS_ERROR)
5977 return ret;
5979 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5980 guess for the predicate was wrong. */
5981 gimple_predicate final_pred = rhs_predicate_for (*to_p);
5982 if (final_pred != initial_pred)
5984 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
5985 if (ret == GS_ERROR)
5986 return ret;
5989 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5990 size as argument to the call. */
5991 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5993 tree call = TREE_OPERAND (*from_p, 0);
5994 tree vlasize = TREE_OPERAND (*from_p, 1);
5996 if (TREE_CODE (call) == CALL_EXPR
5997 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
5999 int nargs = call_expr_nargs (call);
6000 tree type = TREE_TYPE (call);
6001 tree ap = CALL_EXPR_ARG (call, 0);
6002 tree tag = CALL_EXPR_ARG (call, 1);
6003 tree aptag = CALL_EXPR_ARG (call, 2);
6004 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
6005 IFN_VA_ARG, type,
6006 nargs + 1, ap, tag,
6007 aptag, vlasize);
6008 TREE_OPERAND (*from_p, 0) = newcall;
6012 /* Now see if the above changed *from_p to something we handle specially. */
6013 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
6014 want_value);
6015 if (ret != GS_UNHANDLED)
6016 return ret;
6018 /* If we've got a variable sized assignment between two lvalues (i.e. does
6019 not involve a call), then we can make things a bit more straightforward
6020 by converting the assignment to memcpy or memset. */
6021 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
6023 tree from = TREE_OPERAND (*from_p, 0);
6024 tree size = TREE_OPERAND (*from_p, 1);
6026 if (TREE_CODE (from) == CONSTRUCTOR)
6027 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
6029 if (is_gimple_addressable (from))
6031 *from_p = from;
6032 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
6033 pre_p);
6037 /* Transform partial stores to non-addressable complex variables into
6038 total stores. This allows us to use real instead of virtual operands
6039 for these variables, which improves optimization. */
6040 if ((TREE_CODE (*to_p) == REALPART_EXPR
6041 || TREE_CODE (*to_p) == IMAGPART_EXPR)
6042 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
6043 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
6045 /* Try to alleviate the effects of the gimplification creating artificial
6046 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
6047 make sure not to create DECL_DEBUG_EXPR links across functions. */
6048 if (!gimplify_ctxp->into_ssa
6049 && VAR_P (*from_p)
6050 && DECL_IGNORED_P (*from_p)
6051 && DECL_P (*to_p)
6052 && !DECL_IGNORED_P (*to_p)
6053 && decl_function_context (*to_p) == current_function_decl
6054 && decl_function_context (*from_p) == current_function_decl)
6056 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
6057 DECL_NAME (*from_p)
6058 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
6059 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
6060 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
6063 if (want_value && TREE_THIS_VOLATILE (*to_p))
6064 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
6066 if (TREE_CODE (*from_p) == CALL_EXPR)
6068 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
6069 instead of a GIMPLE_ASSIGN. */
6070 gcall *call_stmt;
6071 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
6073 /* Gimplify internal functions created in the FEs. */
6074 int nargs = call_expr_nargs (*from_p), i;
6075 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
6076 auto_vec<tree> vargs (nargs);
6078 for (i = 0; i < nargs; i++)
6080 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
6081 EXPR_LOCATION (*from_p));
6082 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
6084 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
6085 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
6086 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
6088 else
6090 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
6091 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
6092 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
6093 tree fndecl = get_callee_fndecl (*from_p);
6094 if (fndecl
6095 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
6096 && call_expr_nargs (*from_p) == 3)
6097 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
6098 CALL_EXPR_ARG (*from_p, 0),
6099 CALL_EXPR_ARG (*from_p, 1),
6100 CALL_EXPR_ARG (*from_p, 2));
6101 else
6103 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
6106 notice_special_calls (call_stmt);
6107 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
6108 gimple_call_set_lhs (call_stmt, *to_p);
6109 else if (TREE_CODE (*to_p) == SSA_NAME)
6110 /* The above is somewhat premature, avoid ICEing later for a
6111 SSA name w/o a definition. We may have uses in the GIMPLE IL.
6112 ??? This doesn't make it a default-def. */
6113 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
6115 assign = call_stmt;
6117 else
6119 assign = gimple_build_assign (*to_p, *from_p);
6120 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
6121 if (COMPARISON_CLASS_P (*from_p))
6122 copy_warning (assign, *from_p);
6125 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
6127 /* We should have got an SSA name from the start. */
6128 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
6129 || ! gimple_in_ssa_p (cfun));
6132 gimplify_seq_add_stmt (pre_p, assign);
6133 gsi = gsi_last (*pre_p);
6134 maybe_fold_stmt (&gsi);
6136 if (want_value)
6138 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
6139 return GS_OK;
6141 else
6142 *expr_p = NULL;
6144 return GS_ALL_DONE;
6147 /* Gimplify a comparison between two variable-sized objects. Do this
6148 with a call to BUILT_IN_MEMCMP. */
6150 static enum gimplify_status
6151 gimplify_variable_sized_compare (tree *expr_p)
6153 location_t loc = EXPR_LOCATION (*expr_p);
6154 tree op0 = TREE_OPERAND (*expr_p, 0);
6155 tree op1 = TREE_OPERAND (*expr_p, 1);
6156 tree t, arg, dest, src, expr;
6158 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
6159 arg = unshare_expr (arg);
6160 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
6161 src = build_fold_addr_expr_loc (loc, op1);
6162 dest = build_fold_addr_expr_loc (loc, op0);
6163 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
6164 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
6166 expr
6167 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
6168 SET_EXPR_LOCATION (expr, loc);
6169 *expr_p = expr;
6171 return GS_OK;
6174 /* Gimplify a comparison between two aggregate objects of integral scalar
6175 mode as a comparison between the bitwise equivalent scalar values. */
6177 static enum gimplify_status
6178 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
6180 location_t loc = EXPR_LOCATION (*expr_p);
6181 tree op0 = TREE_OPERAND (*expr_p, 0);
6182 tree op1 = TREE_OPERAND (*expr_p, 1);
6184 tree type = TREE_TYPE (op0);
6185 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
6187 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
6188 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
6190 *expr_p
6191 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
6193 return GS_OK;
6196 /* Gimplify an expression sequence. This function gimplifies each
6197 expression and rewrites the original expression with the last
6198 expression of the sequence in GIMPLE form.
6200 PRE_P points to the list where the side effects for all the
6201 expressions in the sequence will be emitted.
6203 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6205 static enum gimplify_status
6206 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
6208 tree t = *expr_p;
6212 tree *sub_p = &TREE_OPERAND (t, 0);
6214 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
6215 gimplify_compound_expr (sub_p, pre_p, false);
6216 else
6217 gimplify_stmt (sub_p, pre_p);
6219 t = TREE_OPERAND (t, 1);
6221 while (TREE_CODE (t) == COMPOUND_EXPR);
6223 *expr_p = t;
6224 if (want_value)
6225 return GS_OK;
6226 else
6228 gimplify_stmt (expr_p, pre_p);
6229 return GS_ALL_DONE;
6233 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6234 gimplify. After gimplification, EXPR_P will point to a new temporary
6235 that holds the original value of the SAVE_EXPR node.
6237 PRE_P points to the list where side effects that must happen before
6238 *EXPR_P should be stored. */
6240 static enum gimplify_status
6241 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6243 enum gimplify_status ret = GS_ALL_DONE;
6244 tree val;
6246 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
6247 val = TREE_OPERAND (*expr_p, 0);
6249 if (TREE_TYPE (val) == error_mark_node)
6250 return GS_ERROR;
6252 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6253 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
6255 /* The operand may be a void-valued expression. It is
6256 being executed only for its side-effects. */
6257 if (TREE_TYPE (val) == void_type_node)
6259 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
6260 is_gimple_stmt, fb_none);
6261 val = NULL;
6263 else
6264 /* The temporary may not be an SSA name as later abnormal and EH
6265 control flow may invalidate use/def domination. When in SSA
6266 form then assume there are no such issues and SAVE_EXPRs only
6267 appear via GENERIC foldings. */
6268 val = get_initialized_tmp_var (val, pre_p, post_p,
6269 gimple_in_ssa_p (cfun));
6271 TREE_OPERAND (*expr_p, 0) = val;
6272 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
6275 *expr_p = val;
6277 return ret;
6280 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6282 unary_expr
6283 : ...
6284 | '&' varname
6287 PRE_P points to the list where side effects that must happen before
6288 *EXPR_P should be stored.
6290 POST_P points to the list where side effects that must happen after
6291 *EXPR_P should be stored. */
6293 static enum gimplify_status
6294 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6296 tree expr = *expr_p;
6297 tree op0 = TREE_OPERAND (expr, 0);
6298 enum gimplify_status ret;
6299 location_t loc = EXPR_LOCATION (*expr_p);
6301 switch (TREE_CODE (op0))
6303 case INDIRECT_REF:
6304 do_indirect_ref:
6305 /* Check if we are dealing with an expression of the form '&*ptr'.
6306 While the front end folds away '&*ptr' into 'ptr', these
6307 expressions may be generated internally by the compiler (e.g.,
6308 builtins like __builtin_va_end). */
6309 /* Caution: the silent array decomposition semantics we allow for
6310 ADDR_EXPR means we can't always discard the pair. */
6311 /* Gimplification of the ADDR_EXPR operand may drop
6312 cv-qualification conversions, so make sure we add them if
6313 needed. */
6315 tree op00 = TREE_OPERAND (op0, 0);
6316 tree t_expr = TREE_TYPE (expr);
6317 tree t_op00 = TREE_TYPE (op00);
6319 if (!useless_type_conversion_p (t_expr, t_op00))
6320 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
6321 *expr_p = op00;
6322 ret = GS_OK;
6324 break;
6326 case VIEW_CONVERT_EXPR:
6327 /* Take the address of our operand and then convert it to the type of
6328 this ADDR_EXPR.
6330 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6331 all clear. The impact of this transformation is even less clear. */
6333 /* If the operand is a useless conversion, look through it. Doing so
6334 guarantees that the ADDR_EXPR and its operand will remain of the
6335 same type. */
6336 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
6337 op0 = TREE_OPERAND (op0, 0);
6339 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
6340 build_fold_addr_expr_loc (loc,
6341 TREE_OPERAND (op0, 0)));
6342 ret = GS_OK;
6343 break;
6345 case MEM_REF:
6346 if (integer_zerop (TREE_OPERAND (op0, 1)))
6347 goto do_indirect_ref;
6349 /* fall through */
6351 default:
6352 /* If we see a call to a declared builtin or see its address
6353 being taken (we can unify those cases here) then we can mark
6354 the builtin for implicit generation by GCC. */
6355 if (TREE_CODE (op0) == FUNCTION_DECL
6356 && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6357 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6358 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6360 /* We use fb_either here because the C frontend sometimes takes
6361 the address of a call that returns a struct; see
6362 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6363 the implied temporary explicit. */
6365 /* Make the operand addressable. */
6366 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6367 is_gimple_addressable, fb_either);
6368 if (ret == GS_ERROR)
6369 break;
6371 /* Then mark it. Beware that it may not be possible to do so directly
6372 if a temporary has been created by the gimplification. */
6373 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6375 op0 = TREE_OPERAND (expr, 0);
6377 /* For various reasons, the gimplification of the expression
6378 may have made a new INDIRECT_REF. */
6379 if (TREE_CODE (op0) == INDIRECT_REF
6380 || (TREE_CODE (op0) == MEM_REF
6381 && integer_zerop (TREE_OPERAND (op0, 1))))
6382 goto do_indirect_ref;
6384 mark_addressable (TREE_OPERAND (expr, 0));
6386 /* The FEs may end up building ADDR_EXPRs early on a decl with
6387 an incomplete type. Re-build ADDR_EXPRs in canonical form
6388 here. */
6389 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6390 *expr_p = build_fold_addr_expr (op0);
6392 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6393 recompute_tree_invariant_for_addr_expr (*expr_p);
6395 /* If we re-built the ADDR_EXPR add a conversion to the original type
6396 if required. */
6397 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6398 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6400 break;
6403 return ret;
6406 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6407 value; output operands should be a gimple lvalue. */
6409 static enum gimplify_status
6410 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6412 tree expr;
6413 int noutputs;
6414 const char **oconstraints;
6415 int i;
6416 tree link;
6417 const char *constraint;
6418 bool allows_mem, allows_reg, is_inout;
6419 enum gimplify_status ret, tret;
6420 gasm *stmt;
6421 vec<tree, va_gc> *inputs;
6422 vec<tree, va_gc> *outputs;
6423 vec<tree, va_gc> *clobbers;
6424 vec<tree, va_gc> *labels;
6425 tree link_next;
6427 expr = *expr_p;
6428 noutputs = list_length (ASM_OUTPUTS (expr));
6429 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6431 inputs = NULL;
6432 outputs = NULL;
6433 clobbers = NULL;
6434 labels = NULL;
6436 ret = GS_ALL_DONE;
6437 link_next = NULL_TREE;
6438 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6440 bool ok;
6441 size_t constraint_len;
6443 link_next = TREE_CHAIN (link);
6445 oconstraints[i]
6446 = constraint
6447 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6448 constraint_len = strlen (constraint);
6449 if (constraint_len == 0)
6450 continue;
6452 ok = parse_output_constraint (&constraint, i, 0, 0,
6453 &allows_mem, &allows_reg, &is_inout);
6454 if (!ok)
6456 ret = GS_ERROR;
6457 is_inout = false;
6460 /* If we can't make copies, we can only accept memory.
6461 Similarly for VLAs. */
6462 tree outtype = TREE_TYPE (TREE_VALUE (link));
6463 if (outtype != error_mark_node
6464 && (TREE_ADDRESSABLE (outtype)
6465 || !COMPLETE_TYPE_P (outtype)
6466 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
6468 if (allows_mem)
6469 allows_reg = 0;
6470 else
6472 error ("impossible constraint in %<asm%>");
6473 error ("non-memory output %d must stay in memory", i);
6474 return GS_ERROR;
6478 if (!allows_reg && allows_mem)
6479 mark_addressable (TREE_VALUE (link));
6481 tree orig = TREE_VALUE (link);
6482 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6483 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6484 fb_lvalue | fb_mayfail);
6485 if (tret == GS_ERROR)
6487 if (orig != error_mark_node)
6488 error ("invalid lvalue in %<asm%> output %d", i);
6489 ret = tret;
6492 /* If the constraint does not allow memory make sure we gimplify
6493 it to a register if it is not already but its base is. This
6494 happens for complex and vector components. */
6495 if (!allows_mem)
6497 tree op = TREE_VALUE (link);
6498 if (! is_gimple_val (op)
6499 && is_gimple_reg_type (TREE_TYPE (op))
6500 && is_gimple_reg (get_base_address (op)))
6502 tree tem = create_tmp_reg (TREE_TYPE (op));
6503 tree ass;
6504 if (is_inout)
6506 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6507 tem, unshare_expr (op));
6508 gimplify_and_add (ass, pre_p);
6510 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6511 gimplify_and_add (ass, post_p);
6513 TREE_VALUE (link) = tem;
6514 tret = GS_OK;
6518 vec_safe_push (outputs, link);
6519 TREE_CHAIN (link) = NULL_TREE;
6521 if (is_inout)
6523 /* An input/output operand. To give the optimizers more
6524 flexibility, split it into separate input and output
6525 operands. */
6526 tree input;
6527 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6528 char buf[11];
6530 /* Turn the in/out constraint into an output constraint. */
6531 char *p = xstrdup (constraint);
6532 p[0] = '=';
6533 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6535 /* And add a matching input constraint. */
6536 if (allows_reg)
6538 sprintf (buf, "%u", i);
6540 /* If there are multiple alternatives in the constraint,
6541 handle each of them individually. Those that allow register
6542 will be replaced with operand number, the others will stay
6543 unchanged. */
6544 if (strchr (p, ',') != NULL)
6546 size_t len = 0, buflen = strlen (buf);
6547 char *beg, *end, *str, *dst;
6549 for (beg = p + 1;;)
6551 end = strchr (beg, ',');
6552 if (end == NULL)
6553 end = strchr (beg, '\0');
6554 if ((size_t) (end - beg) < buflen)
6555 len += buflen + 1;
6556 else
6557 len += end - beg + 1;
6558 if (*end)
6559 beg = end + 1;
6560 else
6561 break;
6564 str = (char *) alloca (len);
6565 for (beg = p + 1, dst = str;;)
6567 const char *tem;
6568 bool mem_p, reg_p, inout_p;
6570 end = strchr (beg, ',');
6571 if (end)
6572 *end = '\0';
6573 beg[-1] = '=';
6574 tem = beg - 1;
6575 parse_output_constraint (&tem, i, 0, 0,
6576 &mem_p, &reg_p, &inout_p);
6577 if (dst != str)
6578 *dst++ = ',';
6579 if (reg_p)
6581 memcpy (dst, buf, buflen);
6582 dst += buflen;
6584 else
6586 if (end)
6587 len = end - beg;
6588 else
6589 len = strlen (beg);
6590 memcpy (dst, beg, len);
6591 dst += len;
6593 if (end)
6594 beg = end + 1;
6595 else
6596 break;
6598 *dst = '\0';
6599 input = build_string (dst - str, str);
6601 else
6602 input = build_string (strlen (buf), buf);
6604 else
6605 input = build_string (constraint_len - 1, constraint + 1);
6607 free (p);
6609 input = build_tree_list (build_tree_list (NULL_TREE, input),
6610 unshare_expr (TREE_VALUE (link)));
6611 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6615 link_next = NULL_TREE;
6616 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6618 link_next = TREE_CHAIN (link);
6619 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6620 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6621 oconstraints, &allows_mem, &allows_reg);
6623 /* If we can't make copies, we can only accept memory. */
6624 tree intype = TREE_TYPE (TREE_VALUE (link));
6625 if (intype != error_mark_node
6626 && (TREE_ADDRESSABLE (intype)
6627 || !COMPLETE_TYPE_P (intype)
6628 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
6630 if (allows_mem)
6631 allows_reg = 0;
6632 else
6634 error ("impossible constraint in %<asm%>");
6635 error ("non-memory input %d must stay in memory", i);
6636 return GS_ERROR;
6640 /* If the operand is a memory input, it should be an lvalue. */
6641 if (!allows_reg && allows_mem)
6643 tree inputv = TREE_VALUE (link);
6644 STRIP_NOPS (inputv);
6645 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6646 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6647 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6648 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6649 || TREE_CODE (inputv) == MODIFY_EXPR)
6650 TREE_VALUE (link) = error_mark_node;
6651 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6652 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6653 if (tret != GS_ERROR)
6655 /* Unlike output operands, memory inputs are not guaranteed
6656 to be lvalues by the FE, and while the expressions are
6657 marked addressable there, if it is e.g. a statement
6658 expression, temporaries in it might not end up being
6659 addressable. They might be already used in the IL and thus
6660 it is too late to make them addressable now though. */
6661 tree x = TREE_VALUE (link);
6662 while (handled_component_p (x))
6663 x = TREE_OPERAND (x, 0);
6664 if (TREE_CODE (x) == MEM_REF
6665 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6666 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6667 if ((VAR_P (x)
6668 || TREE_CODE (x) == PARM_DECL
6669 || TREE_CODE (x) == RESULT_DECL)
6670 && !TREE_ADDRESSABLE (x)
6671 && is_gimple_reg (x))
6673 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6674 input_location), 0,
6675 "memory input %d is not directly addressable",
6677 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6680 mark_addressable (TREE_VALUE (link));
6681 if (tret == GS_ERROR)
6683 if (inputv != error_mark_node)
6684 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6685 "memory input %d is not directly addressable", i);
6686 ret = tret;
6689 else
6691 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6692 is_gimple_asm_val, fb_rvalue);
6693 if (tret == GS_ERROR)
6694 ret = tret;
6697 TREE_CHAIN (link) = NULL_TREE;
6698 vec_safe_push (inputs, link);
6701 link_next = NULL_TREE;
6702 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6704 link_next = TREE_CHAIN (link);
6705 TREE_CHAIN (link) = NULL_TREE;
6706 vec_safe_push (clobbers, link);
6709 link_next = NULL_TREE;
6710 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6712 link_next = TREE_CHAIN (link);
6713 TREE_CHAIN (link) = NULL_TREE;
6714 vec_safe_push (labels, link);
6717 /* Do not add ASMs with errors to the gimple IL stream. */
6718 if (ret != GS_ERROR)
6720 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6721 inputs, outputs, clobbers, labels);
6723 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
6724 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6725 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
6727 gimplify_seq_add_stmt (pre_p, stmt);
6730 return ret;
6733 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6734 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6735 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6736 return to this function.
6738 FIXME should we complexify the prequeue handling instead? Or use flags
6739 for all the cleanups and let the optimizer tighten them up? The current
6740 code seems pretty fragile; it will break on a cleanup within any
6741 non-conditional nesting. But any such nesting would be broken, anyway;
6742 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6743 and continues out of it. We can do that at the RTL level, though, so
6744 having an optimizer to tighten up try/finally regions would be a Good
6745 Thing. */
6747 static enum gimplify_status
6748 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6750 gimple_stmt_iterator iter;
6751 gimple_seq body_sequence = NULL;
6753 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6755 /* We only care about the number of conditions between the innermost
6756 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6757 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6758 int old_conds = gimplify_ctxp->conditions;
6759 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6760 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6761 gimplify_ctxp->conditions = 0;
6762 gimplify_ctxp->conditional_cleanups = NULL;
6763 gimplify_ctxp->in_cleanup_point_expr = true;
6765 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6767 gimplify_ctxp->conditions = old_conds;
6768 gimplify_ctxp->conditional_cleanups = old_cleanups;
6769 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6771 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6773 gimple *wce = gsi_stmt (iter);
6775 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6777 if (gsi_one_before_end_p (iter))
6779 /* Note that gsi_insert_seq_before and gsi_remove do not
6780 scan operands, unlike some other sequence mutators. */
6781 if (!gimple_wce_cleanup_eh_only (wce))
6782 gsi_insert_seq_before_without_update (&iter,
6783 gimple_wce_cleanup (wce),
6784 GSI_SAME_STMT);
6785 gsi_remove (&iter, true);
6786 break;
6788 else
6790 gtry *gtry;
6791 gimple_seq seq;
6792 enum gimple_try_flags kind;
6794 if (gimple_wce_cleanup_eh_only (wce))
6795 kind = GIMPLE_TRY_CATCH;
6796 else
6797 kind = GIMPLE_TRY_FINALLY;
6798 seq = gsi_split_seq_after (iter);
6800 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6801 /* Do not use gsi_replace here, as it may scan operands.
6802 We want to do a simple structural modification only. */
6803 gsi_set_stmt (&iter, gtry);
6804 iter = gsi_start (gtry->eval);
6807 else
6808 gsi_next (&iter);
6811 gimplify_seq_add_seq (pre_p, body_sequence);
6812 if (temp)
6814 *expr_p = temp;
6815 return GS_OK;
6817 else
6819 *expr_p = NULL;
6820 return GS_ALL_DONE;
6824 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6825 is the cleanup action required. EH_ONLY is true if the cleanup should
6826 only be executed if an exception is thrown, not on normal exit.
6827 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6828 only valid for clobbers. */
6830 static void
6831 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6832 bool force_uncond = false)
6834 gimple *wce;
6835 gimple_seq cleanup_stmts = NULL;
6837 /* Errors can result in improperly nested cleanups. Which results in
6838 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6839 if (seen_error ())
6840 return;
6842 if (gimple_conditional_context ())
6844 /* If we're in a conditional context, this is more complex. We only
6845 want to run the cleanup if we actually ran the initialization that
6846 necessitates it, but we want to run it after the end of the
6847 conditional context. So we wrap the try/finally around the
6848 condition and use a flag to determine whether or not to actually
6849 run the destructor. Thus
6851 test ? f(A()) : 0
6853 becomes (approximately)
6855 flag = 0;
6856 try {
6857 if (test) { A::A(temp); flag = 1; val = f(temp); }
6858 else { val = 0; }
6859 } finally {
6860 if (flag) A::~A(temp);
6864 if (force_uncond)
6866 gimplify_stmt (&cleanup, &cleanup_stmts);
6867 wce = gimple_build_wce (cleanup_stmts);
6868 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6870 else
6872 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6873 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
6874 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
6876 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
6877 gimplify_stmt (&cleanup, &cleanup_stmts);
6878 wce = gimple_build_wce (cleanup_stmts);
6880 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
6881 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6882 gimplify_seq_add_stmt (pre_p, ftrue);
6884 /* Because of this manipulation, and the EH edges that jump
6885 threading cannot redirect, the temporary (VAR) will appear
6886 to be used uninitialized. Don't warn. */
6887 suppress_warning (var, OPT_Wuninitialized);
6890 else
6892 gimplify_stmt (&cleanup, &cleanup_stmts);
6893 wce = gimple_build_wce (cleanup_stmts);
6894 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6895 gimplify_seq_add_stmt (pre_p, wce);
6899 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6901 static enum gimplify_status
6902 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6904 tree targ = *expr_p;
6905 tree temp = TARGET_EXPR_SLOT (targ);
6906 tree init = TARGET_EXPR_INITIAL (targ);
6907 enum gimplify_status ret;
6909 bool unpoison_empty_seq = false;
6910 gimple_stmt_iterator unpoison_it;
6912 if (init)
6914 tree cleanup = NULL_TREE;
6916 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6917 to the temps list. Handle also variable length TARGET_EXPRs. */
6918 if (!poly_int_tree_p (DECL_SIZE (temp)))
6920 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
6921 gimplify_type_sizes (TREE_TYPE (temp), pre_p);
6922 /* FIXME: this is correct only when the size of the type does
6923 not depend on expressions evaluated in init. */
6924 gimplify_vla_decl (temp, pre_p);
6926 else
6928 /* Save location where we need to place unpoisoning. It's possible
6929 that a variable will be converted to needs_to_live_in_memory. */
6930 unpoison_it = gsi_last (*pre_p);
6931 unpoison_empty_seq = gsi_end_p (unpoison_it);
6933 gimple_add_tmp_var (temp);
6936 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6937 expression is supposed to initialize the slot. */
6938 if (VOID_TYPE_P (TREE_TYPE (init)))
6939 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6940 else
6942 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
6943 init = init_expr;
6944 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6945 init = NULL;
6946 ggc_free (init_expr);
6948 if (ret == GS_ERROR)
6950 /* PR c++/28266 Make sure this is expanded only once. */
6951 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6952 return GS_ERROR;
6954 if (init)
6955 gimplify_and_add (init, pre_p);
6957 /* If needed, push the cleanup for the temp. */
6958 if (TARGET_EXPR_CLEANUP (targ))
6960 if (CLEANUP_EH_ONLY (targ))
6961 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
6962 CLEANUP_EH_ONLY (targ), pre_p);
6963 else
6964 cleanup = TARGET_EXPR_CLEANUP (targ);
6967 /* Add a clobber for the temporary going out of scope, like
6968 gimplify_bind_expr. */
6969 if (gimplify_ctxp->in_cleanup_point_expr
6970 && needs_to_live_in_memory (temp))
6972 if (flag_stack_reuse == SR_ALL)
6974 tree clobber = build_clobber (TREE_TYPE (temp));
6975 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
6976 gimple_push_cleanup (temp, clobber, false, pre_p, true);
6978 if (asan_poisoned_variables
6979 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
6980 && !TREE_STATIC (temp)
6981 && dbg_cnt (asan_use_after_scope)
6982 && !gimplify_omp_ctxp)
6984 tree asan_cleanup = build_asan_poison_call_expr (temp);
6985 if (asan_cleanup)
6987 if (unpoison_empty_seq)
6988 unpoison_it = gsi_start (*pre_p);
6990 asan_poison_variable (temp, false, &unpoison_it,
6991 unpoison_empty_seq);
6992 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
6996 if (cleanup)
6997 gimple_push_cleanup (temp, cleanup, false, pre_p);
6999 /* Only expand this once. */
7000 TREE_OPERAND (targ, 3) = init;
7001 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
7003 else
7004 /* We should have expanded this before. */
7005 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
7007 *expr_p = temp;
7008 return GS_OK;
7011 /* Gimplification of expression trees. */
7013 /* Gimplify an expression which appears at statement context. The
7014 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
7015 NULL, a new sequence is allocated.
7017 Return true if we actually added a statement to the queue. */
7019 bool
7020 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
7022 gimple_seq_node last;
7024 last = gimple_seq_last (*seq_p);
7025 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
7026 return last != gimple_seq_last (*seq_p);
7029 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
7030 to CTX. If entries already exist, force them to be some flavor of private.
7031 If there is no enclosing parallel, do nothing. */
7033 void
7034 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
7036 splay_tree_node n;
7038 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
7039 return;
7043 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7044 if (n != NULL)
7046 if (n->value & GOVD_SHARED)
7047 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
7048 else if (n->value & GOVD_MAP)
7049 n->value |= GOVD_MAP_TO_ONLY;
7050 else
7051 return;
7053 else if ((ctx->region_type & ORT_TARGET) != 0)
7055 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
7056 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7057 else
7058 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
7060 else if (ctx->region_type != ORT_WORKSHARE
7061 && ctx->region_type != ORT_TASKGROUP
7062 && ctx->region_type != ORT_SIMD
7063 && ctx->region_type != ORT_ACC
7064 && !(ctx->region_type & ORT_TARGET_DATA))
7065 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7067 ctx = ctx->outer_context;
7069 while (ctx);
7072 /* Similarly for each of the type sizes of TYPE. */
7074 static void
7075 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
7077 if (type == NULL || type == error_mark_node)
7078 return;
7079 type = TYPE_MAIN_VARIANT (type);
7081 if (ctx->privatized_types->add (type))
7082 return;
7084 switch (TREE_CODE (type))
7086 case INTEGER_TYPE:
7087 case ENUMERAL_TYPE:
7088 case BOOLEAN_TYPE:
7089 case REAL_TYPE:
7090 case FIXED_POINT_TYPE:
7091 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
7092 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
7093 break;
7095 case ARRAY_TYPE:
7096 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7097 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
7098 break;
7100 case RECORD_TYPE:
7101 case UNION_TYPE:
7102 case QUAL_UNION_TYPE:
7104 tree field;
7105 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
7106 if (TREE_CODE (field) == FIELD_DECL)
7108 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
7109 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
7112 break;
7114 case POINTER_TYPE:
7115 case REFERENCE_TYPE:
7116 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7117 break;
7119 default:
7120 break;
7123 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
7124 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
7125 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
7128 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
7130 static void
7131 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
7133 splay_tree_node n;
7134 unsigned int nflags;
7135 tree t;
7137 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
7138 return;
7140 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
7141 there are constructors involved somewhere. Exception is a shared clause,
7142 there is nothing privatized in that case. */
7143 if ((flags & GOVD_SHARED) == 0
7144 && (TREE_ADDRESSABLE (TREE_TYPE (decl))
7145 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
7146 flags |= GOVD_SEEN;
7148 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7149 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7151 /* We shouldn't be re-adding the decl with the same data
7152 sharing class. */
7153 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
7154 nflags = n->value | flags;
7155 /* The only combination of data sharing classes we should see is
7156 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
7157 reduction variables to be used in data sharing clauses. */
7158 gcc_assert ((ctx->region_type & ORT_ACC) != 0
7159 || ((nflags & GOVD_DATA_SHARE_CLASS)
7160 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
7161 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
7162 n->value = nflags;
7163 return;
7166 /* When adding a variable-sized variable, we have to handle all sorts
7167 of additional bits of data: the pointer replacement variable, and
7168 the parameters of the type. */
7169 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7171 /* Add the pointer replacement variable as PRIVATE if the variable
7172 replacement is private, else FIRSTPRIVATE since we'll need the
7173 address of the original variable either for SHARED, or for the
7174 copy into or out of the context. */
7175 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
7177 if (flags & GOVD_MAP)
7178 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
7179 else if (flags & GOVD_PRIVATE)
7180 nflags = GOVD_PRIVATE;
7181 else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7182 && (flags & GOVD_FIRSTPRIVATE))
7183 || (ctx->region_type == ORT_TARGET_DATA
7184 && (flags & GOVD_DATA_SHARE_CLASS) == 0))
7185 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
7186 else
7187 nflags = GOVD_FIRSTPRIVATE;
7188 nflags |= flags & GOVD_SEEN;
7189 t = DECL_VALUE_EXPR (decl);
7190 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7191 t = TREE_OPERAND (t, 0);
7192 gcc_assert (DECL_P (t));
7193 omp_add_variable (ctx, t, nflags);
7196 /* Add all of the variable and type parameters (which should have
7197 been gimplified to a formal temporary) as FIRSTPRIVATE. */
7198 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
7199 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
7200 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7202 /* The variable-sized variable itself is never SHARED, only some form
7203 of PRIVATE. The sharing would take place via the pointer variable
7204 which we remapped above. */
7205 if (flags & GOVD_SHARED)
7206 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
7207 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
7209 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7210 alloca statement we generate for the variable, so make sure it
7211 is available. This isn't automatically needed for the SHARED
7212 case, since we won't be allocating local storage then.
7213 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7214 in this case omp_notice_variable will be called later
7215 on when it is gimplified. */
7216 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
7217 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
7218 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
7220 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
7221 && omp_privatize_by_reference (decl))
7223 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7225 /* Similar to the direct variable sized case above, we'll need the
7226 size of references being privatized. */
7227 if ((flags & GOVD_SHARED) == 0)
7229 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7230 if (t && DECL_P (t))
7231 omp_notice_variable (ctx, t, true);
7235 if (n != NULL)
7236 n->value |= flags;
7237 else
7238 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
7240 /* For reductions clauses in OpenACC loop directives, by default create a
7241 copy clause on the enclosing parallel construct for carrying back the
7242 results. */
7243 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
7245 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
7246 while (outer_ctx)
7248 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
7249 if (n != NULL)
7251 /* Ignore local variables and explicitly declared clauses. */
7252 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
7253 break;
7254 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
7256 /* According to the OpenACC spec, such a reduction variable
7257 should already have a copy map on a kernels construct,
7258 verify that here. */
7259 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
7260 && (n->value & GOVD_MAP));
7262 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7264 /* Remove firstprivate and make it a copy map. */
7265 n->value &= ~GOVD_FIRSTPRIVATE;
7266 n->value |= GOVD_MAP;
7269 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7271 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
7272 GOVD_MAP | GOVD_SEEN);
7273 break;
7275 outer_ctx = outer_ctx->outer_context;
7280 /* Notice a threadprivate variable DECL used in OMP context CTX.
7281 This just prints out diagnostics about threadprivate variable uses
7282 in untied tasks. If DECL2 is non-NULL, prevent this warning
7283 on that variable. */
7285 static bool
7286 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
7287 tree decl2)
7289 splay_tree_node n;
7290 struct gimplify_omp_ctx *octx;
7292 for (octx = ctx; octx; octx = octx->outer_context)
7293 if ((octx->region_type & ORT_TARGET) != 0
7294 || octx->order_concurrent)
7296 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
7297 if (n == NULL)
7299 if (octx->order_concurrent)
7301 error ("threadprivate variable %qE used in a region with"
7302 " %<order(concurrent)%> clause", DECL_NAME (decl));
7303 inform (octx->location, "enclosing region");
7305 else
7307 error ("threadprivate variable %qE used in target region",
7308 DECL_NAME (decl));
7309 inform (octx->location, "enclosing target region");
7311 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
7313 if (decl2)
7314 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
7317 if (ctx->region_type != ORT_UNTIED_TASK)
7318 return false;
7319 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7320 if (n == NULL)
7322 error ("threadprivate variable %qE used in untied task",
7323 DECL_NAME (decl));
7324 inform (ctx->location, "enclosing task");
7325 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
7327 if (decl2)
7328 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
7329 return false;
7332 /* Return true if global var DECL is device resident. */
7334 static bool
7335 device_resident_p (tree decl)
7337 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
7339 if (!attr)
7340 return false;
7342 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
7344 tree c = TREE_VALUE (t);
7345 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
7346 return true;
7349 return false;
7352 /* Return true if DECL has an ACC DECLARE attribute. */
7354 static bool
7355 is_oacc_declared (tree decl)
7357 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
7358 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
7359 return declared != NULL_TREE;
7362 /* Determine outer default flags for DECL mentioned in an OMP region
7363 but not declared in an enclosing clause.
7365 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7366 remapped firstprivate instead of shared. To some extent this is
7367 addressed in omp_firstprivatize_type_sizes, but not
7368 effectively. */
7370 static unsigned
7371 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
7372 bool in_code, unsigned flags)
7374 enum omp_clause_default_kind default_kind = ctx->default_kind;
7375 enum omp_clause_default_kind kind;
7377 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
7378 if (ctx->region_type & ORT_TASK)
7380 tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH);
7382 /* The event-handle specified by a detach clause should always be firstprivate,
7383 regardless of the current default. */
7384 if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl)
7385 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
7387 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7388 default_kind = kind;
7389 else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
7390 default_kind = OMP_CLAUSE_DEFAULT_SHARED;
7391 /* For C/C++ default({,first}private), variables with static storage duration
7392 declared in a namespace or global scope and referenced in construct
7393 must be explicitly specified, i.e. acts as default(none). */
7394 else if ((default_kind == OMP_CLAUSE_DEFAULT_PRIVATE
7395 || default_kind == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
7396 && VAR_P (decl)
7397 && is_global_var (decl)
7398 && (DECL_FILE_SCOPE_P (decl)
7399 || (DECL_CONTEXT (decl)
7400 && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
7401 && !lang_GNU_Fortran ())
7402 default_kind = OMP_CLAUSE_DEFAULT_NONE;
7404 switch (default_kind)
7406 case OMP_CLAUSE_DEFAULT_NONE:
7408 const char *rtype;
7410 if (ctx->region_type & ORT_PARALLEL)
7411 rtype = "parallel";
7412 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
7413 rtype = "taskloop";
7414 else if (ctx->region_type & ORT_TASK)
7415 rtype = "task";
7416 else if (ctx->region_type & ORT_TEAMS)
7417 rtype = "teams";
7418 else
7419 gcc_unreachable ();
7421 error ("%qE not specified in enclosing %qs",
7422 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7423 inform (ctx->location, "enclosing %qs", rtype);
7425 /* FALLTHRU */
7426 case OMP_CLAUSE_DEFAULT_SHARED:
7427 flags |= GOVD_SHARED;
7428 break;
7429 case OMP_CLAUSE_DEFAULT_PRIVATE:
7430 flags |= GOVD_PRIVATE;
7431 break;
7432 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7433 flags |= GOVD_FIRSTPRIVATE;
7434 break;
7435 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7436 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7437 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7438 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7440 omp_notice_variable (octx, decl, in_code);
7441 for (; octx; octx = octx->outer_context)
7443 splay_tree_node n2;
7445 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7446 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7447 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7448 continue;
7449 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7451 flags |= GOVD_FIRSTPRIVATE;
7452 goto found_outer;
7454 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7456 flags |= GOVD_SHARED;
7457 goto found_outer;
7462 if (TREE_CODE (decl) == PARM_DECL
7463 || (!is_global_var (decl)
7464 && DECL_CONTEXT (decl) == current_function_decl))
7465 flags |= GOVD_FIRSTPRIVATE;
7466 else
7467 flags |= GOVD_SHARED;
7468 found_outer:
7469 break;
7471 default:
7472 gcc_unreachable ();
7475 return flags;
7479 /* Determine outer default flags for DECL mentioned in an OACC region
7480 but not declared in an enclosing clause. */
7482 static unsigned
7483 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7485 const char *rkind;
7486 bool on_device = false;
7487 bool is_private = false;
7488 bool declared = is_oacc_declared (decl);
7489 tree type = TREE_TYPE (decl);
7491 if (omp_privatize_by_reference (decl))
7492 type = TREE_TYPE (type);
7494 /* For Fortran COMMON blocks, only used variables in those blocks are
7495 transfered and remapped. The block itself will have a private clause to
7496 avoid transfering the data twice.
7497 The hook evaluates to false by default. For a variable in Fortran's COMMON
7498 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7499 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7500 the whole block. For C++ and Fortran, it can also be true under certain
7501 other conditions, if DECL_HAS_VALUE_EXPR. */
7502 if (RECORD_OR_UNION_TYPE_P (type))
7503 is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
7505 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7506 && is_global_var (decl)
7507 && device_resident_p (decl)
7508 && !is_private)
7510 on_device = true;
7511 flags |= GOVD_MAP_TO_ONLY;
7514 switch (ctx->region_type)
7516 case ORT_ACC_KERNELS:
7517 rkind = "kernels";
7519 if (is_private)
7520 flags |= GOVD_FIRSTPRIVATE;
7521 else if (AGGREGATE_TYPE_P (type))
7523 /* Aggregates default to 'present_or_copy', or 'present'. */
7524 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7525 flags |= GOVD_MAP;
7526 else
7527 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7529 else
7530 /* Scalars default to 'copy'. */
7531 flags |= GOVD_MAP | GOVD_MAP_FORCE;
7533 break;
7535 case ORT_ACC_PARALLEL:
7536 case ORT_ACC_SERIAL:
7537 rkind = ctx->region_type == ORT_ACC_PARALLEL ? "parallel" : "serial";
7539 if (is_private)
7540 flags |= GOVD_FIRSTPRIVATE;
7541 else if (on_device || declared)
7542 flags |= GOVD_MAP;
7543 else if (AGGREGATE_TYPE_P (type))
7545 /* Aggregates default to 'present_or_copy', or 'present'. */
7546 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7547 flags |= GOVD_MAP;
7548 else
7549 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7551 else
7552 /* Scalars default to 'firstprivate'. */
7553 flags |= GOVD_FIRSTPRIVATE;
7555 break;
7557 default:
7558 gcc_unreachable ();
7561 if (DECL_ARTIFICIAL (decl))
7562 ; /* We can get compiler-generated decls, and should not complain
7563 about them. */
7564 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7566 error ("%qE not specified in enclosing OpenACC %qs construct",
7567 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
7568 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
7570 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7571 ; /* Handled above. */
7572 else
7573 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7575 return flags;
7578 /* Record the fact that DECL was used within the OMP context CTX.
7579 IN_CODE is true when real code uses DECL, and false when we should
7580 merely emit default(none) errors. Return true if DECL is going to
7581 be remapped and thus DECL shouldn't be gimplified into its
7582 DECL_VALUE_EXPR (if any). */
7584 static bool
7585 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7587 splay_tree_node n;
7588 unsigned flags = in_code ? GOVD_SEEN : 0;
7589 bool ret = false, shared;
7591 if (error_operand_p (decl))
7592 return false;
7594 if (ctx->region_type == ORT_NONE)
7595 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7597 if (is_global_var (decl))
7599 /* Threadprivate variables are predetermined. */
7600 if (DECL_THREAD_LOCAL_P (decl))
7601 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7603 if (DECL_HAS_VALUE_EXPR_P (decl))
7605 if (ctx->region_type & ORT_ACC)
7606 /* For OpenACC, defer expansion of value to avoid transfering
7607 privatized common block data instead of im-/explicitly transfered
7608 variables which are in common blocks. */
7610 else
7612 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7614 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7615 return omp_notice_threadprivate_variable (ctx, decl, value);
7619 if (gimplify_omp_ctxp->outer_context == NULL
7620 && VAR_P (decl)
7621 && oacc_get_fn_attrib (current_function_decl))
7623 location_t loc = DECL_SOURCE_LOCATION (decl);
7625 if (lookup_attribute ("omp declare target link",
7626 DECL_ATTRIBUTES (decl)))
7628 error_at (loc,
7629 "%qE with %<link%> clause used in %<routine%> function",
7630 DECL_NAME (decl));
7631 return false;
7633 else if (!lookup_attribute ("omp declare target",
7634 DECL_ATTRIBUTES (decl)))
7636 error_at (loc,
7637 "%qE requires a %<declare%> directive for use "
7638 "in a %<routine%> function", DECL_NAME (decl));
7639 return false;
7644 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7645 if ((ctx->region_type & ORT_TARGET) != 0)
7647 if (ctx->region_type & ORT_ACC)
7648 /* For OpenACC, as remarked above, defer expansion. */
7649 shared = false;
7650 else
7651 shared = true;
7653 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7654 if (n == NULL)
7656 unsigned nflags = flags;
7657 if ((ctx->region_type & ORT_ACC) == 0)
7659 bool is_declare_target = false;
7660 if (is_global_var (decl)
7661 && varpool_node::get_create (decl)->offloadable)
7663 struct gimplify_omp_ctx *octx;
7664 for (octx = ctx->outer_context;
7665 octx; octx = octx->outer_context)
7667 n = splay_tree_lookup (octx->variables,
7668 (splay_tree_key)decl);
7669 if (n
7670 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7671 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7672 break;
7674 is_declare_target = octx == NULL;
7676 if (!is_declare_target)
7678 int gdmk;
7679 enum omp_clause_defaultmap_kind kind;
7680 if (lang_hooks.decls.omp_allocatable_p (decl))
7681 gdmk = GDMK_ALLOCATABLE;
7682 else if (lang_hooks.decls.omp_scalar_target_p (decl))
7683 gdmk = GDMK_SCALAR_TARGET;
7684 else if (lang_hooks.decls.omp_scalar_p (decl, false))
7685 gdmk = GDMK_SCALAR;
7686 else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7687 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7688 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7689 == POINTER_TYPE)))
7690 gdmk = GDMK_POINTER;
7691 else
7692 gdmk = GDMK_AGGREGATE;
7693 kind = lang_hooks.decls.omp_predetermined_mapping (decl);
7694 if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
7696 if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
7697 nflags |= GOVD_FIRSTPRIVATE;
7698 else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
7699 nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
7700 else
7701 gcc_unreachable ();
7703 else if (ctx->defaultmap[gdmk] == 0)
7705 tree d = lang_hooks.decls.omp_report_decl (decl);
7706 error ("%qE not specified in enclosing %<target%>",
7707 DECL_NAME (d));
7708 inform (ctx->location, "enclosing %<target%>");
7710 else if (ctx->defaultmap[gdmk]
7711 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
7712 nflags |= ctx->defaultmap[gdmk];
7713 else
7715 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
7716 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
7721 struct gimplify_omp_ctx *octx = ctx->outer_context;
7722 if ((ctx->region_type & ORT_ACC) && octx)
7724 /* Look in outer OpenACC contexts, to see if there's a
7725 data attribute for this variable. */
7726 omp_notice_variable (octx, decl, in_code);
7728 for (; octx; octx = octx->outer_context)
7730 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7731 break;
7732 splay_tree_node n2
7733 = splay_tree_lookup (octx->variables,
7734 (splay_tree_key) decl);
7735 if (n2)
7737 if (octx->region_type == ORT_ACC_HOST_DATA)
7738 error ("variable %qE declared in enclosing "
7739 "%<host_data%> region", DECL_NAME (decl));
7740 nflags |= GOVD_MAP;
7741 if (octx->region_type == ORT_ACC_DATA
7742 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7743 nflags |= GOVD_MAP_0LEN_ARRAY;
7744 goto found_outer;
7749 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
7750 | GOVD_MAP_ALLOC_ONLY)) == flags)
7752 tree type = TREE_TYPE (decl);
7754 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
7755 && omp_privatize_by_reference (decl))
7756 type = TREE_TYPE (type);
7757 if (!lang_hooks.types.omp_mappable_type (type))
7759 error ("%qD referenced in target region does not have "
7760 "a mappable type", decl);
7761 nflags |= GOVD_MAP | GOVD_EXPLICIT;
7763 else
7765 if ((ctx->region_type & ORT_ACC) != 0)
7766 nflags = oacc_default_clause (ctx, decl, flags);
7767 else
7768 nflags |= GOVD_MAP;
7771 found_outer:
7772 omp_add_variable (ctx, decl, nflags);
7774 else
7776 /* If nothing changed, there's nothing left to do. */
7777 if ((n->value & flags) == flags)
7778 return ret;
7779 flags |= n->value;
7780 n->value = flags;
7782 goto do_outer;
7785 if (n == NULL)
7787 if (ctx->region_type == ORT_WORKSHARE
7788 || ctx->region_type == ORT_TASKGROUP
7789 || ctx->region_type == ORT_SIMD
7790 || ctx->region_type == ORT_ACC
7791 || (ctx->region_type & ORT_TARGET_DATA) != 0)
7792 goto do_outer;
7794 flags = omp_default_clause (ctx, decl, in_code, flags);
7796 if ((flags & GOVD_PRIVATE)
7797 && lang_hooks.decls.omp_private_outer_ref (decl))
7798 flags |= GOVD_PRIVATE_OUTER_REF;
7800 omp_add_variable (ctx, decl, flags);
7802 shared = (flags & GOVD_SHARED) != 0;
7803 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7804 goto do_outer;
7807 /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
7808 lb, b or incr expressions, those shouldn't be turned into simd arrays. */
7809 if (ctx->region_type == ORT_SIMD
7810 && ctx->in_for_exprs
7811 && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
7812 == GOVD_PRIVATE))
7813 flags &= ~GOVD_SEEN;
7815 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7816 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7817 && DECL_SIZE (decl))
7819 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7821 splay_tree_node n2;
7822 tree t = DECL_VALUE_EXPR (decl);
7823 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7824 t = TREE_OPERAND (t, 0);
7825 gcc_assert (DECL_P (t));
7826 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7827 n2->value |= GOVD_SEEN;
7829 else if (omp_privatize_by_reference (decl)
7830 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7831 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7832 != INTEGER_CST))
7834 splay_tree_node n2;
7835 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7836 gcc_assert (DECL_P (t));
7837 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7838 if (n2)
7839 omp_notice_variable (ctx, t, true);
7843 if (ctx->region_type & ORT_ACC)
7844 /* For OpenACC, as remarked above, defer expansion. */
7845 shared = false;
7846 else
7847 shared = ((flags | n->value) & GOVD_SHARED) != 0;
7848 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7850 /* If nothing changed, there's nothing left to do. */
7851 if ((n->value & flags) == flags)
7852 return ret;
7853 flags |= n->value;
7854 n->value = flags;
7856 do_outer:
7857 /* If the variable is private in the current context, then we don't
7858 need to propagate anything to an outer context. */
7859 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7860 return ret;
7861 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7862 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7863 return ret;
7864 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7865 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7866 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7867 return ret;
7868 if (ctx->outer_context
7869 && omp_notice_variable (ctx->outer_context, decl, in_code))
7870 return true;
7871 return ret;
7874 /* Verify that DECL is private within CTX. If there's specific information
7875 to the contrary in the innermost scope, generate an error. */
7877 static bool
7878 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
7880 splay_tree_node n;
7882 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7883 if (n != NULL)
7885 if (n->value & GOVD_SHARED)
7887 if (ctx == gimplify_omp_ctxp)
7889 if (simd)
7890 error ("iteration variable %qE is predetermined linear",
7891 DECL_NAME (decl));
7892 else
7893 error ("iteration variable %qE should be private",
7894 DECL_NAME (decl));
7895 n->value = GOVD_PRIVATE;
7896 return true;
7898 else
7899 return false;
7901 else if ((n->value & GOVD_EXPLICIT) != 0
7902 && (ctx == gimplify_omp_ctxp
7903 || (ctx->region_type == ORT_COMBINED_PARALLEL
7904 && gimplify_omp_ctxp->outer_context == ctx)))
7906 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
7907 error ("iteration variable %qE should not be firstprivate",
7908 DECL_NAME (decl));
7909 else if ((n->value & GOVD_REDUCTION) != 0)
7910 error ("iteration variable %qE should not be reduction",
7911 DECL_NAME (decl));
7912 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
7913 error ("iteration variable %qE should not be linear",
7914 DECL_NAME (decl));
7916 return (ctx == gimplify_omp_ctxp
7917 || (ctx->region_type == ORT_COMBINED_PARALLEL
7918 && gimplify_omp_ctxp->outer_context == ctx));
7921 if (ctx->region_type != ORT_WORKSHARE
7922 && ctx->region_type != ORT_TASKGROUP
7923 && ctx->region_type != ORT_SIMD
7924 && ctx->region_type != ORT_ACC)
7925 return false;
7926 else if (ctx->outer_context)
7927 return omp_is_private (ctx->outer_context, decl, simd);
7928 return false;
7931 /* Return true if DECL is private within a parallel region
7932 that binds to the current construct's context or in parallel
7933 region's REDUCTION clause. */
7935 static bool
7936 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
7938 splay_tree_node n;
7942 ctx = ctx->outer_context;
7943 if (ctx == NULL)
7945 if (is_global_var (decl))
7946 return false;
7948 /* References might be private, but might be shared too,
7949 when checking for copyprivate, assume they might be
7950 private, otherwise assume they might be shared. */
7951 if (copyprivate)
7952 return true;
7954 if (omp_privatize_by_reference (decl))
7955 return false;
7957 /* Treat C++ privatized non-static data members outside
7958 of the privatization the same. */
7959 if (omp_member_access_dummy_var (decl))
7960 return false;
7962 return true;
7965 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
7967 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7968 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
7970 if ((ctx->region_type & ORT_TARGET_DATA) != 0
7971 || n == NULL
7972 || (n->value & GOVD_MAP) == 0)
7973 continue;
7974 return false;
7977 if (n != NULL)
7979 if ((n->value & GOVD_LOCAL) != 0
7980 && omp_member_access_dummy_var (decl))
7981 return false;
7982 return (n->value & GOVD_SHARED) == 0;
7985 if (ctx->region_type == ORT_WORKSHARE
7986 || ctx->region_type == ORT_TASKGROUP
7987 || ctx->region_type == ORT_SIMD
7988 || ctx->region_type == ORT_ACC)
7989 continue;
7991 break;
7993 while (1);
7994 return false;
7997 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7999 static tree
8000 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
8002 tree t = *tp;
8004 /* If this node has been visited, unmark it and keep looking. */
8005 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
8006 return t;
8008 if (IS_TYPE_OR_DECL_P (t))
8009 *walk_subtrees = 0;
8010 return NULL_TREE;
8014 /* Gimplify the affinity clause but effectively ignore it.
8015 Generate:
8016 var = begin;
8017 if ((step > 1) ? var <= end : var > end)
8018 locatator_var_expr; */
8020 static void
8021 gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p)
8023 tree last_iter = NULL_TREE;
8024 tree last_bind = NULL_TREE;
8025 tree label = NULL_TREE;
8026 tree *last_body = NULL;
8027 for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8028 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
8030 tree t = OMP_CLAUSE_DECL (c);
8031 if (TREE_CODE (t) == TREE_LIST
8032 && TREE_PURPOSE (t)
8033 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8035 if (TREE_VALUE (t) == null_pointer_node)
8036 continue;
8037 if (TREE_PURPOSE (t) != last_iter)
8039 if (last_bind)
8041 append_to_statement_list (label, last_body);
8042 gimplify_and_add (last_bind, pre_p);
8043 last_bind = NULL_TREE;
8045 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8047 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8048 is_gimple_val, fb_rvalue) == GS_ERROR
8049 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8050 is_gimple_val, fb_rvalue) == GS_ERROR
8051 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8052 is_gimple_val, fb_rvalue) == GS_ERROR
8053 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8054 is_gimple_val, fb_rvalue)
8055 == GS_ERROR))
8056 return;
8058 last_iter = TREE_PURPOSE (t);
8059 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8060 last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
8061 NULL, block);
8062 last_body = &BIND_EXPR_BODY (last_bind);
8063 tree cond = NULL_TREE;
8064 location_t loc = OMP_CLAUSE_LOCATION (c);
8065 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8067 tree var = TREE_VEC_ELT (it, 0);
8068 tree begin = TREE_VEC_ELT (it, 1);
8069 tree end = TREE_VEC_ELT (it, 2);
8070 tree step = TREE_VEC_ELT (it, 3);
8071 loc = DECL_SOURCE_LOCATION (var);
8072 tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8073 var, begin);
8074 append_to_statement_list_force (tem, last_body);
8076 tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8077 step, build_zero_cst (TREE_TYPE (step)));
8078 tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node,
8079 var, end);
8080 tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8081 var, end);
8082 cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node,
8083 cond1, cond2, cond3);
8084 if (cond)
8085 cond = fold_build2_loc (loc, TRUTH_AND_EXPR,
8086 boolean_type_node, cond, cond1);
8087 else
8088 cond = cond1;
8090 tree cont_label = create_artificial_label (loc);
8091 label = build1 (LABEL_EXPR, void_type_node, cont_label);
8092 tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
8093 void_node,
8094 build_and_jump (&cont_label));
8095 append_to_statement_list_force (tem, last_body);
8097 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8099 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0),
8100 last_body);
8101 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8103 if (error_operand_p (TREE_VALUE (t)))
8104 return;
8105 append_to_statement_list_force (TREE_VALUE (t), last_body);
8106 TREE_VALUE (t) = null_pointer_node;
8108 else
8110 if (last_bind)
8112 append_to_statement_list (label, last_body);
8113 gimplify_and_add (last_bind, pre_p);
8114 last_bind = NULL_TREE;
8116 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8118 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8119 NULL, is_gimple_val, fb_rvalue);
8120 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8122 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8123 return;
8124 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8125 is_gimple_val, fb_rvalue) == GS_ERROR)
8126 return;
8127 gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p);
8130 if (last_bind)
8132 append_to_statement_list (label, last_body);
8133 gimplify_and_add (last_bind, pre_p);
8135 return;
8138 /* If *LIST_P contains any OpenMP depend clauses with iterators,
8139 lower all the depend clauses by populating corresponding depend
8140 array. Returns 0 if there are no such depend clauses, or
8141 2 if all depend clauses should be removed, 1 otherwise. */
8143 static int
8144 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
8146 tree c;
8147 gimple *g;
8148 size_t n[4] = { 0, 0, 0, 0 };
8149 bool unused[4];
8150 tree counts[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
8151 tree last_iter = NULL_TREE, last_count = NULL_TREE;
8152 size_t i, j;
8153 location_t first_loc = UNKNOWN_LOCATION;
8155 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8156 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8158 switch (OMP_CLAUSE_DEPEND_KIND (c))
8160 case OMP_CLAUSE_DEPEND_IN:
8161 i = 2;
8162 break;
8163 case OMP_CLAUSE_DEPEND_OUT:
8164 case OMP_CLAUSE_DEPEND_INOUT:
8165 i = 0;
8166 break;
8167 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8168 i = 1;
8169 break;
8170 case OMP_CLAUSE_DEPEND_DEPOBJ:
8171 i = 3;
8172 break;
8173 case OMP_CLAUSE_DEPEND_SOURCE:
8174 case OMP_CLAUSE_DEPEND_SINK:
8175 continue;
8176 default:
8177 gcc_unreachable ();
8179 tree t = OMP_CLAUSE_DECL (c);
8180 if (first_loc == UNKNOWN_LOCATION)
8181 first_loc = OMP_CLAUSE_LOCATION (c);
8182 if (TREE_CODE (t) == TREE_LIST
8183 && TREE_PURPOSE (t)
8184 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8186 if (TREE_PURPOSE (t) != last_iter)
8188 tree tcnt = size_one_node;
8189 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8191 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8192 is_gimple_val, fb_rvalue) == GS_ERROR
8193 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8194 is_gimple_val, fb_rvalue) == GS_ERROR
8195 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8196 is_gimple_val, fb_rvalue) == GS_ERROR
8197 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8198 is_gimple_val, fb_rvalue)
8199 == GS_ERROR))
8200 return 2;
8201 tree var = TREE_VEC_ELT (it, 0);
8202 tree begin = TREE_VEC_ELT (it, 1);
8203 tree end = TREE_VEC_ELT (it, 2);
8204 tree step = TREE_VEC_ELT (it, 3);
8205 tree orig_step = TREE_VEC_ELT (it, 4);
8206 tree type = TREE_TYPE (var);
8207 tree stype = TREE_TYPE (step);
8208 location_t loc = DECL_SOURCE_LOCATION (var);
8209 tree endmbegin;
8210 /* Compute count for this iterator as
8211 orig_step > 0
8212 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
8213 : (begin > end ? (end - begin + (step + 1)) / step : 0)
8214 and compute product of those for the entire depend
8215 clause. */
8216 if (POINTER_TYPE_P (type))
8217 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
8218 stype, end, begin);
8219 else
8220 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
8221 end, begin);
8222 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
8223 step,
8224 build_int_cst (stype, 1));
8225 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
8226 build_int_cst (stype, 1));
8227 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
8228 unshare_expr (endmbegin),
8229 stepm1);
8230 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8231 pos, step);
8232 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
8233 endmbegin, stepp1);
8234 if (TYPE_UNSIGNED (stype))
8236 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
8237 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
8239 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8240 neg, step);
8241 step = NULL_TREE;
8242 tree cond = fold_build2_loc (loc, LT_EXPR,
8243 boolean_type_node,
8244 begin, end);
8245 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
8246 build_int_cst (stype, 0));
8247 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
8248 end, begin);
8249 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
8250 build_int_cst (stype, 0));
8251 tree osteptype = TREE_TYPE (orig_step);
8252 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8253 orig_step,
8254 build_int_cst (osteptype, 0));
8255 tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
8256 cond, pos, neg);
8257 cnt = fold_convert_loc (loc, sizetype, cnt);
8258 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
8259 fb_rvalue) == GS_ERROR)
8260 return 2;
8261 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
8263 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
8264 fb_rvalue) == GS_ERROR)
8265 return 2;
8266 last_iter = TREE_PURPOSE (t);
8267 last_count = tcnt;
8269 if (counts[i] == NULL_TREE)
8270 counts[i] = last_count;
8271 else
8272 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
8273 PLUS_EXPR, counts[i], last_count);
8275 else
8276 n[i]++;
8278 for (i = 0; i < 4; i++)
8279 if (counts[i])
8280 break;
8281 if (i == 4)
8282 return 0;
8284 tree total = size_zero_node;
8285 for (i = 0; i < 4; i++)
8287 unused[i] = counts[i] == NULL_TREE && n[i] == 0;
8288 if (counts[i] == NULL_TREE)
8289 counts[i] = size_zero_node;
8290 if (n[i])
8291 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
8292 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
8293 fb_rvalue) == GS_ERROR)
8294 return 2;
8295 total = size_binop (PLUS_EXPR, total, counts[i]);
8298 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
8299 == GS_ERROR)
8300 return 2;
8301 bool is_old = unused[1] && unused[3];
8302 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
8303 size_int (is_old ? 1 : 4));
8304 tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
8305 tree array = create_tmp_var_raw (type);
8306 TREE_ADDRESSABLE (array) = 1;
8307 if (!poly_int_tree_p (totalpx))
8309 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
8310 gimplify_type_sizes (TREE_TYPE (array), pre_p);
8311 if (gimplify_omp_ctxp)
8313 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8314 while (ctx
8315 && (ctx->region_type == ORT_WORKSHARE
8316 || ctx->region_type == ORT_TASKGROUP
8317 || ctx->region_type == ORT_SIMD
8318 || ctx->region_type == ORT_ACC))
8319 ctx = ctx->outer_context;
8320 if (ctx)
8321 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
8323 gimplify_vla_decl (array, pre_p);
8325 else
8326 gimple_add_tmp_var (array);
8327 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
8328 NULL_TREE);
8329 tree tem;
8330 if (!is_old)
8332 tem = build2 (MODIFY_EXPR, void_type_node, r,
8333 build_int_cst (ptr_type_node, 0));
8334 gimplify_and_add (tem, pre_p);
8335 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
8336 NULL_TREE);
8338 tem = build2 (MODIFY_EXPR, void_type_node, r,
8339 fold_convert (ptr_type_node, total));
8340 gimplify_and_add (tem, pre_p);
8341 for (i = 1; i < (is_old ? 2 : 4); i++)
8343 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
8344 NULL_TREE, NULL_TREE);
8345 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
8346 gimplify_and_add (tem, pre_p);
8349 tree cnts[4];
8350 for (j = 4; j; j--)
8351 if (!unused[j - 1])
8352 break;
8353 for (i = 0; i < 4; i++)
8355 if (i && (i >= j || unused[i - 1]))
8357 cnts[i] = cnts[i - 1];
8358 continue;
8360 cnts[i] = create_tmp_var (sizetype);
8361 if (i == 0)
8362 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
8363 else
8365 tree t;
8366 if (is_old)
8367 t = size_binop (PLUS_EXPR, counts[0], size_int (2));
8368 else
8369 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
8370 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
8371 == GS_ERROR)
8372 return 2;
8373 g = gimple_build_assign (cnts[i], t);
8375 gimple_seq_add_stmt (pre_p, g);
8378 last_iter = NULL_TREE;
8379 tree last_bind = NULL_TREE;
8380 tree *last_body = NULL;
8381 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8382 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8384 switch (OMP_CLAUSE_DEPEND_KIND (c))
8386 case OMP_CLAUSE_DEPEND_IN:
8387 i = 2;
8388 break;
8389 case OMP_CLAUSE_DEPEND_OUT:
8390 case OMP_CLAUSE_DEPEND_INOUT:
8391 i = 0;
8392 break;
8393 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8394 i = 1;
8395 break;
8396 case OMP_CLAUSE_DEPEND_DEPOBJ:
8397 i = 3;
8398 break;
8399 case OMP_CLAUSE_DEPEND_SOURCE:
8400 case OMP_CLAUSE_DEPEND_SINK:
8401 continue;
8402 default:
8403 gcc_unreachable ();
8405 tree t = OMP_CLAUSE_DECL (c);
8406 if (TREE_CODE (t) == TREE_LIST
8407 && TREE_PURPOSE (t)
8408 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8410 if (TREE_PURPOSE (t) != last_iter)
8412 if (last_bind)
8413 gimplify_and_add (last_bind, pre_p);
8414 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8415 last_bind = build3 (BIND_EXPR, void_type_node,
8416 BLOCK_VARS (block), NULL, block);
8417 TREE_SIDE_EFFECTS (last_bind) = 1;
8418 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
8419 tree *p = &BIND_EXPR_BODY (last_bind);
8420 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8422 tree var = TREE_VEC_ELT (it, 0);
8423 tree begin = TREE_VEC_ELT (it, 1);
8424 tree end = TREE_VEC_ELT (it, 2);
8425 tree step = TREE_VEC_ELT (it, 3);
8426 tree orig_step = TREE_VEC_ELT (it, 4);
8427 tree type = TREE_TYPE (var);
8428 location_t loc = DECL_SOURCE_LOCATION (var);
8429 /* Emit:
8430 var = begin;
8431 goto cond_label;
8432 beg_label:
8434 var = var + step;
8435 cond_label:
8436 if (orig_step > 0) {
8437 if (var < end) goto beg_label;
8438 } else {
8439 if (var > end) goto beg_label;
8441 for each iterator, with inner iterators added to
8442 the ... above. */
8443 tree beg_label = create_artificial_label (loc);
8444 tree cond_label = NULL_TREE;
8445 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8446 var, begin);
8447 append_to_statement_list_force (tem, p);
8448 tem = build_and_jump (&cond_label);
8449 append_to_statement_list_force (tem, p);
8450 tem = build1 (LABEL_EXPR, void_type_node, beg_label);
8451 append_to_statement_list (tem, p);
8452 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
8453 NULL_TREE, NULL_TREE);
8454 TREE_SIDE_EFFECTS (bind) = 1;
8455 SET_EXPR_LOCATION (bind, loc);
8456 append_to_statement_list_force (bind, p);
8457 if (POINTER_TYPE_P (type))
8458 tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
8459 var, fold_convert_loc (loc, sizetype,
8460 step));
8461 else
8462 tem = build2_loc (loc, PLUS_EXPR, type, var, step);
8463 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8464 var, tem);
8465 append_to_statement_list_force (tem, p);
8466 tem = build1 (LABEL_EXPR, void_type_node, cond_label);
8467 append_to_statement_list (tem, p);
8468 tree cond = fold_build2_loc (loc, LT_EXPR,
8469 boolean_type_node,
8470 var, end);
8471 tree pos
8472 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8473 cond, build_and_jump (&beg_label),
8474 void_node);
8475 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8476 var, end);
8477 tree neg
8478 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8479 cond, build_and_jump (&beg_label),
8480 void_node);
8481 tree osteptype = TREE_TYPE (orig_step);
8482 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8483 orig_step,
8484 build_int_cst (osteptype, 0));
8485 tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
8486 cond, pos, neg);
8487 append_to_statement_list_force (tem, p);
8488 p = &BIND_EXPR_BODY (bind);
8490 last_body = p;
8492 last_iter = TREE_PURPOSE (t);
8493 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8495 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
8496 0), last_body);
8497 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8499 if (error_operand_p (TREE_VALUE (t)))
8500 return 2;
8501 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
8502 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8503 NULL_TREE, NULL_TREE);
8504 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8505 void_type_node, r, TREE_VALUE (t));
8506 append_to_statement_list_force (tem, last_body);
8507 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8508 void_type_node, cnts[i],
8509 size_binop (PLUS_EXPR, cnts[i], size_int (1)));
8510 append_to_statement_list_force (tem, last_body);
8511 TREE_VALUE (t) = null_pointer_node;
8513 else
8515 if (last_bind)
8517 gimplify_and_add (last_bind, pre_p);
8518 last_bind = NULL_TREE;
8520 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8522 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8523 NULL, is_gimple_val, fb_rvalue);
8524 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8526 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8527 return 2;
8528 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8529 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8530 is_gimple_val, fb_rvalue) == GS_ERROR)
8531 return 2;
8532 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8533 NULL_TREE, NULL_TREE);
8534 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
8535 gimplify_and_add (tem, pre_p);
8536 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, cnts[i],
8537 size_int (1)));
8538 gimple_seq_add_stmt (pre_p, g);
8541 if (last_bind)
8542 gimplify_and_add (last_bind, pre_p);
8543 tree cond = boolean_false_node;
8544 if (is_old)
8546 if (!unused[0])
8547 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
8548 size_binop_loc (first_loc, PLUS_EXPR, counts[0],
8549 size_int (2)));
8550 if (!unused[2])
8551 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8552 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8553 cnts[2],
8554 size_binop_loc (first_loc, PLUS_EXPR,
8555 totalpx,
8556 size_int (1))));
8558 else
8560 tree prev = size_int (5);
8561 for (i = 0; i < 4; i++)
8563 if (unused[i])
8564 continue;
8565 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
8566 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8567 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8568 cnts[i], unshare_expr (prev)));
8571 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
8572 build_call_expr_loc (first_loc,
8573 builtin_decl_explicit (BUILT_IN_TRAP),
8574 0), void_node);
8575 gimplify_and_add (tem, pre_p);
8576 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
8577 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
8578 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
8579 OMP_CLAUSE_CHAIN (c) = *list_p;
8580 *list_p = c;
8581 return 1;
8584 /* Insert a GOMP_MAP_ALLOC or GOMP_MAP_RELEASE node following a
8585 GOMP_MAP_STRUCT mapping. C is an always_pointer mapping. STRUCT_NODE is
8586 the struct node to insert the new mapping after (when the struct node is
8587 initially created). PREV_NODE is the first of two or three mappings for a
8588 pointer, and is either:
8589 - the node before C, when a pair of mappings is used, e.g. for a C/C++
8590 array section.
8591 - not the node before C. This is true when we have a reference-to-pointer
8592 type (with a mapping for the reference and for the pointer), or for
8593 Fortran derived-type mappings with a GOMP_MAP_TO_PSET.
8594 If SCP is non-null, the new node is inserted before *SCP.
8595 if SCP is null, the new node is inserted before PREV_NODE.
8596 The return type is:
8597 - PREV_NODE, if SCP is non-null.
8598 - The newly-created ALLOC or RELEASE node, if SCP is null.
8599 - The second newly-created ALLOC or RELEASE node, if we are mapping a
8600 reference to a pointer. */
8602 static tree
8603 insert_struct_comp_map (enum tree_code code, tree c, tree struct_node,
8604 tree prev_node, tree *scp)
8606 enum gomp_map_kind mkind
8607 = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
8608 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8610 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8611 tree cl = scp ? prev_node : c2;
8612 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8613 OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (c));
8614 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : prev_node;
8615 if (OMP_CLAUSE_CHAIN (prev_node) != c
8616 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8617 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8618 == GOMP_MAP_TO_PSET))
8619 OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (OMP_CLAUSE_CHAIN (prev_node));
8620 else
8621 OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
8622 if (struct_node)
8623 OMP_CLAUSE_CHAIN (struct_node) = c2;
8625 /* We might need to create an additional mapping if we have a reference to a
8626 pointer (in C++). Don't do this if we have something other than a
8627 GOMP_MAP_ALWAYS_POINTER though, i.e. a GOMP_MAP_TO_PSET. */
8628 if (OMP_CLAUSE_CHAIN (prev_node) != c
8629 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8630 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8631 == GOMP_MAP_ALWAYS_POINTER)
8632 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8633 == GOMP_MAP_ATTACH_DETACH)))
8635 tree c4 = OMP_CLAUSE_CHAIN (prev_node);
8636 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8637 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8638 OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (c4));
8639 OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
8640 OMP_CLAUSE_CHAIN (c3) = prev_node;
8641 if (!scp)
8642 OMP_CLAUSE_CHAIN (c2) = c3;
8643 else
8644 cl = c3;
8647 if (scp)
8648 *scp = c2;
8650 return cl;
8653 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
8654 and set *BITPOSP and *POFFSETP to the bit offset of the access.
8655 If BASE_REF is non-NULL and the containing object is a reference, set
8656 *BASE_REF to that reference before dereferencing the object.
8657 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
8658 has array type, else return NULL. */
8660 static tree
8661 extract_base_bit_offset (tree base, tree *base_ref, poly_int64 *bitposp,
8662 poly_offset_int *poffsetp)
8664 tree offset;
8665 poly_int64 bitsize, bitpos;
8666 machine_mode mode;
8667 int unsignedp, reversep, volatilep = 0;
8668 poly_offset_int poffset;
8670 if (base_ref)
8672 *base_ref = NULL_TREE;
8674 while (TREE_CODE (base) == ARRAY_REF)
8675 base = TREE_OPERAND (base, 0);
8677 if (TREE_CODE (base) == INDIRECT_REF)
8678 base = TREE_OPERAND (base, 0);
8680 else
8682 if (TREE_CODE (base) == ARRAY_REF)
8684 while (TREE_CODE (base) == ARRAY_REF)
8685 base = TREE_OPERAND (base, 0);
8686 if (TREE_CODE (base) != COMPONENT_REF
8687 || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
8688 return NULL_TREE;
8690 else if (TREE_CODE (base) == INDIRECT_REF
8691 && TREE_CODE (TREE_OPERAND (base, 0)) == COMPONENT_REF
8692 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
8693 == REFERENCE_TYPE))
8694 base = TREE_OPERAND (base, 0);
8697 base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
8698 &unsignedp, &reversep, &volatilep);
8700 tree orig_base = base;
8702 if ((TREE_CODE (base) == INDIRECT_REF
8703 || (TREE_CODE (base) == MEM_REF
8704 && integer_zerop (TREE_OPERAND (base, 1))))
8705 && DECL_P (TREE_OPERAND (base, 0))
8706 && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == REFERENCE_TYPE)
8707 base = TREE_OPERAND (base, 0);
8709 gcc_assert (offset == NULL_TREE || poly_int_tree_p (offset));
8711 if (offset)
8712 poffset = wi::to_poly_offset (offset);
8713 else
8714 poffset = 0;
8716 if (maybe_ne (bitpos, 0))
8717 poffset += bits_to_bytes_round_down (bitpos);
8719 *bitposp = bitpos;
8720 *poffsetp = poffset;
8722 /* Set *BASE_REF if BASE was a dereferenced reference variable. */
8723 if (base_ref && orig_base != base)
8724 *base_ref = orig_base;
8726 return base;
8729 /* Returns true if EXPR is or contains (as a sub-component) BASE_PTR. */
8731 static bool
8732 is_or_contains_p (tree expr, tree base_ptr)
8734 while (expr != base_ptr)
8735 if (TREE_CODE (base_ptr) == COMPONENT_REF)
8736 base_ptr = TREE_OPERAND (base_ptr, 0);
8737 else
8738 break;
8739 return expr == base_ptr;
8742 /* Implement OpenMP 5.x map ordering rules for target directives. There are
8743 several rules, and with some level of ambiguity, hopefully we can at least
8744 collect the complexity here in one place. */
8746 static void
8747 omp_target_reorder_clauses (tree *list_p)
8749 /* Collect refs to alloc/release/delete maps. */
8750 auto_vec<tree, 32> ard;
8751 tree *cp = list_p;
8752 while (*cp != NULL_TREE)
8753 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8754 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALLOC
8755 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_RELEASE
8756 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_DELETE))
8758 /* Unlink cp and push to ard. */
8759 tree c = *cp;
8760 tree nc = OMP_CLAUSE_CHAIN (c);
8761 *cp = nc;
8762 ard.safe_push (c);
8764 /* Any associated pointer type maps should also move along. */
8765 while (*cp != NULL_TREE
8766 && OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8767 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
8768 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_POINTER
8769 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH
8770 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_POINTER
8771 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALWAYS_POINTER
8772 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_TO_PSET))
8774 c = *cp;
8775 nc = OMP_CLAUSE_CHAIN (c);
8776 *cp = nc;
8777 ard.safe_push (c);
8780 else
8781 cp = &OMP_CLAUSE_CHAIN (*cp);
8783 /* Link alloc/release/delete maps to the end of list. */
8784 for (unsigned int i = 0; i < ard.length (); i++)
8786 *cp = ard[i];
8787 cp = &OMP_CLAUSE_CHAIN (ard[i]);
8789 *cp = NULL_TREE;
8791 /* OpenMP 5.0 requires that pointer variables are mapped before
8792 its use as a base-pointer. */
8793 auto_vec<tree *, 32> atf;
8794 for (tree *cp = list_p; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
8795 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
8797 /* Collect alloc, to, from, to/from clause tree pointers. */
8798 gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
8799 if (k == GOMP_MAP_ALLOC
8800 || k == GOMP_MAP_TO
8801 || k == GOMP_MAP_FROM
8802 || k == GOMP_MAP_TOFROM
8803 || k == GOMP_MAP_ALWAYS_TO
8804 || k == GOMP_MAP_ALWAYS_FROM
8805 || k == GOMP_MAP_ALWAYS_TOFROM)
8806 atf.safe_push (cp);
8809 for (unsigned int i = 0; i < atf.length (); i++)
8810 if (atf[i])
8812 tree *cp = atf[i];
8813 tree decl = OMP_CLAUSE_DECL (*cp);
8814 if (TREE_CODE (decl) == INDIRECT_REF || TREE_CODE (decl) == MEM_REF)
8816 tree base_ptr = TREE_OPERAND (decl, 0);
8817 STRIP_TYPE_NOPS (base_ptr);
8818 for (unsigned int j = i + 1; j < atf.length (); j++)
8820 tree *cp2 = atf[j];
8821 tree decl2 = OMP_CLAUSE_DECL (*cp2);
8822 if (is_or_contains_p (decl2, base_ptr))
8824 /* Move *cp2 to before *cp. */
8825 tree c = *cp2;
8826 *cp2 = OMP_CLAUSE_CHAIN (c);
8827 OMP_CLAUSE_CHAIN (c) = *cp;
8828 *cp = c;
8829 atf[j] = NULL;
8836 /* DECL is supposed to have lastprivate semantics in the outer contexts
8837 of combined/composite constructs, starting with OCTX.
8838 Add needed lastprivate, shared or map clause if no data sharing or
8839 mapping clause are present. IMPLICIT_P is true if it is an implicit
8840 clause (IV on simd), in which case the lastprivate will not be
8841 copied to some constructs. */
8843 static void
8844 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx,
8845 tree decl, bool implicit_p)
8847 struct gimplify_omp_ctx *orig_octx = octx;
8848 for (; octx; octx = octx->outer_context)
8850 if ((octx->region_type == ORT_COMBINED_PARALLEL
8851 || (octx->region_type & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS)
8852 && splay_tree_lookup (octx->variables,
8853 (splay_tree_key) decl) == NULL)
8855 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
8856 continue;
8858 if ((octx->region_type & ORT_TASK) != 0
8859 && octx->combined_loop
8860 && splay_tree_lookup (octx->variables,
8861 (splay_tree_key) decl) == NULL)
8863 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8864 continue;
8866 if (implicit_p
8867 && octx->region_type == ORT_WORKSHARE
8868 && octx->combined_loop
8869 && splay_tree_lookup (octx->variables,
8870 (splay_tree_key) decl) == NULL
8871 && octx->outer_context
8872 && octx->outer_context->region_type == ORT_COMBINED_PARALLEL
8873 && splay_tree_lookup (octx->outer_context->variables,
8874 (splay_tree_key) decl) == NULL)
8876 octx = octx->outer_context;
8877 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8878 continue;
8880 if ((octx->region_type == ORT_WORKSHARE || octx->region_type == ORT_ACC)
8881 && octx->combined_loop
8882 && splay_tree_lookup (octx->variables,
8883 (splay_tree_key) decl) == NULL
8884 && !omp_check_private (octx, decl, false))
8886 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8887 continue;
8889 if (octx->region_type == ORT_COMBINED_TARGET)
8891 splay_tree_node n = splay_tree_lookup (octx->variables,
8892 (splay_tree_key) decl);
8893 if (n == NULL)
8895 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
8896 octx = octx->outer_context;
8898 else if (!implicit_p
8899 && (n->value & GOVD_FIRSTPRIVATE_IMPLICIT))
8901 n->value &= ~(GOVD_FIRSTPRIVATE
8902 | GOVD_FIRSTPRIVATE_IMPLICIT
8903 | GOVD_EXPLICIT);
8904 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
8905 octx = octx->outer_context;
8908 break;
8910 if (octx && (implicit_p || octx != orig_octx))
8911 omp_notice_variable (octx, decl, true);
8914 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
8915 and previous omp contexts. */
8917 static void
8918 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
8919 enum omp_region_type region_type,
8920 enum tree_code code)
8922 struct gimplify_omp_ctx *ctx, *outer_ctx;
8923 tree c;
8924 hash_map<tree, tree> *struct_map_to_clause = NULL;
8925 hash_set<tree> *struct_deref_set = NULL;
8926 tree *prev_list_p = NULL, *orig_list_p = list_p;
8927 int handled_depend_iterators = -1;
8928 int nowait = -1;
8930 ctx = new_omp_context (region_type);
8931 ctx->code = code;
8932 outer_ctx = ctx->outer_context;
8933 if (code == OMP_TARGET)
8935 if (!lang_GNU_Fortran ())
8936 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
8937 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
8938 ctx->defaultmap[GDMK_SCALAR_TARGET] = (lang_GNU_Fortran ()
8939 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
8941 if (!lang_GNU_Fortran ())
8942 switch (code)
8944 case OMP_TARGET:
8945 case OMP_TARGET_DATA:
8946 case OMP_TARGET_ENTER_DATA:
8947 case OMP_TARGET_EXIT_DATA:
8948 case OACC_DECLARE:
8949 case OACC_HOST_DATA:
8950 case OACC_PARALLEL:
8951 case OACC_KERNELS:
8952 ctx->target_firstprivatize_array_bases = true;
8953 default:
8954 break;
8957 if (code == OMP_TARGET
8958 || code == OMP_TARGET_DATA
8959 || code == OMP_TARGET_ENTER_DATA
8960 || code == OMP_TARGET_EXIT_DATA)
8961 omp_target_reorder_clauses (list_p);
8963 while ((c = *list_p) != NULL)
8965 bool remove = false;
8966 bool notice_outer = true;
8967 const char *check_non_private = NULL;
8968 unsigned int flags;
8969 tree decl;
8971 switch (OMP_CLAUSE_CODE (c))
8973 case OMP_CLAUSE_PRIVATE:
8974 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
8975 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
8977 flags |= GOVD_PRIVATE_OUTER_REF;
8978 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
8980 else
8981 notice_outer = false;
8982 goto do_add;
8983 case OMP_CLAUSE_SHARED:
8984 flags = GOVD_SHARED | GOVD_EXPLICIT;
8985 goto do_add;
8986 case OMP_CLAUSE_FIRSTPRIVATE:
8987 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8988 check_non_private = "firstprivate";
8989 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
8991 gcc_assert (code == OMP_TARGET);
8992 flags |= GOVD_FIRSTPRIVATE_IMPLICIT;
8994 goto do_add;
8995 case OMP_CLAUSE_LASTPRIVATE:
8996 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
8997 switch (code)
8999 case OMP_DISTRIBUTE:
9000 error_at (OMP_CLAUSE_LOCATION (c),
9001 "conditional %<lastprivate%> clause on "
9002 "%qs construct", "distribute");
9003 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9004 break;
9005 case OMP_TASKLOOP:
9006 error_at (OMP_CLAUSE_LOCATION (c),
9007 "conditional %<lastprivate%> clause on "
9008 "%qs construct", "taskloop");
9009 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9010 break;
9011 default:
9012 break;
9014 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
9015 if (code != OMP_LOOP)
9016 check_non_private = "lastprivate";
9017 decl = OMP_CLAUSE_DECL (c);
9018 if (error_operand_p (decl))
9019 goto do_add;
9020 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
9021 && !lang_hooks.decls.omp_scalar_p (decl, true))
9023 error_at (OMP_CLAUSE_LOCATION (c),
9024 "non-scalar variable %qD in conditional "
9025 "%<lastprivate%> clause", decl);
9026 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9028 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
9029 flags |= GOVD_LASTPRIVATE_CONDITIONAL;
9030 omp_lastprivate_for_combined_outer_constructs (outer_ctx, decl,
9031 false);
9032 goto do_add;
9033 case OMP_CLAUSE_REDUCTION:
9034 if (OMP_CLAUSE_REDUCTION_TASK (c))
9036 if (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
9038 if (nowait == -1)
9039 nowait = omp_find_clause (*list_p,
9040 OMP_CLAUSE_NOWAIT) != NULL_TREE;
9041 if (nowait
9042 && (outer_ctx == NULL
9043 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
9045 error_at (OMP_CLAUSE_LOCATION (c),
9046 "%<task%> reduction modifier on a construct "
9047 "with a %<nowait%> clause");
9048 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
9051 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
9053 error_at (OMP_CLAUSE_LOCATION (c),
9054 "invalid %<task%> reduction modifier on construct "
9055 "other than %<parallel%>, %qs, %<sections%> or "
9056 "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
9057 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
9060 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
9061 switch (code)
9063 case OMP_SECTIONS:
9064 error_at (OMP_CLAUSE_LOCATION (c),
9065 "%<inscan%> %<reduction%> clause on "
9066 "%qs construct", "sections");
9067 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9068 break;
9069 case OMP_PARALLEL:
9070 error_at (OMP_CLAUSE_LOCATION (c),
9071 "%<inscan%> %<reduction%> clause on "
9072 "%qs construct", "parallel");
9073 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9074 break;
9075 case OMP_TEAMS:
9076 error_at (OMP_CLAUSE_LOCATION (c),
9077 "%<inscan%> %<reduction%> clause on "
9078 "%qs construct", "teams");
9079 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9080 break;
9081 case OMP_TASKLOOP:
9082 error_at (OMP_CLAUSE_LOCATION (c),
9083 "%<inscan%> %<reduction%> clause on "
9084 "%qs construct", "taskloop");
9085 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9086 break;
9087 case OMP_SCOPE:
9088 error_at (OMP_CLAUSE_LOCATION (c),
9089 "%<inscan%> %<reduction%> clause on "
9090 "%qs construct", "scope");
9091 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9092 break;
9093 default:
9094 break;
9096 /* FALLTHRU */
9097 case OMP_CLAUSE_IN_REDUCTION:
9098 case OMP_CLAUSE_TASK_REDUCTION:
9099 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
9100 /* OpenACC permits reductions on private variables. */
9101 if (!(region_type & ORT_ACC)
9102 /* taskgroup is actually not a worksharing region. */
9103 && code != OMP_TASKGROUP)
9104 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
9105 decl = OMP_CLAUSE_DECL (c);
9106 if (TREE_CODE (decl) == MEM_REF)
9108 tree type = TREE_TYPE (decl);
9109 bool saved_into_ssa = gimplify_ctxp->into_ssa;
9110 gimplify_ctxp->into_ssa = false;
9111 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
9112 NULL, is_gimple_val, fb_rvalue, false)
9113 == GS_ERROR)
9115 gimplify_ctxp->into_ssa = saved_into_ssa;
9116 remove = true;
9117 break;
9119 gimplify_ctxp->into_ssa = saved_into_ssa;
9120 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
9121 if (DECL_P (v))
9123 omp_firstprivatize_variable (ctx, v);
9124 omp_notice_variable (ctx, v, true);
9126 decl = TREE_OPERAND (decl, 0);
9127 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
9129 gimplify_ctxp->into_ssa = false;
9130 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
9131 NULL, is_gimple_val, fb_rvalue, false)
9132 == GS_ERROR)
9134 gimplify_ctxp->into_ssa = saved_into_ssa;
9135 remove = true;
9136 break;
9138 gimplify_ctxp->into_ssa = saved_into_ssa;
9139 v = TREE_OPERAND (decl, 1);
9140 if (DECL_P (v))
9142 omp_firstprivatize_variable (ctx, v);
9143 omp_notice_variable (ctx, v, true);
9145 decl = TREE_OPERAND (decl, 0);
9147 if (TREE_CODE (decl) == ADDR_EXPR
9148 || TREE_CODE (decl) == INDIRECT_REF)
9149 decl = TREE_OPERAND (decl, 0);
9151 goto do_add_decl;
9152 case OMP_CLAUSE_LINEAR:
9153 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
9154 is_gimple_val, fb_rvalue) == GS_ERROR)
9156 remove = true;
9157 break;
9159 else
9161 if (code == OMP_SIMD
9162 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9164 struct gimplify_omp_ctx *octx = outer_ctx;
9165 if (octx
9166 && octx->region_type == ORT_WORKSHARE
9167 && octx->combined_loop
9168 && !octx->distribute)
9170 if (octx->outer_context
9171 && (octx->outer_context->region_type
9172 == ORT_COMBINED_PARALLEL))
9173 octx = octx->outer_context->outer_context;
9174 else
9175 octx = octx->outer_context;
9177 if (octx
9178 && octx->region_type == ORT_WORKSHARE
9179 && octx->combined_loop
9180 && octx->distribute)
9182 error_at (OMP_CLAUSE_LOCATION (c),
9183 "%<linear%> clause for variable other than "
9184 "loop iterator specified on construct "
9185 "combined with %<distribute%>");
9186 remove = true;
9187 break;
9190 /* For combined #pragma omp parallel for simd, need to put
9191 lastprivate and perhaps firstprivate too on the
9192 parallel. Similarly for #pragma omp for simd. */
9193 struct gimplify_omp_ctx *octx = outer_ctx;
9194 bool taskloop_seen = false;
9195 decl = NULL_TREE;
9198 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9199 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9200 break;
9201 decl = OMP_CLAUSE_DECL (c);
9202 if (error_operand_p (decl))
9204 decl = NULL_TREE;
9205 break;
9207 flags = GOVD_SEEN;
9208 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9209 flags |= GOVD_FIRSTPRIVATE;
9210 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9211 flags |= GOVD_LASTPRIVATE;
9212 if (octx
9213 && octx->region_type == ORT_WORKSHARE
9214 && octx->combined_loop)
9216 if (octx->outer_context
9217 && (octx->outer_context->region_type
9218 == ORT_COMBINED_PARALLEL))
9219 octx = octx->outer_context;
9220 else if (omp_check_private (octx, decl, false))
9221 break;
9223 else if (octx
9224 && (octx->region_type & ORT_TASK) != 0
9225 && octx->combined_loop)
9226 taskloop_seen = true;
9227 else if (octx
9228 && octx->region_type == ORT_COMBINED_PARALLEL
9229 && ((ctx->region_type == ORT_WORKSHARE
9230 && octx == outer_ctx)
9231 || taskloop_seen))
9232 flags = GOVD_SEEN | GOVD_SHARED;
9233 else if (octx
9234 && ((octx->region_type & ORT_COMBINED_TEAMS)
9235 == ORT_COMBINED_TEAMS))
9236 flags = GOVD_SEEN | GOVD_SHARED;
9237 else if (octx
9238 && octx->region_type == ORT_COMBINED_TARGET)
9240 if (flags & GOVD_LASTPRIVATE)
9241 flags = GOVD_SEEN | GOVD_MAP;
9243 else
9244 break;
9245 splay_tree_node on
9246 = splay_tree_lookup (octx->variables,
9247 (splay_tree_key) decl);
9248 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
9250 octx = NULL;
9251 break;
9253 omp_add_variable (octx, decl, flags);
9254 if (octx->outer_context == NULL)
9255 break;
9256 octx = octx->outer_context;
9258 while (1);
9259 if (octx
9260 && decl
9261 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9262 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
9263 omp_notice_variable (octx, decl, true);
9265 flags = GOVD_LINEAR | GOVD_EXPLICIT;
9266 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9267 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9269 notice_outer = false;
9270 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9272 goto do_add;
9274 case OMP_CLAUSE_MAP:
9275 decl = OMP_CLAUSE_DECL (c);
9276 if (error_operand_p (decl))
9277 remove = true;
9278 switch (code)
9280 case OMP_TARGET:
9281 break;
9282 case OACC_DATA:
9283 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
9284 break;
9285 /* FALLTHRU */
9286 case OMP_TARGET_DATA:
9287 case OMP_TARGET_ENTER_DATA:
9288 case OMP_TARGET_EXIT_DATA:
9289 case OACC_ENTER_DATA:
9290 case OACC_EXIT_DATA:
9291 case OACC_HOST_DATA:
9292 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9293 || (OMP_CLAUSE_MAP_KIND (c)
9294 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9295 /* For target {,enter ,exit }data only the array slice is
9296 mapped, but not the pointer to it. */
9297 remove = true;
9298 break;
9299 default:
9300 break;
9302 /* For Fortran, not only the pointer to the data is mapped but also
9303 the address of the pointer, the array descriptor etc.; for
9304 'exit data' - and in particular for 'delete:' - having an 'alloc:'
9305 does not make sense. Likewise, for 'update' only transferring the
9306 data itself is needed as the rest has been handled in previous
9307 directives. However, for 'exit data', the array descriptor needs
9308 to be delete; hence, we turn the MAP_TO_PSET into a MAP_DELETE.
9310 NOTE: Generally, it is not safe to perform "enter data" operations
9311 on arrays where the data *or the descriptor* may go out of scope
9312 before a corresponding "exit data" operation -- and such a
9313 descriptor may be synthesized temporarily, e.g. to pass an
9314 explicit-shape array to a function expecting an assumed-shape
9315 argument. Performing "enter data" inside the called function
9316 would thus be problematic. */
9317 if (code == OMP_TARGET_EXIT_DATA
9318 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
9319 OMP_CLAUSE_SET_MAP_KIND (c, OMP_CLAUSE_MAP_KIND (*prev_list_p)
9320 == GOMP_MAP_DELETE
9321 ? GOMP_MAP_DELETE : GOMP_MAP_RELEASE);
9322 else if ((code == OMP_TARGET_EXIT_DATA || code == OMP_TARGET_UPDATE)
9323 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9324 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET))
9325 remove = true;
9327 if (remove)
9328 break;
9329 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
9331 struct gimplify_omp_ctx *octx;
9332 for (octx = outer_ctx; octx; octx = octx->outer_context)
9334 if (octx->region_type != ORT_ACC_HOST_DATA)
9335 break;
9336 splay_tree_node n2
9337 = splay_tree_lookup (octx->variables,
9338 (splay_tree_key) decl);
9339 if (n2)
9340 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
9341 "declared in enclosing %<host_data%> region",
9342 DECL_NAME (decl));
9345 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9346 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
9347 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
9348 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
9349 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
9351 remove = true;
9352 break;
9354 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9355 || (OMP_CLAUSE_MAP_KIND (c)
9356 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9357 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9358 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
9360 OMP_CLAUSE_SIZE (c)
9361 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
9362 false);
9363 if ((region_type & ORT_TARGET) != 0)
9364 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
9365 GOVD_FIRSTPRIVATE | GOVD_SEEN);
9368 if (!DECL_P (decl))
9370 tree d = decl, *pd;
9371 if (TREE_CODE (d) == ARRAY_REF)
9373 while (TREE_CODE (d) == ARRAY_REF)
9374 d = TREE_OPERAND (d, 0);
9375 if (TREE_CODE (d) == COMPONENT_REF
9376 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
9377 decl = d;
9379 pd = &OMP_CLAUSE_DECL (c);
9380 if (d == decl
9381 && TREE_CODE (decl) == INDIRECT_REF
9382 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
9383 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9384 == REFERENCE_TYPE))
9386 pd = &TREE_OPERAND (decl, 0);
9387 decl = TREE_OPERAND (decl, 0);
9389 bool indir_p = false;
9390 tree orig_decl = decl;
9391 tree decl_ref = NULL_TREE;
9392 if ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA)) != 0
9393 && TREE_CODE (*pd) == COMPONENT_REF
9394 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
9395 && code != OACC_UPDATE)
9397 while (TREE_CODE (decl) == COMPONENT_REF)
9399 decl = TREE_OPERAND (decl, 0);
9400 if (((TREE_CODE (decl) == MEM_REF
9401 && integer_zerop (TREE_OPERAND (decl, 1)))
9402 || INDIRECT_REF_P (decl))
9403 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9404 == POINTER_TYPE))
9406 indir_p = true;
9407 decl = TREE_OPERAND (decl, 0);
9409 if (TREE_CODE (decl) == INDIRECT_REF
9410 && DECL_P (TREE_OPERAND (decl, 0))
9411 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9412 == REFERENCE_TYPE))
9414 decl_ref = decl;
9415 decl = TREE_OPERAND (decl, 0);
9419 else if (TREE_CODE (decl) == COMPONENT_REF)
9421 while (TREE_CODE (decl) == COMPONENT_REF)
9422 decl = TREE_OPERAND (decl, 0);
9423 if (TREE_CODE (decl) == INDIRECT_REF
9424 && DECL_P (TREE_OPERAND (decl, 0))
9425 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9426 == REFERENCE_TYPE))
9427 decl = TREE_OPERAND (decl, 0);
9429 if (decl != orig_decl && DECL_P (decl) && indir_p)
9431 gomp_map_kind k
9432 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9433 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9434 /* We have a dereference of a struct member. Make this an
9435 attach/detach operation, and ensure the base pointer is
9436 mapped as a FIRSTPRIVATE_POINTER. */
9437 OMP_CLAUSE_SET_MAP_KIND (c, k);
9438 flags = GOVD_MAP | GOVD_SEEN | GOVD_EXPLICIT;
9439 tree next_clause = OMP_CLAUSE_CHAIN (c);
9440 if (k == GOMP_MAP_ATTACH
9441 && code != OACC_ENTER_DATA
9442 && code != OMP_TARGET_ENTER_DATA
9443 && (!next_clause
9444 || (OMP_CLAUSE_CODE (next_clause) != OMP_CLAUSE_MAP)
9445 || (OMP_CLAUSE_MAP_KIND (next_clause)
9446 != GOMP_MAP_POINTER)
9447 || OMP_CLAUSE_DECL (next_clause) != decl)
9448 && (!struct_deref_set
9449 || !struct_deref_set->contains (decl)))
9451 if (!struct_deref_set)
9452 struct_deref_set = new hash_set<tree> ();
9453 /* As well as the attach, we also need a
9454 FIRSTPRIVATE_POINTER clause to properly map the
9455 pointer to the struct base. */
9456 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9457 OMP_CLAUSE_MAP);
9458 OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALLOC);
9459 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c2)
9460 = 1;
9461 tree charptr_zero
9462 = build_int_cst (build_pointer_type (char_type_node),
9464 OMP_CLAUSE_DECL (c2)
9465 = build2 (MEM_REF, char_type_node,
9466 decl_ref ? decl_ref : decl, charptr_zero);
9467 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9468 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9469 OMP_CLAUSE_MAP);
9470 OMP_CLAUSE_SET_MAP_KIND (c3,
9471 GOMP_MAP_FIRSTPRIVATE_POINTER);
9472 OMP_CLAUSE_DECL (c3) = decl;
9473 OMP_CLAUSE_SIZE (c3) = size_zero_node;
9474 tree mapgrp = *prev_list_p;
9475 *prev_list_p = c2;
9476 OMP_CLAUSE_CHAIN (c3) = mapgrp;
9477 OMP_CLAUSE_CHAIN (c2) = c3;
9479 struct_deref_set->add (decl);
9481 goto do_add_decl;
9483 /* An "attach/detach" operation on an update directive should
9484 behave as a GOMP_MAP_ALWAYS_POINTER. Beware that
9485 unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
9486 depends on the previous mapping. */
9487 if (code == OACC_UPDATE
9488 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9489 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
9490 if (DECL_P (decl)
9491 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
9492 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
9493 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
9494 && code != OACC_UPDATE
9495 && code != OMP_TARGET_UPDATE)
9497 if (error_operand_p (decl))
9499 remove = true;
9500 break;
9503 tree stype = TREE_TYPE (decl);
9504 if (TREE_CODE (stype) == REFERENCE_TYPE)
9505 stype = TREE_TYPE (stype);
9506 if (TYPE_SIZE_UNIT (stype) == NULL
9507 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
9509 error_at (OMP_CLAUSE_LOCATION (c),
9510 "mapping field %qE of variable length "
9511 "structure", OMP_CLAUSE_DECL (c));
9512 remove = true;
9513 break;
9516 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
9517 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9519 /* Error recovery. */
9520 if (prev_list_p == NULL)
9522 remove = true;
9523 break;
9525 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
9527 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
9528 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
9530 remove = true;
9531 break;
9536 poly_offset_int offset1;
9537 poly_int64 bitpos1;
9538 tree base_ref;
9540 tree base
9541 = extract_base_bit_offset (OMP_CLAUSE_DECL (c), &base_ref,
9542 &bitpos1, &offset1);
9544 gcc_assert (base == decl);
9546 splay_tree_node n
9547 = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
9548 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
9549 == GOMP_MAP_ALWAYS_POINTER);
9550 bool attach_detach = (OMP_CLAUSE_MAP_KIND (c)
9551 == GOMP_MAP_ATTACH_DETACH);
9552 bool attach = OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9553 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH;
9554 bool has_attachments = false;
9555 /* For OpenACC, pointers in structs should trigger an
9556 attach action. */
9557 if (attach_detach
9558 && ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA))
9559 || code == OMP_TARGET_ENTER_DATA
9560 || code == OMP_TARGET_EXIT_DATA))
9563 /* Turn a GOMP_MAP_ATTACH_DETACH clause into a
9564 GOMP_MAP_ATTACH or GOMP_MAP_DETACH clause after we
9565 have detected a case that needs a GOMP_MAP_STRUCT
9566 mapping added. */
9567 gomp_map_kind k
9568 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9569 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9570 OMP_CLAUSE_SET_MAP_KIND (c, k);
9571 has_attachments = true;
9573 if (n == NULL || (n->value & GOVD_MAP) == 0)
9575 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9576 OMP_CLAUSE_MAP);
9577 gomp_map_kind k = attach ? GOMP_MAP_FORCE_PRESENT
9578 : GOMP_MAP_STRUCT;
9580 OMP_CLAUSE_SET_MAP_KIND (l, k);
9581 if (base_ref)
9582 OMP_CLAUSE_DECL (l) = unshare_expr (base_ref);
9583 else
9584 OMP_CLAUSE_DECL (l) = decl;
9585 OMP_CLAUSE_SIZE (l)
9586 = (!attach
9587 ? size_int (1)
9588 : DECL_P (OMP_CLAUSE_DECL (l))
9589 ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l))
9590 : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l))));
9591 if (struct_map_to_clause == NULL)
9592 struct_map_to_clause = new hash_map<tree, tree>;
9593 struct_map_to_clause->put (decl, l);
9594 if (ptr || attach_detach)
9596 insert_struct_comp_map (code, c, l, *prev_list_p,
9597 NULL);
9598 *prev_list_p = l;
9599 prev_list_p = NULL;
9601 else
9603 OMP_CLAUSE_CHAIN (l) = c;
9604 *list_p = l;
9605 list_p = &OMP_CLAUSE_CHAIN (l);
9607 if (base_ref && code == OMP_TARGET)
9609 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9610 OMP_CLAUSE_MAP);
9611 enum gomp_map_kind mkind
9612 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
9613 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9614 OMP_CLAUSE_DECL (c2) = decl;
9615 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9616 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
9617 OMP_CLAUSE_CHAIN (l) = c2;
9619 flags = GOVD_MAP | GOVD_EXPLICIT;
9620 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9621 || ptr
9622 || attach_detach)
9623 flags |= GOVD_SEEN;
9624 if (has_attachments)
9625 flags |= GOVD_MAP_HAS_ATTACHMENTS;
9626 goto do_add_decl;
9628 else if (struct_map_to_clause)
9630 tree *osc = struct_map_to_clause->get (decl);
9631 tree *sc = NULL, *scp = NULL;
9632 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9633 || ptr
9634 || attach_detach)
9635 n->value |= GOVD_SEEN;
9636 sc = &OMP_CLAUSE_CHAIN (*osc);
9637 if (*sc != c
9638 && (OMP_CLAUSE_MAP_KIND (*sc)
9639 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9640 sc = &OMP_CLAUSE_CHAIN (*sc);
9641 /* Here "prev_list_p" is the end of the inserted
9642 alloc/release nodes after the struct node, OSC. */
9643 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
9644 if ((ptr || attach_detach) && sc == prev_list_p)
9645 break;
9646 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9647 != COMPONENT_REF
9648 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9649 != INDIRECT_REF)
9650 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9651 != ARRAY_REF))
9652 break;
9653 else
9655 tree sc_decl = OMP_CLAUSE_DECL (*sc);
9656 poly_offset_int offsetn;
9657 poly_int64 bitposn;
9658 tree base
9659 = extract_base_bit_offset (sc_decl, NULL,
9660 &bitposn, &offsetn);
9661 if (base != decl)
9662 break;
9663 if (scp)
9664 continue;
9665 if ((region_type & ORT_ACC) != 0)
9667 /* This duplicate checking code is currently only
9668 enabled for OpenACC. */
9669 tree d1 = OMP_CLAUSE_DECL (*sc);
9670 tree d2 = OMP_CLAUSE_DECL (c);
9671 while (TREE_CODE (d1) == ARRAY_REF)
9672 d1 = TREE_OPERAND (d1, 0);
9673 while (TREE_CODE (d2) == ARRAY_REF)
9674 d2 = TREE_OPERAND (d2, 0);
9675 if (TREE_CODE (d1) == INDIRECT_REF)
9676 d1 = TREE_OPERAND (d1, 0);
9677 if (TREE_CODE (d2) == INDIRECT_REF)
9678 d2 = TREE_OPERAND (d2, 0);
9679 while (TREE_CODE (d1) == COMPONENT_REF)
9680 if (TREE_CODE (d2) == COMPONENT_REF
9681 && TREE_OPERAND (d1, 1)
9682 == TREE_OPERAND (d2, 1))
9684 d1 = TREE_OPERAND (d1, 0);
9685 d2 = TREE_OPERAND (d2, 0);
9687 else
9688 break;
9689 if (d1 == d2)
9691 error_at (OMP_CLAUSE_LOCATION (c),
9692 "%qE appears more than once in map "
9693 "clauses", OMP_CLAUSE_DECL (c));
9694 remove = true;
9695 break;
9698 if (maybe_lt (offset1, offsetn)
9699 || (known_eq (offset1, offsetn)
9700 && maybe_lt (bitpos1, bitposn)))
9702 if (ptr || attach_detach)
9703 scp = sc;
9704 else
9705 break;
9708 if (remove)
9709 break;
9710 if (!attach)
9711 OMP_CLAUSE_SIZE (*osc)
9712 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
9713 size_one_node);
9714 if (ptr || attach_detach)
9716 tree cl = insert_struct_comp_map (code, c, NULL,
9717 *prev_list_p, scp);
9718 if (sc == prev_list_p)
9720 *sc = cl;
9721 prev_list_p = NULL;
9723 else
9725 *prev_list_p = OMP_CLAUSE_CHAIN (c);
9726 list_p = prev_list_p;
9727 prev_list_p = NULL;
9728 OMP_CLAUSE_CHAIN (c) = *sc;
9729 *sc = cl;
9730 continue;
9733 else if (*sc != c)
9735 *list_p = OMP_CLAUSE_CHAIN (c);
9736 OMP_CLAUSE_CHAIN (c) = *sc;
9737 *sc = c;
9738 continue;
9742 else if ((code == OACC_ENTER_DATA
9743 || code == OACC_EXIT_DATA
9744 || code == OACC_DATA
9745 || code == OACC_PARALLEL
9746 || code == OACC_KERNELS
9747 || code == OACC_SERIAL)
9748 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9750 gomp_map_kind k = (code == OACC_EXIT_DATA
9751 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9752 OMP_CLAUSE_SET_MAP_KIND (c, k);
9755 if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
9757 /* Don't gimplify *pd fully at this point, as the base
9758 will need to be adjusted during omp lowering. */
9759 auto_vec<tree, 10> expr_stack;
9760 tree *p = pd;
9761 while (handled_component_p (*p)
9762 || TREE_CODE (*p) == INDIRECT_REF
9763 || TREE_CODE (*p) == ADDR_EXPR
9764 || TREE_CODE (*p) == MEM_REF
9765 || TREE_CODE (*p) == NON_LVALUE_EXPR)
9767 expr_stack.safe_push (*p);
9768 p = &TREE_OPERAND (*p, 0);
9770 for (int i = expr_stack.length () - 1; i >= 0; i--)
9772 tree t = expr_stack[i];
9773 if (TREE_CODE (t) == ARRAY_REF
9774 || TREE_CODE (t) == ARRAY_RANGE_REF)
9776 if (TREE_OPERAND (t, 2) == NULL_TREE)
9778 tree low = unshare_expr (array_ref_low_bound (t));
9779 if (!is_gimple_min_invariant (low))
9781 TREE_OPERAND (t, 2) = low;
9782 if (gimplify_expr (&TREE_OPERAND (t, 2),
9783 pre_p, NULL,
9784 is_gimple_reg,
9785 fb_rvalue) == GS_ERROR)
9786 remove = true;
9789 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
9790 NULL, is_gimple_reg,
9791 fb_rvalue) == GS_ERROR)
9792 remove = true;
9793 if (TREE_OPERAND (t, 3) == NULL_TREE)
9795 tree elmt_size = array_ref_element_size (t);
9796 if (!is_gimple_min_invariant (elmt_size))
9798 elmt_size = unshare_expr (elmt_size);
9799 tree elmt_type
9800 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t,
9801 0)));
9802 tree factor
9803 = size_int (TYPE_ALIGN_UNIT (elmt_type));
9804 elmt_size
9805 = size_binop (EXACT_DIV_EXPR, elmt_size,
9806 factor);
9807 TREE_OPERAND (t, 3) = elmt_size;
9808 if (gimplify_expr (&TREE_OPERAND (t, 3),
9809 pre_p, NULL,
9810 is_gimple_reg,
9811 fb_rvalue) == GS_ERROR)
9812 remove = true;
9815 else if (gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
9816 NULL, is_gimple_reg,
9817 fb_rvalue) == GS_ERROR)
9818 remove = true;
9820 else if (TREE_CODE (t) == COMPONENT_REF)
9822 if (TREE_OPERAND (t, 2) == NULL_TREE)
9824 tree offset = component_ref_field_offset (t);
9825 if (!is_gimple_min_invariant (offset))
9827 offset = unshare_expr (offset);
9828 tree field = TREE_OPERAND (t, 1);
9829 tree factor
9830 = size_int (DECL_OFFSET_ALIGN (field)
9831 / BITS_PER_UNIT);
9832 offset = size_binop (EXACT_DIV_EXPR, offset,
9833 factor);
9834 TREE_OPERAND (t, 2) = offset;
9835 if (gimplify_expr (&TREE_OPERAND (t, 2),
9836 pre_p, NULL,
9837 is_gimple_reg,
9838 fb_rvalue) == GS_ERROR)
9839 remove = true;
9842 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
9843 NULL, is_gimple_reg,
9844 fb_rvalue) == GS_ERROR)
9845 remove = true;
9848 for (; expr_stack.length () > 0; )
9850 tree t = expr_stack.pop ();
9852 if (TREE_CODE (t) == ARRAY_REF
9853 || TREE_CODE (t) == ARRAY_RANGE_REF)
9855 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))
9856 && gimplify_expr (&TREE_OPERAND (t, 1), pre_p,
9857 NULL, is_gimple_val,
9858 fb_rvalue) == GS_ERROR)
9859 remove = true;
9863 else if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
9864 fb_lvalue) == GS_ERROR)
9866 remove = true;
9867 break;
9870 if (!remove
9871 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
9872 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
9873 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
9874 && OMP_CLAUSE_CHAIN (c)
9875 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
9876 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9877 == GOMP_MAP_ALWAYS_POINTER)
9878 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9879 == GOMP_MAP_ATTACH_DETACH)
9880 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9881 == GOMP_MAP_TO_PSET)))
9882 prev_list_p = list_p;
9884 break;
9886 else
9888 /* DECL_P (decl) == true */
9889 tree *sc;
9890 if (struct_map_to_clause
9891 && (sc = struct_map_to_clause->get (decl)) != NULL
9892 && OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_STRUCT
9893 && decl == OMP_CLAUSE_DECL (*sc))
9895 /* We have found a map of the whole structure after a
9896 leading GOMP_MAP_STRUCT has been created, so refill the
9897 leading clause into a map of the whole structure
9898 variable, and remove the current one.
9899 TODO: we should be able to remove some maps of the
9900 following structure element maps if they are of
9901 compatible TO/FROM/ALLOC type. */
9902 OMP_CLAUSE_SET_MAP_KIND (*sc, OMP_CLAUSE_MAP_KIND (c));
9903 OMP_CLAUSE_SIZE (*sc) = unshare_expr (OMP_CLAUSE_SIZE (c));
9904 remove = true;
9905 break;
9908 flags = GOVD_MAP | GOVD_EXPLICIT;
9909 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
9910 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
9911 flags |= GOVD_MAP_ALWAYS_TO;
9913 if ((code == OMP_TARGET
9914 || code == OMP_TARGET_DATA
9915 || code == OMP_TARGET_ENTER_DATA
9916 || code == OMP_TARGET_EXIT_DATA)
9917 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9919 for (struct gimplify_omp_ctx *octx = outer_ctx; octx;
9920 octx = octx->outer_context)
9922 splay_tree_node n
9923 = splay_tree_lookup (octx->variables,
9924 (splay_tree_key) OMP_CLAUSE_DECL (c));
9925 /* If this is contained in an outer OpenMP region as a
9926 firstprivate value, remove the attach/detach. */
9927 if (n && (n->value & GOVD_FIRSTPRIVATE))
9929 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FIRSTPRIVATE_POINTER);
9930 goto do_add;
9934 enum gomp_map_kind map_kind = (code == OMP_TARGET_EXIT_DATA
9935 ? GOMP_MAP_DETACH
9936 : GOMP_MAP_ATTACH);
9937 OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
9940 goto do_add;
9942 case OMP_CLAUSE_AFFINITY:
9943 gimplify_omp_affinity (list_p, pre_p);
9944 remove = true;
9945 break;
9946 case OMP_CLAUSE_DEPEND:
9947 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
9949 tree deps = OMP_CLAUSE_DECL (c);
9950 while (deps && TREE_CODE (deps) == TREE_LIST)
9952 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
9953 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
9954 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
9955 pre_p, NULL, is_gimple_val, fb_rvalue);
9956 deps = TREE_CHAIN (deps);
9958 break;
9960 else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
9961 break;
9962 if (handled_depend_iterators == -1)
9963 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
9964 if (handled_depend_iterators)
9966 if (handled_depend_iterators == 2)
9967 remove = true;
9968 break;
9970 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
9972 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
9973 NULL, is_gimple_val, fb_rvalue);
9974 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
9976 if (error_operand_p (OMP_CLAUSE_DECL (c)))
9978 remove = true;
9979 break;
9981 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
9982 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
9983 is_gimple_val, fb_rvalue) == GS_ERROR)
9985 remove = true;
9986 break;
9988 if (code == OMP_TASK)
9989 ctx->has_depend = true;
9990 break;
9992 case OMP_CLAUSE_TO:
9993 case OMP_CLAUSE_FROM:
9994 case OMP_CLAUSE__CACHE_:
9995 decl = OMP_CLAUSE_DECL (c);
9996 if (error_operand_p (decl))
9998 remove = true;
9999 break;
10001 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10002 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
10003 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
10004 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
10005 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
10007 remove = true;
10008 break;
10010 if (!DECL_P (decl))
10012 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
10013 NULL, is_gimple_lvalue, fb_lvalue)
10014 == GS_ERROR)
10016 remove = true;
10017 break;
10019 break;
10021 goto do_notice;
10023 case OMP_CLAUSE_USE_DEVICE_PTR:
10024 case OMP_CLAUSE_USE_DEVICE_ADDR:
10025 flags = GOVD_EXPLICIT;
10026 goto do_add;
10028 case OMP_CLAUSE_IS_DEVICE_PTR:
10029 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
10030 goto do_add;
10032 do_add:
10033 decl = OMP_CLAUSE_DECL (c);
10034 do_add_decl:
10035 if (error_operand_p (decl))
10037 remove = true;
10038 break;
10040 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
10042 tree t = omp_member_access_dummy_var (decl);
10043 if (t)
10045 tree v = DECL_VALUE_EXPR (decl);
10046 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
10047 if (outer_ctx)
10048 omp_notice_variable (outer_ctx, t, true);
10051 if (code == OACC_DATA
10052 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10053 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
10054 flags |= GOVD_MAP_0LEN_ARRAY;
10055 omp_add_variable (ctx, decl, flags);
10056 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10057 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
10058 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
10059 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
10061 struct gimplify_omp_ctx *pctx
10062 = code == OMP_TARGET ? outer_ctx : ctx;
10063 if (pctx)
10064 omp_add_variable (pctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
10065 GOVD_LOCAL | GOVD_SEEN);
10066 if (pctx
10067 && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
10068 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
10069 find_decl_expr,
10070 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
10071 NULL) == NULL_TREE)
10072 omp_add_variable (pctx,
10073 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
10074 GOVD_LOCAL | GOVD_SEEN);
10075 gimplify_omp_ctxp = pctx;
10076 push_gimplify_context ();
10078 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
10079 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
10081 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
10082 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
10083 pop_gimplify_context
10084 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
10085 push_gimplify_context ();
10086 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
10087 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
10088 pop_gimplify_context
10089 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
10090 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
10091 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
10093 gimplify_omp_ctxp = outer_ctx;
10095 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10096 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
10098 gimplify_omp_ctxp = ctx;
10099 push_gimplify_context ();
10100 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
10102 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
10103 NULL, NULL);
10104 TREE_SIDE_EFFECTS (bind) = 1;
10105 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
10106 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
10108 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
10109 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
10110 pop_gimplify_context
10111 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
10112 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
10114 gimplify_omp_ctxp = outer_ctx;
10116 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10117 && OMP_CLAUSE_LINEAR_STMT (c))
10119 gimplify_omp_ctxp = ctx;
10120 push_gimplify_context ();
10121 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
10123 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
10124 NULL, NULL);
10125 TREE_SIDE_EFFECTS (bind) = 1;
10126 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
10127 OMP_CLAUSE_LINEAR_STMT (c) = bind;
10129 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
10130 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
10131 pop_gimplify_context
10132 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
10133 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
10135 gimplify_omp_ctxp = outer_ctx;
10137 if (notice_outer)
10138 goto do_notice;
10139 break;
10141 case OMP_CLAUSE_COPYIN:
10142 case OMP_CLAUSE_COPYPRIVATE:
10143 decl = OMP_CLAUSE_DECL (c);
10144 if (error_operand_p (decl))
10146 remove = true;
10147 break;
10149 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
10150 && !remove
10151 && !omp_check_private (ctx, decl, true))
10153 remove = true;
10154 if (is_global_var (decl))
10156 if (DECL_THREAD_LOCAL_P (decl))
10157 remove = false;
10158 else if (DECL_HAS_VALUE_EXPR_P (decl))
10160 tree value = get_base_address (DECL_VALUE_EXPR (decl));
10162 if (value
10163 && DECL_P (value)
10164 && DECL_THREAD_LOCAL_P (value))
10165 remove = false;
10168 if (remove)
10169 error_at (OMP_CLAUSE_LOCATION (c),
10170 "copyprivate variable %qE is not threadprivate"
10171 " or private in outer context", DECL_NAME (decl));
10173 do_notice:
10174 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10175 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10176 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
10177 && outer_ctx
10178 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
10179 || (region_type == ORT_WORKSHARE
10180 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10181 && (OMP_CLAUSE_REDUCTION_INSCAN (c)
10182 || code == OMP_LOOP)))
10183 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
10184 || (code == OMP_LOOP
10185 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10186 && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
10187 == ORT_COMBINED_TEAMS))))
10189 splay_tree_node on
10190 = splay_tree_lookup (outer_ctx->variables,
10191 (splay_tree_key)decl);
10192 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
10194 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10195 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10196 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
10197 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
10198 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
10199 == POINTER_TYPE))))
10200 omp_firstprivatize_variable (outer_ctx, decl);
10201 else
10203 omp_add_variable (outer_ctx, decl,
10204 GOVD_SEEN | GOVD_SHARED);
10205 if (outer_ctx->outer_context)
10206 omp_notice_variable (outer_ctx->outer_context, decl,
10207 true);
10211 if (outer_ctx)
10212 omp_notice_variable (outer_ctx, decl, true);
10213 if (check_non_private
10214 && (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
10215 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
10216 || decl == OMP_CLAUSE_DECL (c)
10217 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10218 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10219 == ADDR_EXPR
10220 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10221 == POINTER_PLUS_EXPR
10222 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
10223 (OMP_CLAUSE_DECL (c), 0), 0))
10224 == ADDR_EXPR)))))
10225 && omp_check_private (ctx, decl, false))
10227 error ("%s variable %qE is private in outer context",
10228 check_non_private, DECL_NAME (decl));
10229 remove = true;
10231 break;
10233 case OMP_CLAUSE_DETACH:
10234 flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
10235 goto do_add;
10237 case OMP_CLAUSE_IF:
10238 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
10239 && OMP_CLAUSE_IF_MODIFIER (c) != code)
10241 const char *p[2];
10242 for (int i = 0; i < 2; i++)
10243 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
10245 case VOID_CST: p[i] = "cancel"; break;
10246 case OMP_PARALLEL: p[i] = "parallel"; break;
10247 case OMP_SIMD: p[i] = "simd"; break;
10248 case OMP_TASK: p[i] = "task"; break;
10249 case OMP_TASKLOOP: p[i] = "taskloop"; break;
10250 case OMP_TARGET_DATA: p[i] = "target data"; break;
10251 case OMP_TARGET: p[i] = "target"; break;
10252 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
10253 case OMP_TARGET_ENTER_DATA:
10254 p[i] = "target enter data"; break;
10255 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
10256 default: gcc_unreachable ();
10258 error_at (OMP_CLAUSE_LOCATION (c),
10259 "expected %qs %<if%> clause modifier rather than %qs",
10260 p[0], p[1]);
10261 remove = true;
10263 /* Fall through. */
10265 case OMP_CLAUSE_FINAL:
10266 OMP_CLAUSE_OPERAND (c, 0)
10267 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
10268 /* Fall through. */
10270 case OMP_CLAUSE_NUM_TEAMS:
10271 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
10272 && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
10273 && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
10275 if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
10277 remove = true;
10278 break;
10280 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
10281 = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c),
10282 pre_p, NULL, true);
10284 /* Fall through. */
10286 case OMP_CLAUSE_SCHEDULE:
10287 case OMP_CLAUSE_NUM_THREADS:
10288 case OMP_CLAUSE_THREAD_LIMIT:
10289 case OMP_CLAUSE_DIST_SCHEDULE:
10290 case OMP_CLAUSE_DEVICE:
10291 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE
10292 && OMP_CLAUSE_DEVICE_ANCESTOR (c))
10294 if (code != OMP_TARGET)
10296 error_at (OMP_CLAUSE_LOCATION (c),
10297 "%<device%> clause with %<ancestor%> is only "
10298 "allowed on %<target%> construct");
10299 remove = true;
10300 break;
10303 tree clauses = *orig_list_p;
10304 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
10305 if (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEVICE
10306 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_FIRSTPRIVATE
10307 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_PRIVATE
10308 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEFAULTMAP
10309 && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_MAP
10312 error_at (OMP_CLAUSE_LOCATION (c),
10313 "with %<ancestor%>, only the %<device%>, "
10314 "%<firstprivate%>, %<private%>, %<defaultmap%>, "
10315 "and %<map%> clauses may appear on the "
10316 "construct");
10317 remove = true;
10318 break;
10321 /* Fall through. */
10323 case OMP_CLAUSE_PRIORITY:
10324 case OMP_CLAUSE_GRAINSIZE:
10325 case OMP_CLAUSE_NUM_TASKS:
10326 case OMP_CLAUSE_FILTER:
10327 case OMP_CLAUSE_HINT:
10328 case OMP_CLAUSE_ASYNC:
10329 case OMP_CLAUSE_WAIT:
10330 case OMP_CLAUSE_NUM_GANGS:
10331 case OMP_CLAUSE_NUM_WORKERS:
10332 case OMP_CLAUSE_VECTOR_LENGTH:
10333 case OMP_CLAUSE_WORKER:
10334 case OMP_CLAUSE_VECTOR:
10335 if (OMP_CLAUSE_OPERAND (c, 0)
10336 && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0)))
10338 if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0)))
10340 remove = true;
10341 break;
10343 /* All these clauses care about value, not a particular decl,
10344 so try to force it into a SSA_NAME or fresh temporary. */
10345 OMP_CLAUSE_OPERAND (c, 0)
10346 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0),
10347 pre_p, NULL, true);
10349 break;
10351 case OMP_CLAUSE_GANG:
10352 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
10353 is_gimple_val, fb_rvalue) == GS_ERROR)
10354 remove = true;
10355 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
10356 is_gimple_val, fb_rvalue) == GS_ERROR)
10357 remove = true;
10358 break;
10360 case OMP_CLAUSE_NOWAIT:
10361 nowait = 1;
10362 break;
10364 case OMP_CLAUSE_ORDERED:
10365 case OMP_CLAUSE_UNTIED:
10366 case OMP_CLAUSE_COLLAPSE:
10367 case OMP_CLAUSE_TILE:
10368 case OMP_CLAUSE_AUTO:
10369 case OMP_CLAUSE_SEQ:
10370 case OMP_CLAUSE_INDEPENDENT:
10371 case OMP_CLAUSE_MERGEABLE:
10372 case OMP_CLAUSE_PROC_BIND:
10373 case OMP_CLAUSE_SAFELEN:
10374 case OMP_CLAUSE_SIMDLEN:
10375 case OMP_CLAUSE_NOGROUP:
10376 case OMP_CLAUSE_THREADS:
10377 case OMP_CLAUSE_SIMD:
10378 case OMP_CLAUSE_BIND:
10379 case OMP_CLAUSE_IF_PRESENT:
10380 case OMP_CLAUSE_FINALIZE:
10381 break;
10383 case OMP_CLAUSE_ORDER:
10384 ctx->order_concurrent = true;
10385 break;
10387 case OMP_CLAUSE_DEFAULTMAP:
10388 enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
10389 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
10391 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
10392 gdmkmin = GDMK_SCALAR;
10393 gdmkmax = GDMK_POINTER;
10394 break;
10395 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
10396 gdmkmin = GDMK_SCALAR;
10397 gdmkmax = GDMK_SCALAR_TARGET;
10398 break;
10399 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
10400 gdmkmin = gdmkmax = GDMK_AGGREGATE;
10401 break;
10402 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
10403 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
10404 break;
10405 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
10406 gdmkmin = gdmkmax = GDMK_POINTER;
10407 break;
10408 default:
10409 gcc_unreachable ();
10411 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
10412 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
10414 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
10415 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
10416 break;
10417 case OMP_CLAUSE_DEFAULTMAP_TO:
10418 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
10419 break;
10420 case OMP_CLAUSE_DEFAULTMAP_FROM:
10421 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
10422 break;
10423 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
10424 ctx->defaultmap[gdmk] = GOVD_MAP;
10425 break;
10426 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
10427 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10428 break;
10429 case OMP_CLAUSE_DEFAULTMAP_NONE:
10430 ctx->defaultmap[gdmk] = 0;
10431 break;
10432 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
10433 switch (gdmk)
10435 case GDMK_SCALAR:
10436 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10437 break;
10438 case GDMK_SCALAR_TARGET:
10439 ctx->defaultmap[gdmk] = (lang_GNU_Fortran ()
10440 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
10441 break;
10442 case GDMK_AGGREGATE:
10443 case GDMK_ALLOCATABLE:
10444 ctx->defaultmap[gdmk] = GOVD_MAP;
10445 break;
10446 case GDMK_POINTER:
10447 ctx->defaultmap[gdmk] = GOVD_MAP;
10448 if (!lang_GNU_Fortran ())
10449 ctx->defaultmap[gdmk] |= GOVD_MAP_0LEN_ARRAY;
10450 break;
10451 default:
10452 gcc_unreachable ();
10454 break;
10455 default:
10456 gcc_unreachable ();
10458 break;
10460 case OMP_CLAUSE_ALIGNED:
10461 decl = OMP_CLAUSE_DECL (c);
10462 if (error_operand_p (decl))
10464 remove = true;
10465 break;
10467 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
10468 is_gimple_val, fb_rvalue) == GS_ERROR)
10470 remove = true;
10471 break;
10473 if (!is_global_var (decl)
10474 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
10475 omp_add_variable (ctx, decl, GOVD_ALIGNED);
10476 break;
10478 case OMP_CLAUSE_NONTEMPORAL:
10479 decl = OMP_CLAUSE_DECL (c);
10480 if (error_operand_p (decl))
10482 remove = true;
10483 break;
10485 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
10486 break;
10488 case OMP_CLAUSE_ALLOCATE:
10489 decl = OMP_CLAUSE_DECL (c);
10490 if (error_operand_p (decl))
10492 remove = true;
10493 break;
10495 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL,
10496 is_gimple_val, fb_rvalue) == GS_ERROR)
10498 remove = true;
10499 break;
10501 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
10502 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
10503 == INTEGER_CST))
10505 else if (code == OMP_TASKLOOP
10506 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
10507 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
10508 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
10509 pre_p, NULL, false);
10510 break;
10512 case OMP_CLAUSE_DEFAULT:
10513 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
10514 break;
10516 case OMP_CLAUSE_INCLUSIVE:
10517 case OMP_CLAUSE_EXCLUSIVE:
10518 decl = OMP_CLAUSE_DECL (c);
10520 splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
10521 (splay_tree_key) decl);
10522 if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
10524 error_at (OMP_CLAUSE_LOCATION (c),
10525 "%qD specified in %qs clause but not in %<inscan%> "
10526 "%<reduction%> clause on the containing construct",
10527 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10528 remove = true;
10530 else
10532 n->value |= GOVD_REDUCTION_INSCAN;
10533 if (outer_ctx->region_type == ORT_SIMD
10534 && outer_ctx->outer_context
10535 && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
10537 n = splay_tree_lookup (outer_ctx->outer_context->variables,
10538 (splay_tree_key) decl);
10539 if (n && (n->value & GOVD_REDUCTION) != 0)
10540 n->value |= GOVD_REDUCTION_INSCAN;
10544 break;
10546 case OMP_CLAUSE_NOHOST:
10547 default:
10548 gcc_unreachable ();
10551 if (code == OACC_DATA
10552 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10553 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
10554 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
10555 remove = true;
10556 if (remove)
10557 *list_p = OMP_CLAUSE_CHAIN (c);
10558 else
10559 list_p = &OMP_CLAUSE_CHAIN (c);
10562 ctx->clauses = *orig_list_p;
10563 gimplify_omp_ctxp = ctx;
10564 if (struct_map_to_clause)
10565 delete struct_map_to_clause;
10566 if (struct_deref_set)
10567 delete struct_deref_set;
10570 /* Return true if DECL is a candidate for shared to firstprivate
10571 optimization. We only consider non-addressable scalars, not
10572 too big, and not references. */
10574 static bool
10575 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
10577 if (TREE_ADDRESSABLE (decl))
10578 return false;
10579 tree type = TREE_TYPE (decl);
10580 if (!is_gimple_reg_type (type)
10581 || TREE_CODE (type) == REFERENCE_TYPE
10582 || TREE_ADDRESSABLE (type))
10583 return false;
10584 /* Don't optimize too large decls, as each thread/task will have
10585 its own. */
10586 HOST_WIDE_INT len = int_size_in_bytes (type);
10587 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
10588 return false;
10589 if (omp_privatize_by_reference (decl))
10590 return false;
10591 return true;
10594 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
10595 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
10596 GOVD_WRITTEN in outer contexts. */
10598 static void
10599 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
10601 for (; ctx; ctx = ctx->outer_context)
10603 splay_tree_node n = splay_tree_lookup (ctx->variables,
10604 (splay_tree_key) decl);
10605 if (n == NULL)
10606 continue;
10607 else if (n->value & GOVD_SHARED)
10609 n->value |= GOVD_WRITTEN;
10610 return;
10612 else if (n->value & GOVD_DATA_SHARE_CLASS)
10613 return;
10617 /* Helper callback for walk_gimple_seq to discover possible stores
10618 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10619 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10620 for those. */
10622 static tree
10623 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
10625 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
10627 *walk_subtrees = 0;
10628 if (!wi->is_lhs)
10629 return NULL_TREE;
10631 tree op = *tp;
10634 if (handled_component_p (op))
10635 op = TREE_OPERAND (op, 0);
10636 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
10637 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
10638 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
10639 else
10640 break;
10642 while (1);
10643 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
10644 return NULL_TREE;
10646 omp_mark_stores (gimplify_omp_ctxp, op);
10647 return NULL_TREE;
10650 /* Helper callback for walk_gimple_seq to discover possible stores
10651 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10652 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10653 for those. */
10655 static tree
10656 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
10657 bool *handled_ops_p,
10658 struct walk_stmt_info *wi)
10660 gimple *stmt = gsi_stmt (*gsi_p);
10661 switch (gimple_code (stmt))
10663 /* Don't recurse on OpenMP constructs for which
10664 gimplify_adjust_omp_clauses already handled the bodies,
10665 except handle gimple_omp_for_pre_body. */
10666 case GIMPLE_OMP_FOR:
10667 *handled_ops_p = true;
10668 if (gimple_omp_for_pre_body (stmt))
10669 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
10670 omp_find_stores_stmt, omp_find_stores_op, wi);
10671 break;
10672 case GIMPLE_OMP_PARALLEL:
10673 case GIMPLE_OMP_TASK:
10674 case GIMPLE_OMP_SECTIONS:
10675 case GIMPLE_OMP_SINGLE:
10676 case GIMPLE_OMP_SCOPE:
10677 case GIMPLE_OMP_TARGET:
10678 case GIMPLE_OMP_TEAMS:
10679 case GIMPLE_OMP_CRITICAL:
10680 *handled_ops_p = true;
10681 break;
10682 default:
10683 break;
10685 return NULL_TREE;
10688 struct gimplify_adjust_omp_clauses_data
10690 tree *list_p;
10691 gimple_seq *pre_p;
10694 /* For all variables that were not actually used within the context,
10695 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
10697 static int
10698 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
10700 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
10701 gimple_seq *pre_p
10702 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
10703 tree decl = (tree) n->key;
10704 unsigned flags = n->value;
10705 enum omp_clause_code code;
10706 tree clause;
10707 bool private_debug;
10709 if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
10710 && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
10711 flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
10712 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
10713 return 0;
10714 if ((flags & GOVD_SEEN) == 0)
10715 return 0;
10716 if ((flags & GOVD_MAP_HAS_ATTACHMENTS) != 0)
10717 return 0;
10718 if (flags & GOVD_DEBUG_PRIVATE)
10720 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
10721 private_debug = true;
10723 else if (flags & GOVD_MAP)
10724 private_debug = false;
10725 else
10726 private_debug
10727 = lang_hooks.decls.omp_private_debug_clause (decl,
10728 !!(flags & GOVD_SHARED));
10729 if (private_debug)
10730 code = OMP_CLAUSE_PRIVATE;
10731 else if (flags & GOVD_MAP)
10733 code = OMP_CLAUSE_MAP;
10734 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
10735 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
10737 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
10738 return 0;
10740 if (VAR_P (decl)
10741 && DECL_IN_CONSTANT_POOL (decl)
10742 && !lookup_attribute ("omp declare target",
10743 DECL_ATTRIBUTES (decl)))
10745 tree id = get_identifier ("omp declare target");
10746 DECL_ATTRIBUTES (decl)
10747 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
10748 varpool_node *node = varpool_node::get (decl);
10749 if (node)
10751 node->offloadable = 1;
10752 if (ENABLE_OFFLOADING)
10753 g->have_offload = true;
10757 else if (flags & GOVD_SHARED)
10759 if (is_global_var (decl))
10761 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
10762 while (ctx != NULL)
10764 splay_tree_node on
10765 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10766 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
10767 | GOVD_PRIVATE | GOVD_REDUCTION
10768 | GOVD_LINEAR | GOVD_MAP)) != 0)
10769 break;
10770 ctx = ctx->outer_context;
10772 if (ctx == NULL)
10773 return 0;
10775 code = OMP_CLAUSE_SHARED;
10776 /* Don't optimize shared into firstprivate for read-only vars
10777 on tasks with depend clause, we shouldn't try to copy them
10778 until the dependencies are satisfied. */
10779 if (gimplify_omp_ctxp->has_depend)
10780 flags |= GOVD_WRITTEN;
10782 else if (flags & GOVD_PRIVATE)
10783 code = OMP_CLAUSE_PRIVATE;
10784 else if (flags & GOVD_FIRSTPRIVATE)
10786 code = OMP_CLAUSE_FIRSTPRIVATE;
10787 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
10788 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
10789 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
10791 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
10792 "%<target%> construct", decl);
10793 return 0;
10796 else if (flags & GOVD_LASTPRIVATE)
10797 code = OMP_CLAUSE_LASTPRIVATE;
10798 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
10799 return 0;
10800 else if (flags & GOVD_CONDTEMP)
10802 code = OMP_CLAUSE__CONDTEMP_;
10803 gimple_add_tmp_var (decl);
10805 else
10806 gcc_unreachable ();
10808 if (((flags & GOVD_LASTPRIVATE)
10809 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
10810 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10811 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10813 tree chain = *list_p;
10814 clause = build_omp_clause (input_location, code);
10815 OMP_CLAUSE_DECL (clause) = decl;
10816 OMP_CLAUSE_CHAIN (clause) = chain;
10817 if (private_debug)
10818 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
10819 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
10820 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
10821 else if (code == OMP_CLAUSE_SHARED
10822 && (flags & GOVD_WRITTEN) == 0
10823 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10824 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
10825 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
10826 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
10827 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
10829 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
10830 OMP_CLAUSE_DECL (nc) = decl;
10831 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
10832 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
10833 OMP_CLAUSE_DECL (clause)
10834 = build_simple_mem_ref_loc (input_location, decl);
10835 OMP_CLAUSE_DECL (clause)
10836 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
10837 build_int_cst (build_pointer_type (char_type_node), 0));
10838 OMP_CLAUSE_SIZE (clause) = size_zero_node;
10839 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10840 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
10841 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
10842 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
10843 OMP_CLAUSE_CHAIN (nc) = chain;
10844 OMP_CLAUSE_CHAIN (clause) = nc;
10845 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10846 gimplify_omp_ctxp = ctx->outer_context;
10847 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
10848 pre_p, NULL, is_gimple_val, fb_rvalue);
10849 gimplify_omp_ctxp = ctx;
10851 else if (code == OMP_CLAUSE_MAP)
10853 int kind;
10854 /* Not all combinations of these GOVD_MAP flags are actually valid. */
10855 switch (flags & (GOVD_MAP_TO_ONLY
10856 | GOVD_MAP_FORCE
10857 | GOVD_MAP_FORCE_PRESENT
10858 | GOVD_MAP_ALLOC_ONLY
10859 | GOVD_MAP_FROM_ONLY))
10861 case 0:
10862 kind = GOMP_MAP_TOFROM;
10863 break;
10864 case GOVD_MAP_FORCE:
10865 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
10866 break;
10867 case GOVD_MAP_TO_ONLY:
10868 kind = GOMP_MAP_TO;
10869 break;
10870 case GOVD_MAP_FROM_ONLY:
10871 kind = GOMP_MAP_FROM;
10872 break;
10873 case GOVD_MAP_ALLOC_ONLY:
10874 kind = GOMP_MAP_ALLOC;
10875 break;
10876 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
10877 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
10878 break;
10879 case GOVD_MAP_FORCE_PRESENT:
10880 kind = GOMP_MAP_FORCE_PRESENT;
10881 break;
10882 default:
10883 gcc_unreachable ();
10885 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
10886 /* Setting of the implicit flag for the runtime is currently disabled for
10887 OpenACC. */
10888 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
10889 OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
10890 if (DECL_SIZE (decl)
10891 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
10893 tree decl2 = DECL_VALUE_EXPR (decl);
10894 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
10895 decl2 = TREE_OPERAND (decl2, 0);
10896 gcc_assert (DECL_P (decl2));
10897 tree mem = build_simple_mem_ref (decl2);
10898 OMP_CLAUSE_DECL (clause) = mem;
10899 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
10900 if (gimplify_omp_ctxp->outer_context)
10902 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
10903 omp_notice_variable (ctx, decl2, true);
10904 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
10906 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
10907 OMP_CLAUSE_MAP);
10908 OMP_CLAUSE_DECL (nc) = decl;
10909 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10910 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
10911 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
10912 else
10913 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
10914 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
10915 OMP_CLAUSE_CHAIN (clause) = nc;
10917 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
10918 && omp_privatize_by_reference (decl))
10920 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
10921 OMP_CLAUSE_SIZE (clause)
10922 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
10923 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10924 gimplify_omp_ctxp = ctx->outer_context;
10925 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
10926 pre_p, NULL, is_gimple_val, fb_rvalue);
10927 gimplify_omp_ctxp = ctx;
10928 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
10929 OMP_CLAUSE_MAP);
10930 OMP_CLAUSE_DECL (nc) = decl;
10931 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10932 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
10933 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
10934 OMP_CLAUSE_CHAIN (clause) = nc;
10936 else
10937 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
10939 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
10941 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
10942 OMP_CLAUSE_DECL (nc) = decl;
10943 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
10944 OMP_CLAUSE_CHAIN (nc) = chain;
10945 OMP_CLAUSE_CHAIN (clause) = nc;
10946 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10947 gimplify_omp_ctxp = ctx->outer_context;
10948 lang_hooks.decls.omp_finish_clause (nc, pre_p,
10949 (ctx->region_type & ORT_ACC) != 0);
10950 gimplify_omp_ctxp = ctx;
10952 *list_p = clause;
10953 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10954 gimplify_omp_ctxp = ctx->outer_context;
10955 /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
10956 in simd. Those are only added for the local vars inside of simd body
10957 and they don't need to be e.g. default constructible. */
10958 if (code != OMP_CLAUSE_PRIVATE || ctx->region_type != ORT_SIMD)
10959 lang_hooks.decls.omp_finish_clause (clause, pre_p,
10960 (ctx->region_type & ORT_ACC) != 0);
10961 if (gimplify_omp_ctxp)
10962 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
10963 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
10964 && DECL_P (OMP_CLAUSE_SIZE (clause)))
10965 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
10966 true);
10967 gimplify_omp_ctxp = ctx;
10968 return 0;
10971 static void
10972 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
10973 enum tree_code code)
10975 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10976 tree *orig_list_p = list_p;
10977 tree c, decl;
10978 bool has_inscan_reductions = false;
10980 if (body)
10982 struct gimplify_omp_ctx *octx;
10983 for (octx = ctx; octx; octx = octx->outer_context)
10984 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
10985 break;
10986 if (octx)
10988 struct walk_stmt_info wi;
10989 memset (&wi, 0, sizeof (wi));
10990 walk_gimple_seq (body, omp_find_stores_stmt,
10991 omp_find_stores_op, &wi);
10995 if (ctx->add_safelen1)
10997 /* If there are VLAs in the body of simd loop, prevent
10998 vectorization. */
10999 gcc_assert (ctx->region_type == ORT_SIMD);
11000 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
11001 OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
11002 OMP_CLAUSE_CHAIN (c) = *list_p;
11003 *list_p = c;
11004 list_p = &OMP_CLAUSE_CHAIN (c);
11007 if (ctx->region_type == ORT_WORKSHARE
11008 && ctx->outer_context
11009 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
11011 for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
11012 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11013 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
11015 decl = OMP_CLAUSE_DECL (c);
11016 splay_tree_node n
11017 = splay_tree_lookup (ctx->outer_context->variables,
11018 (splay_tree_key) decl);
11019 gcc_checking_assert (!splay_tree_lookup (ctx->variables,
11020 (splay_tree_key) decl));
11021 omp_add_variable (ctx, decl, n->value);
11022 tree c2 = copy_node (c);
11023 OMP_CLAUSE_CHAIN (c2) = *list_p;
11024 *list_p = c2;
11025 if ((n->value & GOVD_FIRSTPRIVATE) == 0)
11026 continue;
11027 c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11028 OMP_CLAUSE_FIRSTPRIVATE);
11029 OMP_CLAUSE_DECL (c2) = decl;
11030 OMP_CLAUSE_CHAIN (c2) = *list_p;
11031 *list_p = c2;
11034 while ((c = *list_p) != NULL)
11036 splay_tree_node n;
11037 bool remove = false;
11039 switch (OMP_CLAUSE_CODE (c))
11041 case OMP_CLAUSE_FIRSTPRIVATE:
11042 if ((ctx->region_type & ORT_TARGET)
11043 && (ctx->region_type & ORT_ACC) == 0
11044 && TYPE_ATOMIC (strip_array_types
11045 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
11047 error_at (OMP_CLAUSE_LOCATION (c),
11048 "%<_Atomic%> %qD in %<firstprivate%> clause on "
11049 "%<target%> construct", OMP_CLAUSE_DECL (c));
11050 remove = true;
11051 break;
11053 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
11055 decl = OMP_CLAUSE_DECL (c);
11056 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11057 if ((n->value & GOVD_MAP) != 0)
11059 remove = true;
11060 break;
11062 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) = 0;
11063 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) = 0;
11065 /* FALLTHRU */
11066 case OMP_CLAUSE_PRIVATE:
11067 case OMP_CLAUSE_SHARED:
11068 case OMP_CLAUSE_LINEAR:
11069 decl = OMP_CLAUSE_DECL (c);
11070 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11071 remove = !(n->value & GOVD_SEEN);
11072 if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
11073 && code == OMP_PARALLEL
11074 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
11075 remove = true;
11076 if (! remove)
11078 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
11079 if ((n->value & GOVD_DEBUG_PRIVATE)
11080 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
11082 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
11083 || ((n->value & GOVD_DATA_SHARE_CLASS)
11084 == GOVD_SHARED));
11085 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
11086 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
11088 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11089 && ctx->has_depend
11090 && DECL_P (decl))
11091 n->value |= GOVD_WRITTEN;
11092 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11093 && (n->value & GOVD_WRITTEN) == 0
11094 && DECL_P (decl)
11095 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11096 OMP_CLAUSE_SHARED_READONLY (c) = 1;
11097 else if (DECL_P (decl)
11098 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11099 && (n->value & GOVD_WRITTEN) != 0)
11100 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11101 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
11102 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11103 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11105 else
11106 n->value &= ~GOVD_EXPLICIT;
11107 break;
11109 case OMP_CLAUSE_LASTPRIVATE:
11110 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
11111 accurately reflect the presence of a FIRSTPRIVATE clause. */
11112 decl = OMP_CLAUSE_DECL (c);
11113 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11114 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
11115 = (n->value & GOVD_FIRSTPRIVATE) != 0;
11116 if (code == OMP_DISTRIBUTE
11117 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
11119 remove = true;
11120 error_at (OMP_CLAUSE_LOCATION (c),
11121 "same variable used in %<firstprivate%> and "
11122 "%<lastprivate%> clauses on %<distribute%> "
11123 "construct");
11125 if (!remove
11126 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11127 && DECL_P (decl)
11128 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11129 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11130 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
11131 remove = true;
11132 break;
11134 case OMP_CLAUSE_ALIGNED:
11135 decl = OMP_CLAUSE_DECL (c);
11136 if (!is_global_var (decl))
11138 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11139 remove = n == NULL || !(n->value & GOVD_SEEN);
11140 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
11142 struct gimplify_omp_ctx *octx;
11143 if (n != NULL
11144 && (n->value & (GOVD_DATA_SHARE_CLASS
11145 & ~GOVD_FIRSTPRIVATE)))
11146 remove = true;
11147 else
11148 for (octx = ctx->outer_context; octx;
11149 octx = octx->outer_context)
11151 n = splay_tree_lookup (octx->variables,
11152 (splay_tree_key) decl);
11153 if (n == NULL)
11154 continue;
11155 if (n->value & GOVD_LOCAL)
11156 break;
11157 /* We have to avoid assigning a shared variable
11158 to itself when trying to add
11159 __builtin_assume_aligned. */
11160 if (n->value & GOVD_SHARED)
11162 remove = true;
11163 break;
11168 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
11170 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11171 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
11172 remove = true;
11174 break;
11176 case OMP_CLAUSE_NONTEMPORAL:
11177 decl = OMP_CLAUSE_DECL (c);
11178 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11179 remove = n == NULL || !(n->value & GOVD_SEEN);
11180 break;
11182 case OMP_CLAUSE_MAP:
11183 if (code == OMP_TARGET_EXIT_DATA
11184 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
11186 remove = true;
11187 break;
11189 decl = OMP_CLAUSE_DECL (c);
11190 /* Data clauses associated with reductions must be
11191 compatible with present_or_copy. Warn and adjust the clause
11192 if that is not the case. */
11193 if (ctx->region_type == ORT_ACC_PARALLEL
11194 || ctx->region_type == ORT_ACC_SERIAL)
11196 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
11197 n = NULL;
11199 if (DECL_P (t))
11200 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
11202 if (n && (n->value & GOVD_REDUCTION))
11204 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
11206 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
11207 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
11208 && kind != GOMP_MAP_FORCE_PRESENT
11209 && kind != GOMP_MAP_POINTER)
11211 warning_at (OMP_CLAUSE_LOCATION (c), 0,
11212 "incompatible data clause with reduction "
11213 "on %qE; promoting to %<present_or_copy%>",
11214 DECL_NAME (t));
11215 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
11219 if (!DECL_P (decl))
11221 if ((ctx->region_type & ORT_TARGET) != 0
11222 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
11224 if (TREE_CODE (decl) == INDIRECT_REF
11225 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
11226 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
11227 == REFERENCE_TYPE))
11228 decl = TREE_OPERAND (decl, 0);
11229 if (TREE_CODE (decl) == COMPONENT_REF)
11231 while (TREE_CODE (decl) == COMPONENT_REF)
11232 decl = TREE_OPERAND (decl, 0);
11233 if (DECL_P (decl))
11235 n = splay_tree_lookup (ctx->variables,
11236 (splay_tree_key) decl);
11237 if (!(n->value & GOVD_SEEN))
11238 remove = true;
11242 break;
11244 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11245 if ((ctx->region_type & ORT_TARGET) != 0
11246 && !(n->value & GOVD_SEEN)
11247 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
11248 && (!is_global_var (decl)
11249 || !lookup_attribute ("omp declare target link",
11250 DECL_ATTRIBUTES (decl))))
11252 remove = true;
11253 /* For struct element mapping, if struct is never referenced
11254 in target block and none of the mapping has always modifier,
11255 remove all the struct element mappings, which immediately
11256 follow the GOMP_MAP_STRUCT map clause. */
11257 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
11259 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
11260 while (cnt--)
11261 OMP_CLAUSE_CHAIN (c)
11262 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
11265 else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
11266 && (code == OMP_TARGET_EXIT_DATA
11267 || code == OACC_EXIT_DATA))
11268 remove = true;
11269 else if (DECL_SIZE (decl)
11270 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
11271 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
11272 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
11273 && (OMP_CLAUSE_MAP_KIND (c)
11274 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
11276 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
11277 for these, TREE_CODE (DECL_SIZE (decl)) will always be
11278 INTEGER_CST. */
11279 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
11281 tree decl2 = DECL_VALUE_EXPR (decl);
11282 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11283 decl2 = TREE_OPERAND (decl2, 0);
11284 gcc_assert (DECL_P (decl2));
11285 tree mem = build_simple_mem_ref (decl2);
11286 OMP_CLAUSE_DECL (c) = mem;
11287 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11288 if (ctx->outer_context)
11290 omp_notice_variable (ctx->outer_context, decl2, true);
11291 omp_notice_variable (ctx->outer_context,
11292 OMP_CLAUSE_SIZE (c), true);
11294 if (((ctx->region_type & ORT_TARGET) != 0
11295 || !ctx->target_firstprivatize_array_bases)
11296 && ((n->value & GOVD_SEEN) == 0
11297 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
11299 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11300 OMP_CLAUSE_MAP);
11301 OMP_CLAUSE_DECL (nc) = decl;
11302 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11303 if (ctx->target_firstprivatize_array_bases)
11304 OMP_CLAUSE_SET_MAP_KIND (nc,
11305 GOMP_MAP_FIRSTPRIVATE_POINTER);
11306 else
11307 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
11308 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
11309 OMP_CLAUSE_CHAIN (c) = nc;
11310 c = nc;
11313 else
11315 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11316 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11317 gcc_assert ((n->value & GOVD_SEEN) == 0
11318 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11319 == 0));
11321 break;
11323 case OMP_CLAUSE_TO:
11324 case OMP_CLAUSE_FROM:
11325 case OMP_CLAUSE__CACHE_:
11326 decl = OMP_CLAUSE_DECL (c);
11327 if (!DECL_P (decl))
11328 break;
11329 if (DECL_SIZE (decl)
11330 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
11332 tree decl2 = DECL_VALUE_EXPR (decl);
11333 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11334 decl2 = TREE_OPERAND (decl2, 0);
11335 gcc_assert (DECL_P (decl2));
11336 tree mem = build_simple_mem_ref (decl2);
11337 OMP_CLAUSE_DECL (c) = mem;
11338 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11339 if (ctx->outer_context)
11341 omp_notice_variable (ctx->outer_context, decl2, true);
11342 omp_notice_variable (ctx->outer_context,
11343 OMP_CLAUSE_SIZE (c), true);
11346 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11347 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11348 break;
11350 case OMP_CLAUSE_REDUCTION:
11351 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
11353 decl = OMP_CLAUSE_DECL (c);
11354 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11355 if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
11357 remove = true;
11358 error_at (OMP_CLAUSE_LOCATION (c),
11359 "%qD specified in %<inscan%> %<reduction%> clause "
11360 "but not in %<scan%> directive clause", decl);
11361 break;
11363 has_inscan_reductions = true;
11365 /* FALLTHRU */
11366 case OMP_CLAUSE_IN_REDUCTION:
11367 case OMP_CLAUSE_TASK_REDUCTION:
11368 decl = OMP_CLAUSE_DECL (c);
11369 /* OpenACC reductions need a present_or_copy data clause.
11370 Add one if necessary. Emit error when the reduction is private. */
11371 if (ctx->region_type == ORT_ACC_PARALLEL
11372 || ctx->region_type == ORT_ACC_SERIAL)
11374 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11375 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11377 remove = true;
11378 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
11379 "reduction on %qE", DECL_NAME (decl));
11381 else if ((n->value & GOVD_MAP) == 0)
11383 tree next = OMP_CLAUSE_CHAIN (c);
11384 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
11385 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
11386 OMP_CLAUSE_DECL (nc) = decl;
11387 OMP_CLAUSE_CHAIN (c) = nc;
11388 lang_hooks.decls.omp_finish_clause (nc, pre_p,
11389 (ctx->region_type
11390 & ORT_ACC) != 0);
11391 while (1)
11393 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
11394 if (OMP_CLAUSE_CHAIN (nc) == NULL)
11395 break;
11396 nc = OMP_CLAUSE_CHAIN (nc);
11398 OMP_CLAUSE_CHAIN (nc) = next;
11399 n->value |= GOVD_MAP;
11402 if (DECL_P (decl)
11403 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11404 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11405 break;
11407 case OMP_CLAUSE_ALLOCATE:
11408 decl = OMP_CLAUSE_DECL (c);
11409 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11410 if (n != NULL && !(n->value & GOVD_SEEN))
11412 if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR))
11413 != 0
11414 && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0)
11415 remove = true;
11417 if (!remove
11418 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
11419 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST
11420 && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0
11421 || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK
11422 || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS))
11424 tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
11425 n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator);
11426 if (n == NULL)
11428 enum omp_clause_default_kind default_kind
11429 = ctx->default_kind;
11430 ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
11431 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11432 true);
11433 ctx->default_kind = default_kind;
11435 else
11436 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11437 true);
11439 break;
11441 case OMP_CLAUSE_COPYIN:
11442 case OMP_CLAUSE_COPYPRIVATE:
11443 case OMP_CLAUSE_IF:
11444 case OMP_CLAUSE_NUM_THREADS:
11445 case OMP_CLAUSE_NUM_TEAMS:
11446 case OMP_CLAUSE_THREAD_LIMIT:
11447 case OMP_CLAUSE_DIST_SCHEDULE:
11448 case OMP_CLAUSE_DEVICE:
11449 case OMP_CLAUSE_SCHEDULE:
11450 case OMP_CLAUSE_NOWAIT:
11451 case OMP_CLAUSE_ORDERED:
11452 case OMP_CLAUSE_DEFAULT:
11453 case OMP_CLAUSE_UNTIED:
11454 case OMP_CLAUSE_COLLAPSE:
11455 case OMP_CLAUSE_FINAL:
11456 case OMP_CLAUSE_MERGEABLE:
11457 case OMP_CLAUSE_PROC_BIND:
11458 case OMP_CLAUSE_SAFELEN:
11459 case OMP_CLAUSE_SIMDLEN:
11460 case OMP_CLAUSE_DEPEND:
11461 case OMP_CLAUSE_PRIORITY:
11462 case OMP_CLAUSE_GRAINSIZE:
11463 case OMP_CLAUSE_NUM_TASKS:
11464 case OMP_CLAUSE_NOGROUP:
11465 case OMP_CLAUSE_THREADS:
11466 case OMP_CLAUSE_SIMD:
11467 case OMP_CLAUSE_FILTER:
11468 case OMP_CLAUSE_HINT:
11469 case OMP_CLAUSE_DEFAULTMAP:
11470 case OMP_CLAUSE_ORDER:
11471 case OMP_CLAUSE_BIND:
11472 case OMP_CLAUSE_DETACH:
11473 case OMP_CLAUSE_USE_DEVICE_PTR:
11474 case OMP_CLAUSE_USE_DEVICE_ADDR:
11475 case OMP_CLAUSE_IS_DEVICE_PTR:
11476 case OMP_CLAUSE_ASYNC:
11477 case OMP_CLAUSE_WAIT:
11478 case OMP_CLAUSE_INDEPENDENT:
11479 case OMP_CLAUSE_NUM_GANGS:
11480 case OMP_CLAUSE_NUM_WORKERS:
11481 case OMP_CLAUSE_VECTOR_LENGTH:
11482 case OMP_CLAUSE_GANG:
11483 case OMP_CLAUSE_WORKER:
11484 case OMP_CLAUSE_VECTOR:
11485 case OMP_CLAUSE_AUTO:
11486 case OMP_CLAUSE_SEQ:
11487 case OMP_CLAUSE_TILE:
11488 case OMP_CLAUSE_IF_PRESENT:
11489 case OMP_CLAUSE_FINALIZE:
11490 case OMP_CLAUSE_INCLUSIVE:
11491 case OMP_CLAUSE_EXCLUSIVE:
11492 break;
11494 case OMP_CLAUSE_NOHOST:
11495 default:
11496 gcc_unreachable ();
11499 if (remove)
11500 *list_p = OMP_CLAUSE_CHAIN (c);
11501 else
11502 list_p = &OMP_CLAUSE_CHAIN (c);
11505 /* Add in any implicit data sharing. */
11506 struct gimplify_adjust_omp_clauses_data data;
11507 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
11509 /* OpenMP. Implicit clauses are added at the start of the clause list,
11510 but after any non-map clauses. */
11511 tree *implicit_add_list_p = orig_list_p;
11512 while (*implicit_add_list_p
11513 && OMP_CLAUSE_CODE (*implicit_add_list_p) != OMP_CLAUSE_MAP)
11514 implicit_add_list_p = &OMP_CLAUSE_CHAIN (*implicit_add_list_p);
11515 data.list_p = implicit_add_list_p;
11517 else
11518 /* OpenACC. */
11519 data.list_p = list_p;
11520 data.pre_p = pre_p;
11521 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
11523 if (has_inscan_reductions)
11524 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
11525 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11526 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
11528 error_at (OMP_CLAUSE_LOCATION (c),
11529 "%<inscan%> %<reduction%> clause used together with "
11530 "%<linear%> clause for a variable other than loop "
11531 "iterator");
11532 break;
11535 gimplify_omp_ctxp = ctx->outer_context;
11536 delete_omp_context (ctx);
11539 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
11540 -1 if unknown yet (simd is involved, won't be known until vectorization)
11541 and 1 if they do. If SCORES is non-NULL, it should point to an array
11542 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
11543 of the CONSTRUCTS (position -1 if it will never match) followed by
11544 number of constructs in the OpenMP context construct trait. If the
11545 score depends on whether it will be in a declare simd clone or not,
11546 the function returns 2 and there will be two sets of the scores, the first
11547 one for the case that it is not in a declare simd clone, the other
11548 that it is in a declare simd clone. */
11551 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
11552 int *scores)
11554 int matched = 0, cnt = 0;
11555 bool simd_seen = false;
11556 bool target_seen = false;
11557 int declare_simd_cnt = -1;
11558 auto_vec<enum tree_code, 16> codes;
11559 for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
11561 if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
11562 || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
11563 == ORT_TARGET && ctx->code == OMP_TARGET)
11564 || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
11565 || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
11566 || (ctx->region_type == ORT_SIMD
11567 && ctx->code == OMP_SIMD
11568 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
11570 ++cnt;
11571 if (scores)
11572 codes.safe_push (ctx->code);
11573 else if (matched < nconstructs && ctx->code == constructs[matched])
11575 if (ctx->code == OMP_SIMD)
11577 if (matched)
11578 return 0;
11579 simd_seen = true;
11581 ++matched;
11583 if (ctx->code == OMP_TARGET)
11585 if (scores == NULL)
11586 return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
11587 target_seen = true;
11588 break;
11591 else if (ctx->region_type == ORT_WORKSHARE
11592 && ctx->code == OMP_LOOP
11593 && ctx->outer_context
11594 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
11595 && ctx->outer_context->outer_context
11596 && ctx->outer_context->outer_context->code == OMP_LOOP
11597 && ctx->outer_context->outer_context->distribute)
11598 ctx = ctx->outer_context->outer_context;
11599 ctx = ctx->outer_context;
11601 if (!target_seen
11602 && lookup_attribute ("omp declare simd",
11603 DECL_ATTRIBUTES (current_function_decl)))
11605 /* Declare simd is a maybe case, it is supposed to be added only to the
11606 omp-simd-clone.c added clones and not to the base function. */
11607 declare_simd_cnt = cnt++;
11608 if (scores)
11609 codes.safe_push (OMP_SIMD);
11610 else if (cnt == 0
11611 && constructs[0] == OMP_SIMD)
11613 gcc_assert (matched == 0);
11614 simd_seen = true;
11615 if (++matched == nconstructs)
11616 return -1;
11619 if (tree attr = lookup_attribute ("omp declare variant variant",
11620 DECL_ATTRIBUTES (current_function_decl)))
11622 enum tree_code variant_constructs[5];
11623 int variant_nconstructs = 0;
11624 if (!target_seen)
11625 variant_nconstructs
11626 = omp_constructor_traits_to_codes (TREE_VALUE (attr),
11627 variant_constructs);
11628 for (int i = 0; i < variant_nconstructs; i++)
11630 ++cnt;
11631 if (scores)
11632 codes.safe_push (variant_constructs[i]);
11633 else if (matched < nconstructs
11634 && variant_constructs[i] == constructs[matched])
11636 if (variant_constructs[i] == OMP_SIMD)
11638 if (matched)
11639 return 0;
11640 simd_seen = true;
11642 ++matched;
11646 if (!target_seen
11647 && lookup_attribute ("omp declare target block",
11648 DECL_ATTRIBUTES (current_function_decl)))
11650 if (scores)
11651 codes.safe_push (OMP_TARGET);
11652 else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
11653 ++matched;
11655 if (scores)
11657 for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
11659 int j = codes.length () - 1;
11660 for (int i = nconstructs - 1; i >= 0; i--)
11662 while (j >= 0
11663 && (pass != 0 || declare_simd_cnt != j)
11664 && constructs[i] != codes[j])
11665 --j;
11666 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
11667 *scores++ = j - 1;
11668 else
11669 *scores++ = j;
11671 *scores++ = ((pass == 0 && declare_simd_cnt != -1)
11672 ? codes.length () - 1 : codes.length ());
11674 return declare_simd_cnt == -1 ? 1 : 2;
11676 if (matched == nconstructs)
11677 return simd_seen ? -1 : 1;
11678 return 0;
11681 /* Gimplify OACC_CACHE. */
11683 static void
11684 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
11686 tree expr = *expr_p;
11688 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
11689 OACC_CACHE);
11690 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
11691 OACC_CACHE);
11693 /* TODO: Do something sensible with this information. */
11695 *expr_p = NULL_TREE;
11698 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
11699 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
11700 kind. The entry kind will replace the one in CLAUSE, while the exit
11701 kind will be used in a new omp_clause and returned to the caller. */
11703 static tree
11704 gimplify_oacc_declare_1 (tree clause)
11706 HOST_WIDE_INT kind, new_op;
11707 bool ret = false;
11708 tree c = NULL;
11710 kind = OMP_CLAUSE_MAP_KIND (clause);
11712 switch (kind)
11714 case GOMP_MAP_ALLOC:
11715 new_op = GOMP_MAP_RELEASE;
11716 ret = true;
11717 break;
11719 case GOMP_MAP_FROM:
11720 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
11721 new_op = GOMP_MAP_FROM;
11722 ret = true;
11723 break;
11725 case GOMP_MAP_TOFROM:
11726 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
11727 new_op = GOMP_MAP_FROM;
11728 ret = true;
11729 break;
11731 case GOMP_MAP_DEVICE_RESIDENT:
11732 case GOMP_MAP_FORCE_DEVICEPTR:
11733 case GOMP_MAP_FORCE_PRESENT:
11734 case GOMP_MAP_LINK:
11735 case GOMP_MAP_POINTER:
11736 case GOMP_MAP_TO:
11737 break;
11739 default:
11740 gcc_unreachable ();
11741 break;
11744 if (ret)
11746 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
11747 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
11748 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
11751 return c;
11754 /* Gimplify OACC_DECLARE. */
11756 static void
11757 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
11759 tree expr = *expr_p;
11760 gomp_target *stmt;
11761 tree clauses, t, decl;
11763 clauses = OACC_DECLARE_CLAUSES (expr);
11765 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
11766 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
11768 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
11770 decl = OMP_CLAUSE_DECL (t);
11772 if (TREE_CODE (decl) == MEM_REF)
11773 decl = TREE_OPERAND (decl, 0);
11775 if (VAR_P (decl) && !is_oacc_declared (decl))
11777 tree attr = get_identifier ("oacc declare target");
11778 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
11779 DECL_ATTRIBUTES (decl));
11782 if (VAR_P (decl)
11783 && !is_global_var (decl)
11784 && DECL_CONTEXT (decl) == current_function_decl)
11786 tree c = gimplify_oacc_declare_1 (t);
11787 if (c)
11789 if (oacc_declare_returns == NULL)
11790 oacc_declare_returns = new hash_map<tree, tree>;
11792 oacc_declare_returns->put (decl, c);
11796 if (gimplify_omp_ctxp)
11797 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
11800 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
11801 clauses);
11803 gimplify_seq_add_stmt (pre_p, stmt);
11805 *expr_p = NULL_TREE;
11808 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
11809 gimplification of the body, as well as scanning the body for used
11810 variables. We need to do this scan now, because variable-sized
11811 decls will be decomposed during gimplification. */
11813 static void
11814 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
11816 tree expr = *expr_p;
11817 gimple *g;
11818 gimple_seq body = NULL;
11820 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
11821 OMP_PARALLEL_COMBINED (expr)
11822 ? ORT_COMBINED_PARALLEL
11823 : ORT_PARALLEL, OMP_PARALLEL);
11825 push_gimplify_context ();
11827 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
11828 if (gimple_code (g) == GIMPLE_BIND)
11829 pop_gimplify_context (g);
11830 else
11831 pop_gimplify_context (NULL);
11833 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
11834 OMP_PARALLEL);
11836 g = gimple_build_omp_parallel (body,
11837 OMP_PARALLEL_CLAUSES (expr),
11838 NULL_TREE, NULL_TREE);
11839 if (OMP_PARALLEL_COMBINED (expr))
11840 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
11841 gimplify_seq_add_stmt (pre_p, g);
11842 *expr_p = NULL_TREE;
11845 /* Gimplify the contents of an OMP_TASK statement. This involves
11846 gimplification of the body, as well as scanning the body for used
11847 variables. We need to do this scan now, because variable-sized
11848 decls will be decomposed during gimplification. */
11850 static void
11851 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
11853 tree expr = *expr_p;
11854 gimple *g;
11855 gimple_seq body = NULL;
11857 if (OMP_TASK_BODY (expr) == NULL_TREE)
11858 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
11859 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
11860 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
11862 error_at (OMP_CLAUSE_LOCATION (c),
11863 "%<mutexinoutset%> kind in %<depend%> clause on a "
11864 "%<taskwait%> construct");
11865 break;
11868 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
11869 omp_find_clause (OMP_TASK_CLAUSES (expr),
11870 OMP_CLAUSE_UNTIED)
11871 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
11873 if (OMP_TASK_BODY (expr))
11875 push_gimplify_context ();
11877 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
11878 if (gimple_code (g) == GIMPLE_BIND)
11879 pop_gimplify_context (g);
11880 else
11881 pop_gimplify_context (NULL);
11884 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
11885 OMP_TASK);
11887 g = gimple_build_omp_task (body,
11888 OMP_TASK_CLAUSES (expr),
11889 NULL_TREE, NULL_TREE,
11890 NULL_TREE, NULL_TREE, NULL_TREE);
11891 if (OMP_TASK_BODY (expr) == NULL_TREE)
11892 gimple_omp_task_set_taskwait_p (g, true);
11893 gimplify_seq_add_stmt (pre_p, g);
11894 *expr_p = NULL_TREE;
11897 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
11898 force it into a temporary initialized in PRE_P and add firstprivate clause
11899 to ORIG_FOR_STMT. */
11901 static void
11902 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
11903 tree orig_for_stmt)
11905 if (*tp == NULL || is_gimple_constant (*tp))
11906 return;
11908 *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
11909 /* Reference to pointer conversion is considered useless,
11910 but is significant for firstprivate clause. Force it
11911 here. */
11912 if (type
11913 && TREE_CODE (type) == POINTER_TYPE
11914 && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
11916 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
11917 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
11918 gimplify_and_add (m, pre_p);
11919 *tp = v;
11922 tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
11923 OMP_CLAUSE_DECL (c) = *tp;
11924 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
11925 OMP_FOR_CLAUSES (orig_for_stmt) = c;
11928 /* Gimplify the gross structure of an OMP_FOR statement. */
11930 static enum gimplify_status
11931 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
11933 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
11934 enum gimplify_status ret = GS_ALL_DONE;
11935 enum gimplify_status tret;
11936 gomp_for *gfor;
11937 gimple_seq for_body, for_pre_body;
11938 int i;
11939 bitmap has_decl_expr = NULL;
11940 enum omp_region_type ort = ORT_WORKSHARE;
11941 bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
11943 orig_for_stmt = for_stmt = *expr_p;
11945 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
11946 != NULL_TREE);
11947 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
11949 tree *data[4] = { NULL, NULL, NULL, NULL };
11950 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
11951 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
11952 find_combined_omp_for, data, NULL);
11953 if (inner_for_stmt == NULL_TREE)
11955 gcc_assert (seen_error ());
11956 *expr_p = NULL_TREE;
11957 return GS_ERROR;
11959 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
11961 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
11962 &OMP_FOR_PRE_BODY (for_stmt));
11963 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
11965 if (OMP_FOR_PRE_BODY (inner_for_stmt))
11967 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
11968 &OMP_FOR_PRE_BODY (for_stmt));
11969 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
11972 if (data[0])
11974 /* We have some statements or variable declarations in between
11975 the composite construct directives. Move them around the
11976 inner_for_stmt. */
11977 data[0] = expr_p;
11978 for (i = 0; i < 3; i++)
11979 if (data[i])
11981 tree t = *data[i];
11982 if (i < 2 && data[i + 1] == &OMP_BODY (t))
11983 data[i + 1] = data[i];
11984 *data[i] = OMP_BODY (t);
11985 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
11986 NULL_TREE, make_node (BLOCK));
11987 OMP_BODY (t) = body;
11988 append_to_statement_list_force (inner_for_stmt,
11989 &BIND_EXPR_BODY (body));
11990 *data[3] = t;
11991 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
11992 gcc_assert (*data[3] == inner_for_stmt);
11994 return GS_OK;
11997 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
11998 if (!loop_p
11999 && OMP_FOR_ORIG_DECLS (inner_for_stmt)
12000 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12001 i)) == TREE_LIST
12002 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12003 i)))
12005 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
12006 /* Class iterators aren't allowed on OMP_SIMD, so the only
12007 case we need to solve is distribute parallel for. They are
12008 allowed on the loop construct, but that is already handled
12009 in gimplify_omp_loop. */
12010 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
12011 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
12012 && data[1]);
12013 tree orig_decl = TREE_PURPOSE (orig);
12014 tree last = TREE_VALUE (orig);
12015 tree *pc;
12016 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
12017 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
12018 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
12019 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
12020 && OMP_CLAUSE_DECL (*pc) == orig_decl)
12021 break;
12022 if (*pc == NULL_TREE)
12024 tree *spc;
12025 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
12026 *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
12027 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
12028 && OMP_CLAUSE_DECL (*spc) == orig_decl)
12029 break;
12030 if (*spc)
12032 tree c = *spc;
12033 *spc = OMP_CLAUSE_CHAIN (c);
12034 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
12035 *pc = c;
12038 if (*pc == NULL_TREE)
12040 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
12042 /* private clause will appear only on inner_for_stmt.
12043 Change it into firstprivate, and add private clause
12044 on for_stmt. */
12045 tree c = copy_node (*pc);
12046 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12047 OMP_FOR_CLAUSES (for_stmt) = c;
12048 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
12049 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12051 else
12053 /* lastprivate clause will appear on both inner_for_stmt
12054 and for_stmt. Add firstprivate clause to
12055 inner_for_stmt. */
12056 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
12057 OMP_CLAUSE_FIRSTPRIVATE);
12058 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
12059 OMP_CLAUSE_CHAIN (c) = *pc;
12060 *pc = c;
12061 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12063 tree c = build_omp_clause (UNKNOWN_LOCATION,
12064 OMP_CLAUSE_FIRSTPRIVATE);
12065 OMP_CLAUSE_DECL (c) = last;
12066 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12067 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12068 c = build_omp_clause (UNKNOWN_LOCATION,
12069 *pc ? OMP_CLAUSE_SHARED
12070 : OMP_CLAUSE_FIRSTPRIVATE);
12071 OMP_CLAUSE_DECL (c) = orig_decl;
12072 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12073 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12075 /* Similarly, take care of C++ range for temporaries, those should
12076 be firstprivate on OMP_PARALLEL if any. */
12077 if (data[1])
12078 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
12079 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
12080 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12081 i)) == TREE_LIST
12082 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12083 i)))
12085 tree orig
12086 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
12087 tree v = TREE_CHAIN (orig);
12088 tree c = build_omp_clause (UNKNOWN_LOCATION,
12089 OMP_CLAUSE_FIRSTPRIVATE);
12090 /* First add firstprivate clause for the __for_end artificial
12091 decl. */
12092 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
12093 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12094 == REFERENCE_TYPE)
12095 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12096 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12097 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12098 if (TREE_VEC_ELT (v, 0))
12100 /* And now the same for __for_range artificial decl if it
12101 exists. */
12102 c = build_omp_clause (UNKNOWN_LOCATION,
12103 OMP_CLAUSE_FIRSTPRIVATE);
12104 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
12105 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12106 == REFERENCE_TYPE)
12107 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12108 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12109 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12114 switch (TREE_CODE (for_stmt))
12116 case OMP_FOR:
12117 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
12119 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12120 OMP_CLAUSE_SCHEDULE))
12121 error_at (EXPR_LOCATION (for_stmt),
12122 "%qs clause may not appear on non-rectangular %qs",
12123 "schedule", "for");
12124 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
12125 error_at (EXPR_LOCATION (for_stmt),
12126 "%qs clause may not appear on non-rectangular %qs",
12127 "ordered", "for");
12129 break;
12130 case OMP_DISTRIBUTE:
12131 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
12132 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12133 OMP_CLAUSE_DIST_SCHEDULE))
12134 error_at (EXPR_LOCATION (for_stmt),
12135 "%qs clause may not appear on non-rectangular %qs",
12136 "dist_schedule", "distribute");
12137 break;
12138 case OACC_LOOP:
12139 ort = ORT_ACC;
12140 break;
12141 case OMP_TASKLOOP:
12142 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
12143 ort = ORT_UNTIED_TASKLOOP;
12144 else
12145 ort = ORT_TASKLOOP;
12146 break;
12147 case OMP_SIMD:
12148 ort = ORT_SIMD;
12149 break;
12150 default:
12151 gcc_unreachable ();
12154 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
12155 clause for the IV. */
12156 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12158 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
12159 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12160 decl = TREE_OPERAND (t, 0);
12161 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
12162 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12163 && OMP_CLAUSE_DECL (c) == decl)
12165 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12166 break;
12170 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
12171 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
12172 loop_p && TREE_CODE (for_stmt) != OMP_SIMD
12173 ? OMP_LOOP : TREE_CODE (for_stmt));
12175 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
12176 gimplify_omp_ctxp->distribute = true;
12178 /* Handle OMP_FOR_INIT. */
12179 for_pre_body = NULL;
12180 if ((ort == ORT_SIMD
12181 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
12182 && OMP_FOR_PRE_BODY (for_stmt))
12184 has_decl_expr = BITMAP_ALLOC (NULL);
12185 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
12186 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
12187 == VAR_DECL)
12189 t = OMP_FOR_PRE_BODY (for_stmt);
12190 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12192 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
12194 tree_stmt_iterator si;
12195 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
12196 tsi_next (&si))
12198 t = tsi_stmt (si);
12199 if (TREE_CODE (t) == DECL_EXPR
12200 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
12201 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12205 if (OMP_FOR_PRE_BODY (for_stmt))
12207 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
12208 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12209 else
12211 struct gimplify_omp_ctx ctx;
12212 memset (&ctx, 0, sizeof (ctx));
12213 ctx.region_type = ORT_NONE;
12214 gimplify_omp_ctxp = &ctx;
12215 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12216 gimplify_omp_ctxp = NULL;
12219 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
12221 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
12222 for_stmt = inner_for_stmt;
12224 /* For taskloop, need to gimplify the start, end and step before the
12225 taskloop, outside of the taskloop omp context. */
12226 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12228 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12230 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12231 gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
12232 ? pre_p : &for_pre_body);
12233 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
12234 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12236 tree v = TREE_OPERAND (t, 1);
12237 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12238 for_pre_p, orig_for_stmt);
12239 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12240 for_pre_p, orig_for_stmt);
12242 else
12243 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12244 orig_for_stmt);
12246 /* Handle OMP_FOR_COND. */
12247 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12248 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12250 tree v = TREE_OPERAND (t, 1);
12251 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12252 for_pre_p, orig_for_stmt);
12253 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12254 for_pre_p, orig_for_stmt);
12256 else
12257 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12258 orig_for_stmt);
12260 /* Handle OMP_FOR_INCR. */
12261 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12262 if (TREE_CODE (t) == MODIFY_EXPR)
12264 decl = TREE_OPERAND (t, 0);
12265 t = TREE_OPERAND (t, 1);
12266 tree *tp = &TREE_OPERAND (t, 1);
12267 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
12268 tp = &TREE_OPERAND (t, 0);
12270 gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
12271 orig_for_stmt);
12275 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
12276 OMP_TASKLOOP);
12279 if (orig_for_stmt != for_stmt)
12280 gimplify_omp_ctxp->combined_loop = true;
12282 for_body = NULL;
12283 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12284 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
12285 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12286 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
12288 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
12289 bool is_doacross = false;
12290 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
12292 is_doacross = true;
12293 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
12294 (OMP_FOR_INIT (for_stmt))
12295 * 2);
12297 int collapse = 1, tile = 0;
12298 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
12299 if (c)
12300 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
12301 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
12302 if (c)
12303 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
12304 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
12305 hash_set<tree> *allocate_uids = NULL;
12306 if (c)
12308 allocate_uids = new hash_set<tree>;
12309 for (; c; c = OMP_CLAUSE_CHAIN (c))
12310 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
12311 allocate_uids->add (OMP_CLAUSE_DECL (c));
12313 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12315 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12316 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12317 decl = TREE_OPERAND (t, 0);
12318 gcc_assert (DECL_P (decl));
12319 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
12320 || POINTER_TYPE_P (TREE_TYPE (decl)));
12321 if (is_doacross)
12323 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
12325 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12326 if (TREE_CODE (orig_decl) == TREE_LIST)
12328 orig_decl = TREE_PURPOSE (orig_decl);
12329 if (!orig_decl)
12330 orig_decl = decl;
12332 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
12334 else
12335 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12336 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12339 if (for_stmt == orig_for_stmt)
12341 tree orig_decl = decl;
12342 if (OMP_FOR_ORIG_DECLS (for_stmt))
12344 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12345 if (TREE_CODE (orig_decl) == TREE_LIST)
12347 orig_decl = TREE_PURPOSE (orig_decl);
12348 if (!orig_decl)
12349 orig_decl = decl;
12352 if (is_global_var (orig_decl) && DECL_THREAD_LOCAL_P (orig_decl))
12353 error_at (EXPR_LOCATION (for_stmt),
12354 "threadprivate iteration variable %qD", orig_decl);
12357 /* Make sure the iteration variable is private. */
12358 tree c = NULL_TREE;
12359 tree c2 = NULL_TREE;
12360 if (orig_for_stmt != for_stmt)
12362 /* Preserve this information until we gimplify the inner simd. */
12363 if (has_decl_expr
12364 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12365 TREE_PRIVATE (t) = 1;
12367 else if (ort == ORT_SIMD)
12369 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12370 (splay_tree_key) decl);
12371 omp_is_private (gimplify_omp_ctxp, decl,
12372 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12373 != 1));
12374 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
12376 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12377 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
12378 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12379 OMP_CLAUSE_LASTPRIVATE);
12380 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12381 OMP_CLAUSE_LASTPRIVATE))
12382 if (OMP_CLAUSE_DECL (c3) == decl)
12384 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12385 "conditional %<lastprivate%> on loop "
12386 "iterator %qD ignored", decl);
12387 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12388 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12391 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
12393 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12394 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12395 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
12396 if ((has_decl_expr
12397 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12398 || TREE_PRIVATE (t))
12400 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12401 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12403 struct gimplify_omp_ctx *outer
12404 = gimplify_omp_ctxp->outer_context;
12405 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12407 if (outer->region_type == ORT_WORKSHARE
12408 && outer->combined_loop)
12410 n = splay_tree_lookup (outer->variables,
12411 (splay_tree_key)decl);
12412 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12414 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12415 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12417 else
12419 struct gimplify_omp_ctx *octx = outer->outer_context;
12420 if (octx
12421 && octx->region_type == ORT_COMBINED_PARALLEL
12422 && octx->outer_context
12423 && (octx->outer_context->region_type
12424 == ORT_WORKSHARE)
12425 && octx->outer_context->combined_loop)
12427 octx = octx->outer_context;
12428 n = splay_tree_lookup (octx->variables,
12429 (splay_tree_key)decl);
12430 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12432 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12433 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12440 OMP_CLAUSE_DECL (c) = decl;
12441 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12442 OMP_FOR_CLAUSES (for_stmt) = c;
12443 omp_add_variable (gimplify_omp_ctxp, decl, flags);
12444 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12445 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12446 true);
12448 else
12450 bool lastprivate
12451 = (!has_decl_expr
12452 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
12453 if (TREE_PRIVATE (t))
12454 lastprivate = false;
12455 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
12457 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12458 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
12459 lastprivate = false;
12462 struct gimplify_omp_ctx *outer
12463 = gimplify_omp_ctxp->outer_context;
12464 if (outer && lastprivate)
12465 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12466 true);
12468 c = build_omp_clause (input_location,
12469 lastprivate ? OMP_CLAUSE_LASTPRIVATE
12470 : OMP_CLAUSE_PRIVATE);
12471 OMP_CLAUSE_DECL (c) = decl;
12472 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12473 OMP_FOR_CLAUSES (for_stmt) = c;
12474 omp_add_variable (gimplify_omp_ctxp, decl,
12475 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
12476 | GOVD_EXPLICIT | GOVD_SEEN);
12477 c = NULL_TREE;
12480 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
12482 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12483 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12484 (splay_tree_key) decl);
12485 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
12486 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12487 OMP_CLAUSE_LASTPRIVATE);
12488 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12489 OMP_CLAUSE_LASTPRIVATE))
12490 if (OMP_CLAUSE_DECL (c3) == decl)
12492 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12493 "conditional %<lastprivate%> on loop "
12494 "iterator %qD ignored", decl);
12495 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12496 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12499 else
12500 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
12502 /* If DECL is not a gimple register, create a temporary variable to act
12503 as an iteration counter. This is valid, since DECL cannot be
12504 modified in the body of the loop. Similarly for any iteration vars
12505 in simd with collapse > 1 where the iterator vars must be
12506 lastprivate. And similarly for vars mentioned in allocate clauses. */
12507 if (orig_for_stmt != for_stmt)
12508 var = decl;
12509 else if (!is_gimple_reg (decl)
12510 || (ort == ORT_SIMD
12511 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
12512 || (allocate_uids && allocate_uids->contains (decl)))
12514 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12515 /* Make sure omp_add_variable is not called on it prematurely.
12516 We call it ourselves a few lines later. */
12517 gimplify_omp_ctxp = NULL;
12518 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
12519 gimplify_omp_ctxp = ctx;
12520 TREE_OPERAND (t, 0) = var;
12522 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
12524 if (ort == ORT_SIMD
12525 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12527 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12528 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
12529 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
12530 OMP_CLAUSE_DECL (c2) = var;
12531 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
12532 OMP_FOR_CLAUSES (for_stmt) = c2;
12533 omp_add_variable (gimplify_omp_ctxp, var,
12534 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
12535 if (c == NULL_TREE)
12537 c = c2;
12538 c2 = NULL_TREE;
12541 else
12542 omp_add_variable (gimplify_omp_ctxp, var,
12543 GOVD_PRIVATE | GOVD_SEEN);
12545 else
12546 var = decl;
12548 gimplify_omp_ctxp->in_for_exprs = true;
12549 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12551 tree lb = TREE_OPERAND (t, 1);
12552 tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
12553 is_gimple_val, fb_rvalue, false);
12554 ret = MIN (ret, tret);
12555 tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
12556 is_gimple_val, fb_rvalue, false);
12558 else
12559 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12560 is_gimple_val, fb_rvalue, false);
12561 gimplify_omp_ctxp->in_for_exprs = false;
12562 ret = MIN (ret, tret);
12563 if (ret == GS_ERROR)
12564 return ret;
12566 /* Handle OMP_FOR_COND. */
12567 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12568 gcc_assert (COMPARISON_CLASS_P (t));
12569 gcc_assert (TREE_OPERAND (t, 0) == decl);
12571 gimplify_omp_ctxp->in_for_exprs = true;
12572 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12574 tree ub = TREE_OPERAND (t, 1);
12575 tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
12576 is_gimple_val, fb_rvalue, false);
12577 ret = MIN (ret, tret);
12578 tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
12579 is_gimple_val, fb_rvalue, false);
12581 else
12582 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12583 is_gimple_val, fb_rvalue, false);
12584 gimplify_omp_ctxp->in_for_exprs = false;
12585 ret = MIN (ret, tret);
12587 /* Handle OMP_FOR_INCR. */
12588 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12589 switch (TREE_CODE (t))
12591 case PREINCREMENT_EXPR:
12592 case POSTINCREMENT_EXPR:
12594 tree decl = TREE_OPERAND (t, 0);
12595 /* c_omp_for_incr_canonicalize_ptr() should have been
12596 called to massage things appropriately. */
12597 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
12599 if (orig_for_stmt != for_stmt)
12600 break;
12601 t = build_int_cst (TREE_TYPE (decl), 1);
12602 if (c)
12603 OMP_CLAUSE_LINEAR_STEP (c) = t;
12604 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
12605 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
12606 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
12607 break;
12610 case PREDECREMENT_EXPR:
12611 case POSTDECREMENT_EXPR:
12612 /* c_omp_for_incr_canonicalize_ptr() should have been
12613 called to massage things appropriately. */
12614 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
12615 if (orig_for_stmt != for_stmt)
12616 break;
12617 t = build_int_cst (TREE_TYPE (decl), -1);
12618 if (c)
12619 OMP_CLAUSE_LINEAR_STEP (c) = t;
12620 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
12621 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
12622 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
12623 break;
12625 case MODIFY_EXPR:
12626 gcc_assert (TREE_OPERAND (t, 0) == decl);
12627 TREE_OPERAND (t, 0) = var;
12629 t = TREE_OPERAND (t, 1);
12630 switch (TREE_CODE (t))
12632 case PLUS_EXPR:
12633 if (TREE_OPERAND (t, 1) == decl)
12635 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
12636 TREE_OPERAND (t, 0) = var;
12637 break;
12640 /* Fallthru. */
12641 case MINUS_EXPR:
12642 case POINTER_PLUS_EXPR:
12643 gcc_assert (TREE_OPERAND (t, 0) == decl);
12644 TREE_OPERAND (t, 0) = var;
12645 break;
12646 default:
12647 gcc_unreachable ();
12650 gimplify_omp_ctxp->in_for_exprs = true;
12651 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12652 is_gimple_val, fb_rvalue, false);
12653 ret = MIN (ret, tret);
12654 if (c)
12656 tree step = TREE_OPERAND (t, 1);
12657 tree stept = TREE_TYPE (decl);
12658 if (POINTER_TYPE_P (stept))
12659 stept = sizetype;
12660 step = fold_convert (stept, step);
12661 if (TREE_CODE (t) == MINUS_EXPR)
12662 step = fold_build1 (NEGATE_EXPR, stept, step);
12663 OMP_CLAUSE_LINEAR_STEP (c) = step;
12664 if (step != TREE_OPERAND (t, 1))
12666 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
12667 &for_pre_body, NULL,
12668 is_gimple_val, fb_rvalue, false);
12669 ret = MIN (ret, tret);
12672 gimplify_omp_ctxp->in_for_exprs = false;
12673 break;
12675 default:
12676 gcc_unreachable ();
12679 if (c2)
12681 gcc_assert (c);
12682 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
12685 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
12687 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
12688 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12689 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
12690 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12691 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
12692 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
12693 && OMP_CLAUSE_DECL (c) == decl)
12695 if (is_doacross && (collapse == 1 || i >= collapse))
12696 t = var;
12697 else
12699 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12700 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12701 gcc_assert (TREE_OPERAND (t, 0) == var);
12702 t = TREE_OPERAND (t, 1);
12703 gcc_assert (TREE_CODE (t) == PLUS_EXPR
12704 || TREE_CODE (t) == MINUS_EXPR
12705 || TREE_CODE (t) == POINTER_PLUS_EXPR);
12706 gcc_assert (TREE_OPERAND (t, 0) == var);
12707 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
12708 is_doacross ? var : decl,
12709 TREE_OPERAND (t, 1));
12711 gimple_seq *seq;
12712 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
12713 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
12714 else
12715 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
12716 push_gimplify_context ();
12717 gimplify_assign (decl, t, seq);
12718 gimple *bind = NULL;
12719 if (gimplify_ctxp->temps)
12721 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
12722 *seq = NULL;
12723 gimplify_seq_add_stmt (seq, bind);
12725 pop_gimplify_context (bind);
12728 if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
12729 for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
12731 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
12732 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12733 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12734 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12735 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12736 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
12737 gcc_assert (COMPARISON_CLASS_P (t));
12738 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12739 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12740 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12744 BITMAP_FREE (has_decl_expr);
12745 delete allocate_uids;
12747 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
12748 || (loop_p && orig_for_stmt == for_stmt))
12750 push_gimplify_context ();
12751 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
12753 OMP_FOR_BODY (orig_for_stmt)
12754 = build3 (BIND_EXPR, void_type_node, NULL,
12755 OMP_FOR_BODY (orig_for_stmt), NULL);
12756 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
12760 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
12761 &for_body);
12763 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
12764 || (loop_p && orig_for_stmt == for_stmt))
12766 if (gimple_code (g) == GIMPLE_BIND)
12767 pop_gimplify_context (g);
12768 else
12769 pop_gimplify_context (NULL);
12772 if (orig_for_stmt != for_stmt)
12773 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12775 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12776 decl = TREE_OPERAND (t, 0);
12777 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12778 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12779 gimplify_omp_ctxp = ctx->outer_context;
12780 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
12781 gimplify_omp_ctxp = ctx;
12782 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
12783 TREE_OPERAND (t, 0) = var;
12784 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12785 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12786 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
12787 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
12788 for (int j = i + 1;
12789 j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
12791 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
12792 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12793 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12794 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12796 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12797 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12799 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
12800 gcc_assert (COMPARISON_CLASS_P (t));
12801 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12802 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12804 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12805 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12810 gimplify_adjust_omp_clauses (pre_p, for_body,
12811 &OMP_FOR_CLAUSES (orig_for_stmt),
12812 TREE_CODE (orig_for_stmt));
12814 int kind;
12815 switch (TREE_CODE (orig_for_stmt))
12817 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
12818 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
12819 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
12820 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
12821 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
12822 default:
12823 gcc_unreachable ();
12825 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
12827 gimplify_seq_add_seq (pre_p, for_pre_body);
12828 for_pre_body = NULL;
12830 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
12831 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
12832 for_pre_body);
12833 if (orig_for_stmt != for_stmt)
12834 gimple_omp_for_set_combined_p (gfor, true);
12835 if (gimplify_omp_ctxp
12836 && (gimplify_omp_ctxp->combined_loop
12837 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
12838 && gimplify_omp_ctxp->outer_context
12839 && gimplify_omp_ctxp->outer_context->combined_loop)))
12841 gimple_omp_for_set_combined_into_p (gfor, true);
12842 if (gimplify_omp_ctxp->combined_loop)
12843 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
12844 else
12845 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
12848 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12850 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12851 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
12852 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
12853 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12854 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
12855 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
12856 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12857 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
12860 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
12861 constructs with GIMPLE_OMP_TASK sandwiched in between them.
12862 The outer taskloop stands for computing the number of iterations,
12863 counts for collapsed loops and holding taskloop specific clauses.
12864 The task construct stands for the effect of data sharing on the
12865 explicit task it creates and the inner taskloop stands for expansion
12866 of the static loop inside of the explicit task construct. */
12867 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12869 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
12870 tree task_clauses = NULL_TREE;
12871 tree c = *gfor_clauses_ptr;
12872 tree *gtask_clauses_ptr = &task_clauses;
12873 tree outer_for_clauses = NULL_TREE;
12874 tree *gforo_clauses_ptr = &outer_for_clauses;
12875 bitmap lastprivate_uids = NULL;
12876 if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
12878 c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
12879 if (c)
12881 lastprivate_uids = BITMAP_ALLOC (NULL);
12882 for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
12883 OMP_CLAUSE_LASTPRIVATE))
12884 bitmap_set_bit (lastprivate_uids,
12885 DECL_UID (OMP_CLAUSE_DECL (c)));
12887 c = *gfor_clauses_ptr;
12889 for (; c; c = OMP_CLAUSE_CHAIN (c))
12890 switch (OMP_CLAUSE_CODE (c))
12892 /* These clauses are allowed on task, move them there. */
12893 case OMP_CLAUSE_SHARED:
12894 case OMP_CLAUSE_FIRSTPRIVATE:
12895 case OMP_CLAUSE_DEFAULT:
12896 case OMP_CLAUSE_IF:
12897 case OMP_CLAUSE_UNTIED:
12898 case OMP_CLAUSE_FINAL:
12899 case OMP_CLAUSE_MERGEABLE:
12900 case OMP_CLAUSE_PRIORITY:
12901 case OMP_CLAUSE_REDUCTION:
12902 case OMP_CLAUSE_IN_REDUCTION:
12903 *gtask_clauses_ptr = c;
12904 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12905 break;
12906 case OMP_CLAUSE_PRIVATE:
12907 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
12909 /* We want private on outer for and firstprivate
12910 on task. */
12911 *gtask_clauses_ptr
12912 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12913 OMP_CLAUSE_FIRSTPRIVATE);
12914 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12915 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
12916 openacc);
12917 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12918 *gforo_clauses_ptr = c;
12919 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12921 else
12923 *gtask_clauses_ptr = c;
12924 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12926 break;
12927 /* These clauses go into outer taskloop clauses. */
12928 case OMP_CLAUSE_GRAINSIZE:
12929 case OMP_CLAUSE_NUM_TASKS:
12930 case OMP_CLAUSE_NOGROUP:
12931 *gforo_clauses_ptr = c;
12932 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12933 break;
12934 /* Collapse clause we duplicate on both taskloops. */
12935 case OMP_CLAUSE_COLLAPSE:
12936 *gfor_clauses_ptr = c;
12937 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12938 *gforo_clauses_ptr = copy_node (c);
12939 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
12940 break;
12941 /* For lastprivate, keep the clause on inner taskloop, and add
12942 a shared clause on task. If the same decl is also firstprivate,
12943 add also firstprivate clause on the inner taskloop. */
12944 case OMP_CLAUSE_LASTPRIVATE:
12945 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
12947 /* For taskloop C++ lastprivate IVs, we want:
12948 1) private on outer taskloop
12949 2) firstprivate and shared on task
12950 3) lastprivate on inner taskloop */
12951 *gtask_clauses_ptr
12952 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12953 OMP_CLAUSE_FIRSTPRIVATE);
12954 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12955 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
12956 openacc);
12957 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12958 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
12959 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12960 OMP_CLAUSE_PRIVATE);
12961 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
12962 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
12963 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
12964 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
12966 *gfor_clauses_ptr = c;
12967 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12968 *gtask_clauses_ptr
12969 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
12970 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12971 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
12972 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
12973 gtask_clauses_ptr
12974 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12975 break;
12976 /* Allocate clause we duplicate on task and inner taskloop
12977 if the decl is lastprivate, otherwise just put on task. */
12978 case OMP_CLAUSE_ALLOCATE:
12979 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
12980 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
12982 /* Additionally, put firstprivate clause on task
12983 for the allocator if it is not constant. */
12984 *gtask_clauses_ptr
12985 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12986 OMP_CLAUSE_FIRSTPRIVATE);
12987 OMP_CLAUSE_DECL (*gtask_clauses_ptr)
12988 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
12989 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12991 if (lastprivate_uids
12992 && bitmap_bit_p (lastprivate_uids,
12993 DECL_UID (OMP_CLAUSE_DECL (c))))
12995 *gfor_clauses_ptr = c;
12996 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12997 *gtask_clauses_ptr = copy_node (c);
12998 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13000 else
13002 *gtask_clauses_ptr = c;
13003 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13005 break;
13006 default:
13007 gcc_unreachable ();
13009 *gfor_clauses_ptr = NULL_TREE;
13010 *gtask_clauses_ptr = NULL_TREE;
13011 *gforo_clauses_ptr = NULL_TREE;
13012 BITMAP_FREE (lastprivate_uids);
13013 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
13014 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
13015 NULL_TREE, NULL_TREE, NULL_TREE);
13016 gimple_omp_task_set_taskloop_p (g, true);
13017 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
13018 gomp_for *gforo
13019 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
13020 gimple_omp_for_collapse (gfor),
13021 gimple_omp_for_pre_body (gfor));
13022 gimple_omp_for_set_pre_body (gfor, NULL);
13023 gimple_omp_for_set_combined_p (gforo, true);
13024 gimple_omp_for_set_combined_into_p (gfor, true);
13025 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
13027 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
13028 tree v = create_tmp_var (type);
13029 gimple_omp_for_set_index (gforo, i, v);
13030 t = unshare_expr (gimple_omp_for_initial (gfor, i));
13031 gimple_omp_for_set_initial (gforo, i, t);
13032 gimple_omp_for_set_cond (gforo, i,
13033 gimple_omp_for_cond (gfor, i));
13034 t = unshare_expr (gimple_omp_for_final (gfor, i));
13035 gimple_omp_for_set_final (gforo, i, t);
13036 t = unshare_expr (gimple_omp_for_incr (gfor, i));
13037 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
13038 TREE_OPERAND (t, 0) = v;
13039 gimple_omp_for_set_incr (gforo, i, t);
13040 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
13041 OMP_CLAUSE_DECL (t) = v;
13042 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
13043 gimple_omp_for_set_clauses (gforo, t);
13044 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
13046 tree *p1 = NULL, *p2 = NULL;
13047 t = gimple_omp_for_initial (gforo, i);
13048 if (TREE_CODE (t) == TREE_VEC)
13049 p1 = &TREE_VEC_ELT (t, 0);
13050 t = gimple_omp_for_final (gforo, i);
13051 if (TREE_CODE (t) == TREE_VEC)
13053 if (p1)
13054 p2 = &TREE_VEC_ELT (t, 0);
13055 else
13056 p1 = &TREE_VEC_ELT (t, 0);
13058 if (p1)
13060 int j;
13061 for (j = 0; j < i; j++)
13062 if (*p1 == gimple_omp_for_index (gfor, j))
13064 *p1 = gimple_omp_for_index (gforo, j);
13065 if (p2)
13066 *p2 = *p1;
13067 break;
13069 gcc_assert (j < i);
13073 gimplify_seq_add_stmt (pre_p, gforo);
13075 else
13076 gimplify_seq_add_stmt (pre_p, gfor);
13078 if (TREE_CODE (orig_for_stmt) == OMP_FOR)
13080 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13081 unsigned lastprivate_conditional = 0;
13082 while (ctx
13083 && (ctx->region_type == ORT_TARGET_DATA
13084 || ctx->region_type == ORT_TASKGROUP))
13085 ctx = ctx->outer_context;
13086 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
13087 for (tree c = gimple_omp_for_clauses (gfor);
13088 c; c = OMP_CLAUSE_CHAIN (c))
13089 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13090 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13091 ++lastprivate_conditional;
13092 if (lastprivate_conditional)
13094 struct omp_for_data fd;
13095 omp_extract_for_data (gfor, &fd, NULL);
13096 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
13097 lastprivate_conditional);
13098 tree var = create_tmp_var_raw (type);
13099 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
13100 OMP_CLAUSE_DECL (c) = var;
13101 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13102 gimple_omp_for_set_clauses (gfor, c);
13103 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
13106 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
13108 unsigned lastprivate_conditional = 0;
13109 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
13110 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13111 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13112 ++lastprivate_conditional;
13113 if (lastprivate_conditional)
13115 struct omp_for_data fd;
13116 omp_extract_for_data (gfor, &fd, NULL);
13117 tree type = unsigned_type_for (fd.iter_type);
13118 while (lastprivate_conditional--)
13120 tree c = build_omp_clause (UNKNOWN_LOCATION,
13121 OMP_CLAUSE__CONDTEMP_);
13122 OMP_CLAUSE_DECL (c) = create_tmp_var (type);
13123 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13124 gimple_omp_for_set_clauses (gfor, c);
13129 if (ret != GS_ALL_DONE)
13130 return GS_ERROR;
13131 *expr_p = NULL_TREE;
13132 return GS_ALL_DONE;
13135 /* Helper for gimplify_omp_loop, called through walk_tree. */
13137 static tree
13138 note_no_context_vars (tree *tp, int *, void *data)
13140 if (VAR_P (*tp)
13141 && DECL_CONTEXT (*tp) == NULL_TREE
13142 && !is_global_var (*tp))
13144 vec<tree> *d = (vec<tree> *) data;
13145 d->safe_push (*tp);
13146 DECL_CONTEXT (*tp) = current_function_decl;
13148 return NULL_TREE;
13151 /* Gimplify the gross structure of an OMP_LOOP statement. */
13153 static enum gimplify_status
13154 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
13156 tree for_stmt = *expr_p;
13157 tree clauses = OMP_FOR_CLAUSES (for_stmt);
13158 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
13159 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
13160 int i;
13162 /* If order is not present, the behavior is as if order(concurrent)
13163 appeared. */
13164 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
13165 if (order == NULL_TREE)
13167 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
13168 OMP_CLAUSE_CHAIN (order) = clauses;
13169 OMP_FOR_CLAUSES (for_stmt) = clauses = order;
13172 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
13173 if (bind == NULL_TREE)
13175 if (!flag_openmp) /* flag_openmp_simd */
13177 else if (octx && (octx->region_type & ORT_TEAMS) != 0)
13178 kind = OMP_CLAUSE_BIND_TEAMS;
13179 else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
13180 kind = OMP_CLAUSE_BIND_PARALLEL;
13181 else
13183 for (; octx; octx = octx->outer_context)
13185 if ((octx->region_type & ORT_ACC) != 0
13186 || octx->region_type == ORT_NONE
13187 || octx->region_type == ORT_IMPLICIT_TARGET)
13188 continue;
13189 break;
13191 if (octx == NULL && !in_omp_construct)
13192 error_at (EXPR_LOCATION (for_stmt),
13193 "%<bind%> clause not specified on a %<loop%> "
13194 "construct not nested inside another OpenMP construct");
13196 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
13197 OMP_CLAUSE_CHAIN (bind) = clauses;
13198 OMP_CLAUSE_BIND_KIND (bind) = kind;
13199 OMP_FOR_CLAUSES (for_stmt) = bind;
13201 else
13202 switch (OMP_CLAUSE_BIND_KIND (bind))
13204 case OMP_CLAUSE_BIND_THREAD:
13205 break;
13206 case OMP_CLAUSE_BIND_PARALLEL:
13207 if (!flag_openmp) /* flag_openmp_simd */
13209 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13210 break;
13212 for (; octx; octx = octx->outer_context)
13213 if (octx->region_type == ORT_SIMD
13214 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
13216 error_at (EXPR_LOCATION (for_stmt),
13217 "%<bind(parallel)%> on a %<loop%> construct nested "
13218 "inside %<simd%> construct");
13219 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13220 break;
13222 kind = OMP_CLAUSE_BIND_PARALLEL;
13223 break;
13224 case OMP_CLAUSE_BIND_TEAMS:
13225 if (!flag_openmp) /* flag_openmp_simd */
13227 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13228 break;
13230 if ((octx
13231 && octx->region_type != ORT_IMPLICIT_TARGET
13232 && octx->region_type != ORT_NONE
13233 && (octx->region_type & ORT_TEAMS) == 0)
13234 || in_omp_construct)
13236 error_at (EXPR_LOCATION (for_stmt),
13237 "%<bind(teams)%> on a %<loop%> region not strictly "
13238 "nested inside of a %<teams%> region");
13239 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13240 break;
13242 kind = OMP_CLAUSE_BIND_TEAMS;
13243 break;
13244 default:
13245 gcc_unreachable ();
13248 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
13249 switch (OMP_CLAUSE_CODE (*pc))
13251 case OMP_CLAUSE_REDUCTION:
13252 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
13254 error_at (OMP_CLAUSE_LOCATION (*pc),
13255 "%<inscan%> %<reduction%> clause on "
13256 "%qs construct", "loop");
13257 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
13259 if (OMP_CLAUSE_REDUCTION_TASK (*pc))
13261 error_at (OMP_CLAUSE_LOCATION (*pc),
13262 "invalid %<task%> reduction modifier on construct "
13263 "other than %<parallel%>, %qs or %<sections%>",
13264 lang_GNU_Fortran () ? "do" : "for");
13265 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
13267 pc = &OMP_CLAUSE_CHAIN (*pc);
13268 break;
13269 case OMP_CLAUSE_LASTPRIVATE:
13270 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13272 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13273 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13274 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
13275 break;
13276 if (OMP_FOR_ORIG_DECLS (for_stmt)
13277 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13278 i)) == TREE_LIST
13279 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13280 i)))
13282 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13283 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
13284 break;
13287 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
13289 error_at (OMP_CLAUSE_LOCATION (*pc),
13290 "%<lastprivate%> clause on a %<loop%> construct refers "
13291 "to a variable %qD which is not the loop iterator",
13292 OMP_CLAUSE_DECL (*pc));
13293 *pc = OMP_CLAUSE_CHAIN (*pc);
13294 break;
13296 pc = &OMP_CLAUSE_CHAIN (*pc);
13297 break;
13298 default:
13299 pc = &OMP_CLAUSE_CHAIN (*pc);
13300 break;
13303 TREE_SET_CODE (for_stmt, OMP_SIMD);
13305 int last;
13306 switch (kind)
13308 case OMP_CLAUSE_BIND_THREAD: last = 0; break;
13309 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
13310 case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
13312 for (int pass = 1; pass <= last; pass++)
13314 if (pass == 2)
13316 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
13317 make_node (BLOCK));
13318 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
13319 *expr_p = make_node (OMP_PARALLEL);
13320 TREE_TYPE (*expr_p) = void_type_node;
13321 OMP_PARALLEL_BODY (*expr_p) = bind;
13322 OMP_PARALLEL_COMBINED (*expr_p) = 1;
13323 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
13324 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
13325 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13326 if (OMP_FOR_ORIG_DECLS (for_stmt)
13327 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
13328 == TREE_LIST))
13330 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13331 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
13333 *pc = build_omp_clause (UNKNOWN_LOCATION,
13334 OMP_CLAUSE_FIRSTPRIVATE);
13335 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
13336 pc = &OMP_CLAUSE_CHAIN (*pc);
13340 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
13341 tree *pc = &OMP_FOR_CLAUSES (t);
13342 TREE_TYPE (t) = void_type_node;
13343 OMP_FOR_BODY (t) = *expr_p;
13344 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
13345 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
13346 switch (OMP_CLAUSE_CODE (c))
13348 case OMP_CLAUSE_BIND:
13349 case OMP_CLAUSE_ORDER:
13350 case OMP_CLAUSE_COLLAPSE:
13351 *pc = copy_node (c);
13352 pc = &OMP_CLAUSE_CHAIN (*pc);
13353 break;
13354 case OMP_CLAUSE_PRIVATE:
13355 case OMP_CLAUSE_FIRSTPRIVATE:
13356 /* Only needed on innermost. */
13357 break;
13358 case OMP_CLAUSE_LASTPRIVATE:
13359 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
13361 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13362 OMP_CLAUSE_FIRSTPRIVATE);
13363 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
13364 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13365 pc = &OMP_CLAUSE_CHAIN (*pc);
13367 *pc = copy_node (c);
13368 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
13369 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13370 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
13372 if (pass != last)
13373 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
13374 else
13375 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13376 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
13378 pc = &OMP_CLAUSE_CHAIN (*pc);
13379 break;
13380 case OMP_CLAUSE_REDUCTION:
13381 *pc = copy_node (c);
13382 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
13383 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13384 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
13386 auto_vec<tree> no_context_vars;
13387 int walk_subtrees = 0;
13388 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13389 &walk_subtrees, &no_context_vars);
13390 if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c))
13391 note_no_context_vars (&p, &walk_subtrees, &no_context_vars);
13392 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c),
13393 note_no_context_vars,
13394 &no_context_vars);
13395 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c),
13396 note_no_context_vars,
13397 &no_context_vars);
13399 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
13400 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
13401 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13402 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
13403 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
13405 hash_map<tree, tree> decl_map;
13406 decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c));
13407 decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13408 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc));
13409 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13410 decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
13411 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc));
13413 copy_body_data id;
13414 memset (&id, 0, sizeof (id));
13415 id.src_fn = current_function_decl;
13416 id.dst_fn = current_function_decl;
13417 id.src_cfun = cfun;
13418 id.decl_map = &decl_map;
13419 id.copy_decl = copy_decl_no_change;
13420 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
13421 id.transform_new_cfg = true;
13422 id.transform_return_to_modify = false;
13423 id.eh_lp_nr = 0;
13424 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r,
13425 &id, NULL);
13426 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r,
13427 &id, NULL);
13429 for (tree d : no_context_vars)
13431 DECL_CONTEXT (d) = NULL_TREE;
13432 DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE;
13435 else
13437 OMP_CLAUSE_REDUCTION_INIT (*pc)
13438 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
13439 OMP_CLAUSE_REDUCTION_MERGE (*pc)
13440 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
13442 pc = &OMP_CLAUSE_CHAIN (*pc);
13443 break;
13444 default:
13445 gcc_unreachable ();
13447 *pc = NULL_TREE;
13448 *expr_p = t;
13450 return gimplify_omp_for (expr_p, pre_p);
13454 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
13455 of OMP_TARGET's body. */
13457 static tree
13458 find_omp_teams (tree *tp, int *walk_subtrees, void *)
13460 *walk_subtrees = 0;
13461 switch (TREE_CODE (*tp))
13463 case OMP_TEAMS:
13464 return *tp;
13465 case BIND_EXPR:
13466 case STATEMENT_LIST:
13467 *walk_subtrees = 1;
13468 break;
13469 default:
13470 break;
13472 return NULL_TREE;
13475 /* Helper function of optimize_target_teams, determine if the expression
13476 can be computed safely before the target construct on the host. */
13478 static tree
13479 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
13481 splay_tree_node n;
13483 if (TYPE_P (*tp))
13485 *walk_subtrees = 0;
13486 return NULL_TREE;
13488 switch (TREE_CODE (*tp))
13490 case VAR_DECL:
13491 case PARM_DECL:
13492 case RESULT_DECL:
13493 *walk_subtrees = 0;
13494 if (error_operand_p (*tp)
13495 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
13496 || DECL_HAS_VALUE_EXPR_P (*tp)
13497 || DECL_THREAD_LOCAL_P (*tp)
13498 || TREE_SIDE_EFFECTS (*tp)
13499 || TREE_THIS_VOLATILE (*tp))
13500 return *tp;
13501 if (is_global_var (*tp)
13502 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
13503 || lookup_attribute ("omp declare target link",
13504 DECL_ATTRIBUTES (*tp))))
13505 return *tp;
13506 if (VAR_P (*tp)
13507 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
13508 && !is_global_var (*tp)
13509 && decl_function_context (*tp) == current_function_decl)
13510 return *tp;
13511 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
13512 (splay_tree_key) *tp);
13513 if (n == NULL)
13515 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
13516 return NULL_TREE;
13517 return *tp;
13519 else if (n->value & GOVD_LOCAL)
13520 return *tp;
13521 else if (n->value & GOVD_FIRSTPRIVATE)
13522 return NULL_TREE;
13523 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13524 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13525 return NULL_TREE;
13526 return *tp;
13527 case INTEGER_CST:
13528 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13529 return *tp;
13530 return NULL_TREE;
13531 case TARGET_EXPR:
13532 if (TARGET_EXPR_INITIAL (*tp)
13533 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
13534 return *tp;
13535 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
13536 walk_subtrees, NULL);
13537 /* Allow some reasonable subset of integral arithmetics. */
13538 case PLUS_EXPR:
13539 case MINUS_EXPR:
13540 case MULT_EXPR:
13541 case TRUNC_DIV_EXPR:
13542 case CEIL_DIV_EXPR:
13543 case FLOOR_DIV_EXPR:
13544 case ROUND_DIV_EXPR:
13545 case TRUNC_MOD_EXPR:
13546 case CEIL_MOD_EXPR:
13547 case FLOOR_MOD_EXPR:
13548 case ROUND_MOD_EXPR:
13549 case RDIV_EXPR:
13550 case EXACT_DIV_EXPR:
13551 case MIN_EXPR:
13552 case MAX_EXPR:
13553 case LSHIFT_EXPR:
13554 case RSHIFT_EXPR:
13555 case BIT_IOR_EXPR:
13556 case BIT_XOR_EXPR:
13557 case BIT_AND_EXPR:
13558 case NEGATE_EXPR:
13559 case ABS_EXPR:
13560 case BIT_NOT_EXPR:
13561 case NON_LVALUE_EXPR:
13562 CASE_CONVERT:
13563 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13564 return *tp;
13565 return NULL_TREE;
13566 /* And disallow anything else, except for comparisons. */
13567 default:
13568 if (COMPARISON_CLASS_P (*tp))
13569 return NULL_TREE;
13570 return *tp;
13574 /* Try to determine if the num_teams and/or thread_limit expressions
13575 can have their values determined already before entering the
13576 target construct.
13577 INTEGER_CSTs trivially are,
13578 integral decls that are firstprivate (explicitly or implicitly)
13579 or explicitly map(always, to:) or map(always, tofrom:) on the target
13580 region too, and expressions involving simple arithmetics on those
13581 too, function calls are not ok, dereferencing something neither etc.
13582 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
13583 EXPR based on what we find:
13584 0 stands for clause not specified at all, use implementation default
13585 -1 stands for value that can't be determined easily before entering
13586 the target construct.
13587 If teams construct is not present at all, use 1 for num_teams
13588 and 0 for thread_limit (only one team is involved, and the thread
13589 limit is implementation defined. */
13591 static void
13592 optimize_target_teams (tree target, gimple_seq *pre_p)
13594 tree body = OMP_BODY (target);
13595 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
13596 tree num_teams_lower = NULL_TREE;
13597 tree num_teams_upper = integer_zero_node;
13598 tree thread_limit = integer_zero_node;
13599 location_t num_teams_loc = EXPR_LOCATION (target);
13600 location_t thread_limit_loc = EXPR_LOCATION (target);
13601 tree c, *p, expr;
13602 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
13604 if (teams == NULL_TREE)
13605 num_teams_upper = integer_one_node;
13606 else
13607 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
13609 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
13611 p = &num_teams_upper;
13612 num_teams_loc = OMP_CLAUSE_LOCATION (c);
13613 if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))
13615 expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
13616 if (TREE_CODE (expr) == INTEGER_CST)
13617 num_teams_lower = expr;
13618 else if (walk_tree (&expr, computable_teams_clause,
13619 NULL, NULL))
13620 num_teams_lower = integer_minus_one_node;
13621 else
13623 num_teams_lower = expr;
13624 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
13625 if (gimplify_expr (&num_teams_lower, pre_p, NULL,
13626 is_gimple_val, fb_rvalue, false)
13627 == GS_ERROR)
13629 gimplify_omp_ctxp = target_ctx;
13630 num_teams_lower = integer_minus_one_node;
13632 else
13634 gimplify_omp_ctxp = target_ctx;
13635 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
13636 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
13637 = num_teams_lower;
13642 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
13644 p = &thread_limit;
13645 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
13647 else
13648 continue;
13649 expr = OMP_CLAUSE_OPERAND (c, 0);
13650 if (TREE_CODE (expr) == INTEGER_CST)
13652 *p = expr;
13653 continue;
13655 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
13657 *p = integer_minus_one_node;
13658 continue;
13660 *p = expr;
13661 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
13662 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
13663 == GS_ERROR)
13665 gimplify_omp_ctxp = target_ctx;
13666 *p = integer_minus_one_node;
13667 continue;
13669 gimplify_omp_ctxp = target_ctx;
13670 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
13671 OMP_CLAUSE_OPERAND (c, 0) = *p;
13673 if (!omp_find_clause (OMP_TARGET_CLAUSES (target), OMP_CLAUSE_THREAD_LIMIT))
13675 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
13676 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
13677 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
13678 OMP_TARGET_CLAUSES (target) = c;
13680 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
13681 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper;
13682 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower;
13683 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
13684 OMP_TARGET_CLAUSES (target) = c;
13687 /* Gimplify the gross structure of several OMP constructs. */
13689 static void
13690 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
13692 tree expr = *expr_p;
13693 gimple *stmt;
13694 gimple_seq body = NULL;
13695 enum omp_region_type ort;
13697 switch (TREE_CODE (expr))
13699 case OMP_SECTIONS:
13700 case OMP_SINGLE:
13701 ort = ORT_WORKSHARE;
13702 break;
13703 case OMP_SCOPE:
13704 ort = ORT_TASKGROUP;
13705 break;
13706 case OMP_TARGET:
13707 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
13708 break;
13709 case OACC_KERNELS:
13710 ort = ORT_ACC_KERNELS;
13711 break;
13712 case OACC_PARALLEL:
13713 ort = ORT_ACC_PARALLEL;
13714 break;
13715 case OACC_SERIAL:
13716 ort = ORT_ACC_SERIAL;
13717 break;
13718 case OACC_DATA:
13719 ort = ORT_ACC_DATA;
13720 break;
13721 case OMP_TARGET_DATA:
13722 ort = ORT_TARGET_DATA;
13723 break;
13724 case OMP_TEAMS:
13725 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
13726 if (gimplify_omp_ctxp == NULL
13727 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
13728 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
13729 break;
13730 case OACC_HOST_DATA:
13731 ort = ORT_ACC_HOST_DATA;
13732 break;
13733 default:
13734 gcc_unreachable ();
13737 bool save_in_omp_construct = in_omp_construct;
13738 if ((ort & ORT_ACC) == 0)
13739 in_omp_construct = false;
13740 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
13741 TREE_CODE (expr));
13742 if (TREE_CODE (expr) == OMP_TARGET)
13743 optimize_target_teams (expr, pre_p);
13744 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
13745 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
13747 push_gimplify_context ();
13748 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
13749 if (gimple_code (g) == GIMPLE_BIND)
13750 pop_gimplify_context (g);
13751 else
13752 pop_gimplify_context (NULL);
13753 if ((ort & ORT_TARGET_DATA) != 0)
13755 enum built_in_function end_ix;
13756 switch (TREE_CODE (expr))
13758 case OACC_DATA:
13759 case OACC_HOST_DATA:
13760 end_ix = BUILT_IN_GOACC_DATA_END;
13761 break;
13762 case OMP_TARGET_DATA:
13763 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
13764 break;
13765 default:
13766 gcc_unreachable ();
13768 tree fn = builtin_decl_explicit (end_ix);
13769 g = gimple_build_call (fn, 0);
13770 gimple_seq cleanup = NULL;
13771 gimple_seq_add_stmt (&cleanup, g);
13772 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
13773 body = NULL;
13774 gimple_seq_add_stmt (&body, g);
13777 else
13778 gimplify_and_add (OMP_BODY (expr), &body);
13779 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
13780 TREE_CODE (expr));
13781 in_omp_construct = save_in_omp_construct;
13783 switch (TREE_CODE (expr))
13785 case OACC_DATA:
13786 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
13787 OMP_CLAUSES (expr));
13788 break;
13789 case OACC_HOST_DATA:
13790 if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
13792 for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13793 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
13794 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
13797 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
13798 OMP_CLAUSES (expr));
13799 break;
13800 case OACC_KERNELS:
13801 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
13802 OMP_CLAUSES (expr));
13803 break;
13804 case OACC_PARALLEL:
13805 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
13806 OMP_CLAUSES (expr));
13807 break;
13808 case OACC_SERIAL:
13809 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
13810 OMP_CLAUSES (expr));
13811 break;
13812 case OMP_SECTIONS:
13813 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
13814 break;
13815 case OMP_SINGLE:
13816 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
13817 break;
13818 case OMP_SCOPE:
13819 stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr));
13820 break;
13821 case OMP_TARGET:
13822 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
13823 OMP_CLAUSES (expr));
13824 break;
13825 case OMP_TARGET_DATA:
13826 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
13827 to be evaluated before the use_device_{ptr,addr} clauses if they
13828 refer to the same variables. */
13830 tree use_device_clauses;
13831 tree *pc, *uc = &use_device_clauses;
13832 for (pc = &OMP_CLAUSES (expr); *pc; )
13833 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
13834 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
13836 *uc = *pc;
13837 *pc = OMP_CLAUSE_CHAIN (*pc);
13838 uc = &OMP_CLAUSE_CHAIN (*uc);
13840 else
13841 pc = &OMP_CLAUSE_CHAIN (*pc);
13842 *uc = NULL_TREE;
13843 *pc = use_device_clauses;
13844 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
13845 OMP_CLAUSES (expr));
13847 break;
13848 case OMP_TEAMS:
13849 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
13850 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
13851 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
13852 break;
13853 default:
13854 gcc_unreachable ();
13857 gimplify_seq_add_stmt (pre_p, stmt);
13858 *expr_p = NULL_TREE;
13861 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
13862 target update constructs. */
13864 static void
13865 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
13867 tree expr = *expr_p;
13868 int kind;
13869 gomp_target *stmt;
13870 enum omp_region_type ort = ORT_WORKSHARE;
13872 switch (TREE_CODE (expr))
13874 case OACC_ENTER_DATA:
13875 kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA;
13876 ort = ORT_ACC;
13877 break;
13878 case OACC_EXIT_DATA:
13879 kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA;
13880 ort = ORT_ACC;
13881 break;
13882 case OACC_UPDATE:
13883 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
13884 ort = ORT_ACC;
13885 break;
13886 case OMP_TARGET_UPDATE:
13887 kind = GF_OMP_TARGET_KIND_UPDATE;
13888 break;
13889 case OMP_TARGET_ENTER_DATA:
13890 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
13891 break;
13892 case OMP_TARGET_EXIT_DATA:
13893 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
13894 break;
13895 default:
13896 gcc_unreachable ();
13898 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
13899 ort, TREE_CODE (expr));
13900 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
13901 TREE_CODE (expr));
13902 if (TREE_CODE (expr) == OACC_UPDATE
13903 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
13904 OMP_CLAUSE_IF_PRESENT))
13906 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
13907 clause. */
13908 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13909 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
13910 switch (OMP_CLAUSE_MAP_KIND (c))
13912 case GOMP_MAP_FORCE_TO:
13913 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
13914 break;
13915 case GOMP_MAP_FORCE_FROM:
13916 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
13917 break;
13918 default:
13919 break;
13922 else if (TREE_CODE (expr) == OACC_EXIT_DATA
13923 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
13924 OMP_CLAUSE_FINALIZE))
13926 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
13927 semantics. */
13928 bool have_clause = false;
13929 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13930 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
13931 switch (OMP_CLAUSE_MAP_KIND (c))
13933 case GOMP_MAP_FROM:
13934 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
13935 have_clause = true;
13936 break;
13937 case GOMP_MAP_RELEASE:
13938 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
13939 have_clause = true;
13940 break;
13941 case GOMP_MAP_TO_PSET:
13942 /* Fortran arrays with descriptors must map that descriptor when
13943 doing standalone "attach" operations (in OpenACC). In that
13944 case GOMP_MAP_TO_PSET appears by itself with no preceding
13945 clause (see trans-openmp.c:gfc_trans_omp_clauses). */
13946 break;
13947 case GOMP_MAP_POINTER:
13948 /* TODO PR92929: we may see these here, but they'll always follow
13949 one of the clauses above, and will be handled by libgomp as
13950 one group, so no handling required here. */
13951 gcc_assert (have_clause);
13952 break;
13953 case GOMP_MAP_DETACH:
13954 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
13955 have_clause = false;
13956 break;
13957 case GOMP_MAP_STRUCT:
13958 have_clause = false;
13959 break;
13960 default:
13961 gcc_unreachable ();
13964 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
13966 gimplify_seq_add_stmt (pre_p, stmt);
13967 *expr_p = NULL_TREE;
13970 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
13971 stabilized the lhs of the atomic operation as *ADDR. Return true if
13972 EXPR is this stabilized form. */
13974 static bool
13975 goa_lhs_expr_p (tree expr, tree addr)
13977 /* Also include casts to other type variants. The C front end is fond
13978 of adding these for e.g. volatile variables. This is like
13979 STRIP_TYPE_NOPS but includes the main variant lookup. */
13980 STRIP_USELESS_TYPE_CONVERSION (expr);
13982 if (TREE_CODE (expr) == INDIRECT_REF)
13984 expr = TREE_OPERAND (expr, 0);
13985 while (expr != addr
13986 && (CONVERT_EXPR_P (expr)
13987 || TREE_CODE (expr) == NON_LVALUE_EXPR)
13988 && TREE_CODE (expr) == TREE_CODE (addr)
13989 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
13991 expr = TREE_OPERAND (expr, 0);
13992 addr = TREE_OPERAND (addr, 0);
13994 if (expr == addr)
13995 return true;
13996 return (TREE_CODE (addr) == ADDR_EXPR
13997 && TREE_CODE (expr) == ADDR_EXPR
13998 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
14000 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
14001 return true;
14002 return false;
14005 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
14006 expression does not involve the lhs, evaluate it into a temporary.
14007 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
14008 or -1 if an error was encountered. */
14010 static int
14011 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
14012 tree lhs_var, tree &target_expr, bool rhs, int depth)
14014 tree expr = *expr_p;
14015 int saw_lhs = 0;
14017 if (goa_lhs_expr_p (expr, lhs_addr))
14019 if (pre_p)
14020 *expr_p = lhs_var;
14021 return 1;
14023 if (is_gimple_val (expr))
14024 return 0;
14026 /* Maximum depth of lhs in expression is for the
14027 __builtin_clear_padding (...), __builtin_clear_padding (...),
14028 __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs; */
14029 if (++depth > 7)
14030 goto finish;
14032 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
14034 case tcc_binary:
14035 case tcc_comparison:
14036 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
14037 lhs_var, target_expr, true, depth);
14038 /* FALLTHRU */
14039 case tcc_unary:
14040 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
14041 lhs_var, target_expr, true, depth);
14042 break;
14043 case tcc_expression:
14044 switch (TREE_CODE (expr))
14046 case TRUTH_ANDIF_EXPR:
14047 case TRUTH_ORIF_EXPR:
14048 case TRUTH_AND_EXPR:
14049 case TRUTH_OR_EXPR:
14050 case TRUTH_XOR_EXPR:
14051 case BIT_INSERT_EXPR:
14052 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14053 lhs_addr, lhs_var, target_expr, true,
14054 depth);
14055 /* FALLTHRU */
14056 case TRUTH_NOT_EXPR:
14057 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14058 lhs_addr, lhs_var, target_expr, true,
14059 depth);
14060 break;
14061 case MODIFY_EXPR:
14062 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14063 target_expr, true, depth))
14064 break;
14065 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14066 lhs_addr, lhs_var, target_expr, true,
14067 depth);
14068 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14069 lhs_addr, lhs_var, target_expr, false,
14070 depth);
14071 break;
14072 /* FALLTHRU */
14073 case ADDR_EXPR:
14074 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14075 target_expr, true, depth))
14076 break;
14077 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14078 lhs_addr, lhs_var, target_expr, false,
14079 depth);
14080 break;
14081 case COMPOUND_EXPR:
14082 /* Break out any preevaluations from cp_build_modify_expr. */
14083 for (; TREE_CODE (expr) == COMPOUND_EXPR;
14084 expr = TREE_OPERAND (expr, 1))
14086 /* Special-case __builtin_clear_padding call before
14087 __builtin_memcmp. */
14088 if (TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR)
14090 tree fndecl = get_callee_fndecl (TREE_OPERAND (expr, 0));
14091 if (fndecl
14092 && fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14093 && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
14094 && (!pre_p
14095 || goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL,
14096 lhs_addr, lhs_var,
14097 target_expr, true, depth)))
14099 if (pre_p)
14100 *expr_p = expr;
14101 saw_lhs = goa_stabilize_expr (&TREE_OPERAND (expr, 0),
14102 pre_p, lhs_addr, lhs_var,
14103 target_expr, true, depth);
14104 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1),
14105 pre_p, lhs_addr, lhs_var,
14106 target_expr, rhs, depth);
14107 return saw_lhs;
14111 if (pre_p)
14112 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
14114 if (!pre_p)
14115 return goa_stabilize_expr (&expr, pre_p, lhs_addr, lhs_var,
14116 target_expr, rhs, depth);
14117 *expr_p = expr;
14118 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var,
14119 target_expr, rhs, depth);
14120 case COND_EXPR:
14121 if (!goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, lhs_addr,
14122 lhs_var, target_expr, true, depth))
14123 break;
14124 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14125 lhs_addr, lhs_var, target_expr, true,
14126 depth);
14127 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14128 lhs_addr, lhs_var, target_expr, true,
14129 depth);
14130 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 2), pre_p,
14131 lhs_addr, lhs_var, target_expr, true,
14132 depth);
14133 break;
14134 case TARGET_EXPR:
14135 if (TARGET_EXPR_INITIAL (expr))
14137 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr,
14138 lhs_var, target_expr, true,
14139 depth))
14140 break;
14141 if (expr == target_expr)
14142 saw_lhs = 1;
14143 else
14145 saw_lhs = goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr),
14146 pre_p, lhs_addr, lhs_var,
14147 target_expr, true, depth);
14148 if (saw_lhs && target_expr == NULL_TREE && pre_p)
14149 target_expr = expr;
14152 break;
14153 default:
14154 break;
14156 break;
14157 case tcc_reference:
14158 if (TREE_CODE (expr) == BIT_FIELD_REF
14159 || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
14160 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14161 lhs_addr, lhs_var, target_expr, true,
14162 depth);
14163 break;
14164 case tcc_vl_exp:
14165 if (TREE_CODE (expr) == CALL_EXPR)
14167 if (tree fndecl = get_callee_fndecl (expr))
14168 if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14169 || fndecl_built_in_p (fndecl, BUILT_IN_MEMCMP))
14171 int nargs = call_expr_nargs (expr);
14172 for (int i = 0; i < nargs; i++)
14173 saw_lhs |= goa_stabilize_expr (&CALL_EXPR_ARG (expr, i),
14174 pre_p, lhs_addr, lhs_var,
14175 target_expr, true, depth);
14178 break;
14179 default:
14180 break;
14183 finish:
14184 if (saw_lhs == 0 && pre_p)
14186 enum gimplify_status gs;
14187 if (TREE_CODE (expr) == CALL_EXPR && VOID_TYPE_P (TREE_TYPE (expr)))
14189 gimplify_stmt (&expr, pre_p);
14190 return saw_lhs;
14192 else if (rhs)
14193 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
14194 else
14195 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_lvalue, fb_lvalue);
14196 if (gs != GS_ALL_DONE)
14197 saw_lhs = -1;
14200 return saw_lhs;
14203 /* Gimplify an OMP_ATOMIC statement. */
14205 static enum gimplify_status
14206 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
14208 tree addr = TREE_OPERAND (*expr_p, 0);
14209 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
14210 ? NULL : TREE_OPERAND (*expr_p, 1);
14211 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
14212 tree tmp_load;
14213 gomp_atomic_load *loadstmt;
14214 gomp_atomic_store *storestmt;
14215 tree target_expr = NULL_TREE;
14217 tmp_load = create_tmp_reg (type);
14218 if (rhs
14219 && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load, target_expr,
14220 true, 0) < 0)
14221 return GS_ERROR;
14223 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
14224 != GS_ALL_DONE)
14225 return GS_ERROR;
14227 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
14228 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14229 gimplify_seq_add_stmt (pre_p, loadstmt);
14230 if (rhs)
14232 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
14233 representatives. Use BIT_FIELD_REF on the lhs instead. */
14234 tree rhsarg = rhs;
14235 if (TREE_CODE (rhs) == COND_EXPR)
14236 rhsarg = TREE_OPERAND (rhs, 1);
14237 if (TREE_CODE (rhsarg) == BIT_INSERT_EXPR
14238 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
14240 tree bitpos = TREE_OPERAND (rhsarg, 2);
14241 tree op1 = TREE_OPERAND (rhsarg, 1);
14242 tree bitsize;
14243 tree tmp_store = tmp_load;
14244 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
14245 tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
14246 if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
14247 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
14248 else
14249 bitsize = TYPE_SIZE (TREE_TYPE (op1));
14250 gcc_assert (TREE_OPERAND (rhsarg, 0) == tmp_load);
14251 tree t = build2_loc (EXPR_LOCATION (rhsarg),
14252 MODIFY_EXPR, void_type_node,
14253 build3_loc (EXPR_LOCATION (rhsarg),
14254 BIT_FIELD_REF, TREE_TYPE (op1),
14255 tmp_store, bitsize, bitpos), op1);
14256 if (TREE_CODE (rhs) == COND_EXPR)
14257 t = build3_loc (EXPR_LOCATION (rhs), COND_EXPR, void_type_node,
14258 TREE_OPERAND (rhs, 0), t, void_node);
14259 gimplify_and_add (t, pre_p);
14260 rhs = tmp_store;
14262 bool save_allow_rhs_cond_expr = gimplify_ctxp->allow_rhs_cond_expr;
14263 if (TREE_CODE (rhs) == COND_EXPR)
14264 gimplify_ctxp->allow_rhs_cond_expr = true;
14265 enum gimplify_status gs = gimplify_expr (&rhs, pre_p, NULL,
14266 is_gimple_val, fb_rvalue);
14267 gimplify_ctxp->allow_rhs_cond_expr = save_allow_rhs_cond_expr;
14268 if (gs != GS_ALL_DONE)
14269 return GS_ERROR;
14272 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
14273 rhs = tmp_load;
14274 storestmt
14275 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14276 if (TREE_CODE (*expr_p) != OMP_ATOMIC_READ && OMP_ATOMIC_WEAK (*expr_p))
14278 gimple_omp_atomic_set_weak (loadstmt);
14279 gimple_omp_atomic_set_weak (storestmt);
14281 gimplify_seq_add_stmt (pre_p, storestmt);
14282 switch (TREE_CODE (*expr_p))
14284 case OMP_ATOMIC_READ:
14285 case OMP_ATOMIC_CAPTURE_OLD:
14286 *expr_p = tmp_load;
14287 gimple_omp_atomic_set_need_value (loadstmt);
14288 break;
14289 case OMP_ATOMIC_CAPTURE_NEW:
14290 *expr_p = rhs;
14291 gimple_omp_atomic_set_need_value (storestmt);
14292 break;
14293 default:
14294 *expr_p = NULL;
14295 break;
14298 return GS_ALL_DONE;
14301 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
14302 body, and adding some EH bits. */
14304 static enum gimplify_status
14305 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
14307 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
14308 gimple *body_stmt;
14309 gtransaction *trans_stmt;
14310 gimple_seq body = NULL;
14311 int subcode = 0;
14313 /* Wrap the transaction body in a BIND_EXPR so we have a context
14314 where to put decls for OMP. */
14315 if (TREE_CODE (tbody) != BIND_EXPR)
14317 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
14318 TREE_SIDE_EFFECTS (bind) = 1;
14319 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
14320 TRANSACTION_EXPR_BODY (expr) = bind;
14323 push_gimplify_context ();
14324 temp = voidify_wrapper_expr (*expr_p, NULL);
14326 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
14327 pop_gimplify_context (body_stmt);
14329 trans_stmt = gimple_build_transaction (body);
14330 if (TRANSACTION_EXPR_OUTER (expr))
14331 subcode = GTMA_IS_OUTER;
14332 else if (TRANSACTION_EXPR_RELAXED (expr))
14333 subcode = GTMA_IS_RELAXED;
14334 gimple_transaction_set_subcode (trans_stmt, subcode);
14336 gimplify_seq_add_stmt (pre_p, trans_stmt);
14338 if (temp)
14340 *expr_p = temp;
14341 return GS_OK;
14344 *expr_p = NULL_TREE;
14345 return GS_ALL_DONE;
14348 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
14349 is the OMP_BODY of the original EXPR (which has already been
14350 gimplified so it's not present in the EXPR).
14352 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
14354 static gimple *
14355 gimplify_omp_ordered (tree expr, gimple_seq body)
14357 tree c, decls;
14358 int failures = 0;
14359 unsigned int i;
14360 tree source_c = NULL_TREE;
14361 tree sink_c = NULL_TREE;
14363 if (gimplify_omp_ctxp)
14365 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14366 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14367 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
14368 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
14369 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
14371 error_at (OMP_CLAUSE_LOCATION (c),
14372 "%<ordered%> construct with %<depend%> clause must be "
14373 "closely nested inside a loop with %<ordered%> clause "
14374 "with a parameter");
14375 failures++;
14377 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14378 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
14380 bool fail = false;
14381 for (decls = OMP_CLAUSE_DECL (c), i = 0;
14382 decls && TREE_CODE (decls) == TREE_LIST;
14383 decls = TREE_CHAIN (decls), ++i)
14384 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
14385 continue;
14386 else if (TREE_VALUE (decls)
14387 != gimplify_omp_ctxp->loop_iter_var[2 * i])
14389 error_at (OMP_CLAUSE_LOCATION (c),
14390 "variable %qE is not an iteration "
14391 "of outermost loop %d, expected %qE",
14392 TREE_VALUE (decls), i + 1,
14393 gimplify_omp_ctxp->loop_iter_var[2 * i]);
14394 fail = true;
14395 failures++;
14397 else
14398 TREE_VALUE (decls)
14399 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
14400 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
14402 error_at (OMP_CLAUSE_LOCATION (c),
14403 "number of variables in %<depend%> clause with "
14404 "%<sink%> modifier does not match number of "
14405 "iteration variables");
14406 failures++;
14408 sink_c = c;
14410 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14411 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
14413 if (source_c)
14415 error_at (OMP_CLAUSE_LOCATION (c),
14416 "more than one %<depend%> clause with %<source%> "
14417 "modifier on an %<ordered%> construct");
14418 failures++;
14420 else
14421 source_c = c;
14424 if (source_c && sink_c)
14426 error_at (OMP_CLAUSE_LOCATION (source_c),
14427 "%<depend%> clause with %<source%> modifier specified "
14428 "together with %<depend%> clauses with %<sink%> modifier "
14429 "on the same construct");
14430 failures++;
14433 if (failures)
14434 return gimple_build_nop ();
14435 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
14438 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
14439 expression produces a value to be used as an operand inside a GIMPLE
14440 statement, the value will be stored back in *EXPR_P. This value will
14441 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
14442 an SSA_NAME. The corresponding sequence of GIMPLE statements is
14443 emitted in PRE_P and POST_P.
14445 Additionally, this process may overwrite parts of the input
14446 expression during gimplification. Ideally, it should be
14447 possible to do non-destructive gimplification.
14449 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
14450 the expression needs to evaluate to a value to be used as
14451 an operand in a GIMPLE statement, this value will be stored in
14452 *EXPR_P on exit. This happens when the caller specifies one
14453 of fb_lvalue or fb_rvalue fallback flags.
14455 PRE_P will contain the sequence of GIMPLE statements corresponding
14456 to the evaluation of EXPR and all the side-effects that must
14457 be executed before the main expression. On exit, the last
14458 statement of PRE_P is the core statement being gimplified. For
14459 instance, when gimplifying 'if (++a)' the last statement in
14460 PRE_P will be 'if (t.1)' where t.1 is the result of
14461 pre-incrementing 'a'.
14463 POST_P will contain the sequence of GIMPLE statements corresponding
14464 to the evaluation of all the side-effects that must be executed
14465 after the main expression. If this is NULL, the post
14466 side-effects are stored at the end of PRE_P.
14468 The reason why the output is split in two is to handle post
14469 side-effects explicitly. In some cases, an expression may have
14470 inner and outer post side-effects which need to be emitted in
14471 an order different from the one given by the recursive
14472 traversal. For instance, for the expression (*p--)++ the post
14473 side-effects of '--' must actually occur *after* the post
14474 side-effects of '++'. However, gimplification will first visit
14475 the inner expression, so if a separate POST sequence was not
14476 used, the resulting sequence would be:
14478 1 t.1 = *p
14479 2 p = p - 1
14480 3 t.2 = t.1 + 1
14481 4 *p = t.2
14483 However, the post-decrement operation in line #2 must not be
14484 evaluated until after the store to *p at line #4, so the
14485 correct sequence should be:
14487 1 t.1 = *p
14488 2 t.2 = t.1 + 1
14489 3 *p = t.2
14490 4 p = p - 1
14492 So, by specifying a separate post queue, it is possible
14493 to emit the post side-effects in the correct order.
14494 If POST_P is NULL, an internal queue will be used. Before
14495 returning to the caller, the sequence POST_P is appended to
14496 the main output sequence PRE_P.
14498 GIMPLE_TEST_F points to a function that takes a tree T and
14499 returns nonzero if T is in the GIMPLE form requested by the
14500 caller. The GIMPLE predicates are in gimple.c.
14502 FALLBACK tells the function what sort of a temporary we want if
14503 gimplification cannot produce an expression that complies with
14504 GIMPLE_TEST_F.
14506 fb_none means that no temporary should be generated
14507 fb_rvalue means that an rvalue is OK to generate
14508 fb_lvalue means that an lvalue is OK to generate
14509 fb_either means that either is OK, but an lvalue is preferable.
14510 fb_mayfail means that gimplification may fail (in which case
14511 GS_ERROR will be returned)
14513 The return value is either GS_ERROR or GS_ALL_DONE, since this
14514 function iterates until EXPR is completely gimplified or an error
14515 occurs. */
14517 enum gimplify_status
14518 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
14519 bool (*gimple_test_f) (tree), fallback_t fallback)
14521 tree tmp;
14522 gimple_seq internal_pre = NULL;
14523 gimple_seq internal_post = NULL;
14524 tree save_expr;
14525 bool is_statement;
14526 location_t saved_location;
14527 enum gimplify_status ret;
14528 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
14529 tree label;
14531 save_expr = *expr_p;
14532 if (save_expr == NULL_TREE)
14533 return GS_ALL_DONE;
14535 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
14536 is_statement = gimple_test_f == is_gimple_stmt;
14537 if (is_statement)
14538 gcc_assert (pre_p);
14540 /* Consistency checks. */
14541 if (gimple_test_f == is_gimple_reg)
14542 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
14543 else if (gimple_test_f == is_gimple_val
14544 || gimple_test_f == is_gimple_call_addr
14545 || gimple_test_f == is_gimple_condexpr
14546 || gimple_test_f == is_gimple_condexpr_for_cond
14547 || gimple_test_f == is_gimple_mem_rhs
14548 || gimple_test_f == is_gimple_mem_rhs_or_call
14549 || gimple_test_f == is_gimple_reg_rhs
14550 || gimple_test_f == is_gimple_reg_rhs_or_call
14551 || gimple_test_f == is_gimple_asm_val
14552 || gimple_test_f == is_gimple_mem_ref_addr)
14553 gcc_assert (fallback & fb_rvalue);
14554 else if (gimple_test_f == is_gimple_min_lval
14555 || gimple_test_f == is_gimple_lvalue)
14556 gcc_assert (fallback & fb_lvalue);
14557 else if (gimple_test_f == is_gimple_addressable)
14558 gcc_assert (fallback & fb_either);
14559 else if (gimple_test_f == is_gimple_stmt)
14560 gcc_assert (fallback == fb_none);
14561 else
14563 /* We should have recognized the GIMPLE_TEST_F predicate to
14564 know what kind of fallback to use in case a temporary is
14565 needed to hold the value or address of *EXPR_P. */
14566 gcc_unreachable ();
14569 /* We used to check the predicate here and return immediately if it
14570 succeeds. This is wrong; the design is for gimplification to be
14571 idempotent, and for the predicates to only test for valid forms, not
14572 whether they are fully simplified. */
14573 if (pre_p == NULL)
14574 pre_p = &internal_pre;
14576 if (post_p == NULL)
14577 post_p = &internal_post;
14579 /* Remember the last statements added to PRE_P and POST_P. Every
14580 new statement added by the gimplification helpers needs to be
14581 annotated with location information. To centralize the
14582 responsibility, we remember the last statement that had been
14583 added to both queues before gimplifying *EXPR_P. If
14584 gimplification produces new statements in PRE_P and POST_P, those
14585 statements will be annotated with the same location information
14586 as *EXPR_P. */
14587 pre_last_gsi = gsi_last (*pre_p);
14588 post_last_gsi = gsi_last (*post_p);
14590 saved_location = input_location;
14591 if (save_expr != error_mark_node
14592 && EXPR_HAS_LOCATION (*expr_p))
14593 input_location = EXPR_LOCATION (*expr_p);
14595 /* Loop over the specific gimplifiers until the toplevel node
14596 remains the same. */
14599 /* Strip away as many useless type conversions as possible
14600 at the toplevel. */
14601 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
14603 /* Remember the expr. */
14604 save_expr = *expr_p;
14606 /* Die, die, die, my darling. */
14607 if (error_operand_p (save_expr))
14609 ret = GS_ERROR;
14610 break;
14613 /* Do any language-specific gimplification. */
14614 ret = ((enum gimplify_status)
14615 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
14616 if (ret == GS_OK)
14618 if (*expr_p == NULL_TREE)
14619 break;
14620 if (*expr_p != save_expr)
14621 continue;
14623 else if (ret != GS_UNHANDLED)
14624 break;
14626 /* Make sure that all the cases set 'ret' appropriately. */
14627 ret = GS_UNHANDLED;
14628 switch (TREE_CODE (*expr_p))
14630 /* First deal with the special cases. */
14632 case POSTINCREMENT_EXPR:
14633 case POSTDECREMENT_EXPR:
14634 case PREINCREMENT_EXPR:
14635 case PREDECREMENT_EXPR:
14636 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
14637 fallback != fb_none,
14638 TREE_TYPE (*expr_p));
14639 break;
14641 case VIEW_CONVERT_EXPR:
14642 if ((fallback & fb_rvalue)
14643 && is_gimple_reg_type (TREE_TYPE (*expr_p))
14644 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
14646 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14647 post_p, is_gimple_val, fb_rvalue);
14648 recalculate_side_effects (*expr_p);
14649 break;
14651 /* Fallthru. */
14653 case ARRAY_REF:
14654 case ARRAY_RANGE_REF:
14655 case REALPART_EXPR:
14656 case IMAGPART_EXPR:
14657 case COMPONENT_REF:
14658 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
14659 fallback ? fallback : fb_rvalue);
14660 break;
14662 case COND_EXPR:
14663 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
14665 /* C99 code may assign to an array in a structure value of a
14666 conditional expression, and this has undefined behavior
14667 only on execution, so create a temporary if an lvalue is
14668 required. */
14669 if (fallback == fb_lvalue)
14671 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14672 mark_addressable (*expr_p);
14673 ret = GS_OK;
14675 break;
14677 case CALL_EXPR:
14678 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
14680 /* C99 code may assign to an array in a structure returned
14681 from a function, and this has undefined behavior only on
14682 execution, so create a temporary if an lvalue is
14683 required. */
14684 if (fallback == fb_lvalue)
14686 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14687 mark_addressable (*expr_p);
14688 ret = GS_OK;
14690 break;
14692 case TREE_LIST:
14693 gcc_unreachable ();
14695 case COMPOUND_EXPR:
14696 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
14697 break;
14699 case COMPOUND_LITERAL_EXPR:
14700 ret = gimplify_compound_literal_expr (expr_p, pre_p,
14701 gimple_test_f, fallback);
14702 break;
14704 case MODIFY_EXPR:
14705 case INIT_EXPR:
14706 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
14707 fallback != fb_none);
14708 break;
14710 case TRUTH_ANDIF_EXPR:
14711 case TRUTH_ORIF_EXPR:
14713 /* Preserve the original type of the expression and the
14714 source location of the outer expression. */
14715 tree org_type = TREE_TYPE (*expr_p);
14716 *expr_p = gimple_boolify (*expr_p);
14717 *expr_p = build3_loc (input_location, COND_EXPR,
14718 org_type, *expr_p,
14719 fold_convert_loc
14720 (input_location,
14721 org_type, boolean_true_node),
14722 fold_convert_loc
14723 (input_location,
14724 org_type, boolean_false_node));
14725 ret = GS_OK;
14726 break;
14729 case TRUTH_NOT_EXPR:
14731 tree type = TREE_TYPE (*expr_p);
14732 /* The parsers are careful to generate TRUTH_NOT_EXPR
14733 only with operands that are always zero or one.
14734 We do not fold here but handle the only interesting case
14735 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
14736 *expr_p = gimple_boolify (*expr_p);
14737 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
14738 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
14739 TREE_TYPE (*expr_p),
14740 TREE_OPERAND (*expr_p, 0));
14741 else
14742 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
14743 TREE_TYPE (*expr_p),
14744 TREE_OPERAND (*expr_p, 0),
14745 build_int_cst (TREE_TYPE (*expr_p), 1));
14746 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
14747 *expr_p = fold_convert_loc (input_location, type, *expr_p);
14748 ret = GS_OK;
14749 break;
14752 case ADDR_EXPR:
14753 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
14754 break;
14756 case ANNOTATE_EXPR:
14758 tree cond = TREE_OPERAND (*expr_p, 0);
14759 tree kind = TREE_OPERAND (*expr_p, 1);
14760 tree data = TREE_OPERAND (*expr_p, 2);
14761 tree type = TREE_TYPE (cond);
14762 if (!INTEGRAL_TYPE_P (type))
14764 *expr_p = cond;
14765 ret = GS_OK;
14766 break;
14768 tree tmp = create_tmp_var (type);
14769 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
14770 gcall *call
14771 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
14772 gimple_call_set_lhs (call, tmp);
14773 gimplify_seq_add_stmt (pre_p, call);
14774 *expr_p = tmp;
14775 ret = GS_ALL_DONE;
14776 break;
14779 case VA_ARG_EXPR:
14780 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
14781 break;
14783 CASE_CONVERT:
14784 if (IS_EMPTY_STMT (*expr_p))
14786 ret = GS_ALL_DONE;
14787 break;
14790 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
14791 || fallback == fb_none)
14793 /* Just strip a conversion to void (or in void context) and
14794 try again. */
14795 *expr_p = TREE_OPERAND (*expr_p, 0);
14796 ret = GS_OK;
14797 break;
14800 ret = gimplify_conversion (expr_p);
14801 if (ret == GS_ERROR)
14802 break;
14803 if (*expr_p != save_expr)
14804 break;
14805 /* FALLTHRU */
14807 case FIX_TRUNC_EXPR:
14808 /* unary_expr: ... | '(' cast ')' val | ... */
14809 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14810 is_gimple_val, fb_rvalue);
14811 recalculate_side_effects (*expr_p);
14812 break;
14814 case INDIRECT_REF:
14816 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
14817 bool notrap = TREE_THIS_NOTRAP (*expr_p);
14818 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
14820 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
14821 if (*expr_p != save_expr)
14823 ret = GS_OK;
14824 break;
14827 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14828 is_gimple_reg, fb_rvalue);
14829 if (ret == GS_ERROR)
14830 break;
14832 recalculate_side_effects (*expr_p);
14833 *expr_p = fold_build2_loc (input_location, MEM_REF,
14834 TREE_TYPE (*expr_p),
14835 TREE_OPERAND (*expr_p, 0),
14836 build_int_cst (saved_ptr_type, 0));
14837 TREE_THIS_VOLATILE (*expr_p) = volatilep;
14838 TREE_THIS_NOTRAP (*expr_p) = notrap;
14839 ret = GS_OK;
14840 break;
14843 /* We arrive here through the various re-gimplifcation paths. */
14844 case MEM_REF:
14845 /* First try re-folding the whole thing. */
14846 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
14847 TREE_OPERAND (*expr_p, 0),
14848 TREE_OPERAND (*expr_p, 1));
14849 if (tmp)
14851 REF_REVERSE_STORAGE_ORDER (tmp)
14852 = REF_REVERSE_STORAGE_ORDER (*expr_p);
14853 *expr_p = tmp;
14854 recalculate_side_effects (*expr_p);
14855 ret = GS_OK;
14856 break;
14858 /* Avoid re-gimplifying the address operand if it is already
14859 in suitable form. Re-gimplifying would mark the address
14860 operand addressable. Always gimplify when not in SSA form
14861 as we still may have to gimplify decls with value-exprs. */
14862 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
14863 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
14865 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14866 is_gimple_mem_ref_addr, fb_rvalue);
14867 if (ret == GS_ERROR)
14868 break;
14870 recalculate_side_effects (*expr_p);
14871 ret = GS_ALL_DONE;
14872 break;
14874 /* Constants need not be gimplified. */
14875 case INTEGER_CST:
14876 case REAL_CST:
14877 case FIXED_CST:
14878 case STRING_CST:
14879 case COMPLEX_CST:
14880 case VECTOR_CST:
14881 /* Drop the overflow flag on constants, we do not want
14882 that in the GIMPLE IL. */
14883 if (TREE_OVERFLOW_P (*expr_p))
14884 *expr_p = drop_tree_overflow (*expr_p);
14885 ret = GS_ALL_DONE;
14886 break;
14888 case CONST_DECL:
14889 /* If we require an lvalue, such as for ADDR_EXPR, retain the
14890 CONST_DECL node. Otherwise the decl is replaceable by its
14891 value. */
14892 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
14893 if (fallback & fb_lvalue)
14894 ret = GS_ALL_DONE;
14895 else
14897 *expr_p = DECL_INITIAL (*expr_p);
14898 ret = GS_OK;
14900 break;
14902 case DECL_EXPR:
14903 ret = gimplify_decl_expr (expr_p, pre_p);
14904 break;
14906 case BIND_EXPR:
14907 ret = gimplify_bind_expr (expr_p, pre_p);
14908 break;
14910 case LOOP_EXPR:
14911 ret = gimplify_loop_expr (expr_p, pre_p);
14912 break;
14914 case SWITCH_EXPR:
14915 ret = gimplify_switch_expr (expr_p, pre_p);
14916 break;
14918 case EXIT_EXPR:
14919 ret = gimplify_exit_expr (expr_p);
14920 break;
14922 case GOTO_EXPR:
14923 /* If the target is not LABEL, then it is a computed jump
14924 and the target needs to be gimplified. */
14925 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
14927 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
14928 NULL, is_gimple_val, fb_rvalue);
14929 if (ret == GS_ERROR)
14930 break;
14932 gimplify_seq_add_stmt (pre_p,
14933 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
14934 ret = GS_ALL_DONE;
14935 break;
14937 case PREDICT_EXPR:
14938 gimplify_seq_add_stmt (pre_p,
14939 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
14940 PREDICT_EXPR_OUTCOME (*expr_p)));
14941 ret = GS_ALL_DONE;
14942 break;
14944 case LABEL_EXPR:
14945 ret = gimplify_label_expr (expr_p, pre_p);
14946 label = LABEL_EXPR_LABEL (*expr_p);
14947 gcc_assert (decl_function_context (label) == current_function_decl);
14949 /* If the label is used in a goto statement, or address of the label
14950 is taken, we need to unpoison all variables that were seen so far.
14951 Doing so would prevent us from reporting a false positives. */
14952 if (asan_poisoned_variables
14953 && asan_used_labels != NULL
14954 && asan_used_labels->contains (label)
14955 && !gimplify_omp_ctxp)
14956 asan_poison_variables (asan_poisoned_variables, false, pre_p);
14957 break;
14959 case CASE_LABEL_EXPR:
14960 ret = gimplify_case_label_expr (expr_p, pre_p);
14962 if (gimplify_ctxp->live_switch_vars)
14963 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
14964 pre_p);
14965 break;
14967 case RETURN_EXPR:
14968 ret = gimplify_return_expr (*expr_p, pre_p);
14969 break;
14971 case CONSTRUCTOR:
14972 /* Don't reduce this in place; let gimplify_init_constructor work its
14973 magic. Buf if we're just elaborating this for side effects, just
14974 gimplify any element that has side-effects. */
14975 if (fallback == fb_none)
14977 unsigned HOST_WIDE_INT ix;
14978 tree val;
14979 tree temp = NULL_TREE;
14980 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
14981 if (TREE_SIDE_EFFECTS (val))
14982 append_to_statement_list (val, &temp);
14984 *expr_p = temp;
14985 ret = temp ? GS_OK : GS_ALL_DONE;
14987 /* C99 code may assign to an array in a constructed
14988 structure or union, and this has undefined behavior only
14989 on execution, so create a temporary if an lvalue is
14990 required. */
14991 else if (fallback == fb_lvalue)
14993 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14994 mark_addressable (*expr_p);
14995 ret = GS_OK;
14997 else
14998 ret = GS_ALL_DONE;
14999 break;
15001 /* The following are special cases that are not handled by the
15002 original GIMPLE grammar. */
15004 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
15005 eliminated. */
15006 case SAVE_EXPR:
15007 ret = gimplify_save_expr (expr_p, pre_p, post_p);
15008 break;
15010 case BIT_FIELD_REF:
15011 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15012 post_p, is_gimple_lvalue, fb_either);
15013 recalculate_side_effects (*expr_p);
15014 break;
15016 case TARGET_MEM_REF:
15018 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
15020 if (TMR_BASE (*expr_p))
15021 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
15022 post_p, is_gimple_mem_ref_addr, fb_either);
15023 if (TMR_INDEX (*expr_p))
15024 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
15025 post_p, is_gimple_val, fb_rvalue);
15026 if (TMR_INDEX2 (*expr_p))
15027 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
15028 post_p, is_gimple_val, fb_rvalue);
15029 /* TMR_STEP and TMR_OFFSET are always integer constants. */
15030 ret = MIN (r0, r1);
15032 break;
15034 case NON_LVALUE_EXPR:
15035 /* This should have been stripped above. */
15036 gcc_unreachable ();
15038 case ASM_EXPR:
15039 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
15040 break;
15042 case TRY_FINALLY_EXPR:
15043 case TRY_CATCH_EXPR:
15045 gimple_seq eval, cleanup;
15046 gtry *try_;
15048 /* Calls to destructors are generated automatically in FINALLY/CATCH
15049 block. They should have location as UNKNOWN_LOCATION. However,
15050 gimplify_call_expr will reset these call stmts to input_location
15051 if it finds stmt's location is unknown. To prevent resetting for
15052 destructors, we set the input_location to unknown.
15053 Note that this only affects the destructor calls in FINALLY/CATCH
15054 block, and will automatically reset to its original value by the
15055 end of gimplify_expr. */
15056 input_location = UNKNOWN_LOCATION;
15057 eval = cleanup = NULL;
15058 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
15059 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15060 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
15062 gimple_seq n = NULL, e = NULL;
15063 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15064 0), &n);
15065 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15066 1), &e);
15067 if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
15069 geh_else *stmt = gimple_build_eh_else (n, e);
15070 gimple_seq_add_stmt (&cleanup, stmt);
15073 else
15074 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
15075 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
15076 if (gimple_seq_empty_p (cleanup))
15078 gimple_seq_add_seq (pre_p, eval);
15079 ret = GS_ALL_DONE;
15080 break;
15082 try_ = gimple_build_try (eval, cleanup,
15083 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15084 ? GIMPLE_TRY_FINALLY
15085 : GIMPLE_TRY_CATCH);
15086 if (EXPR_HAS_LOCATION (save_expr))
15087 gimple_set_location (try_, EXPR_LOCATION (save_expr));
15088 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
15089 gimple_set_location (try_, saved_location);
15090 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
15091 gimple_try_set_catch_is_cleanup (try_,
15092 TRY_CATCH_IS_CLEANUP (*expr_p));
15093 gimplify_seq_add_stmt (pre_p, try_);
15094 ret = GS_ALL_DONE;
15095 break;
15098 case CLEANUP_POINT_EXPR:
15099 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
15100 break;
15102 case TARGET_EXPR:
15103 ret = gimplify_target_expr (expr_p, pre_p, post_p);
15104 break;
15106 case CATCH_EXPR:
15108 gimple *c;
15109 gimple_seq handler = NULL;
15110 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
15111 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
15112 gimplify_seq_add_stmt (pre_p, c);
15113 ret = GS_ALL_DONE;
15114 break;
15117 case EH_FILTER_EXPR:
15119 gimple *ehf;
15120 gimple_seq failure = NULL;
15122 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
15123 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
15124 copy_warning (ehf, *expr_p);
15125 gimplify_seq_add_stmt (pre_p, ehf);
15126 ret = GS_ALL_DONE;
15127 break;
15130 case OBJ_TYPE_REF:
15132 enum gimplify_status r0, r1;
15133 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
15134 post_p, is_gimple_val, fb_rvalue);
15135 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
15136 post_p, is_gimple_val, fb_rvalue);
15137 TREE_SIDE_EFFECTS (*expr_p) = 0;
15138 ret = MIN (r0, r1);
15140 break;
15142 case LABEL_DECL:
15143 /* We get here when taking the address of a label. We mark
15144 the label as "forced"; meaning it can never be removed and
15145 it is a potential target for any computed goto. */
15146 FORCED_LABEL (*expr_p) = 1;
15147 ret = GS_ALL_DONE;
15148 break;
15150 case STATEMENT_LIST:
15151 ret = gimplify_statement_list (expr_p, pre_p);
15152 break;
15154 case WITH_SIZE_EXPR:
15156 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15157 post_p == &internal_post ? NULL : post_p,
15158 gimple_test_f, fallback);
15159 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15160 is_gimple_val, fb_rvalue);
15161 ret = GS_ALL_DONE;
15163 break;
15165 case VAR_DECL:
15166 case PARM_DECL:
15167 ret = gimplify_var_or_parm_decl (expr_p);
15168 break;
15170 case RESULT_DECL:
15171 /* When within an OMP context, notice uses of variables. */
15172 if (gimplify_omp_ctxp)
15173 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
15174 ret = GS_ALL_DONE;
15175 break;
15177 case DEBUG_EXPR_DECL:
15178 gcc_unreachable ();
15180 case DEBUG_BEGIN_STMT:
15181 gimplify_seq_add_stmt (pre_p,
15182 gimple_build_debug_begin_stmt
15183 (TREE_BLOCK (*expr_p),
15184 EXPR_LOCATION (*expr_p)));
15185 ret = GS_ALL_DONE;
15186 *expr_p = NULL;
15187 break;
15189 case SSA_NAME:
15190 /* Allow callbacks into the gimplifier during optimization. */
15191 ret = GS_ALL_DONE;
15192 break;
15194 case OMP_PARALLEL:
15195 gimplify_omp_parallel (expr_p, pre_p);
15196 ret = GS_ALL_DONE;
15197 break;
15199 case OMP_TASK:
15200 gimplify_omp_task (expr_p, pre_p);
15201 ret = GS_ALL_DONE;
15202 break;
15204 case OMP_FOR:
15205 case OMP_SIMD:
15206 case OMP_DISTRIBUTE:
15207 case OMP_TASKLOOP:
15208 case OACC_LOOP:
15209 ret = gimplify_omp_for (expr_p, pre_p);
15210 break;
15212 case OMP_LOOP:
15213 ret = gimplify_omp_loop (expr_p, pre_p);
15214 break;
15216 case OACC_CACHE:
15217 gimplify_oacc_cache (expr_p, pre_p);
15218 ret = GS_ALL_DONE;
15219 break;
15221 case OACC_DECLARE:
15222 gimplify_oacc_declare (expr_p, pre_p);
15223 ret = GS_ALL_DONE;
15224 break;
15226 case OACC_HOST_DATA:
15227 case OACC_DATA:
15228 case OACC_KERNELS:
15229 case OACC_PARALLEL:
15230 case OACC_SERIAL:
15231 case OMP_SCOPE:
15232 case OMP_SECTIONS:
15233 case OMP_SINGLE:
15234 case OMP_TARGET:
15235 case OMP_TARGET_DATA:
15236 case OMP_TEAMS:
15237 gimplify_omp_workshare (expr_p, pre_p);
15238 ret = GS_ALL_DONE;
15239 break;
15241 case OACC_ENTER_DATA:
15242 case OACC_EXIT_DATA:
15243 case OACC_UPDATE:
15244 case OMP_TARGET_UPDATE:
15245 case OMP_TARGET_ENTER_DATA:
15246 case OMP_TARGET_EXIT_DATA:
15247 gimplify_omp_target_update (expr_p, pre_p);
15248 ret = GS_ALL_DONE;
15249 break;
15251 case OMP_SECTION:
15252 case OMP_MASTER:
15253 case OMP_MASKED:
15254 case OMP_ORDERED:
15255 case OMP_CRITICAL:
15256 case OMP_SCAN:
15258 gimple_seq body = NULL;
15259 gimple *g;
15260 bool saved_in_omp_construct = in_omp_construct;
15262 in_omp_construct = true;
15263 gimplify_and_add (OMP_BODY (*expr_p), &body);
15264 in_omp_construct = saved_in_omp_construct;
15265 switch (TREE_CODE (*expr_p))
15267 case OMP_SECTION:
15268 g = gimple_build_omp_section (body);
15269 break;
15270 case OMP_MASTER:
15271 g = gimple_build_omp_master (body);
15272 break;
15273 case OMP_ORDERED:
15274 g = gimplify_omp_ordered (*expr_p, body);
15275 break;
15276 case OMP_MASKED:
15277 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p),
15278 pre_p, ORT_WORKSHARE, OMP_MASKED);
15279 gimplify_adjust_omp_clauses (pre_p, body,
15280 &OMP_MASKED_CLAUSES (*expr_p),
15281 OMP_MASKED);
15282 g = gimple_build_omp_masked (body,
15283 OMP_MASKED_CLAUSES (*expr_p));
15284 break;
15285 case OMP_CRITICAL:
15286 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
15287 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
15288 gimplify_adjust_omp_clauses (pre_p, body,
15289 &OMP_CRITICAL_CLAUSES (*expr_p),
15290 OMP_CRITICAL);
15291 g = gimple_build_omp_critical (body,
15292 OMP_CRITICAL_NAME (*expr_p),
15293 OMP_CRITICAL_CLAUSES (*expr_p));
15294 break;
15295 case OMP_SCAN:
15296 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
15297 pre_p, ORT_WORKSHARE, OMP_SCAN);
15298 gimplify_adjust_omp_clauses (pre_p, body,
15299 &OMP_SCAN_CLAUSES (*expr_p),
15300 OMP_SCAN);
15301 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
15302 break;
15303 default:
15304 gcc_unreachable ();
15306 gimplify_seq_add_stmt (pre_p, g);
15307 ret = GS_ALL_DONE;
15308 break;
15311 case OMP_TASKGROUP:
15313 gimple_seq body = NULL;
15315 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
15316 bool saved_in_omp_construct = in_omp_construct;
15317 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
15318 OMP_TASKGROUP);
15319 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
15321 in_omp_construct = true;
15322 gimplify_and_add (OMP_BODY (*expr_p), &body);
15323 in_omp_construct = saved_in_omp_construct;
15324 gimple_seq cleanup = NULL;
15325 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
15326 gimple *g = gimple_build_call (fn, 0);
15327 gimple_seq_add_stmt (&cleanup, g);
15328 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
15329 body = NULL;
15330 gimple_seq_add_stmt (&body, g);
15331 g = gimple_build_omp_taskgroup (body, *pclauses);
15332 gimplify_seq_add_stmt (pre_p, g);
15333 ret = GS_ALL_DONE;
15334 break;
15337 case OMP_ATOMIC:
15338 case OMP_ATOMIC_READ:
15339 case OMP_ATOMIC_CAPTURE_OLD:
15340 case OMP_ATOMIC_CAPTURE_NEW:
15341 ret = gimplify_omp_atomic (expr_p, pre_p);
15342 break;
15344 case TRANSACTION_EXPR:
15345 ret = gimplify_transaction (expr_p, pre_p);
15346 break;
15348 case TRUTH_AND_EXPR:
15349 case TRUTH_OR_EXPR:
15350 case TRUTH_XOR_EXPR:
15352 tree orig_type = TREE_TYPE (*expr_p);
15353 tree new_type, xop0, xop1;
15354 *expr_p = gimple_boolify (*expr_p);
15355 new_type = TREE_TYPE (*expr_p);
15356 if (!useless_type_conversion_p (orig_type, new_type))
15358 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
15359 ret = GS_OK;
15360 break;
15363 /* Boolified binary truth expressions are semantically equivalent
15364 to bitwise binary expressions. Canonicalize them to the
15365 bitwise variant. */
15366 switch (TREE_CODE (*expr_p))
15368 case TRUTH_AND_EXPR:
15369 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
15370 break;
15371 case TRUTH_OR_EXPR:
15372 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
15373 break;
15374 case TRUTH_XOR_EXPR:
15375 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
15376 break;
15377 default:
15378 break;
15380 /* Now make sure that operands have compatible type to
15381 expression's new_type. */
15382 xop0 = TREE_OPERAND (*expr_p, 0);
15383 xop1 = TREE_OPERAND (*expr_p, 1);
15384 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
15385 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
15386 new_type,
15387 xop0);
15388 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
15389 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
15390 new_type,
15391 xop1);
15392 /* Continue classified as tcc_binary. */
15393 goto expr_2;
15396 case VEC_COND_EXPR:
15397 goto expr_3;
15399 case VEC_PERM_EXPR:
15400 /* Classified as tcc_expression. */
15401 goto expr_3;
15403 case BIT_INSERT_EXPR:
15404 /* Argument 3 is a constant. */
15405 goto expr_2;
15407 case POINTER_PLUS_EXPR:
15409 enum gimplify_status r0, r1;
15410 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15411 post_p, is_gimple_val, fb_rvalue);
15412 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15413 post_p, is_gimple_val, fb_rvalue);
15414 recalculate_side_effects (*expr_p);
15415 ret = MIN (r0, r1);
15416 break;
15419 default:
15420 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
15422 case tcc_comparison:
15423 /* Handle comparison of objects of non scalar mode aggregates
15424 with a call to memcmp. It would be nice to only have to do
15425 this for variable-sized objects, but then we'd have to allow
15426 the same nest of reference nodes we allow for MODIFY_EXPR and
15427 that's too complex.
15429 Compare scalar mode aggregates as scalar mode values. Using
15430 memcmp for them would be very inefficient at best, and is
15431 plain wrong if bitfields are involved. */
15433 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
15435 /* Vector comparisons need no boolification. */
15436 if (TREE_CODE (type) == VECTOR_TYPE)
15437 goto expr_2;
15438 else if (!AGGREGATE_TYPE_P (type))
15440 tree org_type = TREE_TYPE (*expr_p);
15441 *expr_p = gimple_boolify (*expr_p);
15442 if (!useless_type_conversion_p (org_type,
15443 TREE_TYPE (*expr_p)))
15445 *expr_p = fold_convert_loc (input_location,
15446 org_type, *expr_p);
15447 ret = GS_OK;
15449 else
15450 goto expr_2;
15452 else if (TYPE_MODE (type) != BLKmode)
15453 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
15454 else
15455 ret = gimplify_variable_sized_compare (expr_p);
15457 break;
15460 /* If *EXPR_P does not need to be special-cased, handle it
15461 according to its class. */
15462 case tcc_unary:
15463 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15464 post_p, is_gimple_val, fb_rvalue);
15465 break;
15467 case tcc_binary:
15468 expr_2:
15470 enum gimplify_status r0, r1;
15472 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15473 post_p, is_gimple_val, fb_rvalue);
15474 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15475 post_p, is_gimple_val, fb_rvalue);
15477 ret = MIN (r0, r1);
15478 break;
15481 expr_3:
15483 enum gimplify_status r0, r1, r2;
15485 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15486 post_p, is_gimple_val, fb_rvalue);
15487 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15488 post_p, is_gimple_val, fb_rvalue);
15489 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
15490 post_p, is_gimple_val, fb_rvalue);
15492 ret = MIN (MIN (r0, r1), r2);
15493 break;
15496 case tcc_declaration:
15497 case tcc_constant:
15498 ret = GS_ALL_DONE;
15499 goto dont_recalculate;
15501 default:
15502 gcc_unreachable ();
15505 recalculate_side_effects (*expr_p);
15507 dont_recalculate:
15508 break;
15511 gcc_assert (*expr_p || ret != GS_OK);
15513 while (ret == GS_OK);
15515 /* If we encountered an error_mark somewhere nested inside, either
15516 stub out the statement or propagate the error back out. */
15517 if (ret == GS_ERROR)
15519 if (is_statement)
15520 *expr_p = NULL;
15521 goto out;
15524 /* This was only valid as a return value from the langhook, which
15525 we handled. Make sure it doesn't escape from any other context. */
15526 gcc_assert (ret != GS_UNHANDLED);
15528 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
15530 /* We aren't looking for a value, and we don't have a valid
15531 statement. If it doesn't have side-effects, throw it away.
15532 We can also get here with code such as "*&&L;", where L is
15533 a LABEL_DECL that is marked as FORCED_LABEL. */
15534 if (TREE_CODE (*expr_p) == LABEL_DECL
15535 || !TREE_SIDE_EFFECTS (*expr_p))
15536 *expr_p = NULL;
15537 else if (!TREE_THIS_VOLATILE (*expr_p))
15539 /* This is probably a _REF that contains something nested that
15540 has side effects. Recurse through the operands to find it. */
15541 enum tree_code code = TREE_CODE (*expr_p);
15543 switch (code)
15545 case COMPONENT_REF:
15546 case REALPART_EXPR:
15547 case IMAGPART_EXPR:
15548 case VIEW_CONVERT_EXPR:
15549 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15550 gimple_test_f, fallback);
15551 break;
15553 case ARRAY_REF:
15554 case ARRAY_RANGE_REF:
15555 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15556 gimple_test_f, fallback);
15557 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15558 gimple_test_f, fallback);
15559 break;
15561 default:
15562 /* Anything else with side-effects must be converted to
15563 a valid statement before we get here. */
15564 gcc_unreachable ();
15567 *expr_p = NULL;
15569 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
15570 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode
15571 && !is_empty_type (TREE_TYPE (*expr_p)))
15573 /* Historically, the compiler has treated a bare reference
15574 to a non-BLKmode volatile lvalue as forcing a load. */
15575 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
15577 /* Normally, we do not want to create a temporary for a
15578 TREE_ADDRESSABLE type because such a type should not be
15579 copied by bitwise-assignment. However, we make an
15580 exception here, as all we are doing here is ensuring that
15581 we read the bytes that make up the type. We use
15582 create_tmp_var_raw because create_tmp_var will abort when
15583 given a TREE_ADDRESSABLE type. */
15584 tree tmp = create_tmp_var_raw (type, "vol");
15585 gimple_add_tmp_var (tmp);
15586 gimplify_assign (tmp, *expr_p, pre_p);
15587 *expr_p = NULL;
15589 else
15590 /* We can't do anything useful with a volatile reference to
15591 an incomplete type, so just throw it away. Likewise for
15592 a BLKmode type, since any implicit inner load should
15593 already have been turned into an explicit one by the
15594 gimplification process. */
15595 *expr_p = NULL;
15598 /* If we are gimplifying at the statement level, we're done. Tack
15599 everything together and return. */
15600 if (fallback == fb_none || is_statement)
15602 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
15603 it out for GC to reclaim it. */
15604 *expr_p = NULL_TREE;
15606 if (!gimple_seq_empty_p (internal_pre)
15607 || !gimple_seq_empty_p (internal_post))
15609 gimplify_seq_add_seq (&internal_pre, internal_post);
15610 gimplify_seq_add_seq (pre_p, internal_pre);
15613 /* The result of gimplifying *EXPR_P is going to be the last few
15614 statements in *PRE_P and *POST_P. Add location information
15615 to all the statements that were added by the gimplification
15616 helpers. */
15617 if (!gimple_seq_empty_p (*pre_p))
15618 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
15620 if (!gimple_seq_empty_p (*post_p))
15621 annotate_all_with_location_after (*post_p, post_last_gsi,
15622 input_location);
15624 goto out;
15627 #ifdef ENABLE_GIMPLE_CHECKING
15628 if (*expr_p)
15630 enum tree_code code = TREE_CODE (*expr_p);
15631 /* These expressions should already be in gimple IR form. */
15632 gcc_assert (code != MODIFY_EXPR
15633 && code != ASM_EXPR
15634 && code != BIND_EXPR
15635 && code != CATCH_EXPR
15636 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
15637 && code != EH_FILTER_EXPR
15638 && code != GOTO_EXPR
15639 && code != LABEL_EXPR
15640 && code != LOOP_EXPR
15641 && code != SWITCH_EXPR
15642 && code != TRY_FINALLY_EXPR
15643 && code != EH_ELSE_EXPR
15644 && code != OACC_PARALLEL
15645 && code != OACC_KERNELS
15646 && code != OACC_SERIAL
15647 && code != OACC_DATA
15648 && code != OACC_HOST_DATA
15649 && code != OACC_DECLARE
15650 && code != OACC_UPDATE
15651 && code != OACC_ENTER_DATA
15652 && code != OACC_EXIT_DATA
15653 && code != OACC_CACHE
15654 && code != OMP_CRITICAL
15655 && code != OMP_FOR
15656 && code != OACC_LOOP
15657 && code != OMP_MASTER
15658 && code != OMP_MASKED
15659 && code != OMP_TASKGROUP
15660 && code != OMP_ORDERED
15661 && code != OMP_PARALLEL
15662 && code != OMP_SCAN
15663 && code != OMP_SECTIONS
15664 && code != OMP_SECTION
15665 && code != OMP_SINGLE
15666 && code != OMP_SCOPE);
15668 #endif
15670 /* Otherwise we're gimplifying a subexpression, so the resulting
15671 value is interesting. If it's a valid operand that matches
15672 GIMPLE_TEST_F, we're done. Unless we are handling some
15673 post-effects internally; if that's the case, we need to copy into
15674 a temporary before adding the post-effects to POST_P. */
15675 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
15676 goto out;
15678 /* Otherwise, we need to create a new temporary for the gimplified
15679 expression. */
15681 /* We can't return an lvalue if we have an internal postqueue. The
15682 object the lvalue refers to would (probably) be modified by the
15683 postqueue; we need to copy the value out first, which means an
15684 rvalue. */
15685 if ((fallback & fb_lvalue)
15686 && gimple_seq_empty_p (internal_post)
15687 && is_gimple_addressable (*expr_p))
15689 /* An lvalue will do. Take the address of the expression, store it
15690 in a temporary, and replace the expression with an INDIRECT_REF of
15691 that temporary. */
15692 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
15693 unsigned int ref_align = get_object_alignment (*expr_p);
15694 tree ref_type = TREE_TYPE (*expr_p);
15695 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
15696 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
15697 if (TYPE_ALIGN (ref_type) != ref_align)
15698 ref_type = build_aligned_type (ref_type, ref_align);
15699 *expr_p = build2 (MEM_REF, ref_type,
15700 tmp, build_zero_cst (ref_alias_type));
15702 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
15704 /* An rvalue will do. Assign the gimplified expression into a
15705 new temporary TMP and replace the original expression with
15706 TMP. First, make sure that the expression has a type so that
15707 it can be assigned into a temporary. */
15708 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
15709 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
15711 else
15713 #ifdef ENABLE_GIMPLE_CHECKING
15714 if (!(fallback & fb_mayfail))
15716 fprintf (stderr, "gimplification failed:\n");
15717 print_generic_expr (stderr, *expr_p);
15718 debug_tree (*expr_p);
15719 internal_error ("gimplification failed");
15721 #endif
15722 gcc_assert (fallback & fb_mayfail);
15724 /* If this is an asm statement, and the user asked for the
15725 impossible, don't die. Fail and let gimplify_asm_expr
15726 issue an error. */
15727 ret = GS_ERROR;
15728 goto out;
15731 /* Make sure the temporary matches our predicate. */
15732 gcc_assert ((*gimple_test_f) (*expr_p));
15734 if (!gimple_seq_empty_p (internal_post))
15736 annotate_all_with_location (internal_post, input_location);
15737 gimplify_seq_add_seq (pre_p, internal_post);
15740 out:
15741 input_location = saved_location;
15742 return ret;
15745 /* Like gimplify_expr but make sure the gimplified result is not itself
15746 a SSA name (but a decl if it were). Temporaries required by
15747 evaluating *EXPR_P may be still SSA names. */
15749 static enum gimplify_status
15750 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
15751 bool (*gimple_test_f) (tree), fallback_t fallback,
15752 bool allow_ssa)
15754 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
15755 gimple_test_f, fallback);
15756 if (! allow_ssa
15757 && TREE_CODE (*expr_p) == SSA_NAME)
15758 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
15759 return ret;
15762 /* Look through TYPE for variable-sized objects and gimplify each such
15763 size that we find. Add to LIST_P any statements generated. */
15765 void
15766 gimplify_type_sizes (tree type, gimple_seq *list_p)
15768 if (type == NULL || type == error_mark_node)
15769 return;
15771 const bool ignored_p
15772 = TYPE_NAME (type)
15773 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
15774 && DECL_IGNORED_P (TYPE_NAME (type));
15775 tree t;
15777 /* We first do the main variant, then copy into any other variants. */
15778 type = TYPE_MAIN_VARIANT (type);
15780 /* Avoid infinite recursion. */
15781 if (TYPE_SIZES_GIMPLIFIED (type))
15782 return;
15784 TYPE_SIZES_GIMPLIFIED (type) = 1;
15786 switch (TREE_CODE (type))
15788 case INTEGER_TYPE:
15789 case ENUMERAL_TYPE:
15790 case BOOLEAN_TYPE:
15791 case REAL_TYPE:
15792 case FIXED_POINT_TYPE:
15793 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
15794 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
15796 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
15798 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
15799 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
15801 break;
15803 case ARRAY_TYPE:
15804 /* These types may not have declarations, so handle them here. */
15805 gimplify_type_sizes (TREE_TYPE (type), list_p);
15806 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
15807 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
15808 with assigned stack slots, for -O1+ -g they should be tracked
15809 by VTA. */
15810 if (!ignored_p
15811 && TYPE_DOMAIN (type)
15812 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
15814 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
15815 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
15816 DECL_IGNORED_P (t) = 0;
15817 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
15818 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
15819 DECL_IGNORED_P (t) = 0;
15821 break;
15823 case RECORD_TYPE:
15824 case UNION_TYPE:
15825 case QUAL_UNION_TYPE:
15826 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
15827 if (TREE_CODE (field) == FIELD_DECL)
15829 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
15830 /* Likewise, ensure variable offsets aren't removed. */
15831 if (!ignored_p
15832 && (t = DECL_FIELD_OFFSET (field))
15833 && VAR_P (t)
15834 && DECL_ARTIFICIAL (t))
15835 DECL_IGNORED_P (t) = 0;
15836 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
15837 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
15838 gimplify_type_sizes (TREE_TYPE (field), list_p);
15840 break;
15842 case POINTER_TYPE:
15843 case REFERENCE_TYPE:
15844 /* We used to recurse on the pointed-to type here, which turned out to
15845 be incorrect because its definition might refer to variables not
15846 yet initialized at this point if a forward declaration is involved.
15848 It was actually useful for anonymous pointed-to types to ensure
15849 that the sizes evaluation dominates every possible later use of the
15850 values. Restricting to such types here would be safe since there
15851 is no possible forward declaration around, but would introduce an
15852 undesirable middle-end semantic to anonymity. We then defer to
15853 front-ends the responsibility of ensuring that the sizes are
15854 evaluated both early and late enough, e.g. by attaching artificial
15855 type declarations to the tree. */
15856 break;
15858 default:
15859 break;
15862 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
15863 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
15865 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
15867 TYPE_SIZE (t) = TYPE_SIZE (type);
15868 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
15869 TYPE_SIZES_GIMPLIFIED (t) = 1;
15873 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
15874 a size or position, has had all of its SAVE_EXPRs evaluated.
15875 We add any required statements to *STMT_P. */
15877 void
15878 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
15880 tree expr = *expr_p;
15882 /* We don't do anything if the value isn't there, is constant, or contains
15883 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
15884 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
15885 will want to replace it with a new variable, but that will cause problems
15886 if this type is from outside the function. It's OK to have that here. */
15887 if (expr == NULL_TREE
15888 || is_gimple_constant (expr)
15889 || TREE_CODE (expr) == VAR_DECL
15890 || CONTAINS_PLACEHOLDER_P (expr))
15891 return;
15893 *expr_p = unshare_expr (expr);
15895 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
15896 if the def vanishes. */
15897 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
15899 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
15900 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
15901 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
15902 if (is_gimple_constant (*expr_p))
15903 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
15906 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
15907 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
15908 is true, also gimplify the parameters. */
15910 gbind *
15911 gimplify_body (tree fndecl, bool do_parms)
15913 location_t saved_location = input_location;
15914 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
15915 gimple *outer_stmt;
15916 gbind *outer_bind;
15918 timevar_push (TV_TREE_GIMPLIFY);
15920 init_tree_ssa (cfun);
15922 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
15923 gimplification. */
15924 default_rtl_profile ();
15926 gcc_assert (gimplify_ctxp == NULL);
15927 push_gimplify_context (true);
15929 if (flag_openacc || flag_openmp)
15931 gcc_assert (gimplify_omp_ctxp == NULL);
15932 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
15933 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
15936 /* Unshare most shared trees in the body and in that of any nested functions.
15937 It would seem we don't have to do this for nested functions because
15938 they are supposed to be output and then the outer function gimplified
15939 first, but the g++ front end doesn't always do it that way. */
15940 unshare_body (fndecl);
15941 unvisit_body (fndecl);
15943 /* Make sure input_location isn't set to something weird. */
15944 input_location = DECL_SOURCE_LOCATION (fndecl);
15946 /* Resolve callee-copies. This has to be done before processing
15947 the body so that DECL_VALUE_EXPR gets processed correctly. */
15948 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
15950 /* Gimplify the function's body. */
15951 seq = NULL;
15952 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
15953 outer_stmt = gimple_seq_first_nondebug_stmt (seq);
15954 if (!outer_stmt)
15956 outer_stmt = gimple_build_nop ();
15957 gimplify_seq_add_stmt (&seq, outer_stmt);
15960 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
15961 not the case, wrap everything in a GIMPLE_BIND to make it so. */
15962 if (gimple_code (outer_stmt) == GIMPLE_BIND
15963 && (gimple_seq_first_nondebug_stmt (seq)
15964 == gimple_seq_last_nondebug_stmt (seq)))
15966 outer_bind = as_a <gbind *> (outer_stmt);
15967 if (gimple_seq_first_stmt (seq) != outer_stmt
15968 || gimple_seq_last_stmt (seq) != outer_stmt)
15970 /* If there are debug stmts before or after outer_stmt, move them
15971 inside of outer_bind body. */
15972 gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
15973 gimple_seq second_seq = NULL;
15974 if (gimple_seq_first_stmt (seq) != outer_stmt
15975 && gimple_seq_last_stmt (seq) != outer_stmt)
15977 second_seq = gsi_split_seq_after (gsi);
15978 gsi_remove (&gsi, false);
15980 else if (gimple_seq_first_stmt (seq) != outer_stmt)
15981 gsi_remove (&gsi, false);
15982 else
15984 gsi_remove (&gsi, false);
15985 second_seq = seq;
15986 seq = NULL;
15988 gimple_seq_add_seq_without_update (&seq,
15989 gimple_bind_body (outer_bind));
15990 gimple_seq_add_seq_without_update (&seq, second_seq);
15991 gimple_bind_set_body (outer_bind, seq);
15994 else
15995 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
15997 DECL_SAVED_TREE (fndecl) = NULL_TREE;
15999 /* If we had callee-copies statements, insert them at the beginning
16000 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
16001 if (!gimple_seq_empty_p (parm_stmts))
16003 tree parm;
16005 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
16006 if (parm_cleanup)
16008 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
16009 GIMPLE_TRY_FINALLY);
16010 parm_stmts = NULL;
16011 gimple_seq_add_stmt (&parm_stmts, g);
16013 gimple_bind_set_body (outer_bind, parm_stmts);
16015 for (parm = DECL_ARGUMENTS (current_function_decl);
16016 parm; parm = DECL_CHAIN (parm))
16017 if (DECL_HAS_VALUE_EXPR_P (parm))
16019 DECL_HAS_VALUE_EXPR_P (parm) = 0;
16020 DECL_IGNORED_P (parm) = 0;
16024 if ((flag_openacc || flag_openmp || flag_openmp_simd)
16025 && gimplify_omp_ctxp)
16027 delete_omp_context (gimplify_omp_ctxp);
16028 gimplify_omp_ctxp = NULL;
16031 pop_gimplify_context (outer_bind);
16032 gcc_assert (gimplify_ctxp == NULL);
16034 if (flag_checking && !seen_error ())
16035 verify_gimple_in_seq (gimple_bind_body (outer_bind));
16037 timevar_pop (TV_TREE_GIMPLIFY);
16038 input_location = saved_location;
16040 return outer_bind;
16043 typedef char *char_p; /* For DEF_VEC_P. */
16045 /* Return whether we should exclude FNDECL from instrumentation. */
16047 static bool
16048 flag_instrument_functions_exclude_p (tree fndecl)
16050 vec<char_p> *v;
16052 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
16053 if (v && v->length () > 0)
16055 const char *name;
16056 int i;
16057 char *s;
16059 name = lang_hooks.decl_printable_name (fndecl, 1);
16060 FOR_EACH_VEC_ELT (*v, i, s)
16061 if (strstr (name, s) != NULL)
16062 return true;
16065 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
16066 if (v && v->length () > 0)
16068 const char *name;
16069 int i;
16070 char *s;
16072 name = DECL_SOURCE_FILE (fndecl);
16073 FOR_EACH_VEC_ELT (*v, i, s)
16074 if (strstr (name, s) != NULL)
16075 return true;
16078 return false;
16081 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
16082 node for the function we want to gimplify.
16084 Return the sequence of GIMPLE statements corresponding to the body
16085 of FNDECL. */
16087 void
16088 gimplify_function_tree (tree fndecl)
16090 gimple_seq seq;
16091 gbind *bind;
16093 gcc_assert (!gimple_body (fndecl));
16095 if (DECL_STRUCT_FUNCTION (fndecl))
16096 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
16097 else
16098 push_struct_function (fndecl);
16100 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
16101 if necessary. */
16102 cfun->curr_properties |= PROP_gimple_lva;
16104 if (asan_sanitize_use_after_scope ())
16105 asan_poisoned_variables = new hash_set<tree> ();
16106 bind = gimplify_body (fndecl, true);
16107 if (asan_poisoned_variables)
16109 delete asan_poisoned_variables;
16110 asan_poisoned_variables = NULL;
16113 /* The tree body of the function is no longer needed, replace it
16114 with the new GIMPLE body. */
16115 seq = NULL;
16116 gimple_seq_add_stmt (&seq, bind);
16117 gimple_set_body (fndecl, seq);
16119 /* If we're instrumenting function entry/exit, then prepend the call to
16120 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
16121 catch the exit hook. */
16122 /* ??? Add some way to ignore exceptions for this TFE. */
16123 if (flag_instrument_function_entry_exit
16124 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
16125 /* Do not instrument extern inline functions. */
16126 && !(DECL_DECLARED_INLINE_P (fndecl)
16127 && DECL_EXTERNAL (fndecl)
16128 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
16129 && !flag_instrument_functions_exclude_p (fndecl))
16131 tree x;
16132 gbind *new_bind;
16133 gimple *tf;
16134 gimple_seq cleanup = NULL, body = NULL;
16135 tree tmp_var, this_fn_addr;
16136 gcall *call;
16138 /* The instrumentation hooks aren't going to call the instrumented
16139 function and the address they receive is expected to be matchable
16140 against symbol addresses. Make sure we don't create a trampoline,
16141 in case the current function is nested. */
16142 this_fn_addr = build_fold_addr_expr (current_function_decl);
16143 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
16145 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
16146 call = gimple_build_call (x, 1, integer_zero_node);
16147 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
16148 gimple_call_set_lhs (call, tmp_var);
16149 gimplify_seq_add_stmt (&cleanup, call);
16150 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
16151 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
16152 gimplify_seq_add_stmt (&cleanup, call);
16153 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
16155 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
16156 call = gimple_build_call (x, 1, integer_zero_node);
16157 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
16158 gimple_call_set_lhs (call, tmp_var);
16159 gimplify_seq_add_stmt (&body, call);
16160 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
16161 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
16162 gimplify_seq_add_stmt (&body, call);
16163 gimplify_seq_add_stmt (&body, tf);
16164 new_bind = gimple_build_bind (NULL, body, NULL);
16166 /* Replace the current function body with the body
16167 wrapped in the try/finally TF. */
16168 seq = NULL;
16169 gimple_seq_add_stmt (&seq, new_bind);
16170 gimple_set_body (fndecl, seq);
16171 bind = new_bind;
16174 if (sanitize_flags_p (SANITIZE_THREAD)
16175 && param_tsan_instrument_func_entry_exit)
16177 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
16178 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
16179 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
16180 /* Replace the current function body with the body
16181 wrapped in the try/finally TF. */
16182 seq = NULL;
16183 gimple_seq_add_stmt (&seq, new_bind);
16184 gimple_set_body (fndecl, seq);
16187 DECL_SAVED_TREE (fndecl) = NULL_TREE;
16188 cfun->curr_properties |= PROP_gimple_any;
16190 pop_cfun ();
16192 dump_function (TDI_gimple, fndecl);
16195 /* Return a dummy expression of type TYPE in order to keep going after an
16196 error. */
16198 static tree
16199 dummy_object (tree type)
16201 tree t = build_int_cst (build_pointer_type (type), 0);
16202 return build2 (MEM_REF, type, t, t);
16205 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
16206 builtin function, but a very special sort of operator. */
16208 enum gimplify_status
16209 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
16210 gimple_seq *post_p ATTRIBUTE_UNUSED)
16212 tree promoted_type, have_va_type;
16213 tree valist = TREE_OPERAND (*expr_p, 0);
16214 tree type = TREE_TYPE (*expr_p);
16215 tree t, tag, aptag;
16216 location_t loc = EXPR_LOCATION (*expr_p);
16218 /* Verify that valist is of the proper type. */
16219 have_va_type = TREE_TYPE (valist);
16220 if (have_va_type == error_mark_node)
16221 return GS_ERROR;
16222 have_va_type = targetm.canonical_va_list_type (have_va_type);
16223 if (have_va_type == NULL_TREE
16224 && POINTER_TYPE_P (TREE_TYPE (valist)))
16225 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
16226 have_va_type
16227 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
16228 gcc_assert (have_va_type != NULL_TREE);
16230 /* Generate a diagnostic for requesting data of a type that cannot
16231 be passed through `...' due to type promotion at the call site. */
16232 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
16233 != type)
16235 static bool gave_help;
16236 bool warned;
16237 /* Use the expansion point to handle cases such as passing bool (defined
16238 in a system header) through `...'. */
16239 location_t xloc
16240 = expansion_point_location_if_in_system_header (loc);
16242 /* Unfortunately, this is merely undefined, rather than a constraint
16243 violation, so we cannot make this an error. If this call is never
16244 executed, the program is still strictly conforming. */
16245 auto_diagnostic_group d;
16246 warned = warning_at (xloc, 0,
16247 "%qT is promoted to %qT when passed through %<...%>",
16248 type, promoted_type);
16249 if (!gave_help && warned)
16251 gave_help = true;
16252 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
16253 promoted_type, type);
16256 /* We can, however, treat "undefined" any way we please.
16257 Call abort to encourage the user to fix the program. */
16258 if (warned)
16259 inform (xloc, "if this code is reached, the program will abort");
16260 /* Before the abort, allow the evaluation of the va_list
16261 expression to exit or longjmp. */
16262 gimplify_and_add (valist, pre_p);
16263 t = build_call_expr_loc (loc,
16264 builtin_decl_implicit (BUILT_IN_TRAP), 0);
16265 gimplify_and_add (t, pre_p);
16267 /* This is dead code, but go ahead and finish so that the
16268 mode of the result comes out right. */
16269 *expr_p = dummy_object (type);
16270 return GS_ALL_DONE;
16273 tag = build_int_cst (build_pointer_type (type), 0);
16274 aptag = build_int_cst (TREE_TYPE (valist), 0);
16276 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
16277 valist, tag, aptag);
16279 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
16280 needs to be expanded. */
16281 cfun->curr_properties &= ~PROP_gimple_lva;
16283 return GS_OK;
16286 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
16288 DST/SRC are the destination and source respectively. You can pass
16289 ungimplified trees in DST or SRC, in which case they will be
16290 converted to a gimple operand if necessary.
16292 This function returns the newly created GIMPLE_ASSIGN tuple. */
16294 gimple *
16295 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
16297 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
16298 gimplify_and_add (t, seq_p);
16299 ggc_free (t);
16300 return gimple_seq_last_stmt (*seq_p);
16303 inline hashval_t
16304 gimplify_hasher::hash (const elt_t *p)
16306 tree t = p->val;
16307 return iterative_hash_expr (t, 0);
16310 inline bool
16311 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
16313 tree t1 = p1->val;
16314 tree t2 = p2->val;
16315 enum tree_code code = TREE_CODE (t1);
16317 if (TREE_CODE (t2) != code
16318 || TREE_TYPE (t1) != TREE_TYPE (t2))
16319 return false;
16321 if (!operand_equal_p (t1, t2, 0))
16322 return false;
16324 /* Only allow them to compare equal if they also hash equal; otherwise
16325 results are nondeterminate, and we fail bootstrap comparison. */
16326 gcc_checking_assert (hash (p1) == hash (p2));
16328 return true;