Don't warn when alignment of global common data exceeds maximum alignment.
[official-gcc.git] / gcc / gimplify.c
blob070d0e4df45a6f8ba12c5edbf7790443d10931cb
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 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1747 and initialization explicit. */
1749 static enum gimplify_status
1750 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1752 tree stmt = *stmt_p;
1753 tree decl = DECL_EXPR_DECL (stmt);
1755 *stmt_p = NULL_TREE;
1757 if (TREE_TYPE (decl) == error_mark_node)
1758 return GS_ERROR;
1760 if ((TREE_CODE (decl) == TYPE_DECL
1761 || VAR_P (decl))
1762 && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1764 gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1765 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1766 gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1769 /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1770 in case its size expressions contain problematic nodes like CALL_EXPR. */
1771 if (TREE_CODE (decl) == TYPE_DECL
1772 && DECL_ORIGINAL_TYPE (decl)
1773 && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1775 gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1776 if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1777 gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1780 if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1782 tree init = DECL_INITIAL (decl);
1783 bool is_vla = false;
1785 poly_uint64 size;
1786 if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
1787 || (!TREE_STATIC (decl)
1788 && flag_stack_check == GENERIC_STACK_CHECK
1789 && maybe_gt (size,
1790 (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
1792 gimplify_vla_decl (decl, seq_p);
1793 is_vla = true;
1796 if (asan_poisoned_variables
1797 && !is_vla
1798 && TREE_ADDRESSABLE (decl)
1799 && !TREE_STATIC (decl)
1800 && !DECL_HAS_VALUE_EXPR_P (decl)
1801 && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
1802 && dbg_cnt (asan_use_after_scope)
1803 && !gimplify_omp_ctxp
1804 /* GNAT introduces temporaries to hold return values of calls in
1805 initializers of variables defined in other units, so the
1806 declaration of the variable is discarded completely. We do not
1807 want to issue poison calls for such dropped variables. */
1808 && (DECL_SEEN_IN_BIND_EXPR_P (decl)
1809 || (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)))
1811 asan_poisoned_variables->add (decl);
1812 asan_poison_variable (decl, false, seq_p);
1813 if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
1814 gimplify_ctxp->live_switch_vars->add (decl);
1817 /* Some front ends do not explicitly declare all anonymous
1818 artificial variables. We compensate here by declaring the
1819 variables, though it would be better if the front ends would
1820 explicitly declare them. */
1821 if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1822 && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1823 gimple_add_tmp_var (decl);
1825 if (init && init != error_mark_node)
1827 if (!TREE_STATIC (decl))
1829 DECL_INITIAL (decl) = NULL_TREE;
1830 init = build2 (INIT_EXPR, void_type_node, decl, init);
1831 gimplify_and_add (init, seq_p);
1832 ggc_free (init);
1833 /* Clear TREE_READONLY if we really have an initialization. */
1834 if (!DECL_INITIAL (decl) && !omp_is_reference (decl))
1835 TREE_READONLY (decl) = 0;
1837 else
1838 /* We must still examine initializers for static variables
1839 as they may contain a label address. */
1840 walk_tree (&init, force_labels_r, NULL, NULL);
1844 return GS_ALL_DONE;
1847 /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
1848 and replacing the LOOP_EXPR with goto, but if the loop contains an
1849 EXIT_EXPR, we need to append a label for it to jump to. */
1851 static enum gimplify_status
1852 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1854 tree saved_label = gimplify_ctxp->exit_label;
1855 tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1857 gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1859 gimplify_ctxp->exit_label = NULL_TREE;
1861 gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1863 gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
1865 if (gimplify_ctxp->exit_label)
1866 gimplify_seq_add_stmt (pre_p,
1867 gimple_build_label (gimplify_ctxp->exit_label));
1869 gimplify_ctxp->exit_label = saved_label;
1871 *expr_p = NULL;
1872 return GS_ALL_DONE;
1875 /* Gimplify a statement list onto a sequence. These may be created either
1876 by an enlightened front-end, or by shortcut_cond_expr. */
1878 static enum gimplify_status
1879 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
1881 tree temp = voidify_wrapper_expr (*expr_p, NULL);
1883 tree_stmt_iterator i = tsi_start (*expr_p);
1885 while (!tsi_end_p (i))
1887 gimplify_stmt (tsi_stmt_ptr (i), pre_p);
1888 tsi_delink (&i);
1891 if (temp)
1893 *expr_p = temp;
1894 return GS_OK;
1897 return GS_ALL_DONE;
1900 /* Callback for walk_gimple_seq. */
1902 static tree
1903 warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
1904 struct walk_stmt_info *wi)
1906 gimple *stmt = gsi_stmt (*gsi_p);
1908 *handled_ops_p = true;
1909 switch (gimple_code (stmt))
1911 case GIMPLE_TRY:
1912 /* A compiler-generated cleanup or a user-written try block.
1913 If it's empty, don't dive into it--that would result in
1914 worse location info. */
1915 if (gimple_try_eval (stmt) == NULL)
1917 wi->info = stmt;
1918 return integer_zero_node;
1920 /* Fall through. */
1921 case GIMPLE_BIND:
1922 case GIMPLE_CATCH:
1923 case GIMPLE_EH_FILTER:
1924 case GIMPLE_TRANSACTION:
1925 /* Walk the sub-statements. */
1926 *handled_ops_p = false;
1927 break;
1929 case GIMPLE_DEBUG:
1930 /* Ignore these. We may generate them before declarations that
1931 are never executed. If there's something to warn about,
1932 there will be non-debug stmts too, and we'll catch those. */
1933 break;
1935 case GIMPLE_CALL:
1936 if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
1938 *handled_ops_p = false;
1939 break;
1941 /* Fall through. */
1942 default:
1943 /* Save the first "real" statement (not a decl/lexical scope/...). */
1944 wi->info = stmt;
1945 return integer_zero_node;
1947 return NULL_TREE;
1950 /* Possibly warn about unreachable statements between switch's controlling
1951 expression and the first case. SEQ is the body of a switch expression. */
1953 static void
1954 maybe_warn_switch_unreachable (gimple_seq seq)
1956 if (!warn_switch_unreachable
1957 /* This warning doesn't play well with Fortran when optimizations
1958 are on. */
1959 || lang_GNU_Fortran ()
1960 || seq == NULL)
1961 return;
1963 struct walk_stmt_info wi;
1964 memset (&wi, 0, sizeof (wi));
1965 walk_gimple_seq (seq, warn_switch_unreachable_r, NULL, &wi);
1966 gimple *stmt = (gimple *) wi.info;
1968 if (stmt && gimple_code (stmt) != GIMPLE_LABEL)
1970 if (gimple_code (stmt) == GIMPLE_GOTO
1971 && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
1972 && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
1973 /* Don't warn for compiler-generated gotos. These occur
1974 in Duff's devices, for example. */;
1975 else
1976 warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
1977 "statement will never be executed");
1982 /* A label entry that pairs label and a location. */
1983 struct label_entry
1985 tree label;
1986 location_t loc;
1989 /* Find LABEL in vector of label entries VEC. */
1991 static struct label_entry *
1992 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
1994 unsigned int i;
1995 struct label_entry *l;
1997 FOR_EACH_VEC_ELT (*vec, i, l)
1998 if (l->label == label)
1999 return l;
2000 return NULL;
2003 /* Return true if LABEL, a LABEL_DECL, represents a case label
2004 in a vector of labels CASES. */
2006 static bool
2007 case_label_p (const vec<tree> *cases, tree label)
2009 unsigned int i;
2010 tree l;
2012 FOR_EACH_VEC_ELT (*cases, i, l)
2013 if (CASE_LABEL (l) == label)
2014 return true;
2015 return false;
2018 /* Find the last nondebug statement in a scope STMT. */
2020 static gimple *
2021 last_stmt_in_scope (gimple *stmt)
2023 if (!stmt)
2024 return NULL;
2026 switch (gimple_code (stmt))
2028 case GIMPLE_BIND:
2030 gbind *bind = as_a <gbind *> (stmt);
2031 stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
2032 return last_stmt_in_scope (stmt);
2035 case GIMPLE_TRY:
2037 gtry *try_stmt = as_a <gtry *> (stmt);
2038 stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
2039 gimple *last_eval = last_stmt_in_scope (stmt);
2040 if (gimple_stmt_may_fallthru (last_eval)
2041 && (last_eval == NULL
2042 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
2043 && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
2045 stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
2046 return last_stmt_in_scope (stmt);
2048 else
2049 return last_eval;
2052 case GIMPLE_DEBUG:
2053 gcc_unreachable ();
2055 default:
2056 return stmt;
2060 /* Collect interesting labels in LABELS and return the statement preceding
2061 another case label, or a user-defined label. Store a location useful
2062 to give warnings at *PREVLOC (usually the location of the returned
2063 statement or of its surrounding scope). */
2065 static gimple *
2066 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
2067 auto_vec <struct label_entry> *labels,
2068 location_t *prevloc)
2070 gimple *prev = NULL;
2072 *prevloc = UNKNOWN_LOCATION;
2075 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
2077 /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2078 which starts on a GIMPLE_SWITCH and ends with a break label.
2079 Handle that as a single statement that can fall through. */
2080 gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
2081 gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
2082 gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
2083 if (last
2084 && gimple_code (first) == GIMPLE_SWITCH
2085 && gimple_code (last) == GIMPLE_LABEL)
2087 tree label = gimple_label_label (as_a <glabel *> (last));
2088 if (SWITCH_BREAK_LABEL_P (label))
2090 prev = bind;
2091 gsi_next (gsi_p);
2092 continue;
2096 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
2097 || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
2099 /* Nested scope. Only look at the last statement of
2100 the innermost scope. */
2101 location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
2102 gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
2103 if (last)
2105 prev = last;
2106 /* It might be a label without a location. Use the
2107 location of the scope then. */
2108 if (!gimple_has_location (prev))
2109 *prevloc = bind_loc;
2111 gsi_next (gsi_p);
2112 continue;
2115 /* Ifs are tricky. */
2116 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
2118 gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
2119 tree false_lab = gimple_cond_false_label (cond_stmt);
2120 location_t if_loc = gimple_location (cond_stmt);
2122 /* If we have e.g.
2123 if (i > 1) goto <D.2259>; else goto D;
2124 we can't do much with the else-branch. */
2125 if (!DECL_ARTIFICIAL (false_lab))
2126 break;
2128 /* Go on until the false label, then one step back. */
2129 for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
2131 gimple *stmt = gsi_stmt (*gsi_p);
2132 if (gimple_code (stmt) == GIMPLE_LABEL
2133 && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
2134 break;
2137 /* Not found? Oops. */
2138 if (gsi_end_p (*gsi_p))
2139 break;
2141 struct label_entry l = { false_lab, if_loc };
2142 labels->safe_push (l);
2144 /* Go to the last statement of the then branch. */
2145 gsi_prev (gsi_p);
2147 /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2148 <D.1759>:
2149 <stmt>;
2150 goto <D.1761>;
2151 <D.1760>:
2153 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2154 && !gimple_has_location (gsi_stmt (*gsi_p)))
2156 /* Look at the statement before, it might be
2157 attribute fallthrough, in which case don't warn. */
2158 gsi_prev (gsi_p);
2159 bool fallthru_before_dest
2160 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2161 gsi_next (gsi_p);
2162 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2163 if (!fallthru_before_dest)
2165 struct label_entry l = { goto_dest, if_loc };
2166 labels->safe_push (l);
2169 /* And move back. */
2170 gsi_next (gsi_p);
2173 /* Remember the last statement. Skip labels that are of no interest
2174 to us. */
2175 if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2177 tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2178 if (find_label_entry (labels, label))
2179 prev = gsi_stmt (*gsi_p);
2181 else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2183 else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
2185 else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2186 prev = gsi_stmt (*gsi_p);
2187 gsi_next (gsi_p);
2189 while (!gsi_end_p (*gsi_p)
2190 /* Stop if we find a case or a user-defined label. */
2191 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2192 || !gimple_has_location (gsi_stmt (*gsi_p))));
2194 if (prev && gimple_has_location (prev))
2195 *prevloc = gimple_location (prev);
2196 return prev;
2199 /* Return true if the switch fallthough warning should occur. LABEL is
2200 the label statement that we're falling through to. */
2202 static bool
2203 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2205 gimple_stmt_iterator gsi = *gsi_p;
2207 /* Don't warn if the label is marked with a "falls through" comment. */
2208 if (FALLTHROUGH_LABEL_P (label))
2209 return false;
2211 /* Don't warn for non-case labels followed by a statement:
2212 case 0:
2213 foo ();
2214 label:
2215 bar ();
2216 as these are likely intentional. */
2217 if (!case_label_p (&gimplify_ctxp->case_labels, label))
2219 tree l;
2220 while (!gsi_end_p (gsi)
2221 && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2222 && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2223 && !case_label_p (&gimplify_ctxp->case_labels, l))
2224 gsi_next_nondebug (&gsi);
2225 if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2226 return false;
2229 /* Don't warn for terminated branches, i.e. when the subsequent case labels
2230 immediately breaks. */
2231 gsi = *gsi_p;
2233 /* Skip all immediately following labels. */
2234 while (!gsi_end_p (gsi)
2235 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2236 || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2237 gsi_next_nondebug (&gsi);
2239 /* { ... something; default:; } */
2240 if (gsi_end_p (gsi)
2241 /* { ... something; default: break; } or
2242 { ... something; default: goto L; } */
2243 || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2244 /* { ... something; default: return; } */
2245 || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2246 return false;
2248 return true;
2251 /* Callback for walk_gimple_seq. */
2253 static tree
2254 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2255 struct walk_stmt_info *)
2257 gimple *stmt = gsi_stmt (*gsi_p);
2259 *handled_ops_p = true;
2260 switch (gimple_code (stmt))
2262 case GIMPLE_TRY:
2263 case GIMPLE_BIND:
2264 case GIMPLE_CATCH:
2265 case GIMPLE_EH_FILTER:
2266 case GIMPLE_TRANSACTION:
2267 /* Walk the sub-statements. */
2268 *handled_ops_p = false;
2269 break;
2271 /* Find a sequence of form:
2273 GIMPLE_LABEL
2274 [...]
2275 <may fallthru stmt>
2276 GIMPLE_LABEL
2278 and possibly warn. */
2279 case GIMPLE_LABEL:
2281 /* Found a label. Skip all immediately following labels. */
2282 while (!gsi_end_p (*gsi_p)
2283 && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2284 gsi_next_nondebug (gsi_p);
2286 /* There might be no more statements. */
2287 if (gsi_end_p (*gsi_p))
2288 return integer_zero_node;
2290 /* Vector of labels that fall through. */
2291 auto_vec <struct label_entry> labels;
2292 location_t prevloc;
2293 gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
2295 /* There might be no more statements. */
2296 if (gsi_end_p (*gsi_p))
2297 return integer_zero_node;
2299 gimple *next = gsi_stmt (*gsi_p);
2300 tree label;
2301 /* If what follows is a label, then we may have a fallthrough. */
2302 if (gimple_code (next) == GIMPLE_LABEL
2303 && gimple_has_location (next)
2304 && (label = gimple_label_label (as_a <glabel *> (next)))
2305 && prev != NULL)
2307 struct label_entry *l;
2308 bool warned_p = false;
2309 auto_diagnostic_group d;
2310 if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2311 /* Quiet. */;
2312 else if (gimple_code (prev) == GIMPLE_LABEL
2313 && (label = gimple_label_label (as_a <glabel *> (prev)))
2314 && (l = find_label_entry (&labels, label)))
2315 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2316 "this statement may fall through");
2317 else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2318 /* Try to be clever and don't warn when the statement
2319 can't actually fall through. */
2320 && gimple_stmt_may_fallthru (prev)
2321 && prevloc != UNKNOWN_LOCATION)
2322 warned_p = warning_at (prevloc,
2323 OPT_Wimplicit_fallthrough_,
2324 "this statement may fall through");
2325 if (warned_p)
2326 inform (gimple_location (next), "here");
2328 /* Mark this label as processed so as to prevent multiple
2329 warnings in nested switches. */
2330 FALLTHROUGH_LABEL_P (label) = true;
2332 /* So that next warn_implicit_fallthrough_r will start looking for
2333 a new sequence starting with this label. */
2334 gsi_prev (gsi_p);
2337 break;
2338 default:
2339 break;
2341 return NULL_TREE;
2344 /* Warn when a switch case falls through. */
2346 static void
2347 maybe_warn_implicit_fallthrough (gimple_seq seq)
2349 if (!warn_implicit_fallthrough)
2350 return;
2352 /* This warning is meant for C/C++/ObjC/ObjC++ only. */
2353 if (!(lang_GNU_C ()
2354 || lang_GNU_CXX ()
2355 || lang_GNU_OBJC ()))
2356 return;
2358 struct walk_stmt_info wi;
2359 memset (&wi, 0, sizeof (wi));
2360 walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2363 /* Callback for walk_gimple_seq. */
2365 static tree
2366 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2367 struct walk_stmt_info *wi)
2369 gimple *stmt = gsi_stmt (*gsi_p);
2371 *handled_ops_p = true;
2372 switch (gimple_code (stmt))
2374 case GIMPLE_TRY:
2375 case GIMPLE_BIND:
2376 case GIMPLE_CATCH:
2377 case GIMPLE_EH_FILTER:
2378 case GIMPLE_TRANSACTION:
2379 /* Walk the sub-statements. */
2380 *handled_ops_p = false;
2381 break;
2382 case GIMPLE_CALL:
2383 if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2385 gsi_remove (gsi_p, true);
2386 if (gsi_end_p (*gsi_p))
2388 *static_cast<location_t *>(wi->info) = gimple_location (stmt);
2389 return integer_zero_node;
2392 bool found = false;
2393 location_t loc = gimple_location (stmt);
2395 gimple_stmt_iterator gsi2 = *gsi_p;
2396 stmt = gsi_stmt (gsi2);
2397 if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2399 /* Go on until the artificial label. */
2400 tree goto_dest = gimple_goto_dest (stmt);
2401 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2403 if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2404 && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2405 == goto_dest)
2406 break;
2409 /* Not found? Stop. */
2410 if (gsi_end_p (gsi2))
2411 break;
2413 /* Look one past it. */
2414 gsi_next (&gsi2);
2417 /* We're looking for a case label or default label here. */
2418 while (!gsi_end_p (gsi2))
2420 stmt = gsi_stmt (gsi2);
2421 if (gimple_code (stmt) == GIMPLE_LABEL)
2423 tree label = gimple_label_label (as_a <glabel *> (stmt));
2424 if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2426 found = true;
2427 break;
2430 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2432 else if (!is_gimple_debug (stmt))
2433 /* Anything else is not expected. */
2434 break;
2435 gsi_next (&gsi2);
2437 if (!found)
2438 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2439 "a case label or default label");
2441 break;
2442 default:
2443 break;
2445 return NULL_TREE;
2448 /* Expand all FALLTHROUGH () calls in SEQ. */
2450 static void
2451 expand_FALLTHROUGH (gimple_seq *seq_p)
2453 struct walk_stmt_info wi;
2454 location_t loc;
2455 memset (&wi, 0, sizeof (wi));
2456 wi.info = (void *) &loc;
2457 walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2458 if (wi.callback_result == integer_zero_node)
2459 /* We've found [[fallthrough]]; at the end of a switch, which the C++
2460 standard says is ill-formed; see [dcl.attr.fallthrough]. */
2461 pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2462 "a case label or default label");
2466 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2467 branch to. */
2469 static enum gimplify_status
2470 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2472 tree switch_expr = *expr_p;
2473 gimple_seq switch_body_seq = NULL;
2474 enum gimplify_status ret;
2475 tree index_type = TREE_TYPE (switch_expr);
2476 if (index_type == NULL_TREE)
2477 index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2479 ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2480 fb_rvalue);
2481 if (ret == GS_ERROR || ret == GS_UNHANDLED)
2482 return ret;
2484 if (SWITCH_BODY (switch_expr))
2486 vec<tree> labels;
2487 vec<tree> saved_labels;
2488 hash_set<tree> *saved_live_switch_vars = NULL;
2489 tree default_case = NULL_TREE;
2490 gswitch *switch_stmt;
2492 /* Save old labels, get new ones from body, then restore the old
2493 labels. Save all the things from the switch body to append after. */
2494 saved_labels = gimplify_ctxp->case_labels;
2495 gimplify_ctxp->case_labels.create (8);
2497 /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */
2498 saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2499 tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2500 if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2501 gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2502 else
2503 gimplify_ctxp->live_switch_vars = NULL;
2505 bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2506 gimplify_ctxp->in_switch_expr = true;
2508 gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2510 gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2511 maybe_warn_switch_unreachable (switch_body_seq);
2512 maybe_warn_implicit_fallthrough (switch_body_seq);
2513 /* Only do this for the outermost GIMPLE_SWITCH. */
2514 if (!gimplify_ctxp->in_switch_expr)
2515 expand_FALLTHROUGH (&switch_body_seq);
2517 labels = gimplify_ctxp->case_labels;
2518 gimplify_ctxp->case_labels = saved_labels;
2520 if (gimplify_ctxp->live_switch_vars)
2522 gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
2523 delete gimplify_ctxp->live_switch_vars;
2525 gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2527 preprocess_case_label_vec_for_gimple (labels, index_type,
2528 &default_case);
2530 bool add_bind = false;
2531 if (!default_case)
2533 glabel *new_default;
2535 default_case
2536 = build_case_label (NULL_TREE, NULL_TREE,
2537 create_artificial_label (UNKNOWN_LOCATION));
2538 if (old_in_switch_expr)
2540 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2541 add_bind = true;
2543 new_default = gimple_build_label (CASE_LABEL (default_case));
2544 gimplify_seq_add_stmt (&switch_body_seq, new_default);
2546 else if (old_in_switch_expr)
2548 gimple *last = gimple_seq_last_stmt (switch_body_seq);
2549 if (last && gimple_code (last) == GIMPLE_LABEL)
2551 tree label = gimple_label_label (as_a <glabel *> (last));
2552 if (SWITCH_BREAK_LABEL_P (label))
2553 add_bind = true;
2557 switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2558 default_case, labels);
2559 /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2560 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2561 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2562 so that we can easily find the start and end of the switch
2563 statement. */
2564 if (add_bind)
2566 gimple_seq bind_body = NULL;
2567 gimplify_seq_add_stmt (&bind_body, switch_stmt);
2568 gimple_seq_add_seq (&bind_body, switch_body_seq);
2569 gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
2570 gimple_set_location (bind, EXPR_LOCATION (switch_expr));
2571 gimplify_seq_add_stmt (pre_p, bind);
2573 else
2575 gimplify_seq_add_stmt (pre_p, switch_stmt);
2576 gimplify_seq_add_seq (pre_p, switch_body_seq);
2578 labels.release ();
2580 else
2581 gcc_unreachable ();
2583 return GS_ALL_DONE;
2586 /* Gimplify the LABEL_EXPR pointed to by EXPR_P. */
2588 static enum gimplify_status
2589 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2591 gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2592 == current_function_decl);
2594 tree label = LABEL_EXPR_LABEL (*expr_p);
2595 glabel *label_stmt = gimple_build_label (label);
2596 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2597 gimplify_seq_add_stmt (pre_p, label_stmt);
2599 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2600 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2601 NOT_TAKEN));
2602 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2603 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2604 TAKEN));
2606 return GS_ALL_DONE;
2609 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P. */
2611 static enum gimplify_status
2612 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2614 struct gimplify_ctx *ctxp;
2615 glabel *label_stmt;
2617 /* Invalid programs can play Duff's Device type games with, for example,
2618 #pragma omp parallel. At least in the C front end, we don't
2619 detect such invalid branches until after gimplification, in the
2620 diagnose_omp_blocks pass. */
2621 for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2622 if (ctxp->case_labels.exists ())
2623 break;
2625 tree label = CASE_LABEL (*expr_p);
2626 label_stmt = gimple_build_label (label);
2627 gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2628 ctxp->case_labels.safe_push (*expr_p);
2629 gimplify_seq_add_stmt (pre_p, label_stmt);
2631 if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2632 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2633 NOT_TAKEN));
2634 else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2635 gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2636 TAKEN));
2638 return GS_ALL_DONE;
2641 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2642 if necessary. */
2644 tree
2645 build_and_jump (tree *label_p)
2647 if (label_p == NULL)
2648 /* If there's nowhere to jump, just fall through. */
2649 return NULL_TREE;
2651 if (*label_p == NULL_TREE)
2653 tree label = create_artificial_label (UNKNOWN_LOCATION);
2654 *label_p = label;
2657 return build1 (GOTO_EXPR, void_type_node, *label_p);
2660 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2661 This also involves building a label to jump to and communicating it to
2662 gimplify_loop_expr through gimplify_ctxp->exit_label. */
2664 static enum gimplify_status
2665 gimplify_exit_expr (tree *expr_p)
2667 tree cond = TREE_OPERAND (*expr_p, 0);
2668 tree expr;
2670 expr = build_and_jump (&gimplify_ctxp->exit_label);
2671 expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2672 *expr_p = expr;
2674 return GS_OK;
2677 /* *EXPR_P is a COMPONENT_REF being used as an rvalue. If its type is
2678 different from its canonical type, wrap the whole thing inside a
2679 NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2680 type.
2682 The canonical type of a COMPONENT_REF is the type of the field being
2683 referenced--unless the field is a bit-field which can be read directly
2684 in a smaller mode, in which case the canonical type is the
2685 sign-appropriate type corresponding to that mode. */
2687 static void
2688 canonicalize_component_ref (tree *expr_p)
2690 tree expr = *expr_p;
2691 tree type;
2693 gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2695 if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2696 type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2697 else
2698 type = TREE_TYPE (TREE_OPERAND (expr, 1));
2700 /* One could argue that all the stuff below is not necessary for
2701 the non-bitfield case and declare it a FE error if type
2702 adjustment would be needed. */
2703 if (TREE_TYPE (expr) != type)
2705 #ifdef ENABLE_TYPES_CHECKING
2706 tree old_type = TREE_TYPE (expr);
2707 #endif
2708 int type_quals;
2710 /* We need to preserve qualifiers and propagate them from
2711 operand 0. */
2712 type_quals = TYPE_QUALS (type)
2713 | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2714 if (TYPE_QUALS (type) != type_quals)
2715 type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2717 /* Set the type of the COMPONENT_REF to the underlying type. */
2718 TREE_TYPE (expr) = type;
2720 #ifdef ENABLE_TYPES_CHECKING
2721 /* It is now a FE error, if the conversion from the canonical
2722 type to the original expression type is not useless. */
2723 gcc_assert (useless_type_conversion_p (old_type, type));
2724 #endif
2728 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2729 to foo, embed that change in the ADDR_EXPR by converting
2730 T array[U];
2731 (T *)&array
2733 &array[L]
2734 where L is the lower bound. For simplicity, only do this for constant
2735 lower bound.
2736 The constraint is that the type of &array[L] is trivially convertible
2737 to T *. */
2739 static void
2740 canonicalize_addr_expr (tree *expr_p)
2742 tree expr = *expr_p;
2743 tree addr_expr = TREE_OPERAND (expr, 0);
2744 tree datype, ddatype, pddatype;
2746 /* We simplify only conversions from an ADDR_EXPR to a pointer type. */
2747 if (!POINTER_TYPE_P (TREE_TYPE (expr))
2748 || TREE_CODE (addr_expr) != ADDR_EXPR)
2749 return;
2751 /* The addr_expr type should be a pointer to an array. */
2752 datype = TREE_TYPE (TREE_TYPE (addr_expr));
2753 if (TREE_CODE (datype) != ARRAY_TYPE)
2754 return;
2756 /* The pointer to element type shall be trivially convertible to
2757 the expression pointer type. */
2758 ddatype = TREE_TYPE (datype);
2759 pddatype = build_pointer_type (ddatype);
2760 if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2761 pddatype))
2762 return;
2764 /* The lower bound and element sizes must be constant. */
2765 if (!TYPE_SIZE_UNIT (ddatype)
2766 || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2767 || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2768 || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2769 return;
2771 /* All checks succeeded. Build a new node to merge the cast. */
2772 *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2773 TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2774 NULL_TREE, NULL_TREE);
2775 *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2777 /* We can have stripped a required restrict qualifier above. */
2778 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2779 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2782 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions
2783 underneath as appropriate. */
2785 static enum gimplify_status
2786 gimplify_conversion (tree *expr_p)
2788 location_t loc = EXPR_LOCATION (*expr_p);
2789 gcc_assert (CONVERT_EXPR_P (*expr_p));
2791 /* Then strip away all but the outermost conversion. */
2792 STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
2794 /* And remove the outermost conversion if it's useless. */
2795 if (tree_ssa_useless_type_conversion (*expr_p))
2796 *expr_p = TREE_OPERAND (*expr_p, 0);
2798 /* If we still have a conversion at the toplevel,
2799 then canonicalize some constructs. */
2800 if (CONVERT_EXPR_P (*expr_p))
2802 tree sub = TREE_OPERAND (*expr_p, 0);
2804 /* If a NOP conversion is changing the type of a COMPONENT_REF
2805 expression, then canonicalize its type now in order to expose more
2806 redundant conversions. */
2807 if (TREE_CODE (sub) == COMPONENT_REF)
2808 canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
2810 /* If a NOP conversion is changing a pointer to array of foo
2811 to a pointer to foo, embed that change in the ADDR_EXPR. */
2812 else if (TREE_CODE (sub) == ADDR_EXPR)
2813 canonicalize_addr_expr (expr_p);
2816 /* If we have a conversion to a non-register type force the
2817 use of a VIEW_CONVERT_EXPR instead. */
2818 if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
2819 *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
2820 TREE_OPERAND (*expr_p, 0));
2822 /* Canonicalize CONVERT_EXPR to NOP_EXPR. */
2823 if (TREE_CODE (*expr_p) == CONVERT_EXPR)
2824 TREE_SET_CODE (*expr_p, NOP_EXPR);
2826 return GS_OK;
2829 /* Gimplify a VAR_DECL or PARM_DECL. Return GS_OK if we expanded a
2830 DECL_VALUE_EXPR, and it's worth re-examining things. */
2832 static enum gimplify_status
2833 gimplify_var_or_parm_decl (tree *expr_p)
2835 tree decl = *expr_p;
2837 /* ??? If this is a local variable, and it has not been seen in any
2838 outer BIND_EXPR, then it's probably the result of a duplicate
2839 declaration, for which we've already issued an error. It would
2840 be really nice if the front end wouldn't leak these at all.
2841 Currently the only known culprit is C++ destructors, as seen
2842 in g++.old-deja/g++.jason/binding.C. */
2843 if (VAR_P (decl)
2844 && !DECL_SEEN_IN_BIND_EXPR_P (decl)
2845 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
2846 && decl_function_context (decl) == current_function_decl)
2848 gcc_assert (seen_error ());
2849 return GS_ERROR;
2852 /* When within an OMP context, notice uses of variables. */
2853 if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
2854 return GS_ALL_DONE;
2856 /* If the decl is an alias for another expression, substitute it now. */
2857 if (DECL_HAS_VALUE_EXPR_P (decl))
2859 *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
2860 return GS_OK;
2863 return GS_ALL_DONE;
2866 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T. */
2868 static void
2869 recalculate_side_effects (tree t)
2871 enum tree_code code = TREE_CODE (t);
2872 int len = TREE_OPERAND_LENGTH (t);
2873 int i;
2875 switch (TREE_CODE_CLASS (code))
2877 case tcc_expression:
2878 switch (code)
2880 case INIT_EXPR:
2881 case MODIFY_EXPR:
2882 case VA_ARG_EXPR:
2883 case PREDECREMENT_EXPR:
2884 case PREINCREMENT_EXPR:
2885 case POSTDECREMENT_EXPR:
2886 case POSTINCREMENT_EXPR:
2887 /* All of these have side-effects, no matter what their
2888 operands are. */
2889 return;
2891 default:
2892 break;
2894 /* Fall through. */
2896 case tcc_comparison: /* a comparison expression */
2897 case tcc_unary: /* a unary arithmetic expression */
2898 case tcc_binary: /* a binary arithmetic expression */
2899 case tcc_reference: /* a reference */
2900 case tcc_vl_exp: /* a function call */
2901 TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
2902 for (i = 0; i < len; ++i)
2904 tree op = TREE_OPERAND (t, i);
2905 if (op && TREE_SIDE_EFFECTS (op))
2906 TREE_SIDE_EFFECTS (t) = 1;
2908 break;
2910 case tcc_constant:
2911 /* No side-effects. */
2912 return;
2914 default:
2915 gcc_unreachable ();
2919 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
2920 node *EXPR_P.
2922 compound_lval
2923 : min_lval '[' val ']'
2924 | min_lval '.' ID
2925 | compound_lval '[' val ']'
2926 | compound_lval '.' ID
2928 This is not part of the original SIMPLE definition, which separates
2929 array and member references, but it seems reasonable to handle them
2930 together. Also, this way we don't run into problems with union
2931 aliasing; gcc requires that for accesses through a union to alias, the
2932 union reference must be explicit, which was not always the case when we
2933 were splitting up array and member refs.
2935 PRE_P points to the sequence where side effects that must happen before
2936 *EXPR_P should be stored.
2938 POST_P points to the sequence where side effects that must happen after
2939 *EXPR_P should be stored. */
2941 static enum gimplify_status
2942 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
2943 fallback_t fallback)
2945 tree *p;
2946 enum gimplify_status ret = GS_ALL_DONE, tret;
2947 int i;
2948 location_t loc = EXPR_LOCATION (*expr_p);
2949 tree expr = *expr_p;
2951 /* Create a stack of the subexpressions so later we can walk them in
2952 order from inner to outer. */
2953 auto_vec<tree, 10> expr_stack;
2955 /* We can handle anything that get_inner_reference can deal with. */
2956 for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
2958 restart:
2959 /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs. */
2960 if (TREE_CODE (*p) == INDIRECT_REF)
2961 *p = fold_indirect_ref_loc (loc, *p);
2963 if (handled_component_p (*p))
2965 /* Expand DECL_VALUE_EXPR now. In some cases that may expose
2966 additional COMPONENT_REFs. */
2967 else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
2968 && gimplify_var_or_parm_decl (p) == GS_OK)
2969 goto restart;
2970 else
2971 break;
2973 expr_stack.safe_push (*p);
2976 gcc_assert (expr_stack.length ());
2978 /* Now EXPR_STACK is a stack of pointers to all the refs we've
2979 walked through and P points to the innermost expression.
2981 Java requires that we elaborated nodes in source order. That
2982 means we must gimplify the inner expression followed by each of
2983 the indices, in order. But we can't gimplify the inner
2984 expression until we deal with any variable bounds, sizes, or
2985 positions in order to deal with PLACEHOLDER_EXPRs.
2987 So we do this in three steps. First we deal with the annotations
2988 for any variables in the components, then we gimplify the base,
2989 then we gimplify any indices, from left to right. */
2990 for (i = expr_stack.length () - 1; i >= 0; i--)
2992 tree t = expr_stack[i];
2994 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
2996 /* Gimplify the low bound and element type size and put them into
2997 the ARRAY_REF. If these values are set, they have already been
2998 gimplified. */
2999 if (TREE_OPERAND (t, 2) == NULL_TREE)
3001 tree low = unshare_expr (array_ref_low_bound (t));
3002 if (!is_gimple_min_invariant (low))
3004 TREE_OPERAND (t, 2) = low;
3005 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
3006 post_p, is_gimple_reg,
3007 fb_rvalue);
3008 ret = MIN (ret, tret);
3011 else
3013 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3014 is_gimple_reg, fb_rvalue);
3015 ret = MIN (ret, tret);
3018 if (TREE_OPERAND (t, 3) == NULL_TREE)
3020 tree elmt_size = array_ref_element_size (t);
3021 if (!is_gimple_min_invariant (elmt_size))
3023 elmt_size = unshare_expr (elmt_size);
3024 tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
3025 tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
3027 /* Divide the element size by the alignment of the element
3028 type (above). */
3029 elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR,
3030 elmt_size, factor);
3032 TREE_OPERAND (t, 3) = elmt_size;
3033 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
3034 post_p, is_gimple_reg,
3035 fb_rvalue);
3036 ret = MIN (ret, tret);
3039 else
3041 tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
3042 is_gimple_reg, fb_rvalue);
3043 ret = MIN (ret, tret);
3046 else if (TREE_CODE (t) == COMPONENT_REF)
3048 /* Set the field offset into T and gimplify it. */
3049 if (TREE_OPERAND (t, 2) == NULL_TREE)
3051 tree offset = component_ref_field_offset (t);
3052 if (!is_gimple_min_invariant (offset))
3054 offset = unshare_expr (offset);
3055 tree field = TREE_OPERAND (t, 1);
3056 tree factor
3057 = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
3059 /* Divide the offset by its alignment. */
3060 offset = size_binop_loc (loc, EXACT_DIV_EXPR,
3061 offset, factor);
3063 TREE_OPERAND (t, 2) = offset;
3064 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
3065 post_p, is_gimple_reg,
3066 fb_rvalue);
3067 ret = MIN (ret, tret);
3070 else
3072 tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3073 is_gimple_reg, fb_rvalue);
3074 ret = MIN (ret, tret);
3079 /* Step 2 is to gimplify the base expression. Make sure lvalue is set
3080 so as to match the min_lval predicate. Failure to do so may result
3081 in the creation of large aggregate temporaries. */
3082 tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
3083 fallback | fb_lvalue);
3084 ret = MIN (ret, tret);
3086 /* And finally, the indices and operands of ARRAY_REF. During this
3087 loop we also remove any useless conversions. */
3088 for (; expr_stack.length () > 0; )
3090 tree t = expr_stack.pop ();
3092 if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3094 /* Gimplify the dimension. */
3095 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
3097 tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
3098 is_gimple_val, fb_rvalue);
3099 ret = MIN (ret, tret);
3103 STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
3105 /* The innermost expression P may have originally had
3106 TREE_SIDE_EFFECTS set which would have caused all the outer
3107 expressions in *EXPR_P leading to P to also have had
3108 TREE_SIDE_EFFECTS set. */
3109 recalculate_side_effects (t);
3112 /* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
3113 if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
3115 canonicalize_component_ref (expr_p);
3118 expr_stack.release ();
3120 gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
3122 return ret;
3125 /* Gimplify the self modifying expression pointed to by EXPR_P
3126 (++, --, +=, -=).
3128 PRE_P points to the list where side effects that must happen before
3129 *EXPR_P should be stored.
3131 POST_P points to the list where side effects that must happen after
3132 *EXPR_P should be stored.
3134 WANT_VALUE is nonzero iff we want to use the value of this expression
3135 in another expression.
3137 ARITH_TYPE is the type the computation should be performed in. */
3139 enum gimplify_status
3140 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3141 bool want_value, tree arith_type)
3143 enum tree_code code;
3144 tree lhs, lvalue, rhs, t1;
3145 gimple_seq post = NULL, *orig_post_p = post_p;
3146 bool postfix;
3147 enum tree_code arith_code;
3148 enum gimplify_status ret;
3149 location_t loc = EXPR_LOCATION (*expr_p);
3151 code = TREE_CODE (*expr_p);
3153 gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3154 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3156 /* Prefix or postfix? */
3157 if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3158 /* Faster to treat as prefix if result is not used. */
3159 postfix = want_value;
3160 else
3161 postfix = false;
3163 /* For postfix, make sure the inner expression's post side effects
3164 are executed after side effects from this expression. */
3165 if (postfix)
3166 post_p = &post;
3168 /* Add or subtract? */
3169 if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3170 arith_code = PLUS_EXPR;
3171 else
3172 arith_code = MINUS_EXPR;
3174 /* Gimplify the LHS into a GIMPLE lvalue. */
3175 lvalue = TREE_OPERAND (*expr_p, 0);
3176 ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3177 if (ret == GS_ERROR)
3178 return ret;
3180 /* Extract the operands to the arithmetic operation. */
3181 lhs = lvalue;
3182 rhs = TREE_OPERAND (*expr_p, 1);
3184 /* For postfix operator, we evaluate the LHS to an rvalue and then use
3185 that as the result value and in the postqueue operation. */
3186 if (postfix)
3188 ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3189 if (ret == GS_ERROR)
3190 return ret;
3192 lhs = get_initialized_tmp_var (lhs, pre_p);
3195 /* For POINTERs increment, use POINTER_PLUS_EXPR. */
3196 if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3198 rhs = convert_to_ptrofftype_loc (loc, rhs);
3199 if (arith_code == MINUS_EXPR)
3200 rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3201 t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3203 else
3204 t1 = fold_convert (TREE_TYPE (*expr_p),
3205 fold_build2 (arith_code, arith_type,
3206 fold_convert (arith_type, lhs),
3207 fold_convert (arith_type, rhs)));
3209 if (postfix)
3211 gimplify_assign (lvalue, t1, pre_p);
3212 gimplify_seq_add_seq (orig_post_p, post);
3213 *expr_p = lhs;
3214 return GS_ALL_DONE;
3216 else
3218 *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3219 return GS_OK;
3223 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
3225 static void
3226 maybe_with_size_expr (tree *expr_p)
3228 tree expr = *expr_p;
3229 tree type = TREE_TYPE (expr);
3230 tree size;
3232 /* If we've already wrapped this or the type is error_mark_node, we can't do
3233 anything. */
3234 if (TREE_CODE (expr) == WITH_SIZE_EXPR
3235 || type == error_mark_node)
3236 return;
3238 /* If the size isn't known or is a constant, we have nothing to do. */
3239 size = TYPE_SIZE_UNIT (type);
3240 if (!size || poly_int_tree_p (size))
3241 return;
3243 /* Otherwise, make a WITH_SIZE_EXPR. */
3244 size = unshare_expr (size);
3245 size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3246 *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3249 /* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
3250 Store any side-effects in PRE_P. CALL_LOCATION is the location of
3251 the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
3252 gimplified to an SSA name. */
3254 enum gimplify_status
3255 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3256 bool allow_ssa)
3258 bool (*test) (tree);
3259 fallback_t fb;
3261 /* In general, we allow lvalues for function arguments to avoid
3262 extra overhead of copying large aggregates out of even larger
3263 aggregates into temporaries only to copy the temporaries to
3264 the argument list. Make optimizers happy by pulling out to
3265 temporaries those types that fit in registers. */
3266 if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3267 test = is_gimple_val, fb = fb_rvalue;
3268 else
3270 test = is_gimple_lvalue, fb = fb_either;
3271 /* Also strip a TARGET_EXPR that would force an extra copy. */
3272 if (TREE_CODE (*arg_p) == TARGET_EXPR)
3274 tree init = TARGET_EXPR_INITIAL (*arg_p);
3275 if (init
3276 && !VOID_TYPE_P (TREE_TYPE (init)))
3277 *arg_p = init;
3281 /* If this is a variable sized type, we must remember the size. */
3282 maybe_with_size_expr (arg_p);
3284 /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
3285 /* Make sure arguments have the same location as the function call
3286 itself. */
3287 protected_set_expr_location (*arg_p, call_location);
3289 /* There is a sequence point before a function call. Side effects in
3290 the argument list must occur before the actual call. So, when
3291 gimplifying arguments, force gimplify_expr to use an internal
3292 post queue which is then appended to the end of PRE_P. */
3293 return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3296 /* Don't fold inside offloading or taskreg regions: it can break code by
3297 adding decl references that weren't in the source. We'll do it during
3298 omplower pass instead. */
3300 static bool
3301 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3303 struct gimplify_omp_ctx *ctx;
3304 for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3305 if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3306 return false;
3307 else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3308 return false;
3309 /* Delay folding of builtins until the IL is in consistent state
3310 so the diagnostic machinery can do a better job. */
3311 if (gimple_call_builtin_p (gsi_stmt (*gsi)))
3312 return false;
3313 return fold_stmt (gsi);
3316 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3317 WANT_VALUE is true if the result of the call is desired. */
3319 static enum gimplify_status
3320 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3322 tree fndecl, parms, p, fnptrtype;
3323 enum gimplify_status ret;
3324 int i, nargs;
3325 gcall *call;
3326 bool builtin_va_start_p = false;
3327 location_t loc = EXPR_LOCATION (*expr_p);
3329 gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3331 /* For reliable diagnostics during inlining, it is necessary that
3332 every call_expr be annotated with file and line. */
3333 if (! EXPR_HAS_LOCATION (*expr_p))
3334 SET_EXPR_LOCATION (*expr_p, input_location);
3336 /* Gimplify internal functions created in the FEs. */
3337 if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3339 if (want_value)
3340 return GS_ALL_DONE;
3342 nargs = call_expr_nargs (*expr_p);
3343 enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3344 auto_vec<tree> vargs (nargs);
3346 for (i = 0; i < nargs; i++)
3348 gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3349 EXPR_LOCATION (*expr_p));
3350 vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3353 gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3354 gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3355 gimplify_seq_add_stmt (pre_p, call);
3356 return GS_ALL_DONE;
3359 /* This may be a call to a builtin function.
3361 Builtin function calls may be transformed into different
3362 (and more efficient) builtin function calls under certain
3363 circumstances. Unfortunately, gimplification can muck things
3364 up enough that the builtin expanders are not aware that certain
3365 transformations are still valid.
3367 So we attempt transformation/gimplification of the call before
3368 we gimplify the CALL_EXPR. At this time we do not manage to
3369 transform all calls in the same manner as the expanders do, but
3370 we do transform most of them. */
3371 fndecl = get_callee_fndecl (*expr_p);
3372 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3373 switch (DECL_FUNCTION_CODE (fndecl))
3375 CASE_BUILT_IN_ALLOCA:
3376 /* If the call has been built for a variable-sized object, then we
3377 want to restore the stack level when the enclosing BIND_EXPR is
3378 exited to reclaim the allocated space; otherwise, we precisely
3379 need to do the opposite and preserve the latest stack level. */
3380 if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3381 gimplify_ctxp->save_stack = true;
3382 else
3383 gimplify_ctxp->keep_stack = true;
3384 break;
3386 case BUILT_IN_VA_START:
3388 builtin_va_start_p = TRUE;
3389 if (call_expr_nargs (*expr_p) < 2)
3391 error ("too few arguments to function %<va_start%>");
3392 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3393 return GS_OK;
3396 if (fold_builtin_next_arg (*expr_p, true))
3398 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3399 return GS_OK;
3401 break;
3404 case BUILT_IN_EH_RETURN:
3405 cfun->calls_eh_return = true;
3406 break;
3408 case BUILT_IN_CLEAR_PADDING:
3409 if (call_expr_nargs (*expr_p) == 1)
3411 /* Remember the original type of the argument in an internal
3412 dummy second argument, as in GIMPLE pointer conversions are
3413 useless. */
3414 p = CALL_EXPR_ARG (*expr_p, 0);
3415 *expr_p
3416 = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p,
3417 build_zero_cst (TREE_TYPE (p)));
3418 return GS_OK;
3420 break;
3422 default:
3425 if (fndecl && fndecl_built_in_p (fndecl))
3427 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3428 if (new_tree && new_tree != *expr_p)
3430 /* There was a transformation of this call which computes the
3431 same value, but in a more efficient way. Return and try
3432 again. */
3433 *expr_p = new_tree;
3434 return GS_OK;
3438 /* Remember the original function pointer type. */
3439 fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3441 if (flag_openmp
3442 && fndecl
3443 && cfun
3444 && (cfun->curr_properties & PROP_gimple_any) == 0)
3446 tree variant = omp_resolve_declare_variant (fndecl);
3447 if (variant != fndecl)
3448 CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
3451 /* There is a sequence point before the call, so any side effects in
3452 the calling expression must occur before the actual call. Force
3453 gimplify_expr to use an internal post queue. */
3454 ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3455 is_gimple_call_addr, fb_rvalue);
3457 nargs = call_expr_nargs (*expr_p);
3459 /* Get argument types for verification. */
3460 fndecl = get_callee_fndecl (*expr_p);
3461 parms = NULL_TREE;
3462 if (fndecl)
3463 parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3464 else
3465 parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3467 if (fndecl && DECL_ARGUMENTS (fndecl))
3468 p = DECL_ARGUMENTS (fndecl);
3469 else if (parms)
3470 p = parms;
3471 else
3472 p = NULL_TREE;
3473 for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3476 /* If the last argument is __builtin_va_arg_pack () and it is not
3477 passed as a named argument, decrease the number of CALL_EXPR
3478 arguments and set instead the CALL_EXPR_VA_ARG_PACK flag. */
3479 if (!p
3480 && i < nargs
3481 && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3483 tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3484 tree last_arg_fndecl = get_callee_fndecl (last_arg);
3486 if (last_arg_fndecl
3487 && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3489 tree call = *expr_p;
3491 --nargs;
3492 *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3493 CALL_EXPR_FN (call),
3494 nargs, CALL_EXPR_ARGP (call));
3496 /* Copy all CALL_EXPR flags, location and block, except
3497 CALL_EXPR_VA_ARG_PACK flag. */
3498 CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3499 CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3500 CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3501 = CALL_EXPR_RETURN_SLOT_OPT (call);
3502 CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3503 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3505 /* Set CALL_EXPR_VA_ARG_PACK. */
3506 CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3510 /* If the call returns twice then after building the CFG the call
3511 argument computations will no longer dominate the call because
3512 we add an abnormal incoming edge to the call. So do not use SSA
3513 vars there. */
3514 bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3516 /* Gimplify the function arguments. */
3517 if (nargs > 0)
3519 for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3520 PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3521 PUSH_ARGS_REVERSED ? i-- : i++)
3523 enum gimplify_status t;
3525 /* Avoid gimplifying the second argument to va_start, which needs to
3526 be the plain PARM_DECL. */
3527 if ((i != 1) || !builtin_va_start_p)
3529 t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3530 EXPR_LOCATION (*expr_p), ! returns_twice);
3532 if (t == GS_ERROR)
3533 ret = GS_ERROR;
3538 /* Gimplify the static chain. */
3539 if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3541 if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3542 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3543 else
3545 enum gimplify_status t;
3546 t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3547 EXPR_LOCATION (*expr_p), ! returns_twice);
3548 if (t == GS_ERROR)
3549 ret = GS_ERROR;
3553 /* Verify the function result. */
3554 if (want_value && fndecl
3555 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3557 error_at (loc, "using result of function returning %<void%>");
3558 ret = GS_ERROR;
3561 /* Try this again in case gimplification exposed something. */
3562 if (ret != GS_ERROR)
3564 tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3566 if (new_tree && new_tree != *expr_p)
3568 /* There was a transformation of this call which computes the
3569 same value, but in a more efficient way. Return and try
3570 again. */
3571 *expr_p = new_tree;
3572 return GS_OK;
3575 else
3577 *expr_p = error_mark_node;
3578 return GS_ERROR;
3581 /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3582 decl. This allows us to eliminate redundant or useless
3583 calls to "const" functions. */
3584 if (TREE_CODE (*expr_p) == CALL_EXPR)
3586 int flags = call_expr_flags (*expr_p);
3587 if (flags & (ECF_CONST | ECF_PURE)
3588 /* An infinite loop is considered a side effect. */
3589 && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3590 TREE_SIDE_EFFECTS (*expr_p) = 0;
3593 /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3594 and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
3595 form and delegate the creation of a GIMPLE_CALL to
3596 gimplify_modify_expr. This is always possible because when
3597 WANT_VALUE is true, the caller wants the result of this call into
3598 a temporary, which means that we will emit an INIT_EXPR in
3599 internal_get_tmp_var which will then be handled by
3600 gimplify_modify_expr. */
3601 if (!want_value)
3603 /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3604 have to do is replicate it as a GIMPLE_CALL tuple. */
3605 gimple_stmt_iterator gsi;
3606 call = gimple_build_call_from_tree (*expr_p, fnptrtype);
3607 notice_special_calls (call);
3608 gimplify_seq_add_stmt (pre_p, call);
3609 gsi = gsi_last (*pre_p);
3610 maybe_fold_stmt (&gsi);
3611 *expr_p = NULL_TREE;
3613 else
3614 /* Remember the original function type. */
3615 CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3616 CALL_EXPR_FN (*expr_p));
3618 return ret;
3621 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3622 rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3624 TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3625 condition is true or false, respectively. If null, we should generate
3626 our own to skip over the evaluation of this specific expression.
3628 LOCUS is the source location of the COND_EXPR.
3630 This function is the tree equivalent of do_jump.
3632 shortcut_cond_r should only be called by shortcut_cond_expr. */
3634 static tree
3635 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3636 location_t locus)
3638 tree local_label = NULL_TREE;
3639 tree t, expr = NULL;
3641 /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3642 retain the shortcut semantics. Just insert the gotos here;
3643 shortcut_cond_expr will append the real blocks later. */
3644 if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3646 location_t new_locus;
3648 /* Turn if (a && b) into
3650 if (a); else goto no;
3651 if (b) goto yes; else goto no;
3652 (no:) */
3654 if (false_label_p == NULL)
3655 false_label_p = &local_label;
3657 /* Keep the original source location on the first 'if'. */
3658 t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3659 append_to_statement_list (t, &expr);
3661 /* Set the source location of the && on the second 'if'. */
3662 new_locus = rexpr_location (pred, locus);
3663 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3664 new_locus);
3665 append_to_statement_list (t, &expr);
3667 else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3669 location_t new_locus;
3671 /* Turn if (a || b) into
3673 if (a) goto yes;
3674 if (b) goto yes; else goto no;
3675 (yes:) */
3677 if (true_label_p == NULL)
3678 true_label_p = &local_label;
3680 /* Keep the original source location on the first 'if'. */
3681 t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3682 append_to_statement_list (t, &expr);
3684 /* Set the source location of the || on the second 'if'. */
3685 new_locus = rexpr_location (pred, locus);
3686 t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3687 new_locus);
3688 append_to_statement_list (t, &expr);
3690 else if (TREE_CODE (pred) == COND_EXPR
3691 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3692 && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3694 location_t new_locus;
3696 /* As long as we're messing with gotos, turn if (a ? b : c) into
3697 if (a)
3698 if (b) goto yes; else goto no;
3699 else
3700 if (c) goto yes; else goto no;
3702 Don't do this if one of the arms has void type, which can happen
3703 in C++ when the arm is throw. */
3705 /* Keep the original source location on the first 'if'. Set the source
3706 location of the ? on the second 'if'. */
3707 new_locus = rexpr_location (pred, locus);
3708 expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3709 shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3710 false_label_p, locus),
3711 shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3712 false_label_p, new_locus));
3714 else
3716 expr = build3 (COND_EXPR, void_type_node, pred,
3717 build_and_jump (true_label_p),
3718 build_and_jump (false_label_p));
3719 SET_EXPR_LOCATION (expr, locus);
3722 if (local_label)
3724 t = build1 (LABEL_EXPR, void_type_node, local_label);
3725 append_to_statement_list (t, &expr);
3728 return expr;
3731 /* If EXPR is a GOTO_EXPR, return it. If it is a STATEMENT_LIST, skip
3732 any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3733 statement, if it is the last one. Otherwise, return NULL. */
3735 static tree
3736 find_goto (tree expr)
3738 if (!expr)
3739 return NULL_TREE;
3741 if (TREE_CODE (expr) == GOTO_EXPR)
3742 return expr;
3744 if (TREE_CODE (expr) != STATEMENT_LIST)
3745 return NULL_TREE;
3747 tree_stmt_iterator i = tsi_start (expr);
3749 while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
3750 tsi_next (&i);
3752 if (!tsi_one_before_end_p (i))
3753 return NULL_TREE;
3755 return find_goto (tsi_stmt (i));
3758 /* Same as find_goto, except that it returns NULL if the destination
3759 is not a LABEL_DECL. */
3761 static inline tree
3762 find_goto_label (tree expr)
3764 tree dest = find_goto (expr);
3765 if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
3766 return dest;
3767 return NULL_TREE;
3770 /* Given a conditional expression EXPR with short-circuit boolean
3771 predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3772 predicate apart into the equivalent sequence of conditionals. */
3774 static tree
3775 shortcut_cond_expr (tree expr)
3777 tree pred = TREE_OPERAND (expr, 0);
3778 tree then_ = TREE_OPERAND (expr, 1);
3779 tree else_ = TREE_OPERAND (expr, 2);
3780 tree true_label, false_label, end_label, t;
3781 tree *true_label_p;
3782 tree *false_label_p;
3783 bool emit_end, emit_false, jump_over_else;
3784 bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3785 bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3787 /* First do simple transformations. */
3788 if (!else_se)
3790 /* If there is no 'else', turn
3791 if (a && b) then c
3792 into
3793 if (a) if (b) then c. */
3794 while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3796 /* Keep the original source location on the first 'if'. */
3797 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3798 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3799 /* Set the source location of the && on the second 'if'. */
3800 if (rexpr_has_location (pred))
3801 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3802 then_ = shortcut_cond_expr (expr);
3803 then_se = then_ && TREE_SIDE_EFFECTS (then_);
3804 pred = TREE_OPERAND (pred, 0);
3805 expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
3806 SET_EXPR_LOCATION (expr, locus);
3810 if (!then_se)
3812 /* If there is no 'then', turn
3813 if (a || b); else d
3814 into
3815 if (a); else if (b); else d. */
3816 while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3818 /* Keep the original source location on the first 'if'. */
3819 location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
3820 TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
3821 /* Set the source location of the || on the second 'if'. */
3822 if (rexpr_has_location (pred))
3823 SET_EXPR_LOCATION (expr, rexpr_location (pred));
3824 else_ = shortcut_cond_expr (expr);
3825 else_se = else_ && TREE_SIDE_EFFECTS (else_);
3826 pred = TREE_OPERAND (pred, 0);
3827 expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
3828 SET_EXPR_LOCATION (expr, locus);
3832 /* If we're done, great. */
3833 if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
3834 && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
3835 return expr;
3837 /* Otherwise we need to mess with gotos. Change
3838 if (a) c; else d;
3840 if (a); else goto no;
3841 c; goto end;
3842 no: d; end:
3843 and recursively gimplify the condition. */
3845 true_label = false_label = end_label = NULL_TREE;
3847 /* If our arms just jump somewhere, hijack those labels so we don't
3848 generate jumps to jumps. */
3850 if (tree then_goto = find_goto_label (then_))
3852 true_label = GOTO_DESTINATION (then_goto);
3853 then_ = NULL;
3854 then_se = false;
3857 if (tree else_goto = find_goto_label (else_))
3859 false_label = GOTO_DESTINATION (else_goto);
3860 else_ = NULL;
3861 else_se = false;
3864 /* If we aren't hijacking a label for the 'then' branch, it falls through. */
3865 if (true_label)
3866 true_label_p = &true_label;
3867 else
3868 true_label_p = NULL;
3870 /* The 'else' branch also needs a label if it contains interesting code. */
3871 if (false_label || else_se)
3872 false_label_p = &false_label;
3873 else
3874 false_label_p = NULL;
3876 /* If there was nothing else in our arms, just forward the label(s). */
3877 if (!then_se && !else_se)
3878 return shortcut_cond_r (pred, true_label_p, false_label_p,
3879 EXPR_LOC_OR_LOC (expr, input_location));
3881 /* If our last subexpression already has a terminal label, reuse it. */
3882 if (else_se)
3883 t = expr_last (else_);
3884 else if (then_se)
3885 t = expr_last (then_);
3886 else
3887 t = NULL;
3888 if (t && TREE_CODE (t) == LABEL_EXPR)
3889 end_label = LABEL_EXPR_LABEL (t);
3891 /* If we don't care about jumping to the 'else' branch, jump to the end
3892 if the condition is false. */
3893 if (!false_label_p)
3894 false_label_p = &end_label;
3896 /* We only want to emit these labels if we aren't hijacking them. */
3897 emit_end = (end_label == NULL_TREE);
3898 emit_false = (false_label == NULL_TREE);
3900 /* We only emit the jump over the else clause if we have to--if the
3901 then clause may fall through. Otherwise we can wind up with a
3902 useless jump and a useless label at the end of gimplified code,
3903 which will cause us to think that this conditional as a whole
3904 falls through even if it doesn't. If we then inline a function
3905 which ends with such a condition, that can cause us to issue an
3906 inappropriate warning about control reaching the end of a
3907 non-void function. */
3908 jump_over_else = block_may_fallthru (then_);
3910 pred = shortcut_cond_r (pred, true_label_p, false_label_p,
3911 EXPR_LOC_OR_LOC (expr, input_location));
3913 expr = NULL;
3914 append_to_statement_list (pred, &expr);
3916 append_to_statement_list (then_, &expr);
3917 if (else_se)
3919 if (jump_over_else)
3921 tree last = expr_last (expr);
3922 t = build_and_jump (&end_label);
3923 if (rexpr_has_location (last))
3924 SET_EXPR_LOCATION (t, rexpr_location (last));
3925 append_to_statement_list (t, &expr);
3927 if (emit_false)
3929 t = build1 (LABEL_EXPR, void_type_node, false_label);
3930 append_to_statement_list (t, &expr);
3932 append_to_statement_list (else_, &expr);
3934 if (emit_end && end_label)
3936 t = build1 (LABEL_EXPR, void_type_node, end_label);
3937 append_to_statement_list (t, &expr);
3940 return expr;
3943 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
3945 tree
3946 gimple_boolify (tree expr)
3948 tree type = TREE_TYPE (expr);
3949 location_t loc = EXPR_LOCATION (expr);
3951 if (TREE_CODE (expr) == NE_EXPR
3952 && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
3953 && integer_zerop (TREE_OPERAND (expr, 1)))
3955 tree call = TREE_OPERAND (expr, 0);
3956 tree fn = get_callee_fndecl (call);
3958 /* For __builtin_expect ((long) (x), y) recurse into x as well
3959 if x is truth_value_p. */
3960 if (fn
3961 && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
3962 && call_expr_nargs (call) == 2)
3964 tree arg = CALL_EXPR_ARG (call, 0);
3965 if (arg)
3967 if (TREE_CODE (arg) == NOP_EXPR
3968 && TREE_TYPE (arg) == TREE_TYPE (call))
3969 arg = TREE_OPERAND (arg, 0);
3970 if (truth_value_p (TREE_CODE (arg)))
3972 arg = gimple_boolify (arg);
3973 CALL_EXPR_ARG (call, 0)
3974 = fold_convert_loc (loc, TREE_TYPE (call), arg);
3980 switch (TREE_CODE (expr))
3982 case TRUTH_AND_EXPR:
3983 case TRUTH_OR_EXPR:
3984 case TRUTH_XOR_EXPR:
3985 case TRUTH_ANDIF_EXPR:
3986 case TRUTH_ORIF_EXPR:
3987 /* Also boolify the arguments of truth exprs. */
3988 TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
3989 /* FALLTHRU */
3991 case TRUTH_NOT_EXPR:
3992 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
3994 /* These expressions always produce boolean results. */
3995 if (TREE_CODE (type) != BOOLEAN_TYPE)
3996 TREE_TYPE (expr) = boolean_type_node;
3997 return expr;
3999 case ANNOTATE_EXPR:
4000 switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
4002 case annot_expr_ivdep_kind:
4003 case annot_expr_unroll_kind:
4004 case annot_expr_no_vector_kind:
4005 case annot_expr_vector_kind:
4006 case annot_expr_parallel_kind:
4007 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4008 if (TREE_CODE (type) != BOOLEAN_TYPE)
4009 TREE_TYPE (expr) = boolean_type_node;
4010 return expr;
4011 default:
4012 gcc_unreachable ();
4015 default:
4016 if (COMPARISON_CLASS_P (expr))
4018 /* There expressions always prduce boolean results. */
4019 if (TREE_CODE (type) != BOOLEAN_TYPE)
4020 TREE_TYPE (expr) = boolean_type_node;
4021 return expr;
4023 /* Other expressions that get here must have boolean values, but
4024 might need to be converted to the appropriate mode. */
4025 if (TREE_CODE (type) == BOOLEAN_TYPE)
4026 return expr;
4027 return fold_convert_loc (loc, boolean_type_node, expr);
4031 /* Given a conditional expression *EXPR_P without side effects, gimplify
4032 its operands. New statements are inserted to PRE_P. */
4034 static enum gimplify_status
4035 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
4037 tree expr = *expr_p, cond;
4038 enum gimplify_status ret, tret;
4039 enum tree_code code;
4041 cond = gimple_boolify (COND_EXPR_COND (expr));
4043 /* We need to handle && and || specially, as their gimplification
4044 creates pure cond_expr, thus leading to an infinite cycle otherwise. */
4045 code = TREE_CODE (cond);
4046 if (code == TRUTH_ANDIF_EXPR)
4047 TREE_SET_CODE (cond, TRUTH_AND_EXPR);
4048 else if (code == TRUTH_ORIF_EXPR)
4049 TREE_SET_CODE (cond, TRUTH_OR_EXPR);
4050 ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
4051 COND_EXPR_COND (*expr_p) = cond;
4053 tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
4054 is_gimple_val, fb_rvalue);
4055 ret = MIN (ret, tret);
4056 tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
4057 is_gimple_val, fb_rvalue);
4059 return MIN (ret, tret);
4062 /* Return true if evaluating EXPR could trap.
4063 EXPR is GENERIC, while tree_could_trap_p can be called
4064 only on GIMPLE. */
4066 bool
4067 generic_expr_could_trap_p (tree expr)
4069 unsigned i, n;
4071 if (!expr || is_gimple_val (expr))
4072 return false;
4074 if (!EXPR_P (expr) || tree_could_trap_p (expr))
4075 return true;
4077 n = TREE_OPERAND_LENGTH (expr);
4078 for (i = 0; i < n; i++)
4079 if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
4080 return true;
4082 return false;
4085 /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4086 into
4088 if (p) if (p)
4089 t1 = a; a;
4090 else or else
4091 t1 = b; b;
4094 The second form is used when *EXPR_P is of type void.
4096 PRE_P points to the list where side effects that must happen before
4097 *EXPR_P should be stored. */
4099 static enum gimplify_status
4100 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
4102 tree expr = *expr_p;
4103 tree type = TREE_TYPE (expr);
4104 location_t loc = EXPR_LOCATION (expr);
4105 tree tmp, arm1, arm2;
4106 enum gimplify_status ret;
4107 tree label_true, label_false, label_cont;
4108 bool have_then_clause_p, have_else_clause_p;
4109 gcond *cond_stmt;
4110 enum tree_code pred_code;
4111 gimple_seq seq = NULL;
4113 /* If this COND_EXPR has a value, copy the values into a temporary within
4114 the arms. */
4115 if (!VOID_TYPE_P (type))
4117 tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
4118 tree result;
4120 /* If either an rvalue is ok or we do not require an lvalue, create the
4121 temporary. But we cannot do that if the type is addressable. */
4122 if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
4123 && !TREE_ADDRESSABLE (type))
4125 if (gimplify_ctxp->allow_rhs_cond_expr
4126 /* If either branch has side effects or could trap, it can't be
4127 evaluated unconditionally. */
4128 && !TREE_SIDE_EFFECTS (then_)
4129 && !generic_expr_could_trap_p (then_)
4130 && !TREE_SIDE_EFFECTS (else_)
4131 && !generic_expr_could_trap_p (else_))
4132 return gimplify_pure_cond_expr (expr_p, pre_p);
4134 tmp = create_tmp_var (type, "iftmp");
4135 result = tmp;
4138 /* Otherwise, only create and copy references to the values. */
4139 else
4141 type = build_pointer_type (type);
4143 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4144 then_ = build_fold_addr_expr_loc (loc, then_);
4146 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4147 else_ = build_fold_addr_expr_loc (loc, else_);
4149 expr
4150 = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
4152 tmp = create_tmp_var (type, "iftmp");
4153 result = build_simple_mem_ref_loc (loc, tmp);
4156 /* Build the new then clause, `tmp = then_;'. But don't build the
4157 assignment if the value is void; in C++ it can be if it's a throw. */
4158 if (!VOID_TYPE_P (TREE_TYPE (then_)))
4159 TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
4161 /* Similarly, build the new else clause, `tmp = else_;'. */
4162 if (!VOID_TYPE_P (TREE_TYPE (else_)))
4163 TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
4165 TREE_TYPE (expr) = void_type_node;
4166 recalculate_side_effects (expr);
4168 /* Move the COND_EXPR to the prequeue. */
4169 gimplify_stmt (&expr, pre_p);
4171 *expr_p = result;
4172 return GS_ALL_DONE;
4175 /* Remove any COMPOUND_EXPR so the following cases will be caught. */
4176 STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4177 if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4178 gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4180 /* Make sure the condition has BOOLEAN_TYPE. */
4181 TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4183 /* Break apart && and || conditions. */
4184 if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4185 || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4187 expr = shortcut_cond_expr (expr);
4189 if (expr != *expr_p)
4191 *expr_p = expr;
4193 /* We can't rely on gimplify_expr to re-gimplify the expanded
4194 form properly, as cleanups might cause the target labels to be
4195 wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
4196 set up a conditional context. */
4197 gimple_push_condition ();
4198 gimplify_stmt (expr_p, &seq);
4199 gimple_pop_condition (pre_p);
4200 gimple_seq_add_seq (pre_p, seq);
4202 return GS_ALL_DONE;
4206 /* Now do the normal gimplification. */
4208 /* Gimplify condition. */
4209 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
4210 is_gimple_condexpr_for_cond, fb_rvalue);
4211 if (ret == GS_ERROR)
4212 return GS_ERROR;
4213 gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4215 gimple_push_condition ();
4217 have_then_clause_p = have_else_clause_p = false;
4218 label_true = find_goto_label (TREE_OPERAND (expr, 1));
4219 if (label_true
4220 && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4221 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4222 have different locations, otherwise we end up with incorrect
4223 location information on the branches. */
4224 && (optimize
4225 || !EXPR_HAS_LOCATION (expr)
4226 || !rexpr_has_location (label_true)
4227 || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4229 have_then_clause_p = true;
4230 label_true = GOTO_DESTINATION (label_true);
4232 else
4233 label_true = create_artificial_label (UNKNOWN_LOCATION);
4234 label_false = find_goto_label (TREE_OPERAND (expr, 2));
4235 if (label_false
4236 && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4237 /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4238 have different locations, otherwise we end up with incorrect
4239 location information on the branches. */
4240 && (optimize
4241 || !EXPR_HAS_LOCATION (expr)
4242 || !rexpr_has_location (label_false)
4243 || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4245 have_else_clause_p = true;
4246 label_false = GOTO_DESTINATION (label_false);
4248 else
4249 label_false = create_artificial_label (UNKNOWN_LOCATION);
4251 gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4252 &arm2);
4253 cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4254 label_false);
4255 gimple_set_location (cond_stmt, EXPR_LOCATION (expr));
4256 copy_warning (cond_stmt, COND_EXPR_COND (expr));
4257 gimplify_seq_add_stmt (&seq, cond_stmt);
4258 gimple_stmt_iterator gsi = gsi_last (seq);
4259 maybe_fold_stmt (&gsi);
4261 label_cont = NULL_TREE;
4262 if (!have_then_clause_p)
4264 /* For if (...) {} else { code; } put label_true after
4265 the else block. */
4266 if (TREE_OPERAND (expr, 1) == NULL_TREE
4267 && !have_else_clause_p
4268 && TREE_OPERAND (expr, 2) != NULL_TREE)
4269 label_cont = label_true;
4270 else
4272 gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4273 have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4274 /* For if (...) { code; } else {} or
4275 if (...) { code; } else goto label; or
4276 if (...) { code; return; } else { ... }
4277 label_cont isn't needed. */
4278 if (!have_else_clause_p
4279 && TREE_OPERAND (expr, 2) != NULL_TREE
4280 && gimple_seq_may_fallthru (seq))
4282 gimple *g;
4283 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4285 g = gimple_build_goto (label_cont);
4287 /* GIMPLE_COND's are very low level; they have embedded
4288 gotos. This particular embedded goto should not be marked
4289 with the location of the original COND_EXPR, as it would
4290 correspond to the COND_EXPR's condition, not the ELSE or the
4291 THEN arms. To avoid marking it with the wrong location, flag
4292 it as "no location". */
4293 gimple_set_do_not_emit_location (g);
4295 gimplify_seq_add_stmt (&seq, g);
4299 if (!have_else_clause_p)
4301 gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4302 have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4304 if (label_cont)
4305 gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4307 gimple_pop_condition (pre_p);
4308 gimple_seq_add_seq (pre_p, seq);
4310 if (ret == GS_ERROR)
4311 ; /* Do nothing. */
4312 else if (have_then_clause_p || have_else_clause_p)
4313 ret = GS_ALL_DONE;
4314 else
4316 /* Both arms are empty; replace the COND_EXPR with its predicate. */
4317 expr = TREE_OPERAND (expr, 0);
4318 gimplify_stmt (&expr, pre_p);
4321 *expr_p = NULL;
4322 return ret;
4325 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4326 to be marked addressable.
4328 We cannot rely on such an expression being directly markable if a temporary
4329 has been created by the gimplification. In this case, we create another
4330 temporary and initialize it with a copy, which will become a store after we
4331 mark it addressable. This can happen if the front-end passed us something
4332 that it could not mark addressable yet, like a Fortran pass-by-reference
4333 parameter (int) floatvar. */
4335 static void
4336 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4338 while (handled_component_p (*expr_p))
4339 expr_p = &TREE_OPERAND (*expr_p, 0);
4340 if (is_gimple_reg (*expr_p))
4342 /* Do not allow an SSA name as the temporary. */
4343 tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
4344 DECL_NOT_GIMPLE_REG_P (var) = 1;
4345 *expr_p = var;
4349 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4350 a call to __builtin_memcpy. */
4352 static enum gimplify_status
4353 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4354 gimple_seq *seq_p)
4356 tree t, to, to_ptr, from, from_ptr;
4357 gcall *gs;
4358 location_t loc = EXPR_LOCATION (*expr_p);
4360 to = TREE_OPERAND (*expr_p, 0);
4361 from = TREE_OPERAND (*expr_p, 1);
4363 /* Mark the RHS addressable. Beware that it may not be possible to do so
4364 directly if a temporary has been created by the gimplification. */
4365 prepare_gimple_addressable (&from, seq_p);
4367 mark_addressable (from);
4368 from_ptr = build_fold_addr_expr_loc (loc, from);
4369 gimplify_arg (&from_ptr, seq_p, loc);
4371 mark_addressable (to);
4372 to_ptr = build_fold_addr_expr_loc (loc, to);
4373 gimplify_arg (&to_ptr, seq_p, loc);
4375 t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4377 gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4378 gimple_call_set_alloca_for_var (gs, true);
4380 if (want_value)
4382 /* tmp = memcpy() */
4383 t = create_tmp_var (TREE_TYPE (to_ptr));
4384 gimple_call_set_lhs (gs, t);
4385 gimplify_seq_add_stmt (seq_p, gs);
4387 *expr_p = build_simple_mem_ref (t);
4388 return GS_ALL_DONE;
4391 gimplify_seq_add_stmt (seq_p, gs);
4392 *expr_p = NULL;
4393 return GS_ALL_DONE;
4396 /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
4397 a call to __builtin_memset. In this case we know that the RHS is
4398 a CONSTRUCTOR with an empty element list. */
4400 static enum gimplify_status
4401 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4402 gimple_seq *seq_p)
4404 tree t, from, to, to_ptr;
4405 gcall *gs;
4406 location_t loc = EXPR_LOCATION (*expr_p);
4408 /* Assert our assumptions, to abort instead of producing wrong code
4409 silently if they are not met. Beware that the RHS CONSTRUCTOR might
4410 not be immediately exposed. */
4411 from = TREE_OPERAND (*expr_p, 1);
4412 if (TREE_CODE (from) == WITH_SIZE_EXPR)
4413 from = TREE_OPERAND (from, 0);
4415 gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4416 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4418 /* Now proceed. */
4419 to = TREE_OPERAND (*expr_p, 0);
4421 to_ptr = build_fold_addr_expr_loc (loc, to);
4422 gimplify_arg (&to_ptr, seq_p, loc);
4423 t = builtin_decl_implicit (BUILT_IN_MEMSET);
4425 gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4427 if (want_value)
4429 /* tmp = memset() */
4430 t = create_tmp_var (TREE_TYPE (to_ptr));
4431 gimple_call_set_lhs (gs, t);
4432 gimplify_seq_add_stmt (seq_p, gs);
4434 *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4435 return GS_ALL_DONE;
4438 gimplify_seq_add_stmt (seq_p, gs);
4439 *expr_p = NULL;
4440 return GS_ALL_DONE;
4443 /* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
4444 determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4445 assignment. Return non-null if we detect a potential overlap. */
4447 struct gimplify_init_ctor_preeval_data
4449 /* The base decl of the lhs object. May be NULL, in which case we
4450 have to assume the lhs is indirect. */
4451 tree lhs_base_decl;
4453 /* The alias set of the lhs object. */
4454 alias_set_type lhs_alias_set;
4457 static tree
4458 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4460 struct gimplify_init_ctor_preeval_data *data
4461 = (struct gimplify_init_ctor_preeval_data *) xdata;
4462 tree t = *tp;
4464 /* If we find the base object, obviously we have overlap. */
4465 if (data->lhs_base_decl == t)
4466 return t;
4468 /* If the constructor component is indirect, determine if we have a
4469 potential overlap with the lhs. The only bits of information we
4470 have to go on at this point are addressability and alias sets. */
4471 if ((INDIRECT_REF_P (t)
4472 || TREE_CODE (t) == MEM_REF)
4473 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4474 && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4475 return t;
4477 /* If the constructor component is a call, determine if it can hide a
4478 potential overlap with the lhs through an INDIRECT_REF like above.
4479 ??? Ugh - this is completely broken. In fact this whole analysis
4480 doesn't look conservative. */
4481 if (TREE_CODE (t) == CALL_EXPR)
4483 tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4485 for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4486 if (POINTER_TYPE_P (TREE_VALUE (type))
4487 && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4488 && alias_sets_conflict_p (data->lhs_alias_set,
4489 get_alias_set
4490 (TREE_TYPE (TREE_VALUE (type)))))
4491 return t;
4494 if (IS_TYPE_OR_DECL_P (t))
4495 *walk_subtrees = 0;
4496 return NULL;
4499 /* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
4500 force values that overlap with the lhs (as described by *DATA)
4501 into temporaries. */
4503 static void
4504 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4505 struct gimplify_init_ctor_preeval_data *data)
4507 enum gimplify_status one;
4509 /* If the value is constant, then there's nothing to pre-evaluate. */
4510 if (TREE_CONSTANT (*expr_p))
4512 /* Ensure it does not have side effects, it might contain a reference to
4513 the object we're initializing. */
4514 gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4515 return;
4518 /* If the type has non-trivial constructors, we can't pre-evaluate. */
4519 if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4520 return;
4522 /* Recurse for nested constructors. */
4523 if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4525 unsigned HOST_WIDE_INT ix;
4526 constructor_elt *ce;
4527 vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4529 FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4530 gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4532 return;
4535 /* If this is a variable sized type, we must remember the size. */
4536 maybe_with_size_expr (expr_p);
4538 /* Gimplify the constructor element to something appropriate for the rhs
4539 of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
4540 the gimplifier will consider this a store to memory. Doing this
4541 gimplification now means that we won't have to deal with complicated
4542 language-specific trees, nor trees like SAVE_EXPR that can induce
4543 exponential search behavior. */
4544 one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4545 if (one == GS_ERROR)
4547 *expr_p = NULL;
4548 return;
4551 /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4552 with the lhs, since "a = { .x=a }" doesn't make sense. This will
4553 always be true for all scalars, since is_gimple_mem_rhs insists on a
4554 temporary variable for them. */
4555 if (DECL_P (*expr_p))
4556 return;
4558 /* If this is of variable size, we have no choice but to assume it doesn't
4559 overlap since we can't make a temporary for it. */
4560 if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4561 return;
4563 /* Otherwise, we must search for overlap ... */
4564 if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4565 return;
4567 /* ... and if found, force the value into a temporary. */
4568 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4571 /* A subroutine of gimplify_init_ctor_eval. Create a loop for
4572 a RANGE_EXPR in a CONSTRUCTOR for an array.
4574 var = lower;
4575 loop_entry:
4576 object[var] = value;
4577 if (var == upper)
4578 goto loop_exit;
4579 var = var + 1;
4580 goto loop_entry;
4581 loop_exit:
4583 We increment var _after_ the loop exit check because we might otherwise
4584 fail if upper == TYPE_MAX_VALUE (type for upper).
4586 Note that we never have to deal with SAVE_EXPRs here, because this has
4587 already been taken care of for us, in gimplify_init_ctor_preeval(). */
4589 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4590 gimple_seq *, bool);
4592 static void
4593 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4594 tree value, tree array_elt_type,
4595 gimple_seq *pre_p, bool cleared)
4597 tree loop_entry_label, loop_exit_label, fall_thru_label;
4598 tree var, var_type, cref, tmp;
4600 loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4601 loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4602 fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4604 /* Create and initialize the index variable. */
4605 var_type = TREE_TYPE (upper);
4606 var = create_tmp_var (var_type);
4607 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4609 /* Add the loop entry label. */
4610 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4612 /* Build the reference. */
4613 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4614 var, NULL_TREE, NULL_TREE);
4616 /* If we are a constructor, just call gimplify_init_ctor_eval to do
4617 the store. Otherwise just assign value to the reference. */
4619 if (TREE_CODE (value) == CONSTRUCTOR)
4620 /* NB we might have to call ourself recursively through
4621 gimplify_init_ctor_eval if the value is a constructor. */
4622 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4623 pre_p, cleared);
4624 else
4626 if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue)
4627 != GS_ERROR)
4628 gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4631 /* We exit the loop when the index var is equal to the upper bound. */
4632 gimplify_seq_add_stmt (pre_p,
4633 gimple_build_cond (EQ_EXPR, var, upper,
4634 loop_exit_label, fall_thru_label));
4636 gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4638 /* Otherwise, increment the index var... */
4639 tmp = build2 (PLUS_EXPR, var_type, var,
4640 fold_convert (var_type, integer_one_node));
4641 gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4643 /* ...and jump back to the loop entry. */
4644 gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4646 /* Add the loop exit label. */
4647 gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4650 /* A subroutine of gimplify_init_constructor. Generate individual
4651 MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
4652 assignments should happen. ELTS is the CONSTRUCTOR_ELTS of the
4653 CONSTRUCTOR. CLEARED is true if the entire LHS object has been
4654 zeroed first. */
4656 static void
4657 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4658 gimple_seq *pre_p, bool cleared)
4660 tree array_elt_type = NULL;
4661 unsigned HOST_WIDE_INT ix;
4662 tree purpose, value;
4664 if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4665 array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4667 FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4669 tree cref;
4671 /* NULL values are created above for gimplification errors. */
4672 if (value == NULL)
4673 continue;
4675 if (cleared && initializer_zerop (value))
4676 continue;
4678 /* ??? Here's to hoping the front end fills in all of the indices,
4679 so we don't have to figure out what's missing ourselves. */
4680 gcc_assert (purpose);
4682 /* Skip zero-sized fields, unless value has side-effects. This can
4683 happen with calls to functions returning a empty type, which
4684 we shouldn't discard. As a number of downstream passes don't
4685 expect sets of empty type fields, we rely on the gimplification of
4686 the MODIFY_EXPR we make below to drop the assignment statement. */
4687 if (!TREE_SIDE_EFFECTS (value)
4688 && TREE_CODE (purpose) == FIELD_DECL
4689 && is_empty_type (TREE_TYPE (purpose)))
4690 continue;
4692 /* If we have a RANGE_EXPR, we have to build a loop to assign the
4693 whole range. */
4694 if (TREE_CODE (purpose) == RANGE_EXPR)
4696 tree lower = TREE_OPERAND (purpose, 0);
4697 tree upper = TREE_OPERAND (purpose, 1);
4699 /* If the lower bound is equal to upper, just treat it as if
4700 upper was the index. */
4701 if (simple_cst_equal (lower, upper))
4702 purpose = upper;
4703 else
4705 gimplify_init_ctor_eval_range (object, lower, upper, value,
4706 array_elt_type, pre_p, cleared);
4707 continue;
4711 if (array_elt_type)
4713 /* Do not use bitsizetype for ARRAY_REF indices. */
4714 if (TYPE_DOMAIN (TREE_TYPE (object)))
4715 purpose
4716 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4717 purpose);
4718 cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4719 purpose, NULL_TREE, NULL_TREE);
4721 else
4723 gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4724 cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4725 unshare_expr (object), purpose, NULL_TREE);
4728 if (TREE_CODE (value) == CONSTRUCTOR
4729 && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4730 gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4731 pre_p, cleared);
4732 else
4734 tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4735 gimplify_and_add (init, pre_p);
4736 ggc_free (init);
4741 /* Return the appropriate RHS predicate for this LHS. */
4743 gimple_predicate
4744 rhs_predicate_for (tree lhs)
4746 if (is_gimple_reg (lhs))
4747 return is_gimple_reg_rhs_or_call;
4748 else
4749 return is_gimple_mem_rhs_or_call;
4752 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4753 before the LHS has been gimplified. */
4755 static gimple_predicate
4756 initial_rhs_predicate_for (tree lhs)
4758 if (is_gimple_reg_type (TREE_TYPE (lhs)))
4759 return is_gimple_reg_rhs_or_call;
4760 else
4761 return is_gimple_mem_rhs_or_call;
4764 /* Gimplify a C99 compound literal expression. This just means adding
4765 the DECL_EXPR before the current statement and using its anonymous
4766 decl instead. */
4768 static enum gimplify_status
4769 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
4770 bool (*gimple_test_f) (tree),
4771 fallback_t fallback)
4773 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
4774 tree decl = DECL_EXPR_DECL (decl_s);
4775 tree init = DECL_INITIAL (decl);
4776 /* Mark the decl as addressable if the compound literal
4777 expression is addressable now, otherwise it is marked too late
4778 after we gimplify the initialization expression. */
4779 if (TREE_ADDRESSABLE (*expr_p))
4780 TREE_ADDRESSABLE (decl) = 1;
4781 /* Otherwise, if we don't need an lvalue and have a literal directly
4782 substitute it. Check if it matches the gimple predicate, as
4783 otherwise we'd generate a new temporary, and we can as well just
4784 use the decl we already have. */
4785 else if (!TREE_ADDRESSABLE (decl)
4786 && !TREE_THIS_VOLATILE (decl)
4787 && init
4788 && (fallback & fb_lvalue) == 0
4789 && gimple_test_f (init))
4791 *expr_p = init;
4792 return GS_OK;
4795 /* If the decl is not addressable, then it is being used in some
4796 expression or on the right hand side of a statement, and it can
4797 be put into a readonly data section. */
4798 if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
4799 TREE_READONLY (decl) = 1;
4801 /* This decl isn't mentioned in the enclosing block, so add it to the
4802 list of temps. FIXME it seems a bit of a kludge to say that
4803 anonymous artificial vars aren't pushed, but everything else is. */
4804 if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
4805 gimple_add_tmp_var (decl);
4807 gimplify_and_add (decl_s, pre_p);
4808 *expr_p = decl;
4809 return GS_OK;
4812 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
4813 return a new CONSTRUCTOR if something changed. */
4815 static tree
4816 optimize_compound_literals_in_ctor (tree orig_ctor)
4818 tree ctor = orig_ctor;
4819 vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
4820 unsigned int idx, num = vec_safe_length (elts);
4822 for (idx = 0; idx < num; idx++)
4824 tree value = (*elts)[idx].value;
4825 tree newval = value;
4826 if (TREE_CODE (value) == CONSTRUCTOR)
4827 newval = optimize_compound_literals_in_ctor (value);
4828 else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
4830 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
4831 tree decl = DECL_EXPR_DECL (decl_s);
4832 tree init = DECL_INITIAL (decl);
4834 if (!TREE_ADDRESSABLE (value)
4835 && !TREE_ADDRESSABLE (decl)
4836 && init
4837 && TREE_CODE (init) == CONSTRUCTOR)
4838 newval = optimize_compound_literals_in_ctor (init);
4840 if (newval == value)
4841 continue;
4843 if (ctor == orig_ctor)
4845 ctor = copy_node (orig_ctor);
4846 CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
4847 elts = CONSTRUCTOR_ELTS (ctor);
4849 (*elts)[idx].value = newval;
4851 return ctor;
4854 /* A subroutine of gimplify_modify_expr. Break out elements of a
4855 CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
4857 Note that we still need to clear any elements that don't have explicit
4858 initializers, so if not all elements are initialized we keep the
4859 original MODIFY_EXPR, we just remove all of the constructor elements.
4861 If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
4862 GS_ERROR if we would have to create a temporary when gimplifying
4863 this constructor. Otherwise, return GS_OK.
4865 If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
4867 static enum gimplify_status
4868 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4869 bool want_value, bool notify_temp_creation)
4871 tree object, ctor, type;
4872 enum gimplify_status ret;
4873 vec<constructor_elt, va_gc> *elts;
4875 gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
4877 if (!notify_temp_creation)
4879 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
4880 is_gimple_lvalue, fb_lvalue);
4881 if (ret == GS_ERROR)
4882 return ret;
4885 object = TREE_OPERAND (*expr_p, 0);
4886 ctor = TREE_OPERAND (*expr_p, 1)
4887 = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
4888 type = TREE_TYPE (ctor);
4889 elts = CONSTRUCTOR_ELTS (ctor);
4890 ret = GS_ALL_DONE;
4892 switch (TREE_CODE (type))
4894 case RECORD_TYPE:
4895 case UNION_TYPE:
4896 case QUAL_UNION_TYPE:
4897 case ARRAY_TYPE:
4899 /* Use readonly data for initializers of this or smaller size
4900 regardless of the num_nonzero_elements / num_unique_nonzero_elements
4901 ratio. */
4902 const HOST_WIDE_INT min_unique_size = 64;
4903 /* If num_nonzero_elements / num_unique_nonzero_elements ratio
4904 is smaller than this, use readonly data. */
4905 const int unique_nonzero_ratio = 8;
4906 /* True if a single access of the object must be ensured. This is the
4907 case if the target is volatile, the type is non-addressable and more
4908 than one field need to be assigned. */
4909 const bool ensure_single_access
4910 = TREE_THIS_VOLATILE (object)
4911 && !TREE_ADDRESSABLE (type)
4912 && vec_safe_length (elts) > 1;
4913 struct gimplify_init_ctor_preeval_data preeval_data;
4914 HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
4915 HOST_WIDE_INT num_unique_nonzero_elements;
4916 bool cleared, complete_p, valid_const_initializer;
4918 /* Aggregate types must lower constructors to initialization of
4919 individual elements. The exception is that a CONSTRUCTOR node
4920 with no elements indicates zero-initialization of the whole. */
4921 if (vec_safe_is_empty (elts))
4923 if (notify_temp_creation)
4924 return GS_OK;
4925 break;
4928 /* Fetch information about the constructor to direct later processing.
4929 We might want to make static versions of it in various cases, and
4930 can only do so if it known to be a valid constant initializer. */
4931 valid_const_initializer
4932 = categorize_ctor_elements (ctor, &num_nonzero_elements,
4933 &num_unique_nonzero_elements,
4934 &num_ctor_elements, &complete_p);
4936 /* If a const aggregate variable is being initialized, then it
4937 should never be a lose to promote the variable to be static. */
4938 if (valid_const_initializer
4939 && num_nonzero_elements > 1
4940 && TREE_READONLY (object)
4941 && VAR_P (object)
4942 && !DECL_REGISTER (object)
4943 && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))
4944 /* For ctors that have many repeated nonzero elements
4945 represented through RANGE_EXPRs, prefer initializing
4946 those through runtime loops over copies of large amounts
4947 of data from readonly data section. */
4948 && (num_unique_nonzero_elements
4949 > num_nonzero_elements / unique_nonzero_ratio
4950 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
4951 <= (unsigned HOST_WIDE_INT) min_unique_size)))
4953 if (notify_temp_creation)
4954 return GS_ERROR;
4956 DECL_INITIAL (object) = ctor;
4957 TREE_STATIC (object) = 1;
4958 if (!DECL_NAME (object))
4959 DECL_NAME (object) = create_tmp_var_name ("C");
4960 walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
4962 /* ??? C++ doesn't automatically append a .<number> to the
4963 assembler name, and even when it does, it looks at FE private
4964 data structures to figure out what that number should be,
4965 which are not set for this variable. I suppose this is
4966 important for local statics for inline functions, which aren't
4967 "local" in the object file sense. So in order to get a unique
4968 TU-local symbol, we must invoke the lhd version now. */
4969 lhd_set_decl_assembler_name (object);
4971 *expr_p = NULL_TREE;
4972 break;
4975 /* If there are "lots" of initialized elements, even discounting
4976 those that are not address constants (and thus *must* be
4977 computed at runtime), then partition the constructor into
4978 constant and non-constant parts. Block copy the constant
4979 parts in, then generate code for the non-constant parts. */
4980 /* TODO. There's code in cp/typeck.c to do this. */
4982 if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
4983 /* store_constructor will ignore the clearing of variable-sized
4984 objects. Initializers for such objects must explicitly set
4985 every field that needs to be set. */
4986 cleared = false;
4987 else if (!complete_p)
4988 /* If the constructor isn't complete, clear the whole object
4989 beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
4991 ??? This ought not to be needed. For any element not present
4992 in the initializer, we should simply set them to zero. Except
4993 we'd need to *find* the elements that are not present, and that
4994 requires trickery to avoid quadratic compile-time behavior in
4995 large cases or excessive memory use in small cases. */
4996 cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
4997 else if (num_ctor_elements - num_nonzero_elements
4998 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
4999 && num_nonzero_elements < num_ctor_elements / 4)
5000 /* If there are "lots" of zeros, it's more efficient to clear
5001 the memory and then set the nonzero elements. */
5002 cleared = true;
5003 else if (ensure_single_access && num_nonzero_elements == 0)
5004 /* If a single access to the target must be ensured and all elements
5005 are zero, then it's optimal to clear whatever their number. */
5006 cleared = true;
5007 else
5008 cleared = false;
5010 /* If there are "lots" of initialized elements, and all of them
5011 are valid address constants, then the entire initializer can
5012 be dropped to memory, and then memcpy'd out. Don't do this
5013 for sparse arrays, though, as it's more efficient to follow
5014 the standard CONSTRUCTOR behavior of memset followed by
5015 individual element initialization. Also don't do this for small
5016 all-zero initializers (which aren't big enough to merit
5017 clearing), and don't try to make bitwise copies of
5018 TREE_ADDRESSABLE types. */
5019 if (valid_const_initializer
5020 && complete_p
5021 && !(cleared || num_nonzero_elements == 0)
5022 && !TREE_ADDRESSABLE (type))
5024 HOST_WIDE_INT size = int_size_in_bytes (type);
5025 unsigned int align;
5027 /* ??? We can still get unbounded array types, at least
5028 from the C++ front end. This seems wrong, but attempt
5029 to work around it for now. */
5030 if (size < 0)
5032 size = int_size_in_bytes (TREE_TYPE (object));
5033 if (size >= 0)
5034 TREE_TYPE (ctor) = type = TREE_TYPE (object);
5037 /* Find the maximum alignment we can assume for the object. */
5038 /* ??? Make use of DECL_OFFSET_ALIGN. */
5039 if (DECL_P (object))
5040 align = DECL_ALIGN (object);
5041 else
5042 align = TYPE_ALIGN (type);
5044 /* Do a block move either if the size is so small as to make
5045 each individual move a sub-unit move on average, or if it
5046 is so large as to make individual moves inefficient. */
5047 if (size > 0
5048 && num_nonzero_elements > 1
5049 /* For ctors that have many repeated nonzero elements
5050 represented through RANGE_EXPRs, prefer initializing
5051 those through runtime loops over copies of large amounts
5052 of data from readonly data section. */
5053 && (num_unique_nonzero_elements
5054 > num_nonzero_elements / unique_nonzero_ratio
5055 || size <= min_unique_size)
5056 && (size < num_nonzero_elements
5057 || !can_move_by_pieces (size, align)))
5059 if (notify_temp_creation)
5060 return GS_ERROR;
5062 walk_tree (&ctor, force_labels_r, NULL, NULL);
5063 ctor = tree_output_constant_def (ctor);
5064 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
5065 ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
5066 TREE_OPERAND (*expr_p, 1) = ctor;
5068 /* This is no longer an assignment of a CONSTRUCTOR, but
5069 we still may have processing to do on the LHS. So
5070 pretend we didn't do anything here to let that happen. */
5071 return GS_UNHANDLED;
5075 /* If a single access to the target must be ensured and there are
5076 nonzero elements or the zero elements are not assigned en masse,
5077 initialize the target from a temporary. */
5078 if (ensure_single_access && (num_nonzero_elements > 0 || !cleared))
5080 if (notify_temp_creation)
5081 return GS_ERROR;
5083 tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
5084 TREE_OPERAND (*expr_p, 0) = temp;
5085 *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
5086 *expr_p,
5087 build2 (MODIFY_EXPR, void_type_node,
5088 object, temp));
5089 return GS_OK;
5092 if (notify_temp_creation)
5093 return GS_OK;
5095 /* If there are nonzero elements and if needed, pre-evaluate to capture
5096 elements overlapping with the lhs into temporaries. We must do this
5097 before clearing to fetch the values before they are zeroed-out. */
5098 if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
5100 preeval_data.lhs_base_decl = get_base_address (object);
5101 if (!DECL_P (preeval_data.lhs_base_decl))
5102 preeval_data.lhs_base_decl = NULL;
5103 preeval_data.lhs_alias_set = get_alias_set (object);
5105 gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
5106 pre_p, post_p, &preeval_data);
5109 bool ctor_has_side_effects_p
5110 = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
5112 if (cleared)
5114 /* Zap the CONSTRUCTOR element list, which simplifies this case.
5115 Note that we still have to gimplify, in order to handle the
5116 case of variable sized types. Avoid shared tree structures. */
5117 CONSTRUCTOR_ELTS (ctor) = NULL;
5118 TREE_SIDE_EFFECTS (ctor) = 0;
5119 object = unshare_expr (object);
5120 gimplify_stmt (expr_p, pre_p);
5123 /* If we have not block cleared the object, or if there are nonzero
5124 elements in the constructor, or if the constructor has side effects,
5125 add assignments to the individual scalar fields of the object. */
5126 if (!cleared
5127 || num_nonzero_elements > 0
5128 || ctor_has_side_effects_p)
5129 gimplify_init_ctor_eval (object, elts, pre_p, cleared);
5131 *expr_p = NULL_TREE;
5133 break;
5135 case COMPLEX_TYPE:
5137 tree r, i;
5139 if (notify_temp_creation)
5140 return GS_OK;
5142 /* Extract the real and imaginary parts out of the ctor. */
5143 gcc_assert (elts->length () == 2);
5144 r = (*elts)[0].value;
5145 i = (*elts)[1].value;
5146 if (r == NULL || i == NULL)
5148 tree zero = build_zero_cst (TREE_TYPE (type));
5149 if (r == NULL)
5150 r = zero;
5151 if (i == NULL)
5152 i = zero;
5155 /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5156 represent creation of a complex value. */
5157 if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
5159 ctor = build_complex (type, r, i);
5160 TREE_OPERAND (*expr_p, 1) = ctor;
5162 else
5164 ctor = build2 (COMPLEX_EXPR, type, r, i);
5165 TREE_OPERAND (*expr_p, 1) = ctor;
5166 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
5167 pre_p,
5168 post_p,
5169 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
5170 fb_rvalue);
5173 break;
5175 case VECTOR_TYPE:
5177 unsigned HOST_WIDE_INT ix;
5178 constructor_elt *ce;
5180 if (notify_temp_creation)
5181 return GS_OK;
5183 /* Go ahead and simplify constant constructors to VECTOR_CST. */
5184 if (TREE_CONSTANT (ctor))
5186 bool constant_p = true;
5187 tree value;
5189 /* Even when ctor is constant, it might contain non-*_CST
5190 elements, such as addresses or trapping values like
5191 1.0/0.0 - 1.0/0.0. Such expressions don't belong
5192 in VECTOR_CST nodes. */
5193 FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5194 if (!CONSTANT_CLASS_P (value))
5196 constant_p = false;
5197 break;
5200 if (constant_p)
5202 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5203 break;
5206 TREE_CONSTANT (ctor) = 0;
5209 /* Vector types use CONSTRUCTOR all the way through gimple
5210 compilation as a general initializer. */
5211 FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5213 enum gimplify_status tret;
5214 tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5215 fb_rvalue);
5216 if (tret == GS_ERROR)
5217 ret = GS_ERROR;
5218 else if (TREE_STATIC (ctor)
5219 && !initializer_constant_valid_p (ce->value,
5220 TREE_TYPE (ce->value)))
5221 TREE_STATIC (ctor) = 0;
5223 recompute_constructor_flags (ctor);
5224 if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5225 TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5227 break;
5229 default:
5230 /* So how did we get a CONSTRUCTOR for a scalar type? */
5231 gcc_unreachable ();
5234 if (ret == GS_ERROR)
5235 return GS_ERROR;
5236 /* If we have gimplified both sides of the initializer but have
5237 not emitted an assignment, do so now. */
5238 if (*expr_p)
5240 tree lhs = TREE_OPERAND (*expr_p, 0);
5241 tree rhs = TREE_OPERAND (*expr_p, 1);
5242 if (want_value && object == lhs)
5243 lhs = unshare_expr (lhs);
5244 gassign *init = gimple_build_assign (lhs, rhs);
5245 gimplify_seq_add_stmt (pre_p, init);
5247 if (want_value)
5249 *expr_p = object;
5250 return GS_OK;
5252 else
5254 *expr_p = NULL;
5255 return GS_ALL_DONE;
5259 /* Given a pointer value OP0, return a simplified version of an
5260 indirection through OP0, or NULL_TREE if no simplification is
5261 possible. This may only be applied to a rhs of an expression.
5262 Note that the resulting type may be different from the type pointed
5263 to in the sense that it is still compatible from the langhooks
5264 point of view. */
5266 static tree
5267 gimple_fold_indirect_ref_rhs (tree t)
5269 return gimple_fold_indirect_ref (t);
5272 /* Subroutine of gimplify_modify_expr to do simplifications of
5273 MODIFY_EXPRs based on the code of the RHS. We loop for as long as
5274 something changes. */
5276 static enum gimplify_status
5277 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5278 gimple_seq *pre_p, gimple_seq *post_p,
5279 bool want_value)
5281 enum gimplify_status ret = GS_UNHANDLED;
5282 bool changed;
5286 changed = false;
5287 switch (TREE_CODE (*from_p))
5289 case VAR_DECL:
5290 /* If we're assigning from a read-only variable initialized with
5291 a constructor and not volatile, do the direct assignment from
5292 the constructor, but only if the target is not volatile either
5293 since this latter assignment might end up being done on a per
5294 field basis. However, if the target is volatile and the type
5295 is aggregate and non-addressable, gimplify_init_constructor
5296 knows that it needs to ensure a single access to the target
5297 and it will return GS_OK only in this case. */
5298 if (TREE_READONLY (*from_p)
5299 && DECL_INITIAL (*from_p)
5300 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR
5301 && !TREE_THIS_VOLATILE (*from_p)
5302 && (!TREE_THIS_VOLATILE (*to_p)
5303 || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p))
5304 && !TREE_ADDRESSABLE (TREE_TYPE (*to_p)))))
5306 tree old_from = *from_p;
5307 enum gimplify_status subret;
5309 /* Move the constructor into the RHS. */
5310 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5312 /* Let's see if gimplify_init_constructor will need to put
5313 it in memory. */
5314 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5315 false, true);
5316 if (subret == GS_ERROR)
5318 /* If so, revert the change. */
5319 *from_p = old_from;
5321 else
5323 ret = GS_OK;
5324 changed = true;
5327 break;
5328 case INDIRECT_REF:
5330 /* If we have code like
5332 *(const A*)(A*)&x
5334 where the type of "x" is a (possibly cv-qualified variant
5335 of "A"), treat the entire expression as identical to "x".
5336 This kind of code arises in C++ when an object is bound
5337 to a const reference, and if "x" is a TARGET_EXPR we want
5338 to take advantage of the optimization below. */
5339 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5340 tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5341 if (t)
5343 if (TREE_THIS_VOLATILE (t) != volatile_p)
5345 if (DECL_P (t))
5346 t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5347 build_fold_addr_expr (t));
5348 if (REFERENCE_CLASS_P (t))
5349 TREE_THIS_VOLATILE (t) = volatile_p;
5351 *from_p = t;
5352 ret = GS_OK;
5353 changed = true;
5355 break;
5358 case TARGET_EXPR:
5360 /* If we are initializing something from a TARGET_EXPR, strip the
5361 TARGET_EXPR and initialize it directly, if possible. This can't
5362 be done if the initializer is void, since that implies that the
5363 temporary is set in some non-trivial way.
5365 ??? What about code that pulls out the temp and uses it
5366 elsewhere? I think that such code never uses the TARGET_EXPR as
5367 an initializer. If I'm wrong, we'll die because the temp won't
5368 have any RTL. In that case, I guess we'll need to replace
5369 references somehow. */
5370 tree init = TARGET_EXPR_INITIAL (*from_p);
5372 if (init
5373 && (TREE_CODE (*expr_p) != MODIFY_EXPR
5374 || !TARGET_EXPR_NO_ELIDE (*from_p))
5375 && !VOID_TYPE_P (TREE_TYPE (init)))
5377 *from_p = init;
5378 ret = GS_OK;
5379 changed = true;
5382 break;
5384 case COMPOUND_EXPR:
5385 /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5386 caught. */
5387 gimplify_compound_expr (from_p, pre_p, true);
5388 ret = GS_OK;
5389 changed = true;
5390 break;
5392 case CONSTRUCTOR:
5393 /* If we already made some changes, let the front end have a
5394 crack at this before we break it down. */
5395 if (ret != GS_UNHANDLED)
5396 break;
5397 /* If we're initializing from a CONSTRUCTOR, break this into
5398 individual MODIFY_EXPRs. */
5399 return gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5400 false);
5402 case COND_EXPR:
5403 /* If we're assigning to a non-register type, push the assignment
5404 down into the branches. This is mandatory for ADDRESSABLE types,
5405 since we cannot generate temporaries for such, but it saves a
5406 copy in other cases as well. */
5407 if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5409 /* This code should mirror the code in gimplify_cond_expr. */
5410 enum tree_code code = TREE_CODE (*expr_p);
5411 tree cond = *from_p;
5412 tree result = *to_p;
5414 ret = gimplify_expr (&result, pre_p, post_p,
5415 is_gimple_lvalue, fb_lvalue);
5416 if (ret != GS_ERROR)
5417 ret = GS_OK;
5419 /* If we are going to write RESULT more than once, clear
5420 TREE_READONLY flag, otherwise we might incorrectly promote
5421 the variable to static const and initialize it at compile
5422 time in one of the branches. */
5423 if (VAR_P (result)
5424 && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5425 && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5426 TREE_READONLY (result) = 0;
5427 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5428 TREE_OPERAND (cond, 1)
5429 = build2 (code, void_type_node, result,
5430 TREE_OPERAND (cond, 1));
5431 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5432 TREE_OPERAND (cond, 2)
5433 = build2 (code, void_type_node, unshare_expr (result),
5434 TREE_OPERAND (cond, 2));
5436 TREE_TYPE (cond) = void_type_node;
5437 recalculate_side_effects (cond);
5439 if (want_value)
5441 gimplify_and_add (cond, pre_p);
5442 *expr_p = unshare_expr (result);
5444 else
5445 *expr_p = cond;
5446 return ret;
5448 break;
5450 case CALL_EXPR:
5451 /* For calls that return in memory, give *to_p as the CALL_EXPR's
5452 return slot so that we don't generate a temporary. */
5453 if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5454 && aggregate_value_p (*from_p, *from_p))
5456 bool use_target;
5458 if (!(rhs_predicate_for (*to_p))(*from_p))
5459 /* If we need a temporary, *to_p isn't accurate. */
5460 use_target = false;
5461 /* It's OK to use the return slot directly unless it's an NRV. */
5462 else if (TREE_CODE (*to_p) == RESULT_DECL
5463 && DECL_NAME (*to_p) == NULL_TREE
5464 && needs_to_live_in_memory (*to_p))
5465 use_target = true;
5466 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5467 || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5468 /* Don't force regs into memory. */
5469 use_target = false;
5470 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5471 /* It's OK to use the target directly if it's being
5472 initialized. */
5473 use_target = true;
5474 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5475 != INTEGER_CST)
5476 /* Always use the target and thus RSO for variable-sized types.
5477 GIMPLE cannot deal with a variable-sized assignment
5478 embedded in a call statement. */
5479 use_target = true;
5480 else if (TREE_CODE (*to_p) != SSA_NAME
5481 && (!is_gimple_variable (*to_p)
5482 || needs_to_live_in_memory (*to_p)))
5483 /* Don't use the original target if it's already addressable;
5484 if its address escapes, and the called function uses the
5485 NRV optimization, a conforming program could see *to_p
5486 change before the called function returns; see c++/19317.
5487 When optimizing, the return_slot pass marks more functions
5488 as safe after we have escape info. */
5489 use_target = false;
5490 else
5491 use_target = true;
5493 if (use_target)
5495 CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5496 mark_addressable (*to_p);
5499 break;
5501 case WITH_SIZE_EXPR:
5502 /* Likewise for calls that return an aggregate of non-constant size,
5503 since we would not be able to generate a temporary at all. */
5504 if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5506 *from_p = TREE_OPERAND (*from_p, 0);
5507 /* We don't change ret in this case because the
5508 WITH_SIZE_EXPR might have been added in
5509 gimplify_modify_expr, so returning GS_OK would lead to an
5510 infinite loop. */
5511 changed = true;
5513 break;
5515 /* If we're initializing from a container, push the initialization
5516 inside it. */
5517 case CLEANUP_POINT_EXPR:
5518 case BIND_EXPR:
5519 case STATEMENT_LIST:
5521 tree wrap = *from_p;
5522 tree t;
5524 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5525 fb_lvalue);
5526 if (ret != GS_ERROR)
5527 ret = GS_OK;
5529 t = voidify_wrapper_expr (wrap, *expr_p);
5530 gcc_assert (t == *expr_p);
5532 if (want_value)
5534 gimplify_and_add (wrap, pre_p);
5535 *expr_p = unshare_expr (*to_p);
5537 else
5538 *expr_p = wrap;
5539 return GS_OK;
5542 case NOP_EXPR:
5543 /* Pull out compound literal expressions from a NOP_EXPR.
5544 Those are created in the C FE to drop qualifiers during
5545 lvalue conversion. */
5546 if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
5547 && tree_ssa_useless_type_conversion (*from_p))
5549 *from_p = TREE_OPERAND (*from_p, 0);
5550 ret = GS_OK;
5551 changed = true;
5553 break;
5555 case COMPOUND_LITERAL_EXPR:
5557 tree complit = TREE_OPERAND (*expr_p, 1);
5558 tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5559 tree decl = DECL_EXPR_DECL (decl_s);
5560 tree init = DECL_INITIAL (decl);
5562 /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5563 into struct T x = { 0, 1, 2 } if the address of the
5564 compound literal has never been taken. */
5565 if (!TREE_ADDRESSABLE (complit)
5566 && !TREE_ADDRESSABLE (decl)
5567 && init)
5569 *expr_p = copy_node (*expr_p);
5570 TREE_OPERAND (*expr_p, 1) = init;
5571 return GS_OK;
5575 default:
5576 break;
5579 while (changed);
5581 return ret;
5585 /* Return true if T looks like a valid GIMPLE statement. */
5587 static bool
5588 is_gimple_stmt (tree t)
5590 const enum tree_code code = TREE_CODE (t);
5592 switch (code)
5594 case NOP_EXPR:
5595 /* The only valid NOP_EXPR is the empty statement. */
5596 return IS_EMPTY_STMT (t);
5598 case BIND_EXPR:
5599 case COND_EXPR:
5600 /* These are only valid if they're void. */
5601 return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5603 case SWITCH_EXPR:
5604 case GOTO_EXPR:
5605 case RETURN_EXPR:
5606 case LABEL_EXPR:
5607 case CASE_LABEL_EXPR:
5608 case TRY_CATCH_EXPR:
5609 case TRY_FINALLY_EXPR:
5610 case EH_FILTER_EXPR:
5611 case CATCH_EXPR:
5612 case ASM_EXPR:
5613 case STATEMENT_LIST:
5614 case OACC_PARALLEL:
5615 case OACC_KERNELS:
5616 case OACC_SERIAL:
5617 case OACC_DATA:
5618 case OACC_HOST_DATA:
5619 case OACC_DECLARE:
5620 case OACC_UPDATE:
5621 case OACC_ENTER_DATA:
5622 case OACC_EXIT_DATA:
5623 case OACC_CACHE:
5624 case OMP_PARALLEL:
5625 case OMP_FOR:
5626 case OMP_SIMD:
5627 case OMP_DISTRIBUTE:
5628 case OMP_LOOP:
5629 case OACC_LOOP:
5630 case OMP_SCAN:
5631 case OMP_SCOPE:
5632 case OMP_SECTIONS:
5633 case OMP_SECTION:
5634 case OMP_SINGLE:
5635 case OMP_MASTER:
5636 case OMP_MASKED:
5637 case OMP_TASKGROUP:
5638 case OMP_ORDERED:
5639 case OMP_CRITICAL:
5640 case OMP_TASK:
5641 case OMP_TARGET:
5642 case OMP_TARGET_DATA:
5643 case OMP_TARGET_UPDATE:
5644 case OMP_TARGET_ENTER_DATA:
5645 case OMP_TARGET_EXIT_DATA:
5646 case OMP_TASKLOOP:
5647 case OMP_TEAMS:
5648 /* These are always void. */
5649 return true;
5651 case CALL_EXPR:
5652 case MODIFY_EXPR:
5653 case PREDICT_EXPR:
5654 /* These are valid regardless of their type. */
5655 return true;
5657 default:
5658 return false;
5663 /* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
5664 a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
5666 IMPORTANT NOTE: This promotion is performed by introducing a load of the
5667 other, unmodified part of the complex object just before the total store.
5668 As a consequence, if the object is still uninitialized, an undefined value
5669 will be loaded into a register, which may result in a spurious exception
5670 if the register is floating-point and the value happens to be a signaling
5671 NaN for example. Then the fully-fledged complex operations lowering pass
5672 followed by a DCE pass are necessary in order to fix things up. */
5674 static enum gimplify_status
5675 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5676 bool want_value)
5678 enum tree_code code, ocode;
5679 tree lhs, rhs, new_rhs, other, realpart, imagpart;
5681 lhs = TREE_OPERAND (*expr_p, 0);
5682 rhs = TREE_OPERAND (*expr_p, 1);
5683 code = TREE_CODE (lhs);
5684 lhs = TREE_OPERAND (lhs, 0);
5686 ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5687 other = build1 (ocode, TREE_TYPE (rhs), lhs);
5688 suppress_warning (other);
5689 other = get_formal_tmp_var (other, pre_p);
5691 realpart = code == REALPART_EXPR ? rhs : other;
5692 imagpart = code == REALPART_EXPR ? other : rhs;
5694 if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5695 new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5696 else
5697 new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5699 gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5700 *expr_p = (want_value) ? rhs : NULL_TREE;
5702 return GS_ALL_DONE;
5705 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5707 modify_expr
5708 : varname '=' rhs
5709 | '*' ID '=' rhs
5711 PRE_P points to the list where side effects that must happen before
5712 *EXPR_P should be stored.
5714 POST_P points to the list where side effects that must happen after
5715 *EXPR_P should be stored.
5717 WANT_VALUE is nonzero iff we want to use the value of this expression
5718 in another expression. */
5720 static enum gimplify_status
5721 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5722 bool want_value)
5724 tree *from_p = &TREE_OPERAND (*expr_p, 1);
5725 tree *to_p = &TREE_OPERAND (*expr_p, 0);
5726 enum gimplify_status ret = GS_UNHANDLED;
5727 gimple *assign;
5728 location_t loc = EXPR_LOCATION (*expr_p);
5729 gimple_stmt_iterator gsi;
5731 gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
5732 || TREE_CODE (*expr_p) == INIT_EXPR);
5734 /* Trying to simplify a clobber using normal logic doesn't work,
5735 so handle it here. */
5736 if (TREE_CLOBBER_P (*from_p))
5738 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5739 if (ret == GS_ERROR)
5740 return ret;
5741 gcc_assert (!want_value);
5742 if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
5744 tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
5745 pre_p, post_p);
5746 *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
5748 gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
5749 *expr_p = NULL;
5750 return GS_ALL_DONE;
5753 /* Insert pointer conversions required by the middle-end that are not
5754 required by the frontend. This fixes middle-end type checking for
5755 for example gcc.dg/redecl-6.c. */
5756 if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
5758 STRIP_USELESS_TYPE_CONVERSION (*from_p);
5759 if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
5760 *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
5763 /* See if any simplifications can be done based on what the RHS is. */
5764 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5765 want_value);
5766 if (ret != GS_UNHANDLED)
5767 return ret;
5769 /* For empty types only gimplify the left hand side and right hand
5770 side as statements and throw away the assignment. Do this after
5771 gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
5772 types properly. */
5773 if (is_empty_type (TREE_TYPE (*from_p))
5774 && !want_value
5775 /* Don't do this for calls that return addressable types, expand_call
5776 relies on those having a lhs. */
5777 && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
5778 && TREE_CODE (*from_p) == CALL_EXPR))
5780 gimplify_stmt (from_p, pre_p);
5781 gimplify_stmt (to_p, pre_p);
5782 *expr_p = NULL_TREE;
5783 return GS_ALL_DONE;
5786 /* If the value being copied is of variable width, compute the length
5787 of the copy into a WITH_SIZE_EXPR. Note that we need to do this
5788 before gimplifying any of the operands so that we can resolve any
5789 PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
5790 the size of the expression to be copied, not of the destination, so
5791 that is what we must do here. */
5792 maybe_with_size_expr (from_p);
5794 /* As a special case, we have to temporarily allow for assignments
5795 with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
5796 a toplevel statement, when gimplifying the GENERIC expression
5797 MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
5798 GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
5800 Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
5801 prevent gimplify_expr from trying to create a new temporary for
5802 foo's LHS, we tell it that it should only gimplify until it
5803 reaches the CALL_EXPR. On return from gimplify_expr, the newly
5804 created GIMPLE_CALL <foo> will be the last statement in *PRE_P
5805 and all we need to do here is set 'a' to be its LHS. */
5807 /* Gimplify the RHS first for C++17 and bug 71104. */
5808 gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
5809 ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
5810 if (ret == GS_ERROR)
5811 return ret;
5813 /* Then gimplify the LHS. */
5814 /* If we gimplified the RHS to a CALL_EXPR and that call may return
5815 twice we have to make sure to gimplify into non-SSA as otherwise
5816 the abnormal edge added later will make those defs not dominate
5817 their uses.
5818 ??? Technically this applies only to the registers used in the
5819 resulting non-register *TO_P. */
5820 bool saved_into_ssa = gimplify_ctxp->into_ssa;
5821 if (saved_into_ssa
5822 && TREE_CODE (*from_p) == CALL_EXPR
5823 && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
5824 gimplify_ctxp->into_ssa = false;
5825 ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
5826 gimplify_ctxp->into_ssa = saved_into_ssa;
5827 if (ret == GS_ERROR)
5828 return ret;
5830 /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
5831 guess for the predicate was wrong. */
5832 gimple_predicate final_pred = rhs_predicate_for (*to_p);
5833 if (final_pred != initial_pred)
5835 ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
5836 if (ret == GS_ERROR)
5837 return ret;
5840 /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
5841 size as argument to the call. */
5842 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5844 tree call = TREE_OPERAND (*from_p, 0);
5845 tree vlasize = TREE_OPERAND (*from_p, 1);
5847 if (TREE_CODE (call) == CALL_EXPR
5848 && CALL_EXPR_IFN (call) == IFN_VA_ARG)
5850 int nargs = call_expr_nargs (call);
5851 tree type = TREE_TYPE (call);
5852 tree ap = CALL_EXPR_ARG (call, 0);
5853 tree tag = CALL_EXPR_ARG (call, 1);
5854 tree aptag = CALL_EXPR_ARG (call, 2);
5855 tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
5856 IFN_VA_ARG, type,
5857 nargs + 1, ap, tag,
5858 aptag, vlasize);
5859 TREE_OPERAND (*from_p, 0) = newcall;
5863 /* Now see if the above changed *from_p to something we handle specially. */
5864 ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
5865 want_value);
5866 if (ret != GS_UNHANDLED)
5867 return ret;
5869 /* If we've got a variable sized assignment between two lvalues (i.e. does
5870 not involve a call), then we can make things a bit more straightforward
5871 by converting the assignment to memcpy or memset. */
5872 if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
5874 tree from = TREE_OPERAND (*from_p, 0);
5875 tree size = TREE_OPERAND (*from_p, 1);
5877 if (TREE_CODE (from) == CONSTRUCTOR)
5878 return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
5880 if (is_gimple_addressable (from))
5882 *from_p = from;
5883 return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
5884 pre_p);
5888 /* Transform partial stores to non-addressable complex variables into
5889 total stores. This allows us to use real instead of virtual operands
5890 for these variables, which improves optimization. */
5891 if ((TREE_CODE (*to_p) == REALPART_EXPR
5892 || TREE_CODE (*to_p) == IMAGPART_EXPR)
5893 && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
5894 return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
5896 /* Try to alleviate the effects of the gimplification creating artificial
5897 temporaries (see for example is_gimple_reg_rhs) on the debug info, but
5898 make sure not to create DECL_DEBUG_EXPR links across functions. */
5899 if (!gimplify_ctxp->into_ssa
5900 && VAR_P (*from_p)
5901 && DECL_IGNORED_P (*from_p)
5902 && DECL_P (*to_p)
5903 && !DECL_IGNORED_P (*to_p)
5904 && decl_function_context (*to_p) == current_function_decl
5905 && decl_function_context (*from_p) == current_function_decl)
5907 if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
5908 DECL_NAME (*from_p)
5909 = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
5910 DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
5911 SET_DECL_DEBUG_EXPR (*from_p, *to_p);
5914 if (want_value && TREE_THIS_VOLATILE (*to_p))
5915 *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
5917 if (TREE_CODE (*from_p) == CALL_EXPR)
5919 /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
5920 instead of a GIMPLE_ASSIGN. */
5921 gcall *call_stmt;
5922 if (CALL_EXPR_FN (*from_p) == NULL_TREE)
5924 /* Gimplify internal functions created in the FEs. */
5925 int nargs = call_expr_nargs (*from_p), i;
5926 enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
5927 auto_vec<tree> vargs (nargs);
5929 for (i = 0; i < nargs; i++)
5931 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
5932 EXPR_LOCATION (*from_p));
5933 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
5935 call_stmt = gimple_build_call_internal_vec (ifn, vargs);
5936 gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
5937 gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
5939 else
5941 tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
5942 CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
5943 STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
5944 tree fndecl = get_callee_fndecl (*from_p);
5945 if (fndecl
5946 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
5947 && call_expr_nargs (*from_p) == 3)
5948 call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
5949 CALL_EXPR_ARG (*from_p, 0),
5950 CALL_EXPR_ARG (*from_p, 1),
5951 CALL_EXPR_ARG (*from_p, 2));
5952 else
5954 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
5957 notice_special_calls (call_stmt);
5958 if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
5959 gimple_call_set_lhs (call_stmt, *to_p);
5960 else if (TREE_CODE (*to_p) == SSA_NAME)
5961 /* The above is somewhat premature, avoid ICEing later for a
5962 SSA name w/o a definition. We may have uses in the GIMPLE IL.
5963 ??? This doesn't make it a default-def. */
5964 SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
5966 assign = call_stmt;
5968 else
5970 assign = gimple_build_assign (*to_p, *from_p);
5971 gimple_set_location (assign, EXPR_LOCATION (*expr_p));
5972 if (COMPARISON_CLASS_P (*from_p))
5973 copy_warning (assign, *from_p);
5976 if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
5978 /* We should have got an SSA name from the start. */
5979 gcc_assert (TREE_CODE (*to_p) == SSA_NAME
5980 || ! gimple_in_ssa_p (cfun));
5983 gimplify_seq_add_stmt (pre_p, assign);
5984 gsi = gsi_last (*pre_p);
5985 maybe_fold_stmt (&gsi);
5987 if (want_value)
5989 *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
5990 return GS_OK;
5992 else
5993 *expr_p = NULL;
5995 return GS_ALL_DONE;
5998 /* Gimplify a comparison between two variable-sized objects. Do this
5999 with a call to BUILT_IN_MEMCMP. */
6001 static enum gimplify_status
6002 gimplify_variable_sized_compare (tree *expr_p)
6004 location_t loc = EXPR_LOCATION (*expr_p);
6005 tree op0 = TREE_OPERAND (*expr_p, 0);
6006 tree op1 = TREE_OPERAND (*expr_p, 1);
6007 tree t, arg, dest, src, expr;
6009 arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
6010 arg = unshare_expr (arg);
6011 arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
6012 src = build_fold_addr_expr_loc (loc, op1);
6013 dest = build_fold_addr_expr_loc (loc, op0);
6014 t = builtin_decl_implicit (BUILT_IN_MEMCMP);
6015 t = build_call_expr_loc (loc, t, 3, dest, src, arg);
6017 expr
6018 = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
6019 SET_EXPR_LOCATION (expr, loc);
6020 *expr_p = expr;
6022 return GS_OK;
6025 /* Gimplify a comparison between two aggregate objects of integral scalar
6026 mode as a comparison between the bitwise equivalent scalar values. */
6028 static enum gimplify_status
6029 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
6031 location_t loc = EXPR_LOCATION (*expr_p);
6032 tree op0 = TREE_OPERAND (*expr_p, 0);
6033 tree op1 = TREE_OPERAND (*expr_p, 1);
6035 tree type = TREE_TYPE (op0);
6036 tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
6038 op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
6039 op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
6041 *expr_p
6042 = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
6044 return GS_OK;
6047 /* Gimplify an expression sequence. This function gimplifies each
6048 expression and rewrites the original expression with the last
6049 expression of the sequence in GIMPLE form.
6051 PRE_P points to the list where the side effects for all the
6052 expressions in the sequence will be emitted.
6054 WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
6056 static enum gimplify_status
6057 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
6059 tree t = *expr_p;
6063 tree *sub_p = &TREE_OPERAND (t, 0);
6065 if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
6066 gimplify_compound_expr (sub_p, pre_p, false);
6067 else
6068 gimplify_stmt (sub_p, pre_p);
6070 t = TREE_OPERAND (t, 1);
6072 while (TREE_CODE (t) == COMPOUND_EXPR);
6074 *expr_p = t;
6075 if (want_value)
6076 return GS_OK;
6077 else
6079 gimplify_stmt (expr_p, pre_p);
6080 return GS_ALL_DONE;
6084 /* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
6085 gimplify. After gimplification, EXPR_P will point to a new temporary
6086 that holds the original value of the SAVE_EXPR node.
6088 PRE_P points to the list where side effects that must happen before
6089 *EXPR_P should be stored. */
6091 static enum gimplify_status
6092 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6094 enum gimplify_status ret = GS_ALL_DONE;
6095 tree val;
6097 gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
6098 val = TREE_OPERAND (*expr_p, 0);
6100 /* If the SAVE_EXPR has not been resolved, then evaluate it once. */
6101 if (!SAVE_EXPR_RESOLVED_P (*expr_p))
6103 /* The operand may be a void-valued expression. It is
6104 being executed only for its side-effects. */
6105 if (TREE_TYPE (val) == void_type_node)
6107 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
6108 is_gimple_stmt, fb_none);
6109 val = NULL;
6111 else
6112 /* The temporary may not be an SSA name as later abnormal and EH
6113 control flow may invalidate use/def domination. When in SSA
6114 form then assume there are no such issues and SAVE_EXPRs only
6115 appear via GENERIC foldings. */
6116 val = get_initialized_tmp_var (val, pre_p, post_p,
6117 gimple_in_ssa_p (cfun));
6119 TREE_OPERAND (*expr_p, 0) = val;
6120 SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
6123 *expr_p = val;
6125 return ret;
6128 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6130 unary_expr
6131 : ...
6132 | '&' varname
6135 PRE_P points to the list where side effects that must happen before
6136 *EXPR_P should be stored.
6138 POST_P points to the list where side effects that must happen after
6139 *EXPR_P should be stored. */
6141 static enum gimplify_status
6142 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6144 tree expr = *expr_p;
6145 tree op0 = TREE_OPERAND (expr, 0);
6146 enum gimplify_status ret;
6147 location_t loc = EXPR_LOCATION (*expr_p);
6149 switch (TREE_CODE (op0))
6151 case INDIRECT_REF:
6152 do_indirect_ref:
6153 /* Check if we are dealing with an expression of the form '&*ptr'.
6154 While the front end folds away '&*ptr' into 'ptr', these
6155 expressions may be generated internally by the compiler (e.g.,
6156 builtins like __builtin_va_end). */
6157 /* Caution: the silent array decomposition semantics we allow for
6158 ADDR_EXPR means we can't always discard the pair. */
6159 /* Gimplification of the ADDR_EXPR operand may drop
6160 cv-qualification conversions, so make sure we add them if
6161 needed. */
6163 tree op00 = TREE_OPERAND (op0, 0);
6164 tree t_expr = TREE_TYPE (expr);
6165 tree t_op00 = TREE_TYPE (op00);
6167 if (!useless_type_conversion_p (t_expr, t_op00))
6168 op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
6169 *expr_p = op00;
6170 ret = GS_OK;
6172 break;
6174 case VIEW_CONVERT_EXPR:
6175 /* Take the address of our operand and then convert it to the type of
6176 this ADDR_EXPR.
6178 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6179 all clear. The impact of this transformation is even less clear. */
6181 /* If the operand is a useless conversion, look through it. Doing so
6182 guarantees that the ADDR_EXPR and its operand will remain of the
6183 same type. */
6184 if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
6185 op0 = TREE_OPERAND (op0, 0);
6187 *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
6188 build_fold_addr_expr_loc (loc,
6189 TREE_OPERAND (op0, 0)));
6190 ret = GS_OK;
6191 break;
6193 case MEM_REF:
6194 if (integer_zerop (TREE_OPERAND (op0, 1)))
6195 goto do_indirect_ref;
6197 /* fall through */
6199 default:
6200 /* If we see a call to a declared builtin or see its address
6201 being taken (we can unify those cases here) then we can mark
6202 the builtin for implicit generation by GCC. */
6203 if (TREE_CODE (op0) == FUNCTION_DECL
6204 && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6205 && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6206 set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6208 /* We use fb_either here because the C frontend sometimes takes
6209 the address of a call that returns a struct; see
6210 gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
6211 the implied temporary explicit. */
6213 /* Make the operand addressable. */
6214 ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6215 is_gimple_addressable, fb_either);
6216 if (ret == GS_ERROR)
6217 break;
6219 /* Then mark it. Beware that it may not be possible to do so directly
6220 if a temporary has been created by the gimplification. */
6221 prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6223 op0 = TREE_OPERAND (expr, 0);
6225 /* For various reasons, the gimplification of the expression
6226 may have made a new INDIRECT_REF. */
6227 if (TREE_CODE (op0) == INDIRECT_REF
6228 || (TREE_CODE (op0) == MEM_REF
6229 && integer_zerop (TREE_OPERAND (op0, 1))))
6230 goto do_indirect_ref;
6232 mark_addressable (TREE_OPERAND (expr, 0));
6234 /* The FEs may end up building ADDR_EXPRs early on a decl with
6235 an incomplete type. Re-build ADDR_EXPRs in canonical form
6236 here. */
6237 if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6238 *expr_p = build_fold_addr_expr (op0);
6240 /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */
6241 recompute_tree_invariant_for_addr_expr (*expr_p);
6243 /* If we re-built the ADDR_EXPR add a conversion to the original type
6244 if required. */
6245 if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6246 *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6248 break;
6251 return ret;
6254 /* Gimplify the operands of an ASM_EXPR. Input operands should be a gimple
6255 value; output operands should be a gimple lvalue. */
6257 static enum gimplify_status
6258 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6260 tree expr;
6261 int noutputs;
6262 const char **oconstraints;
6263 int i;
6264 tree link;
6265 const char *constraint;
6266 bool allows_mem, allows_reg, is_inout;
6267 enum gimplify_status ret, tret;
6268 gasm *stmt;
6269 vec<tree, va_gc> *inputs;
6270 vec<tree, va_gc> *outputs;
6271 vec<tree, va_gc> *clobbers;
6272 vec<tree, va_gc> *labels;
6273 tree link_next;
6275 expr = *expr_p;
6276 noutputs = list_length (ASM_OUTPUTS (expr));
6277 oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6279 inputs = NULL;
6280 outputs = NULL;
6281 clobbers = NULL;
6282 labels = NULL;
6284 ret = GS_ALL_DONE;
6285 link_next = NULL_TREE;
6286 for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6288 bool ok;
6289 size_t constraint_len;
6291 link_next = TREE_CHAIN (link);
6293 oconstraints[i]
6294 = constraint
6295 = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6296 constraint_len = strlen (constraint);
6297 if (constraint_len == 0)
6298 continue;
6300 ok = parse_output_constraint (&constraint, i, 0, 0,
6301 &allows_mem, &allows_reg, &is_inout);
6302 if (!ok)
6304 ret = GS_ERROR;
6305 is_inout = false;
6308 /* If we can't make copies, we can only accept memory.
6309 Similarly for VLAs. */
6310 tree outtype = TREE_TYPE (TREE_VALUE (link));
6311 if (outtype != error_mark_node
6312 && (TREE_ADDRESSABLE (outtype)
6313 || !COMPLETE_TYPE_P (outtype)
6314 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
6316 if (allows_mem)
6317 allows_reg = 0;
6318 else
6320 error ("impossible constraint in %<asm%>");
6321 error ("non-memory output %d must stay in memory", i);
6322 return GS_ERROR;
6326 if (!allows_reg && allows_mem)
6327 mark_addressable (TREE_VALUE (link));
6329 tree orig = TREE_VALUE (link);
6330 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6331 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6332 fb_lvalue | fb_mayfail);
6333 if (tret == GS_ERROR)
6335 if (orig != error_mark_node)
6336 error ("invalid lvalue in %<asm%> output %d", i);
6337 ret = tret;
6340 /* If the constraint does not allow memory make sure we gimplify
6341 it to a register if it is not already but its base is. This
6342 happens for complex and vector components. */
6343 if (!allows_mem)
6345 tree op = TREE_VALUE (link);
6346 if (! is_gimple_val (op)
6347 && is_gimple_reg_type (TREE_TYPE (op))
6348 && is_gimple_reg (get_base_address (op)))
6350 tree tem = create_tmp_reg (TREE_TYPE (op));
6351 tree ass;
6352 if (is_inout)
6354 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6355 tem, unshare_expr (op));
6356 gimplify_and_add (ass, pre_p);
6358 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6359 gimplify_and_add (ass, post_p);
6361 TREE_VALUE (link) = tem;
6362 tret = GS_OK;
6366 vec_safe_push (outputs, link);
6367 TREE_CHAIN (link) = NULL_TREE;
6369 if (is_inout)
6371 /* An input/output operand. To give the optimizers more
6372 flexibility, split it into separate input and output
6373 operands. */
6374 tree input;
6375 /* Buffer big enough to format a 32-bit UINT_MAX into. */
6376 char buf[11];
6378 /* Turn the in/out constraint into an output constraint. */
6379 char *p = xstrdup (constraint);
6380 p[0] = '=';
6381 TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6383 /* And add a matching input constraint. */
6384 if (allows_reg)
6386 sprintf (buf, "%u", i);
6388 /* If there are multiple alternatives in the constraint,
6389 handle each of them individually. Those that allow register
6390 will be replaced with operand number, the others will stay
6391 unchanged. */
6392 if (strchr (p, ',') != NULL)
6394 size_t len = 0, buflen = strlen (buf);
6395 char *beg, *end, *str, *dst;
6397 for (beg = p + 1;;)
6399 end = strchr (beg, ',');
6400 if (end == NULL)
6401 end = strchr (beg, '\0');
6402 if ((size_t) (end - beg) < buflen)
6403 len += buflen + 1;
6404 else
6405 len += end - beg + 1;
6406 if (*end)
6407 beg = end + 1;
6408 else
6409 break;
6412 str = (char *) alloca (len);
6413 for (beg = p + 1, dst = str;;)
6415 const char *tem;
6416 bool mem_p, reg_p, inout_p;
6418 end = strchr (beg, ',');
6419 if (end)
6420 *end = '\0';
6421 beg[-1] = '=';
6422 tem = beg - 1;
6423 parse_output_constraint (&tem, i, 0, 0,
6424 &mem_p, &reg_p, &inout_p);
6425 if (dst != str)
6426 *dst++ = ',';
6427 if (reg_p)
6429 memcpy (dst, buf, buflen);
6430 dst += buflen;
6432 else
6434 if (end)
6435 len = end - beg;
6436 else
6437 len = strlen (beg);
6438 memcpy (dst, beg, len);
6439 dst += len;
6441 if (end)
6442 beg = end + 1;
6443 else
6444 break;
6446 *dst = '\0';
6447 input = build_string (dst - str, str);
6449 else
6450 input = build_string (strlen (buf), buf);
6452 else
6453 input = build_string (constraint_len - 1, constraint + 1);
6455 free (p);
6457 input = build_tree_list (build_tree_list (NULL_TREE, input),
6458 unshare_expr (TREE_VALUE (link)));
6459 ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6463 link_next = NULL_TREE;
6464 for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6466 link_next = TREE_CHAIN (link);
6467 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6468 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6469 oconstraints, &allows_mem, &allows_reg);
6471 /* If we can't make copies, we can only accept memory. */
6472 tree intype = TREE_TYPE (TREE_VALUE (link));
6473 if (intype != error_mark_node
6474 && (TREE_ADDRESSABLE (intype)
6475 || !COMPLETE_TYPE_P (intype)
6476 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
6478 if (allows_mem)
6479 allows_reg = 0;
6480 else
6482 error ("impossible constraint in %<asm%>");
6483 error ("non-memory input %d must stay in memory", i);
6484 return GS_ERROR;
6488 /* If the operand is a memory input, it should be an lvalue. */
6489 if (!allows_reg && allows_mem)
6491 tree inputv = TREE_VALUE (link);
6492 STRIP_NOPS (inputv);
6493 if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6494 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6495 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6496 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6497 || TREE_CODE (inputv) == MODIFY_EXPR)
6498 TREE_VALUE (link) = error_mark_node;
6499 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6500 is_gimple_lvalue, fb_lvalue | fb_mayfail);
6501 if (tret != GS_ERROR)
6503 /* Unlike output operands, memory inputs are not guaranteed
6504 to be lvalues by the FE, and while the expressions are
6505 marked addressable there, if it is e.g. a statement
6506 expression, temporaries in it might not end up being
6507 addressable. They might be already used in the IL and thus
6508 it is too late to make them addressable now though. */
6509 tree x = TREE_VALUE (link);
6510 while (handled_component_p (x))
6511 x = TREE_OPERAND (x, 0);
6512 if (TREE_CODE (x) == MEM_REF
6513 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6514 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6515 if ((VAR_P (x)
6516 || TREE_CODE (x) == PARM_DECL
6517 || TREE_CODE (x) == RESULT_DECL)
6518 && !TREE_ADDRESSABLE (x)
6519 && is_gimple_reg (x))
6521 warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6522 input_location), 0,
6523 "memory input %d is not directly addressable",
6525 prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6528 mark_addressable (TREE_VALUE (link));
6529 if (tret == GS_ERROR)
6531 if (inputv != error_mark_node)
6532 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6533 "memory input %d is not directly addressable", i);
6534 ret = tret;
6537 else
6539 tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6540 is_gimple_asm_val, fb_rvalue);
6541 if (tret == GS_ERROR)
6542 ret = tret;
6545 TREE_CHAIN (link) = NULL_TREE;
6546 vec_safe_push (inputs, link);
6549 link_next = NULL_TREE;
6550 for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6552 link_next = TREE_CHAIN (link);
6553 TREE_CHAIN (link) = NULL_TREE;
6554 vec_safe_push (clobbers, link);
6557 link_next = NULL_TREE;
6558 for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6560 link_next = TREE_CHAIN (link);
6561 TREE_CHAIN (link) = NULL_TREE;
6562 vec_safe_push (labels, link);
6565 /* Do not add ASMs with errors to the gimple IL stream. */
6566 if (ret != GS_ERROR)
6568 stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6569 inputs, outputs, clobbers, labels);
6571 gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr) || noutputs == 0);
6572 gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6573 gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
6575 gimplify_seq_add_stmt (pre_p, stmt);
6578 return ret;
6581 /* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
6582 GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6583 gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6584 return to this function.
6586 FIXME should we complexify the prequeue handling instead? Or use flags
6587 for all the cleanups and let the optimizer tighten them up? The current
6588 code seems pretty fragile; it will break on a cleanup within any
6589 non-conditional nesting. But any such nesting would be broken, anyway;
6590 we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6591 and continues out of it. We can do that at the RTL level, though, so
6592 having an optimizer to tighten up try/finally regions would be a Good
6593 Thing. */
6595 static enum gimplify_status
6596 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6598 gimple_stmt_iterator iter;
6599 gimple_seq body_sequence = NULL;
6601 tree temp = voidify_wrapper_expr (*expr_p, NULL);
6603 /* We only care about the number of conditions between the innermost
6604 CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
6605 any cleanups collected outside the CLEANUP_POINT_EXPR. */
6606 int old_conds = gimplify_ctxp->conditions;
6607 gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6608 bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6609 gimplify_ctxp->conditions = 0;
6610 gimplify_ctxp->conditional_cleanups = NULL;
6611 gimplify_ctxp->in_cleanup_point_expr = true;
6613 gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6615 gimplify_ctxp->conditions = old_conds;
6616 gimplify_ctxp->conditional_cleanups = old_cleanups;
6617 gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6619 for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6621 gimple *wce = gsi_stmt (iter);
6623 if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6625 if (gsi_one_before_end_p (iter))
6627 /* Note that gsi_insert_seq_before and gsi_remove do not
6628 scan operands, unlike some other sequence mutators. */
6629 if (!gimple_wce_cleanup_eh_only (wce))
6630 gsi_insert_seq_before_without_update (&iter,
6631 gimple_wce_cleanup (wce),
6632 GSI_SAME_STMT);
6633 gsi_remove (&iter, true);
6634 break;
6636 else
6638 gtry *gtry;
6639 gimple_seq seq;
6640 enum gimple_try_flags kind;
6642 if (gimple_wce_cleanup_eh_only (wce))
6643 kind = GIMPLE_TRY_CATCH;
6644 else
6645 kind = GIMPLE_TRY_FINALLY;
6646 seq = gsi_split_seq_after (iter);
6648 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6649 /* Do not use gsi_replace here, as it may scan operands.
6650 We want to do a simple structural modification only. */
6651 gsi_set_stmt (&iter, gtry);
6652 iter = gsi_start (gtry->eval);
6655 else
6656 gsi_next (&iter);
6659 gimplify_seq_add_seq (pre_p, body_sequence);
6660 if (temp)
6662 *expr_p = temp;
6663 return GS_OK;
6665 else
6667 *expr_p = NULL;
6668 return GS_ALL_DONE;
6672 /* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
6673 is the cleanup action required. EH_ONLY is true if the cleanup should
6674 only be executed if an exception is thrown, not on normal exit.
6675 If FORCE_UNCOND is true perform the cleanup unconditionally; this is
6676 only valid for clobbers. */
6678 static void
6679 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6680 bool force_uncond = false)
6682 gimple *wce;
6683 gimple_seq cleanup_stmts = NULL;
6685 /* Errors can result in improperly nested cleanups. Which results in
6686 confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
6687 if (seen_error ())
6688 return;
6690 if (gimple_conditional_context ())
6692 /* If we're in a conditional context, this is more complex. We only
6693 want to run the cleanup if we actually ran the initialization that
6694 necessitates it, but we want to run it after the end of the
6695 conditional context. So we wrap the try/finally around the
6696 condition and use a flag to determine whether or not to actually
6697 run the destructor. Thus
6699 test ? f(A()) : 0
6701 becomes (approximately)
6703 flag = 0;
6704 try {
6705 if (test) { A::A(temp); flag = 1; val = f(temp); }
6706 else { val = 0; }
6707 } finally {
6708 if (flag) A::~A(temp);
6712 if (force_uncond)
6714 gimplify_stmt (&cleanup, &cleanup_stmts);
6715 wce = gimple_build_wce (cleanup_stmts);
6716 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6718 else
6720 tree flag = create_tmp_var (boolean_type_node, "cleanup");
6721 gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
6722 gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
6724 cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
6725 gimplify_stmt (&cleanup, &cleanup_stmts);
6726 wce = gimple_build_wce (cleanup_stmts);
6728 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
6729 gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
6730 gimplify_seq_add_stmt (pre_p, ftrue);
6732 /* Because of this manipulation, and the EH edges that jump
6733 threading cannot redirect, the temporary (VAR) will appear
6734 to be used uninitialized. Don't warn. */
6735 suppress_warning (var, OPT_Wuninitialized);
6738 else
6740 gimplify_stmt (&cleanup, &cleanup_stmts);
6741 wce = gimple_build_wce (cleanup_stmts);
6742 gimple_wce_set_cleanup_eh_only (wce, eh_only);
6743 gimplify_seq_add_stmt (pre_p, wce);
6747 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
6749 static enum gimplify_status
6750 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6752 tree targ = *expr_p;
6753 tree temp = TARGET_EXPR_SLOT (targ);
6754 tree init = TARGET_EXPR_INITIAL (targ);
6755 enum gimplify_status ret;
6757 bool unpoison_empty_seq = false;
6758 gimple_stmt_iterator unpoison_it;
6760 if (init)
6762 tree cleanup = NULL_TREE;
6764 /* TARGET_EXPR temps aren't part of the enclosing block, so add it
6765 to the temps list. Handle also variable length TARGET_EXPRs. */
6766 if (!poly_int_tree_p (DECL_SIZE (temp)))
6768 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
6769 gimplify_type_sizes (TREE_TYPE (temp), pre_p);
6770 gimplify_vla_decl (temp, pre_p);
6772 else
6774 /* Save location where we need to place unpoisoning. It's possible
6775 that a variable will be converted to needs_to_live_in_memory. */
6776 unpoison_it = gsi_last (*pre_p);
6777 unpoison_empty_seq = gsi_end_p (unpoison_it);
6779 gimple_add_tmp_var (temp);
6782 /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
6783 expression is supposed to initialize the slot. */
6784 if (VOID_TYPE_P (TREE_TYPE (init)))
6785 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6786 else
6788 tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
6789 init = init_expr;
6790 ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
6791 init = NULL;
6792 ggc_free (init_expr);
6794 if (ret == GS_ERROR)
6796 /* PR c++/28266 Make sure this is expanded only once. */
6797 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6798 return GS_ERROR;
6800 if (init)
6801 gimplify_and_add (init, pre_p);
6803 /* If needed, push the cleanup for the temp. */
6804 if (TARGET_EXPR_CLEANUP (targ))
6806 if (CLEANUP_EH_ONLY (targ))
6807 gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
6808 CLEANUP_EH_ONLY (targ), pre_p);
6809 else
6810 cleanup = TARGET_EXPR_CLEANUP (targ);
6813 /* Add a clobber for the temporary going out of scope, like
6814 gimplify_bind_expr. */
6815 if (gimplify_ctxp->in_cleanup_point_expr
6816 && needs_to_live_in_memory (temp))
6818 if (flag_stack_reuse == SR_ALL)
6820 tree clobber = build_clobber (TREE_TYPE (temp));
6821 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
6822 gimple_push_cleanup (temp, clobber, false, pre_p, true);
6824 if (asan_poisoned_variables
6825 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
6826 && !TREE_STATIC (temp)
6827 && dbg_cnt (asan_use_after_scope)
6828 && !gimplify_omp_ctxp)
6830 tree asan_cleanup = build_asan_poison_call_expr (temp);
6831 if (asan_cleanup)
6833 if (unpoison_empty_seq)
6834 unpoison_it = gsi_start (*pre_p);
6836 asan_poison_variable (temp, false, &unpoison_it,
6837 unpoison_empty_seq);
6838 gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
6842 if (cleanup)
6843 gimple_push_cleanup (temp, cleanup, false, pre_p);
6845 /* Only expand this once. */
6846 TREE_OPERAND (targ, 3) = init;
6847 TARGET_EXPR_INITIAL (targ) = NULL_TREE;
6849 else
6850 /* We should have expanded this before. */
6851 gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
6853 *expr_p = temp;
6854 return GS_OK;
6857 /* Gimplification of expression trees. */
6859 /* Gimplify an expression which appears at statement context. The
6860 corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
6861 NULL, a new sequence is allocated.
6863 Return true if we actually added a statement to the queue. */
6865 bool
6866 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
6868 gimple_seq_node last;
6870 last = gimple_seq_last (*seq_p);
6871 gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
6872 return last != gimple_seq_last (*seq_p);
6875 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
6876 to CTX. If entries already exist, force them to be some flavor of private.
6877 If there is no enclosing parallel, do nothing. */
6879 void
6880 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
6882 splay_tree_node n;
6884 if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
6885 return;
6889 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6890 if (n != NULL)
6892 if (n->value & GOVD_SHARED)
6893 n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
6894 else if (n->value & GOVD_MAP)
6895 n->value |= GOVD_MAP_TO_ONLY;
6896 else
6897 return;
6899 else if ((ctx->region_type & ORT_TARGET) != 0)
6901 if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
6902 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6903 else
6904 omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
6906 else if (ctx->region_type != ORT_WORKSHARE
6907 && ctx->region_type != ORT_TASKGROUP
6908 && ctx->region_type != ORT_SIMD
6909 && ctx->region_type != ORT_ACC
6910 && !(ctx->region_type & ORT_TARGET_DATA))
6911 omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
6913 ctx = ctx->outer_context;
6915 while (ctx);
6918 /* Similarly for each of the type sizes of TYPE. */
6920 static void
6921 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
6923 if (type == NULL || type == error_mark_node)
6924 return;
6925 type = TYPE_MAIN_VARIANT (type);
6927 if (ctx->privatized_types->add (type))
6928 return;
6930 switch (TREE_CODE (type))
6932 case INTEGER_TYPE:
6933 case ENUMERAL_TYPE:
6934 case BOOLEAN_TYPE:
6935 case REAL_TYPE:
6936 case FIXED_POINT_TYPE:
6937 omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
6938 omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
6939 break;
6941 case ARRAY_TYPE:
6942 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6943 omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
6944 break;
6946 case RECORD_TYPE:
6947 case UNION_TYPE:
6948 case QUAL_UNION_TYPE:
6950 tree field;
6951 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
6952 if (TREE_CODE (field) == FIELD_DECL)
6954 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
6955 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
6958 break;
6960 case POINTER_TYPE:
6961 case REFERENCE_TYPE:
6962 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
6963 break;
6965 default:
6966 break;
6969 omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
6970 omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
6971 lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
6974 /* Add an entry for DECL in the OMP context CTX with FLAGS. */
6976 static void
6977 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
6979 splay_tree_node n;
6980 unsigned int nflags;
6981 tree t;
6983 if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
6984 return;
6986 /* Never elide decls whose type has TREE_ADDRESSABLE set. This means
6987 there are constructors involved somewhere. Exception is a shared clause,
6988 there is nothing privatized in that case. */
6989 if ((flags & GOVD_SHARED) == 0
6990 && (TREE_ADDRESSABLE (TREE_TYPE (decl))
6991 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
6992 flags |= GOVD_SEEN;
6994 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
6995 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
6997 /* We shouldn't be re-adding the decl with the same data
6998 sharing class. */
6999 gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
7000 nflags = n->value | flags;
7001 /* The only combination of data sharing classes we should see is
7002 FIRSTPRIVATE and LASTPRIVATE. However, OpenACC permits
7003 reduction variables to be used in data sharing clauses. */
7004 gcc_assert ((ctx->region_type & ORT_ACC) != 0
7005 || ((nflags & GOVD_DATA_SHARE_CLASS)
7006 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
7007 || (flags & GOVD_DATA_SHARE_CLASS) == 0);
7008 n->value = nflags;
7009 return;
7012 /* When adding a variable-sized variable, we have to handle all sorts
7013 of additional bits of data: the pointer replacement variable, and
7014 the parameters of the type. */
7015 if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7017 /* Add the pointer replacement variable as PRIVATE if the variable
7018 replacement is private, else FIRSTPRIVATE since we'll need the
7019 address of the original variable either for SHARED, or for the
7020 copy into or out of the context. */
7021 if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
7023 if (flags & GOVD_MAP)
7024 nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
7025 else if (flags & GOVD_PRIVATE)
7026 nflags = GOVD_PRIVATE;
7027 else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7028 && (flags & GOVD_FIRSTPRIVATE))
7029 || (ctx->region_type == ORT_TARGET_DATA
7030 && (flags & GOVD_DATA_SHARE_CLASS) == 0))
7031 nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
7032 else
7033 nflags = GOVD_FIRSTPRIVATE;
7034 nflags |= flags & GOVD_SEEN;
7035 t = DECL_VALUE_EXPR (decl);
7036 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7037 t = TREE_OPERAND (t, 0);
7038 gcc_assert (DECL_P (t));
7039 omp_add_variable (ctx, t, nflags);
7042 /* Add all of the variable and type parameters (which should have
7043 been gimplified to a formal temporary) as FIRSTPRIVATE. */
7044 omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
7045 omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
7046 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7048 /* The variable-sized variable itself is never SHARED, only some form
7049 of PRIVATE. The sharing would take place via the pointer variable
7050 which we remapped above. */
7051 if (flags & GOVD_SHARED)
7052 flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
7053 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
7055 /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7056 alloca statement we generate for the variable, so make sure it
7057 is available. This isn't automatically needed for the SHARED
7058 case, since we won't be allocating local storage then.
7059 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7060 in this case omp_notice_variable will be called later
7061 on when it is gimplified. */
7062 else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
7063 && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
7064 omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
7066 else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
7067 && lang_hooks.decls.omp_privatize_by_reference (decl))
7069 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7071 /* Similar to the direct variable sized case above, we'll need the
7072 size of references being privatized. */
7073 if ((flags & GOVD_SHARED) == 0)
7075 t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7076 if (t && DECL_P (t))
7077 omp_notice_variable (ctx, t, true);
7081 if (n != NULL)
7082 n->value |= flags;
7083 else
7084 splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
7086 /* For reductions clauses in OpenACC loop directives, by default create a
7087 copy clause on the enclosing parallel construct for carrying back the
7088 results. */
7089 if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
7091 struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
7092 while (outer_ctx)
7094 n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
7095 if (n != NULL)
7097 /* Ignore local variables and explicitly declared clauses. */
7098 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
7099 break;
7100 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
7102 /* According to the OpenACC spec, such a reduction variable
7103 should already have a copy map on a kernels construct,
7104 verify that here. */
7105 gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
7106 && (n->value & GOVD_MAP));
7108 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7110 /* Remove firstprivate and make it a copy map. */
7111 n->value &= ~GOVD_FIRSTPRIVATE;
7112 n->value |= GOVD_MAP;
7115 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7117 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
7118 GOVD_MAP | GOVD_SEEN);
7119 break;
7121 outer_ctx = outer_ctx->outer_context;
7126 /* Notice a threadprivate variable DECL used in OMP context CTX.
7127 This just prints out diagnostics about threadprivate variable uses
7128 in untied tasks. If DECL2 is non-NULL, prevent this warning
7129 on that variable. */
7131 static bool
7132 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
7133 tree decl2)
7135 splay_tree_node n;
7136 struct gimplify_omp_ctx *octx;
7138 for (octx = ctx; octx; octx = octx->outer_context)
7139 if ((octx->region_type & ORT_TARGET) != 0
7140 || octx->order_concurrent)
7142 n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
7143 if (n == NULL)
7145 if (octx->order_concurrent)
7147 error ("threadprivate variable %qE used in a region with"
7148 " %<order(concurrent)%> clause", DECL_NAME (decl));
7149 inform (octx->location, "enclosing region");
7151 else
7153 error ("threadprivate variable %qE used in target region",
7154 DECL_NAME (decl));
7155 inform (octx->location, "enclosing target region");
7157 splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
7159 if (decl2)
7160 splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
7163 if (ctx->region_type != ORT_UNTIED_TASK)
7164 return false;
7165 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7166 if (n == NULL)
7168 error ("threadprivate variable %qE used in untied task",
7169 DECL_NAME (decl));
7170 inform (ctx->location, "enclosing task");
7171 splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
7173 if (decl2)
7174 splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
7175 return false;
7178 /* Return true if global var DECL is device resident. */
7180 static bool
7181 device_resident_p (tree decl)
7183 tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
7185 if (!attr)
7186 return false;
7188 for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
7190 tree c = TREE_VALUE (t);
7191 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
7192 return true;
7195 return false;
7198 /* Return true if DECL has an ACC DECLARE attribute. */
7200 static bool
7201 is_oacc_declared (tree decl)
7203 tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
7204 tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
7205 return declared != NULL_TREE;
7208 /* Determine outer default flags for DECL mentioned in an OMP region
7209 but not declared in an enclosing clause.
7211 ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7212 remapped firstprivate instead of shared. To some extent this is
7213 addressed in omp_firstprivatize_type_sizes, but not
7214 effectively. */
7216 static unsigned
7217 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
7218 bool in_code, unsigned flags)
7220 enum omp_clause_default_kind default_kind = ctx->default_kind;
7221 enum omp_clause_default_kind kind;
7223 kind = lang_hooks.decls.omp_predetermined_sharing (decl);
7224 if (ctx->region_type & ORT_TASK)
7226 tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH);
7228 /* The event-handle specified by a detach clause should always be firstprivate,
7229 regardless of the current default. */
7230 if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl)
7231 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
7233 if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7234 default_kind = kind;
7235 else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
7236 default_kind = OMP_CLAUSE_DEFAULT_SHARED;
7238 switch (default_kind)
7240 case OMP_CLAUSE_DEFAULT_NONE:
7242 const char *rtype;
7244 if (ctx->region_type & ORT_PARALLEL)
7245 rtype = "parallel";
7246 else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
7247 rtype = "taskloop";
7248 else if (ctx->region_type & ORT_TASK)
7249 rtype = "task";
7250 else if (ctx->region_type & ORT_TEAMS)
7251 rtype = "teams";
7252 else
7253 gcc_unreachable ();
7255 error ("%qE not specified in enclosing %qs",
7256 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7257 inform (ctx->location, "enclosing %qs", rtype);
7259 /* FALLTHRU */
7260 case OMP_CLAUSE_DEFAULT_SHARED:
7261 flags |= GOVD_SHARED;
7262 break;
7263 case OMP_CLAUSE_DEFAULT_PRIVATE:
7264 flags |= GOVD_PRIVATE;
7265 break;
7266 case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7267 flags |= GOVD_FIRSTPRIVATE;
7268 break;
7269 case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7270 /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
7271 gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7272 if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7274 omp_notice_variable (octx, decl, in_code);
7275 for (; octx; octx = octx->outer_context)
7277 splay_tree_node n2;
7279 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7280 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7281 && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7282 continue;
7283 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7285 flags |= GOVD_FIRSTPRIVATE;
7286 goto found_outer;
7288 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7290 flags |= GOVD_SHARED;
7291 goto found_outer;
7296 if (TREE_CODE (decl) == PARM_DECL
7297 || (!is_global_var (decl)
7298 && DECL_CONTEXT (decl) == current_function_decl))
7299 flags |= GOVD_FIRSTPRIVATE;
7300 else
7301 flags |= GOVD_SHARED;
7302 found_outer:
7303 break;
7305 default:
7306 gcc_unreachable ();
7309 return flags;
7313 /* Determine outer default flags for DECL mentioned in an OACC region
7314 but not declared in an enclosing clause. */
7316 static unsigned
7317 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7319 const char *rkind;
7320 bool on_device = false;
7321 bool is_private = false;
7322 bool declared = is_oacc_declared (decl);
7323 tree type = TREE_TYPE (decl);
7325 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7326 type = TREE_TYPE (type);
7328 /* For Fortran COMMON blocks, only used variables in those blocks are
7329 transfered and remapped. The block itself will have a private clause to
7330 avoid transfering the data twice.
7331 The hook evaluates to false by default. For a variable in Fortran's COMMON
7332 or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7333 the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7334 the whole block. For C++ and Fortran, it can also be true under certain
7335 other conditions, if DECL_HAS_VALUE_EXPR. */
7336 if (RECORD_OR_UNION_TYPE_P (type))
7337 is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
7339 if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7340 && is_global_var (decl)
7341 && device_resident_p (decl)
7342 && !is_private)
7344 on_device = true;
7345 flags |= GOVD_MAP_TO_ONLY;
7348 switch (ctx->region_type)
7350 case ORT_ACC_KERNELS:
7351 rkind = "kernels";
7353 if (is_private)
7354 flags |= GOVD_FIRSTPRIVATE;
7355 else if (AGGREGATE_TYPE_P (type))
7357 /* Aggregates default to 'present_or_copy', or 'present'. */
7358 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7359 flags |= GOVD_MAP;
7360 else
7361 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7363 else
7364 /* Scalars default to 'copy'. */
7365 flags |= GOVD_MAP | GOVD_MAP_FORCE;
7367 break;
7369 case ORT_ACC_PARALLEL:
7370 case ORT_ACC_SERIAL:
7371 rkind = ctx->region_type == ORT_ACC_PARALLEL ? "parallel" : "serial";
7373 if (is_private)
7374 flags |= GOVD_FIRSTPRIVATE;
7375 else if (on_device || declared)
7376 flags |= GOVD_MAP;
7377 else if (AGGREGATE_TYPE_P (type))
7379 /* Aggregates default to 'present_or_copy', or 'present'. */
7380 if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7381 flags |= GOVD_MAP;
7382 else
7383 flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7385 else
7386 /* Scalars default to 'firstprivate'. */
7387 flags |= GOVD_FIRSTPRIVATE;
7389 break;
7391 default:
7392 gcc_unreachable ();
7395 if (DECL_ARTIFICIAL (decl))
7396 ; /* We can get compiler-generated decls, and should not complain
7397 about them. */
7398 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7400 error ("%qE not specified in enclosing OpenACC %qs construct",
7401 DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
7402 inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
7404 else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7405 ; /* Handled above. */
7406 else
7407 gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7409 return flags;
7412 /* Record the fact that DECL was used within the OMP context CTX.
7413 IN_CODE is true when real code uses DECL, and false when we should
7414 merely emit default(none) errors. Return true if DECL is going to
7415 be remapped and thus DECL shouldn't be gimplified into its
7416 DECL_VALUE_EXPR (if any). */
7418 static bool
7419 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7421 splay_tree_node n;
7422 unsigned flags = in_code ? GOVD_SEEN : 0;
7423 bool ret = false, shared;
7425 if (error_operand_p (decl))
7426 return false;
7428 if (ctx->region_type == ORT_NONE)
7429 return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7431 if (is_global_var (decl))
7433 /* Threadprivate variables are predetermined. */
7434 if (DECL_THREAD_LOCAL_P (decl))
7435 return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7437 if (DECL_HAS_VALUE_EXPR_P (decl))
7439 if (ctx->region_type & ORT_ACC)
7440 /* For OpenACC, defer expansion of value to avoid transfering
7441 privatized common block data instead of im-/explicitly transfered
7442 variables which are in common blocks. */
7444 else
7446 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7448 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7449 return omp_notice_threadprivate_variable (ctx, decl, value);
7453 if (gimplify_omp_ctxp->outer_context == NULL
7454 && VAR_P (decl)
7455 && oacc_get_fn_attrib (current_function_decl))
7457 location_t loc = DECL_SOURCE_LOCATION (decl);
7459 if (lookup_attribute ("omp declare target link",
7460 DECL_ATTRIBUTES (decl)))
7462 error_at (loc,
7463 "%qE with %<link%> clause used in %<routine%> function",
7464 DECL_NAME (decl));
7465 return false;
7467 else if (!lookup_attribute ("omp declare target",
7468 DECL_ATTRIBUTES (decl)))
7470 error_at (loc,
7471 "%qE requires a %<declare%> directive for use "
7472 "in a %<routine%> function", DECL_NAME (decl));
7473 return false;
7478 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7479 if ((ctx->region_type & ORT_TARGET) != 0)
7481 if (ctx->region_type & ORT_ACC)
7482 /* For OpenACC, as remarked above, defer expansion. */
7483 shared = false;
7484 else
7485 shared = true;
7487 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7488 if (n == NULL)
7490 unsigned nflags = flags;
7491 if ((ctx->region_type & ORT_ACC) == 0)
7493 bool is_declare_target = false;
7494 if (is_global_var (decl)
7495 && varpool_node::get_create (decl)->offloadable)
7497 struct gimplify_omp_ctx *octx;
7498 for (octx = ctx->outer_context;
7499 octx; octx = octx->outer_context)
7501 n = splay_tree_lookup (octx->variables,
7502 (splay_tree_key)decl);
7503 if (n
7504 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7505 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7506 break;
7508 is_declare_target = octx == NULL;
7510 if (!is_declare_target)
7512 int gdmk;
7513 enum omp_clause_defaultmap_kind kind;
7514 if (lang_hooks.decls.omp_allocatable_p (decl))
7515 gdmk = GDMK_ALLOCATABLE;
7516 else if (lang_hooks.decls.omp_scalar_target_p (decl))
7517 gdmk = GDMK_SCALAR_TARGET;
7518 else if (lang_hooks.decls.omp_scalar_p (decl, false))
7519 gdmk = GDMK_SCALAR;
7520 else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7521 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7522 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7523 == POINTER_TYPE)))
7524 gdmk = GDMK_POINTER;
7525 else
7526 gdmk = GDMK_AGGREGATE;
7527 kind = lang_hooks.decls.omp_predetermined_mapping (decl);
7528 if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
7530 if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
7531 nflags |= GOVD_FIRSTPRIVATE;
7532 else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
7533 nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
7534 else
7535 gcc_unreachable ();
7537 else if (ctx->defaultmap[gdmk] == 0)
7539 tree d = lang_hooks.decls.omp_report_decl (decl);
7540 error ("%qE not specified in enclosing %<target%>",
7541 DECL_NAME (d));
7542 inform (ctx->location, "enclosing %<target%>");
7544 else if (ctx->defaultmap[gdmk]
7545 & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
7546 nflags |= ctx->defaultmap[gdmk];
7547 else
7549 gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
7550 nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
7555 struct gimplify_omp_ctx *octx = ctx->outer_context;
7556 if ((ctx->region_type & ORT_ACC) && octx)
7558 /* Look in outer OpenACC contexts, to see if there's a
7559 data attribute for this variable. */
7560 omp_notice_variable (octx, decl, in_code);
7562 for (; octx; octx = octx->outer_context)
7564 if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7565 break;
7566 splay_tree_node n2
7567 = splay_tree_lookup (octx->variables,
7568 (splay_tree_key) decl);
7569 if (n2)
7571 if (octx->region_type == ORT_ACC_HOST_DATA)
7572 error ("variable %qE declared in enclosing "
7573 "%<host_data%> region", DECL_NAME (decl));
7574 nflags |= GOVD_MAP;
7575 if (octx->region_type == ORT_ACC_DATA
7576 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7577 nflags |= GOVD_MAP_0LEN_ARRAY;
7578 goto found_outer;
7583 if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
7584 | GOVD_MAP_ALLOC_ONLY)) == flags)
7586 tree type = TREE_TYPE (decl);
7588 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
7589 && lang_hooks.decls.omp_privatize_by_reference (decl))
7590 type = TREE_TYPE (type);
7591 if (!lang_hooks.types.omp_mappable_type (type))
7593 error ("%qD referenced in target region does not have "
7594 "a mappable type", decl);
7595 nflags |= GOVD_MAP | GOVD_EXPLICIT;
7597 else
7599 if ((ctx->region_type & ORT_ACC) != 0)
7600 nflags = oacc_default_clause (ctx, decl, flags);
7601 else
7602 nflags |= GOVD_MAP;
7605 found_outer:
7606 omp_add_variable (ctx, decl, nflags);
7608 else
7610 /* If nothing changed, there's nothing left to do. */
7611 if ((n->value & flags) == flags)
7612 return ret;
7613 flags |= n->value;
7614 n->value = flags;
7616 goto do_outer;
7619 if (n == NULL)
7621 if (ctx->region_type == ORT_WORKSHARE
7622 || ctx->region_type == ORT_TASKGROUP
7623 || ctx->region_type == ORT_SIMD
7624 || ctx->region_type == ORT_ACC
7625 || (ctx->region_type & ORT_TARGET_DATA) != 0)
7626 goto do_outer;
7628 flags = omp_default_clause (ctx, decl, in_code, flags);
7630 if ((flags & GOVD_PRIVATE)
7631 && lang_hooks.decls.omp_private_outer_ref (decl))
7632 flags |= GOVD_PRIVATE_OUTER_REF;
7634 omp_add_variable (ctx, decl, flags);
7636 shared = (flags & GOVD_SHARED) != 0;
7637 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7638 goto do_outer;
7641 /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
7642 lb, b or incr expressions, those shouldn't be turned into simd arrays. */
7643 if (ctx->region_type == ORT_SIMD
7644 && ctx->in_for_exprs
7645 && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
7646 == GOVD_PRIVATE))
7647 flags &= ~GOVD_SEEN;
7649 if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7650 && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7651 && DECL_SIZE (decl))
7653 if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7655 splay_tree_node n2;
7656 tree t = DECL_VALUE_EXPR (decl);
7657 gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7658 t = TREE_OPERAND (t, 0);
7659 gcc_assert (DECL_P (t));
7660 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7661 n2->value |= GOVD_SEEN;
7663 else if (lang_hooks.decls.omp_privatize_by_reference (decl)
7664 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7665 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7666 != INTEGER_CST))
7668 splay_tree_node n2;
7669 tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7670 gcc_assert (DECL_P (t));
7671 n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7672 if (n2)
7673 omp_notice_variable (ctx, t, true);
7677 if (ctx->region_type & ORT_ACC)
7678 /* For OpenACC, as remarked above, defer expansion. */
7679 shared = false;
7680 else
7681 shared = ((flags | n->value) & GOVD_SHARED) != 0;
7682 ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7684 /* If nothing changed, there's nothing left to do. */
7685 if ((n->value & flags) == flags)
7686 return ret;
7687 flags |= n->value;
7688 n->value = flags;
7690 do_outer:
7691 /* If the variable is private in the current context, then we don't
7692 need to propagate anything to an outer context. */
7693 if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7694 return ret;
7695 if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7696 == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7697 return ret;
7698 if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7699 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7700 == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7701 return ret;
7702 if (ctx->outer_context
7703 && omp_notice_variable (ctx->outer_context, decl, in_code))
7704 return true;
7705 return ret;
7708 /* Verify that DECL is private within CTX. If there's specific information
7709 to the contrary in the innermost scope, generate an error. */
7711 static bool
7712 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
7714 splay_tree_node n;
7716 n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7717 if (n != NULL)
7719 if (n->value & GOVD_SHARED)
7721 if (ctx == gimplify_omp_ctxp)
7723 if (simd)
7724 error ("iteration variable %qE is predetermined linear",
7725 DECL_NAME (decl));
7726 else
7727 error ("iteration variable %qE should be private",
7728 DECL_NAME (decl));
7729 n->value = GOVD_PRIVATE;
7730 return true;
7732 else
7733 return false;
7735 else if ((n->value & GOVD_EXPLICIT) != 0
7736 && (ctx == gimplify_omp_ctxp
7737 || (ctx->region_type == ORT_COMBINED_PARALLEL
7738 && gimplify_omp_ctxp->outer_context == ctx)))
7740 if ((n->value & GOVD_FIRSTPRIVATE) != 0)
7741 error ("iteration variable %qE should not be firstprivate",
7742 DECL_NAME (decl));
7743 else if ((n->value & GOVD_REDUCTION) != 0)
7744 error ("iteration variable %qE should not be reduction",
7745 DECL_NAME (decl));
7746 else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
7747 error ("iteration variable %qE should not be linear",
7748 DECL_NAME (decl));
7750 return (ctx == gimplify_omp_ctxp
7751 || (ctx->region_type == ORT_COMBINED_PARALLEL
7752 && gimplify_omp_ctxp->outer_context == ctx));
7755 if (ctx->region_type != ORT_WORKSHARE
7756 && ctx->region_type != ORT_TASKGROUP
7757 && ctx->region_type != ORT_SIMD
7758 && ctx->region_type != ORT_ACC)
7759 return false;
7760 else if (ctx->outer_context)
7761 return omp_is_private (ctx->outer_context, decl, simd);
7762 return false;
7765 /* Return true if DECL is private within a parallel region
7766 that binds to the current construct's context or in parallel
7767 region's REDUCTION clause. */
7769 static bool
7770 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
7772 splay_tree_node n;
7776 ctx = ctx->outer_context;
7777 if (ctx == NULL)
7779 if (is_global_var (decl))
7780 return false;
7782 /* References might be private, but might be shared too,
7783 when checking for copyprivate, assume they might be
7784 private, otherwise assume they might be shared. */
7785 if (copyprivate)
7786 return true;
7788 if (lang_hooks.decls.omp_privatize_by_reference (decl))
7789 return false;
7791 /* Treat C++ privatized non-static data members outside
7792 of the privatization the same. */
7793 if (omp_member_access_dummy_var (decl))
7794 return false;
7796 return true;
7799 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
7801 if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7802 && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
7804 if ((ctx->region_type & ORT_TARGET_DATA) != 0
7805 || n == NULL
7806 || (n->value & GOVD_MAP) == 0)
7807 continue;
7808 return false;
7811 if (n != NULL)
7813 if ((n->value & GOVD_LOCAL) != 0
7814 && omp_member_access_dummy_var (decl))
7815 return false;
7816 return (n->value & GOVD_SHARED) == 0;
7819 if (ctx->region_type == ORT_WORKSHARE
7820 || ctx->region_type == ORT_TASKGROUP
7821 || ctx->region_type == ORT_SIMD
7822 || ctx->region_type == ORT_ACC)
7823 continue;
7825 break;
7827 while (1);
7828 return false;
7831 /* Callback for walk_tree to find a DECL_EXPR for the given DECL. */
7833 static tree
7834 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
7836 tree t = *tp;
7838 /* If this node has been visited, unmark it and keep looking. */
7839 if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
7840 return t;
7842 if (IS_TYPE_OR_DECL_P (t))
7843 *walk_subtrees = 0;
7844 return NULL_TREE;
7848 /* Gimplify the affinity clause but effectively ignore it.
7849 Generate:
7850 var = begin;
7851 if ((step > 1) ? var <= end : var > end)
7852 locatator_var_expr; */
7854 static void
7855 gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p)
7857 tree last_iter = NULL_TREE;
7858 tree last_bind = NULL_TREE;
7859 tree label = NULL_TREE;
7860 tree *last_body = NULL;
7861 for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
7862 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
7864 tree t = OMP_CLAUSE_DECL (c);
7865 if (TREE_CODE (t) == TREE_LIST
7866 && TREE_PURPOSE (t)
7867 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
7869 if (TREE_VALUE (t) == null_pointer_node)
7870 continue;
7871 if (TREE_PURPOSE (t) != last_iter)
7873 if (last_bind)
7875 append_to_statement_list (label, last_body);
7876 gimplify_and_add (last_bind, pre_p);
7877 last_bind = NULL_TREE;
7879 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
7881 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
7882 is_gimple_val, fb_rvalue) == GS_ERROR
7883 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
7884 is_gimple_val, fb_rvalue) == GS_ERROR
7885 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
7886 is_gimple_val, fb_rvalue) == GS_ERROR
7887 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
7888 is_gimple_val, fb_rvalue)
7889 == GS_ERROR))
7890 return;
7892 last_iter = TREE_PURPOSE (t);
7893 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
7894 last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
7895 NULL, block);
7896 last_body = &BIND_EXPR_BODY (last_bind);
7897 tree cond = NULL_TREE;
7898 location_t loc = OMP_CLAUSE_LOCATION (c);
7899 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
7901 tree var = TREE_VEC_ELT (it, 0);
7902 tree begin = TREE_VEC_ELT (it, 1);
7903 tree end = TREE_VEC_ELT (it, 2);
7904 tree step = TREE_VEC_ELT (it, 3);
7905 loc = DECL_SOURCE_LOCATION (var);
7906 tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
7907 var, begin);
7908 append_to_statement_list_force (tem, last_body);
7910 tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
7911 step, build_zero_cst (TREE_TYPE (step)));
7912 tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node,
7913 var, end);
7914 tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
7915 var, end);
7916 cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node,
7917 cond1, cond2, cond3);
7918 if (cond)
7919 cond = fold_build2_loc (loc, TRUTH_AND_EXPR,
7920 boolean_type_node, cond, cond1);
7921 else
7922 cond = cond1;
7924 tree cont_label = create_artificial_label (loc);
7925 label = build1 (LABEL_EXPR, void_type_node, cont_label);
7926 tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
7927 void_node,
7928 build_and_jump (&cont_label));
7929 append_to_statement_list_force (tem, last_body);
7931 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
7933 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0),
7934 last_body);
7935 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
7937 if (error_operand_p (TREE_VALUE (t)))
7938 return;
7939 append_to_statement_list_force (TREE_VALUE (t), last_body);
7940 TREE_VALUE (t) = null_pointer_node;
7942 else
7944 if (last_bind)
7946 append_to_statement_list (label, last_body);
7947 gimplify_and_add (last_bind, pre_p);
7948 last_bind = NULL_TREE;
7950 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
7952 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
7953 NULL, is_gimple_val, fb_rvalue);
7954 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
7956 if (error_operand_p (OMP_CLAUSE_DECL (c)))
7957 return;
7958 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
7959 is_gimple_val, fb_rvalue) == GS_ERROR)
7960 return;
7961 gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p);
7964 if (last_bind)
7966 append_to_statement_list (label, last_body);
7967 gimplify_and_add (last_bind, pre_p);
7969 return;
7972 /* If *LIST_P contains any OpenMP depend clauses with iterators,
7973 lower all the depend clauses by populating corresponding depend
7974 array. Returns 0 if there are no such depend clauses, or
7975 2 if all depend clauses should be removed, 1 otherwise. */
7977 static int
7978 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
7980 tree c;
7981 gimple *g;
7982 size_t n[4] = { 0, 0, 0, 0 };
7983 bool unused[4];
7984 tree counts[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
7985 tree last_iter = NULL_TREE, last_count = NULL_TREE;
7986 size_t i, j;
7987 location_t first_loc = UNKNOWN_LOCATION;
7989 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
7990 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
7992 switch (OMP_CLAUSE_DEPEND_KIND (c))
7994 case OMP_CLAUSE_DEPEND_IN:
7995 i = 2;
7996 break;
7997 case OMP_CLAUSE_DEPEND_OUT:
7998 case OMP_CLAUSE_DEPEND_INOUT:
7999 i = 0;
8000 break;
8001 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8002 i = 1;
8003 break;
8004 case OMP_CLAUSE_DEPEND_DEPOBJ:
8005 i = 3;
8006 break;
8007 case OMP_CLAUSE_DEPEND_SOURCE:
8008 case OMP_CLAUSE_DEPEND_SINK:
8009 continue;
8010 default:
8011 gcc_unreachable ();
8013 tree t = OMP_CLAUSE_DECL (c);
8014 if (first_loc == UNKNOWN_LOCATION)
8015 first_loc = OMP_CLAUSE_LOCATION (c);
8016 if (TREE_CODE (t) == TREE_LIST
8017 && TREE_PURPOSE (t)
8018 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8020 if (TREE_PURPOSE (t) != last_iter)
8022 tree tcnt = size_one_node;
8023 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8025 if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8026 is_gimple_val, fb_rvalue) == GS_ERROR
8027 || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8028 is_gimple_val, fb_rvalue) == GS_ERROR
8029 || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8030 is_gimple_val, fb_rvalue) == GS_ERROR
8031 || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8032 is_gimple_val, fb_rvalue)
8033 == GS_ERROR))
8034 return 2;
8035 tree var = TREE_VEC_ELT (it, 0);
8036 tree begin = TREE_VEC_ELT (it, 1);
8037 tree end = TREE_VEC_ELT (it, 2);
8038 tree step = TREE_VEC_ELT (it, 3);
8039 tree orig_step = TREE_VEC_ELT (it, 4);
8040 tree type = TREE_TYPE (var);
8041 tree stype = TREE_TYPE (step);
8042 location_t loc = DECL_SOURCE_LOCATION (var);
8043 tree endmbegin;
8044 /* Compute count for this iterator as
8045 orig_step > 0
8046 ? (begin < end ? (end - begin + (step - 1)) / step : 0)
8047 : (begin > end ? (end - begin + (step + 1)) / step : 0)
8048 and compute product of those for the entire depend
8049 clause. */
8050 if (POINTER_TYPE_P (type))
8051 endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
8052 stype, end, begin);
8053 else
8054 endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
8055 end, begin);
8056 tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
8057 step,
8058 build_int_cst (stype, 1));
8059 tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
8060 build_int_cst (stype, 1));
8061 tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
8062 unshare_expr (endmbegin),
8063 stepm1);
8064 pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8065 pos, step);
8066 tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
8067 endmbegin, stepp1);
8068 if (TYPE_UNSIGNED (stype))
8070 neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
8071 step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
8073 neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8074 neg, step);
8075 step = NULL_TREE;
8076 tree cond = fold_build2_loc (loc, LT_EXPR,
8077 boolean_type_node,
8078 begin, end);
8079 pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
8080 build_int_cst (stype, 0));
8081 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
8082 end, begin);
8083 neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
8084 build_int_cst (stype, 0));
8085 tree osteptype = TREE_TYPE (orig_step);
8086 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8087 orig_step,
8088 build_int_cst (osteptype, 0));
8089 tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
8090 cond, pos, neg);
8091 cnt = fold_convert_loc (loc, sizetype, cnt);
8092 if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
8093 fb_rvalue) == GS_ERROR)
8094 return 2;
8095 tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
8097 if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
8098 fb_rvalue) == GS_ERROR)
8099 return 2;
8100 last_iter = TREE_PURPOSE (t);
8101 last_count = tcnt;
8103 if (counts[i] == NULL_TREE)
8104 counts[i] = last_count;
8105 else
8106 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
8107 PLUS_EXPR, counts[i], last_count);
8109 else
8110 n[i]++;
8112 for (i = 0; i < 4; i++)
8113 if (counts[i])
8114 break;
8115 if (i == 4)
8116 return 0;
8118 tree total = size_zero_node;
8119 for (i = 0; i < 4; i++)
8121 unused[i] = counts[i] == NULL_TREE && n[i] == 0;
8122 if (counts[i] == NULL_TREE)
8123 counts[i] = size_zero_node;
8124 if (n[i])
8125 counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
8126 if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
8127 fb_rvalue) == GS_ERROR)
8128 return 2;
8129 total = size_binop (PLUS_EXPR, total, counts[i]);
8132 if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
8133 == GS_ERROR)
8134 return 2;
8135 bool is_old = unused[1] && unused[3];
8136 tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
8137 size_int (is_old ? 1 : 4));
8138 tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
8139 tree array = create_tmp_var_raw (type);
8140 TREE_ADDRESSABLE (array) = 1;
8141 if (!poly_int_tree_p (totalpx))
8143 if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
8144 gimplify_type_sizes (TREE_TYPE (array), pre_p);
8145 if (gimplify_omp_ctxp)
8147 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8148 while (ctx
8149 && (ctx->region_type == ORT_WORKSHARE
8150 || ctx->region_type == ORT_TASKGROUP
8151 || ctx->region_type == ORT_SIMD
8152 || ctx->region_type == ORT_ACC))
8153 ctx = ctx->outer_context;
8154 if (ctx)
8155 omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
8157 gimplify_vla_decl (array, pre_p);
8159 else
8160 gimple_add_tmp_var (array);
8161 tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
8162 NULL_TREE);
8163 tree tem;
8164 if (!is_old)
8166 tem = build2 (MODIFY_EXPR, void_type_node, r,
8167 build_int_cst (ptr_type_node, 0));
8168 gimplify_and_add (tem, pre_p);
8169 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
8170 NULL_TREE);
8172 tem = build2 (MODIFY_EXPR, void_type_node, r,
8173 fold_convert (ptr_type_node, total));
8174 gimplify_and_add (tem, pre_p);
8175 for (i = 1; i < (is_old ? 2 : 4); i++)
8177 r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
8178 NULL_TREE, NULL_TREE);
8179 tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
8180 gimplify_and_add (tem, pre_p);
8183 tree cnts[4];
8184 for (j = 4; j; j--)
8185 if (!unused[j - 1])
8186 break;
8187 for (i = 0; i < 4; i++)
8189 if (i && (i >= j || unused[i - 1]))
8191 cnts[i] = cnts[i - 1];
8192 continue;
8194 cnts[i] = create_tmp_var (sizetype);
8195 if (i == 0)
8196 g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
8197 else
8199 tree t;
8200 if (is_old)
8201 t = size_binop (PLUS_EXPR, counts[0], size_int (2));
8202 else
8203 t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
8204 if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
8205 == GS_ERROR)
8206 return 2;
8207 g = gimple_build_assign (cnts[i], t);
8209 gimple_seq_add_stmt (pre_p, g);
8212 last_iter = NULL_TREE;
8213 tree last_bind = NULL_TREE;
8214 tree *last_body = NULL;
8215 for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8216 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8218 switch (OMP_CLAUSE_DEPEND_KIND (c))
8220 case OMP_CLAUSE_DEPEND_IN:
8221 i = 2;
8222 break;
8223 case OMP_CLAUSE_DEPEND_OUT:
8224 case OMP_CLAUSE_DEPEND_INOUT:
8225 i = 0;
8226 break;
8227 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8228 i = 1;
8229 break;
8230 case OMP_CLAUSE_DEPEND_DEPOBJ:
8231 i = 3;
8232 break;
8233 case OMP_CLAUSE_DEPEND_SOURCE:
8234 case OMP_CLAUSE_DEPEND_SINK:
8235 continue;
8236 default:
8237 gcc_unreachable ();
8239 tree t = OMP_CLAUSE_DECL (c);
8240 if (TREE_CODE (t) == TREE_LIST
8241 && TREE_PURPOSE (t)
8242 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8244 if (TREE_PURPOSE (t) != last_iter)
8246 if (last_bind)
8247 gimplify_and_add (last_bind, pre_p);
8248 tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8249 last_bind = build3 (BIND_EXPR, void_type_node,
8250 BLOCK_VARS (block), NULL, block);
8251 TREE_SIDE_EFFECTS (last_bind) = 1;
8252 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
8253 tree *p = &BIND_EXPR_BODY (last_bind);
8254 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8256 tree var = TREE_VEC_ELT (it, 0);
8257 tree begin = TREE_VEC_ELT (it, 1);
8258 tree end = TREE_VEC_ELT (it, 2);
8259 tree step = TREE_VEC_ELT (it, 3);
8260 tree orig_step = TREE_VEC_ELT (it, 4);
8261 tree type = TREE_TYPE (var);
8262 location_t loc = DECL_SOURCE_LOCATION (var);
8263 /* Emit:
8264 var = begin;
8265 goto cond_label;
8266 beg_label:
8268 var = var + step;
8269 cond_label:
8270 if (orig_step > 0) {
8271 if (var < end) goto beg_label;
8272 } else {
8273 if (var > end) goto beg_label;
8275 for each iterator, with inner iterators added to
8276 the ... above. */
8277 tree beg_label = create_artificial_label (loc);
8278 tree cond_label = NULL_TREE;
8279 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8280 var, begin);
8281 append_to_statement_list_force (tem, p);
8282 tem = build_and_jump (&cond_label);
8283 append_to_statement_list_force (tem, p);
8284 tem = build1 (LABEL_EXPR, void_type_node, beg_label);
8285 append_to_statement_list (tem, p);
8286 tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
8287 NULL_TREE, NULL_TREE);
8288 TREE_SIDE_EFFECTS (bind) = 1;
8289 SET_EXPR_LOCATION (bind, loc);
8290 append_to_statement_list_force (bind, p);
8291 if (POINTER_TYPE_P (type))
8292 tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
8293 var, fold_convert_loc (loc, sizetype,
8294 step));
8295 else
8296 tem = build2_loc (loc, PLUS_EXPR, type, var, step);
8297 tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8298 var, tem);
8299 append_to_statement_list_force (tem, p);
8300 tem = build1 (LABEL_EXPR, void_type_node, cond_label);
8301 append_to_statement_list (tem, p);
8302 tree cond = fold_build2_loc (loc, LT_EXPR,
8303 boolean_type_node,
8304 var, end);
8305 tree pos
8306 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8307 cond, build_and_jump (&beg_label),
8308 void_node);
8309 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8310 var, end);
8311 tree neg
8312 = fold_build3_loc (loc, COND_EXPR, void_type_node,
8313 cond, build_and_jump (&beg_label),
8314 void_node);
8315 tree osteptype = TREE_TYPE (orig_step);
8316 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8317 orig_step,
8318 build_int_cst (osteptype, 0));
8319 tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
8320 cond, pos, neg);
8321 append_to_statement_list_force (tem, p);
8322 p = &BIND_EXPR_BODY (bind);
8324 last_body = p;
8326 last_iter = TREE_PURPOSE (t);
8327 if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8329 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
8330 0), last_body);
8331 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8333 if (error_operand_p (TREE_VALUE (t)))
8334 return 2;
8335 TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
8336 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8337 NULL_TREE, NULL_TREE);
8338 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8339 void_type_node, r, TREE_VALUE (t));
8340 append_to_statement_list_force (tem, last_body);
8341 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8342 void_type_node, cnts[i],
8343 size_binop (PLUS_EXPR, cnts[i], size_int (1)));
8344 append_to_statement_list_force (tem, last_body);
8345 TREE_VALUE (t) = null_pointer_node;
8347 else
8349 if (last_bind)
8351 gimplify_and_add (last_bind, pre_p);
8352 last_bind = NULL_TREE;
8354 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8356 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8357 NULL, is_gimple_val, fb_rvalue);
8358 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8360 if (error_operand_p (OMP_CLAUSE_DECL (c)))
8361 return 2;
8362 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8363 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8364 is_gimple_val, fb_rvalue) == GS_ERROR)
8365 return 2;
8366 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8367 NULL_TREE, NULL_TREE);
8368 tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
8369 gimplify_and_add (tem, pre_p);
8370 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, cnts[i],
8371 size_int (1)));
8372 gimple_seq_add_stmt (pre_p, g);
8375 if (last_bind)
8376 gimplify_and_add (last_bind, pre_p);
8377 tree cond = boolean_false_node;
8378 if (is_old)
8380 if (!unused[0])
8381 cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
8382 size_binop_loc (first_loc, PLUS_EXPR, counts[0],
8383 size_int (2)));
8384 if (!unused[2])
8385 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8386 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8387 cnts[2],
8388 size_binop_loc (first_loc, PLUS_EXPR,
8389 totalpx,
8390 size_int (1))));
8392 else
8394 tree prev = size_int (5);
8395 for (i = 0; i < 4; i++)
8397 if (unused[i])
8398 continue;
8399 prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
8400 cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8401 build2_loc (first_loc, NE_EXPR, boolean_type_node,
8402 cnts[i], unshare_expr (prev)));
8405 tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
8406 build_call_expr_loc (first_loc,
8407 builtin_decl_explicit (BUILT_IN_TRAP),
8408 0), void_node);
8409 gimplify_and_add (tem, pre_p);
8410 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
8411 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
8412 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
8413 OMP_CLAUSE_CHAIN (c) = *list_p;
8414 *list_p = c;
8415 return 1;
8418 /* Insert a GOMP_MAP_ALLOC or GOMP_MAP_RELEASE node following a
8419 GOMP_MAP_STRUCT mapping. C is an always_pointer mapping. STRUCT_NODE is
8420 the struct node to insert the new mapping after (when the struct node is
8421 initially created). PREV_NODE is the first of two or three mappings for a
8422 pointer, and is either:
8423 - the node before C, when a pair of mappings is used, e.g. for a C/C++
8424 array section.
8425 - not the node before C. This is true when we have a reference-to-pointer
8426 type (with a mapping for the reference and for the pointer), or for
8427 Fortran derived-type mappings with a GOMP_MAP_TO_PSET.
8428 If SCP is non-null, the new node is inserted before *SCP.
8429 if SCP is null, the new node is inserted before PREV_NODE.
8430 The return type is:
8431 - PREV_NODE, if SCP is non-null.
8432 - The newly-created ALLOC or RELEASE node, if SCP is null.
8433 - The second newly-created ALLOC or RELEASE node, if we are mapping a
8434 reference to a pointer. */
8436 static tree
8437 insert_struct_comp_map (enum tree_code code, tree c, tree struct_node,
8438 tree prev_node, tree *scp)
8440 enum gomp_map_kind mkind
8441 = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
8442 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8444 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8445 tree cl = scp ? prev_node : c2;
8446 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8447 OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (c));
8448 OMP_CLAUSE_CHAIN (c2) = scp ? *scp : prev_node;
8449 if (OMP_CLAUSE_CHAIN (prev_node) != c
8450 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8451 && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8452 == GOMP_MAP_TO_PSET))
8453 OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (OMP_CLAUSE_CHAIN (prev_node));
8454 else
8455 OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
8456 if (struct_node)
8457 OMP_CLAUSE_CHAIN (struct_node) = c2;
8459 /* We might need to create an additional mapping if we have a reference to a
8460 pointer (in C++). Don't do this if we have something other than a
8461 GOMP_MAP_ALWAYS_POINTER though, i.e. a GOMP_MAP_TO_PSET. */
8462 if (OMP_CLAUSE_CHAIN (prev_node) != c
8463 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8464 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8465 == GOMP_MAP_ALWAYS_POINTER)
8466 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8467 == GOMP_MAP_ATTACH_DETACH)))
8469 tree c4 = OMP_CLAUSE_CHAIN (prev_node);
8470 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8471 OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8472 OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (c4));
8473 OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
8474 OMP_CLAUSE_CHAIN (c3) = prev_node;
8475 if (!scp)
8476 OMP_CLAUSE_CHAIN (c2) = c3;
8477 else
8478 cl = c3;
8481 if (scp)
8482 *scp = c2;
8484 return cl;
8487 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
8488 and set *BITPOSP and *POFFSETP to the bit offset of the access.
8489 If BASE_REF is non-NULL and the containing object is a reference, set
8490 *BASE_REF to that reference before dereferencing the object.
8491 If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
8492 has array type, else return NULL. */
8494 static tree
8495 extract_base_bit_offset (tree base, tree *base_ref, poly_int64 *bitposp,
8496 poly_offset_int *poffsetp)
8498 tree offset;
8499 poly_int64 bitsize, bitpos;
8500 machine_mode mode;
8501 int unsignedp, reversep, volatilep = 0;
8502 poly_offset_int poffset;
8504 if (base_ref)
8506 *base_ref = NULL_TREE;
8508 while (TREE_CODE (base) == ARRAY_REF)
8509 base = TREE_OPERAND (base, 0);
8511 if (TREE_CODE (base) == INDIRECT_REF)
8512 base = TREE_OPERAND (base, 0);
8514 else
8516 if (TREE_CODE (base) == ARRAY_REF)
8518 while (TREE_CODE (base) == ARRAY_REF)
8519 base = TREE_OPERAND (base, 0);
8520 if (TREE_CODE (base) != COMPONENT_REF
8521 || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
8522 return NULL_TREE;
8524 else if (TREE_CODE (base) == INDIRECT_REF
8525 && TREE_CODE (TREE_OPERAND (base, 0)) == COMPONENT_REF
8526 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
8527 == REFERENCE_TYPE))
8528 base = TREE_OPERAND (base, 0);
8531 base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
8532 &unsignedp, &reversep, &volatilep);
8534 tree orig_base = base;
8536 if ((TREE_CODE (base) == INDIRECT_REF
8537 || (TREE_CODE (base) == MEM_REF
8538 && integer_zerop (TREE_OPERAND (base, 1))))
8539 && DECL_P (TREE_OPERAND (base, 0))
8540 && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == REFERENCE_TYPE)
8541 base = TREE_OPERAND (base, 0);
8543 gcc_assert (offset == NULL_TREE || poly_int_tree_p (offset));
8545 if (offset)
8546 poffset = wi::to_poly_offset (offset);
8547 else
8548 poffset = 0;
8550 if (maybe_ne (bitpos, 0))
8551 poffset += bits_to_bytes_round_down (bitpos);
8553 *bitposp = bitpos;
8554 *poffsetp = poffset;
8556 /* Set *BASE_REF if BASE was a dereferenced reference variable. */
8557 if (base_ref && orig_base != base)
8558 *base_ref = orig_base;
8560 return base;
8563 /* Returns true if EXPR is or contains (as a sub-component) BASE_PTR. */
8565 static bool
8566 is_or_contains_p (tree expr, tree base_ptr)
8568 while (expr != base_ptr)
8569 if (TREE_CODE (base_ptr) == COMPONENT_REF)
8570 base_ptr = TREE_OPERAND (base_ptr, 0);
8571 else
8572 break;
8573 return expr == base_ptr;
8576 /* Implement OpenMP 5.x map ordering rules for target directives. There are
8577 several rules, and with some level of ambiguity, hopefully we can at least
8578 collect the complexity here in one place. */
8580 static void
8581 omp_target_reorder_clauses (tree *list_p)
8583 /* Collect refs to alloc/release/delete maps. */
8584 auto_vec<tree, 32> ard;
8585 tree *cp = list_p;
8586 while (*cp != NULL_TREE)
8587 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8588 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALLOC
8589 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_RELEASE
8590 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_DELETE))
8592 /* Unlink cp and push to ard. */
8593 tree c = *cp;
8594 tree nc = OMP_CLAUSE_CHAIN (c);
8595 *cp = nc;
8596 ard.safe_push (c);
8598 /* Any associated pointer type maps should also move along. */
8599 while (*cp != NULL_TREE
8600 && OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8601 && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
8602 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_POINTER
8603 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH
8604 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_POINTER
8605 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALWAYS_POINTER
8606 || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_TO_PSET))
8608 c = *cp;
8609 nc = OMP_CLAUSE_CHAIN (c);
8610 *cp = nc;
8611 ard.safe_push (c);
8614 else
8615 cp = &OMP_CLAUSE_CHAIN (*cp);
8617 /* Link alloc/release/delete maps to the end of list. */
8618 for (unsigned int i = 0; i < ard.length (); i++)
8620 *cp = ard[i];
8621 cp = &OMP_CLAUSE_CHAIN (ard[i]);
8623 *cp = NULL_TREE;
8625 /* OpenMP 5.0 requires that pointer variables are mapped before
8626 its use as a base-pointer. */
8627 auto_vec<tree *, 32> atf;
8628 for (tree *cp = list_p; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
8629 if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
8631 /* Collect alloc, to, from, to/from clause tree pointers. */
8632 gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
8633 if (k == GOMP_MAP_ALLOC
8634 || k == GOMP_MAP_TO
8635 || k == GOMP_MAP_FROM
8636 || k == GOMP_MAP_TOFROM
8637 || k == GOMP_MAP_ALWAYS_TO
8638 || k == GOMP_MAP_ALWAYS_FROM
8639 || k == GOMP_MAP_ALWAYS_TOFROM)
8640 atf.safe_push (cp);
8643 for (unsigned int i = 0; i < atf.length (); i++)
8644 if (atf[i])
8646 tree *cp = atf[i];
8647 tree decl = OMP_CLAUSE_DECL (*cp);
8648 if (TREE_CODE (decl) == INDIRECT_REF || TREE_CODE (decl) == MEM_REF)
8650 tree base_ptr = TREE_OPERAND (decl, 0);
8651 STRIP_TYPE_NOPS (base_ptr);
8652 for (unsigned int j = i + 1; j < atf.length (); j++)
8654 tree *cp2 = atf[j];
8655 tree decl2 = OMP_CLAUSE_DECL (*cp2);
8656 if (is_or_contains_p (decl2, base_ptr))
8658 /* Move *cp2 to before *cp. */
8659 tree c = *cp2;
8660 *cp2 = OMP_CLAUSE_CHAIN (c);
8661 OMP_CLAUSE_CHAIN (c) = *cp;
8662 *cp = c;
8663 atf[j] = NULL;
8670 /* DECL is supposed to have lastprivate semantics in the outer contexts
8671 of combined/composite constructs, starting with OCTX.
8672 Add needed lastprivate, shared or map clause if no data sharing or
8673 mapping clause are present. IMPLICIT_P is true if it is an implicit
8674 clause (IV on simd), in which case the lastprivate will not be
8675 copied to some constructs. */
8677 static void
8678 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx,
8679 tree decl, bool implicit_p)
8681 struct gimplify_omp_ctx *orig_octx = octx;
8682 for (; octx; octx = octx->outer_context)
8684 if ((octx->region_type == ORT_COMBINED_PARALLEL
8685 || (octx->region_type & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS)
8686 && splay_tree_lookup (octx->variables,
8687 (splay_tree_key) decl) == NULL)
8689 omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
8690 continue;
8692 if ((octx->region_type & ORT_TASK) != 0
8693 && octx->combined_loop
8694 && splay_tree_lookup (octx->variables,
8695 (splay_tree_key) decl) == NULL)
8697 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8698 continue;
8700 if (implicit_p
8701 && octx->region_type == ORT_WORKSHARE
8702 && octx->combined_loop
8703 && splay_tree_lookup (octx->variables,
8704 (splay_tree_key) decl) == NULL
8705 && octx->outer_context
8706 && octx->outer_context->region_type == ORT_COMBINED_PARALLEL
8707 && splay_tree_lookup (octx->outer_context->variables,
8708 (splay_tree_key) decl) == NULL)
8710 octx = octx->outer_context;
8711 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8712 continue;
8714 if ((octx->region_type == ORT_WORKSHARE || octx->region_type == ORT_ACC)
8715 && octx->combined_loop
8716 && splay_tree_lookup (octx->variables,
8717 (splay_tree_key) decl) == NULL
8718 && !omp_check_private (octx, decl, false))
8720 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
8721 continue;
8723 if (octx->region_type == ORT_COMBINED_TARGET)
8725 splay_tree_node n = splay_tree_lookup (octx->variables,
8726 (splay_tree_key) decl);
8727 if (n == NULL)
8729 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
8730 octx = octx->outer_context;
8732 else if (!implicit_p
8733 && (n->value & GOVD_FIRSTPRIVATE_IMPLICIT))
8735 n->value &= ~(GOVD_FIRSTPRIVATE
8736 | GOVD_FIRSTPRIVATE_IMPLICIT
8737 | GOVD_EXPLICIT);
8738 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
8739 octx = octx->outer_context;
8742 break;
8744 if (octx && (implicit_p || octx != orig_octx))
8745 omp_notice_variable (octx, decl, true);
8748 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
8749 and previous omp contexts. */
8751 static void
8752 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
8753 enum omp_region_type region_type,
8754 enum tree_code code)
8756 struct gimplify_omp_ctx *ctx, *outer_ctx;
8757 tree c;
8758 hash_map<tree, tree> *struct_map_to_clause = NULL;
8759 hash_set<tree> *struct_deref_set = NULL;
8760 tree *prev_list_p = NULL, *orig_list_p = list_p;
8761 int handled_depend_iterators = -1;
8762 int nowait = -1;
8764 ctx = new_omp_context (region_type);
8765 ctx->code = code;
8766 outer_ctx = ctx->outer_context;
8767 if (code == OMP_TARGET)
8769 if (!lang_GNU_Fortran ())
8770 ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
8771 ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
8772 ctx->defaultmap[GDMK_SCALAR_TARGET] = (lang_GNU_Fortran ()
8773 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
8775 if (!lang_GNU_Fortran ())
8776 switch (code)
8778 case OMP_TARGET:
8779 case OMP_TARGET_DATA:
8780 case OMP_TARGET_ENTER_DATA:
8781 case OMP_TARGET_EXIT_DATA:
8782 case OACC_DECLARE:
8783 case OACC_HOST_DATA:
8784 case OACC_PARALLEL:
8785 case OACC_KERNELS:
8786 ctx->target_firstprivatize_array_bases = true;
8787 default:
8788 break;
8791 if (code == OMP_TARGET
8792 || code == OMP_TARGET_DATA
8793 || code == OMP_TARGET_ENTER_DATA
8794 || code == OMP_TARGET_EXIT_DATA)
8795 omp_target_reorder_clauses (list_p);
8797 while ((c = *list_p) != NULL)
8799 bool remove = false;
8800 bool notice_outer = true;
8801 const char *check_non_private = NULL;
8802 unsigned int flags;
8803 tree decl;
8805 switch (OMP_CLAUSE_CODE (c))
8807 case OMP_CLAUSE_PRIVATE:
8808 flags = GOVD_PRIVATE | GOVD_EXPLICIT;
8809 if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
8811 flags |= GOVD_PRIVATE_OUTER_REF;
8812 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
8814 else
8815 notice_outer = false;
8816 goto do_add;
8817 case OMP_CLAUSE_SHARED:
8818 flags = GOVD_SHARED | GOVD_EXPLICIT;
8819 goto do_add;
8820 case OMP_CLAUSE_FIRSTPRIVATE:
8821 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
8822 check_non_private = "firstprivate";
8823 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
8825 gcc_assert (code == OMP_TARGET);
8826 flags |= GOVD_FIRSTPRIVATE_IMPLICIT;
8828 goto do_add;
8829 case OMP_CLAUSE_LASTPRIVATE:
8830 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
8831 switch (code)
8833 case OMP_DISTRIBUTE:
8834 error_at (OMP_CLAUSE_LOCATION (c),
8835 "conditional %<lastprivate%> clause on "
8836 "%qs construct", "distribute");
8837 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8838 break;
8839 case OMP_TASKLOOP:
8840 error_at (OMP_CLAUSE_LOCATION (c),
8841 "conditional %<lastprivate%> clause on "
8842 "%qs construct", "taskloop");
8843 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8844 break;
8845 default:
8846 break;
8848 flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
8849 if (code != OMP_LOOP)
8850 check_non_private = "lastprivate";
8851 decl = OMP_CLAUSE_DECL (c);
8852 if (error_operand_p (decl))
8853 goto do_add;
8854 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
8855 && !lang_hooks.decls.omp_scalar_p (decl, true))
8857 error_at (OMP_CLAUSE_LOCATION (c),
8858 "non-scalar variable %qD in conditional "
8859 "%<lastprivate%> clause", decl);
8860 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
8862 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
8863 flags |= GOVD_LASTPRIVATE_CONDITIONAL;
8864 omp_lastprivate_for_combined_outer_constructs (outer_ctx, decl,
8865 false);
8866 goto do_add;
8867 case OMP_CLAUSE_REDUCTION:
8868 if (OMP_CLAUSE_REDUCTION_TASK (c))
8870 if (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
8872 if (nowait == -1)
8873 nowait = omp_find_clause (*list_p,
8874 OMP_CLAUSE_NOWAIT) != NULL_TREE;
8875 if (nowait
8876 && (outer_ctx == NULL
8877 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
8879 error_at (OMP_CLAUSE_LOCATION (c),
8880 "%<task%> reduction modifier on a construct "
8881 "with a %<nowait%> clause");
8882 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
8885 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
8887 error_at (OMP_CLAUSE_LOCATION (c),
8888 "invalid %<task%> reduction modifier on construct "
8889 "other than %<parallel%>, %qs, %<sections%> or "
8890 "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
8891 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
8894 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
8895 switch (code)
8897 case OMP_SECTIONS:
8898 error_at (OMP_CLAUSE_LOCATION (c),
8899 "%<inscan%> %<reduction%> clause on "
8900 "%qs construct", "sections");
8901 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8902 break;
8903 case OMP_PARALLEL:
8904 error_at (OMP_CLAUSE_LOCATION (c),
8905 "%<inscan%> %<reduction%> clause on "
8906 "%qs construct", "parallel");
8907 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8908 break;
8909 case OMP_TEAMS:
8910 error_at (OMP_CLAUSE_LOCATION (c),
8911 "%<inscan%> %<reduction%> clause on "
8912 "%qs construct", "teams");
8913 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8914 break;
8915 case OMP_TASKLOOP:
8916 error_at (OMP_CLAUSE_LOCATION (c),
8917 "%<inscan%> %<reduction%> clause on "
8918 "%qs construct", "taskloop");
8919 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8920 break;
8921 case OMP_SCOPE:
8922 error_at (OMP_CLAUSE_LOCATION (c),
8923 "%<inscan%> %<reduction%> clause on "
8924 "%qs construct", "scope");
8925 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
8926 break;
8927 default:
8928 break;
8930 /* FALLTHRU */
8931 case OMP_CLAUSE_IN_REDUCTION:
8932 case OMP_CLAUSE_TASK_REDUCTION:
8933 flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
8934 /* OpenACC permits reductions on private variables. */
8935 if (!(region_type & ORT_ACC)
8936 /* taskgroup is actually not a worksharing region. */
8937 && code != OMP_TASKGROUP)
8938 check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
8939 decl = OMP_CLAUSE_DECL (c);
8940 if (TREE_CODE (decl) == MEM_REF)
8942 tree type = TREE_TYPE (decl);
8943 bool saved_into_ssa = gimplify_ctxp->into_ssa;
8944 gimplify_ctxp->into_ssa = false;
8945 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
8946 NULL, is_gimple_val, fb_rvalue, false)
8947 == GS_ERROR)
8949 gimplify_ctxp->into_ssa = saved_into_ssa;
8950 remove = true;
8951 break;
8953 gimplify_ctxp->into_ssa = saved_into_ssa;
8954 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
8955 if (DECL_P (v))
8957 omp_firstprivatize_variable (ctx, v);
8958 omp_notice_variable (ctx, v, true);
8960 decl = TREE_OPERAND (decl, 0);
8961 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
8963 gimplify_ctxp->into_ssa = false;
8964 if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
8965 NULL, is_gimple_val, fb_rvalue, false)
8966 == GS_ERROR)
8968 gimplify_ctxp->into_ssa = saved_into_ssa;
8969 remove = true;
8970 break;
8972 gimplify_ctxp->into_ssa = saved_into_ssa;
8973 v = TREE_OPERAND (decl, 1);
8974 if (DECL_P (v))
8976 omp_firstprivatize_variable (ctx, v);
8977 omp_notice_variable (ctx, v, true);
8979 decl = TREE_OPERAND (decl, 0);
8981 if (TREE_CODE (decl) == ADDR_EXPR
8982 || TREE_CODE (decl) == INDIRECT_REF)
8983 decl = TREE_OPERAND (decl, 0);
8985 goto do_add_decl;
8986 case OMP_CLAUSE_LINEAR:
8987 if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
8988 is_gimple_val, fb_rvalue) == GS_ERROR)
8990 remove = true;
8991 break;
8993 else
8995 if (code == OMP_SIMD
8996 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
8998 struct gimplify_omp_ctx *octx = outer_ctx;
8999 if (octx
9000 && octx->region_type == ORT_WORKSHARE
9001 && octx->combined_loop
9002 && !octx->distribute)
9004 if (octx->outer_context
9005 && (octx->outer_context->region_type
9006 == ORT_COMBINED_PARALLEL))
9007 octx = octx->outer_context->outer_context;
9008 else
9009 octx = octx->outer_context;
9011 if (octx
9012 && octx->region_type == ORT_WORKSHARE
9013 && octx->combined_loop
9014 && octx->distribute)
9016 error_at (OMP_CLAUSE_LOCATION (c),
9017 "%<linear%> clause for variable other than "
9018 "loop iterator specified on construct "
9019 "combined with %<distribute%>");
9020 remove = true;
9021 break;
9024 /* For combined #pragma omp parallel for simd, need to put
9025 lastprivate and perhaps firstprivate too on the
9026 parallel. Similarly for #pragma omp for simd. */
9027 struct gimplify_omp_ctx *octx = outer_ctx;
9028 bool taskloop_seen = false;
9029 decl = NULL_TREE;
9032 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9033 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9034 break;
9035 decl = OMP_CLAUSE_DECL (c);
9036 if (error_operand_p (decl))
9038 decl = NULL_TREE;
9039 break;
9041 flags = GOVD_SEEN;
9042 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9043 flags |= GOVD_FIRSTPRIVATE;
9044 if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9045 flags |= GOVD_LASTPRIVATE;
9046 if (octx
9047 && octx->region_type == ORT_WORKSHARE
9048 && octx->combined_loop)
9050 if (octx->outer_context
9051 && (octx->outer_context->region_type
9052 == ORT_COMBINED_PARALLEL))
9053 octx = octx->outer_context;
9054 else if (omp_check_private (octx, decl, false))
9055 break;
9057 else if (octx
9058 && (octx->region_type & ORT_TASK) != 0
9059 && octx->combined_loop)
9060 taskloop_seen = true;
9061 else if (octx
9062 && octx->region_type == ORT_COMBINED_PARALLEL
9063 && ((ctx->region_type == ORT_WORKSHARE
9064 && octx == outer_ctx)
9065 || taskloop_seen))
9066 flags = GOVD_SEEN | GOVD_SHARED;
9067 else if (octx
9068 && ((octx->region_type & ORT_COMBINED_TEAMS)
9069 == ORT_COMBINED_TEAMS))
9070 flags = GOVD_SEEN | GOVD_SHARED;
9071 else if (octx
9072 && octx->region_type == ORT_COMBINED_TARGET)
9074 if (flags & GOVD_LASTPRIVATE)
9075 flags = GOVD_SEEN | GOVD_MAP;
9077 else
9078 break;
9079 splay_tree_node on
9080 = splay_tree_lookup (octx->variables,
9081 (splay_tree_key) decl);
9082 if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
9084 octx = NULL;
9085 break;
9087 omp_add_variable (octx, decl, flags);
9088 if (octx->outer_context == NULL)
9089 break;
9090 octx = octx->outer_context;
9092 while (1);
9093 if (octx
9094 && decl
9095 && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9096 || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
9097 omp_notice_variable (octx, decl, true);
9099 flags = GOVD_LINEAR | GOVD_EXPLICIT;
9100 if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9101 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9103 notice_outer = false;
9104 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9106 goto do_add;
9108 case OMP_CLAUSE_MAP:
9109 decl = OMP_CLAUSE_DECL (c);
9110 if (error_operand_p (decl))
9111 remove = true;
9112 switch (code)
9114 case OMP_TARGET:
9115 break;
9116 case OACC_DATA:
9117 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
9118 break;
9119 /* FALLTHRU */
9120 case OMP_TARGET_DATA:
9121 case OMP_TARGET_ENTER_DATA:
9122 case OMP_TARGET_EXIT_DATA:
9123 case OACC_ENTER_DATA:
9124 case OACC_EXIT_DATA:
9125 case OACC_HOST_DATA:
9126 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9127 || (OMP_CLAUSE_MAP_KIND (c)
9128 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9129 /* For target {,enter ,exit }data only the array slice is
9130 mapped, but not the pointer to it. */
9131 remove = true;
9132 break;
9133 default:
9134 break;
9136 /* For Fortran, not only the pointer to the data is mapped but also
9137 the address of the pointer, the array descriptor etc.; for
9138 'exit data' - and in particular for 'delete:' - having an 'alloc:'
9139 does not make sense. Likewise, for 'update' only transferring the
9140 data itself is needed as the rest has been handled in previous
9141 directives. However, for 'exit data', the array descriptor needs
9142 to be delete; hence, we turn the MAP_TO_PSET into a MAP_DELETE.
9144 NOTE: Generally, it is not safe to perform "enter data" operations
9145 on arrays where the data *or the descriptor* may go out of scope
9146 before a corresponding "exit data" operation -- and such a
9147 descriptor may be synthesized temporarily, e.g. to pass an
9148 explicit-shape array to a function expecting an assumed-shape
9149 argument. Performing "enter data" inside the called function
9150 would thus be problematic. */
9151 if (code == OMP_TARGET_EXIT_DATA
9152 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
9153 OMP_CLAUSE_SET_MAP_KIND (c, OMP_CLAUSE_MAP_KIND (*prev_list_p)
9154 == GOMP_MAP_DELETE
9155 ? GOMP_MAP_DELETE : GOMP_MAP_RELEASE);
9156 else if ((code == OMP_TARGET_EXIT_DATA || code == OMP_TARGET_UPDATE)
9157 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9158 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET))
9159 remove = true;
9161 if (remove)
9162 break;
9163 if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
9165 struct gimplify_omp_ctx *octx;
9166 for (octx = outer_ctx; octx; octx = octx->outer_context)
9168 if (octx->region_type != ORT_ACC_HOST_DATA)
9169 break;
9170 splay_tree_node n2
9171 = splay_tree_lookup (octx->variables,
9172 (splay_tree_key) decl);
9173 if (n2)
9174 error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
9175 "declared in enclosing %<host_data%> region",
9176 DECL_NAME (decl));
9179 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9180 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
9181 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
9182 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
9183 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
9185 remove = true;
9186 break;
9188 else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9189 || (OMP_CLAUSE_MAP_KIND (c)
9190 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9191 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9192 && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
9194 OMP_CLAUSE_SIZE (c)
9195 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
9196 false);
9197 if ((region_type & ORT_TARGET) != 0)
9198 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
9199 GOVD_FIRSTPRIVATE | GOVD_SEEN);
9202 if (!DECL_P (decl))
9204 tree d = decl, *pd;
9205 if (TREE_CODE (d) == ARRAY_REF)
9207 while (TREE_CODE (d) == ARRAY_REF)
9208 d = TREE_OPERAND (d, 0);
9209 if (TREE_CODE (d) == COMPONENT_REF
9210 && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
9211 decl = d;
9213 pd = &OMP_CLAUSE_DECL (c);
9214 if (d == decl
9215 && TREE_CODE (decl) == INDIRECT_REF
9216 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
9217 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9218 == REFERENCE_TYPE))
9220 pd = &TREE_OPERAND (decl, 0);
9221 decl = TREE_OPERAND (decl, 0);
9223 bool indir_p = false;
9224 tree orig_decl = decl;
9225 tree decl_ref = NULL_TREE;
9226 if ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA)) != 0
9227 && TREE_CODE (*pd) == COMPONENT_REF
9228 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
9229 && code != OACC_UPDATE)
9231 while (TREE_CODE (decl) == COMPONENT_REF)
9233 decl = TREE_OPERAND (decl, 0);
9234 if (((TREE_CODE (decl) == MEM_REF
9235 && integer_zerop (TREE_OPERAND (decl, 1)))
9236 || INDIRECT_REF_P (decl))
9237 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9238 == POINTER_TYPE))
9240 indir_p = true;
9241 decl = TREE_OPERAND (decl, 0);
9243 if (TREE_CODE (decl) == INDIRECT_REF
9244 && DECL_P (TREE_OPERAND (decl, 0))
9245 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9246 == REFERENCE_TYPE))
9248 decl_ref = decl;
9249 decl = TREE_OPERAND (decl, 0);
9253 else if (TREE_CODE (decl) == COMPONENT_REF)
9255 while (TREE_CODE (decl) == COMPONENT_REF)
9256 decl = TREE_OPERAND (decl, 0);
9257 if (TREE_CODE (decl) == INDIRECT_REF
9258 && DECL_P (TREE_OPERAND (decl, 0))
9259 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9260 == REFERENCE_TYPE))
9261 decl = TREE_OPERAND (decl, 0);
9263 if (decl != orig_decl && DECL_P (decl) && indir_p)
9265 gomp_map_kind k
9266 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9267 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9268 /* We have a dereference of a struct member. Make this an
9269 attach/detach operation, and ensure the base pointer is
9270 mapped as a FIRSTPRIVATE_POINTER. */
9271 OMP_CLAUSE_SET_MAP_KIND (c, k);
9272 flags = GOVD_MAP | GOVD_SEEN | GOVD_EXPLICIT;
9273 tree next_clause = OMP_CLAUSE_CHAIN (c);
9274 if (k == GOMP_MAP_ATTACH
9275 && code != OACC_ENTER_DATA
9276 && code != OMP_TARGET_ENTER_DATA
9277 && (!next_clause
9278 || (OMP_CLAUSE_CODE (next_clause) != OMP_CLAUSE_MAP)
9279 || (OMP_CLAUSE_MAP_KIND (next_clause)
9280 != GOMP_MAP_POINTER)
9281 || OMP_CLAUSE_DECL (next_clause) != decl)
9282 && (!struct_deref_set
9283 || !struct_deref_set->contains (decl)))
9285 if (!struct_deref_set)
9286 struct_deref_set = new hash_set<tree> ();
9287 /* As well as the attach, we also need a
9288 FIRSTPRIVATE_POINTER clause to properly map the
9289 pointer to the struct base. */
9290 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9291 OMP_CLAUSE_MAP);
9292 OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALLOC);
9293 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c2)
9294 = 1;
9295 tree charptr_zero
9296 = build_int_cst (build_pointer_type (char_type_node),
9298 OMP_CLAUSE_DECL (c2)
9299 = build2 (MEM_REF, char_type_node,
9300 decl_ref ? decl_ref : decl, charptr_zero);
9301 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9302 tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9303 OMP_CLAUSE_MAP);
9304 OMP_CLAUSE_SET_MAP_KIND (c3,
9305 GOMP_MAP_FIRSTPRIVATE_POINTER);
9306 OMP_CLAUSE_DECL (c3) = decl;
9307 OMP_CLAUSE_SIZE (c3) = size_zero_node;
9308 tree mapgrp = *prev_list_p;
9309 *prev_list_p = c2;
9310 OMP_CLAUSE_CHAIN (c3) = mapgrp;
9311 OMP_CLAUSE_CHAIN (c2) = c3;
9313 struct_deref_set->add (decl);
9315 goto do_add_decl;
9317 /* An "attach/detach" operation on an update directive should
9318 behave as a GOMP_MAP_ALWAYS_POINTER. Beware that
9319 unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
9320 depends on the previous mapping. */
9321 if (code == OACC_UPDATE
9322 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9323 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
9324 if (DECL_P (decl)
9325 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
9326 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
9327 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
9328 && code != OACC_UPDATE
9329 && code != OMP_TARGET_UPDATE)
9331 if (error_operand_p (decl))
9333 remove = true;
9334 break;
9337 tree stype = TREE_TYPE (decl);
9338 if (TREE_CODE (stype) == REFERENCE_TYPE)
9339 stype = TREE_TYPE (stype);
9340 if (TYPE_SIZE_UNIT (stype) == NULL
9341 || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
9343 error_at (OMP_CLAUSE_LOCATION (c),
9344 "mapping field %qE of variable length "
9345 "structure", OMP_CLAUSE_DECL (c));
9346 remove = true;
9347 break;
9350 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
9351 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9353 /* Error recovery. */
9354 if (prev_list_p == NULL)
9356 remove = true;
9357 break;
9359 if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
9361 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
9362 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
9364 remove = true;
9365 break;
9370 poly_offset_int offset1;
9371 poly_int64 bitpos1;
9372 tree base_ref;
9374 tree base
9375 = extract_base_bit_offset (OMP_CLAUSE_DECL (c), &base_ref,
9376 &bitpos1, &offset1);
9378 gcc_assert (base == decl);
9380 splay_tree_node n
9381 = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
9382 bool ptr = (OMP_CLAUSE_MAP_KIND (c)
9383 == GOMP_MAP_ALWAYS_POINTER);
9384 bool attach_detach = (OMP_CLAUSE_MAP_KIND (c)
9385 == GOMP_MAP_ATTACH_DETACH);
9386 bool attach = OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9387 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH;
9388 bool has_attachments = false;
9389 /* For OpenACC, pointers in structs should trigger an
9390 attach action. */
9391 if (attach_detach
9392 && ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA))
9393 || code == OMP_TARGET_ENTER_DATA
9394 || code == OMP_TARGET_EXIT_DATA))
9397 /* Turn a GOMP_MAP_ATTACH_DETACH clause into a
9398 GOMP_MAP_ATTACH or GOMP_MAP_DETACH clause after we
9399 have detected a case that needs a GOMP_MAP_STRUCT
9400 mapping added. */
9401 gomp_map_kind k
9402 = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9403 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9404 OMP_CLAUSE_SET_MAP_KIND (c, k);
9405 has_attachments = true;
9407 if (n == NULL || (n->value & GOVD_MAP) == 0)
9409 tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9410 OMP_CLAUSE_MAP);
9411 gomp_map_kind k = attach ? GOMP_MAP_FORCE_PRESENT
9412 : GOMP_MAP_STRUCT;
9414 OMP_CLAUSE_SET_MAP_KIND (l, k);
9415 if (base_ref)
9416 OMP_CLAUSE_DECL (l) = unshare_expr (base_ref);
9417 else
9418 OMP_CLAUSE_DECL (l) = decl;
9419 OMP_CLAUSE_SIZE (l)
9420 = (!attach
9421 ? size_int (1)
9422 : DECL_P (OMP_CLAUSE_DECL (l))
9423 ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l))
9424 : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l))));
9425 if (struct_map_to_clause == NULL)
9426 struct_map_to_clause = new hash_map<tree, tree>;
9427 struct_map_to_clause->put (decl, l);
9428 if (ptr || attach_detach)
9430 insert_struct_comp_map (code, c, l, *prev_list_p,
9431 NULL);
9432 *prev_list_p = l;
9433 prev_list_p = NULL;
9435 else
9437 OMP_CLAUSE_CHAIN (l) = c;
9438 *list_p = l;
9439 list_p = &OMP_CLAUSE_CHAIN (l);
9441 if (base_ref && code == OMP_TARGET)
9443 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9444 OMP_CLAUSE_MAP);
9445 enum gomp_map_kind mkind
9446 = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
9447 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9448 OMP_CLAUSE_DECL (c2) = decl;
9449 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9450 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
9451 OMP_CLAUSE_CHAIN (l) = c2;
9453 flags = GOVD_MAP | GOVD_EXPLICIT;
9454 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9455 || ptr
9456 || attach_detach)
9457 flags |= GOVD_SEEN;
9458 if (has_attachments)
9459 flags |= GOVD_MAP_HAS_ATTACHMENTS;
9460 goto do_add_decl;
9462 else if (struct_map_to_clause)
9464 tree *osc = struct_map_to_clause->get (decl);
9465 tree *sc = NULL, *scp = NULL;
9466 if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9467 || ptr
9468 || attach_detach)
9469 n->value |= GOVD_SEEN;
9470 sc = &OMP_CLAUSE_CHAIN (*osc);
9471 if (*sc != c
9472 && (OMP_CLAUSE_MAP_KIND (*sc)
9473 == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9474 sc = &OMP_CLAUSE_CHAIN (*sc);
9475 /* Here "prev_list_p" is the end of the inserted
9476 alloc/release nodes after the struct node, OSC. */
9477 for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
9478 if ((ptr || attach_detach) && sc == prev_list_p)
9479 break;
9480 else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9481 != COMPONENT_REF
9482 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9483 != INDIRECT_REF)
9484 && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9485 != ARRAY_REF))
9486 break;
9487 else
9489 tree sc_decl = OMP_CLAUSE_DECL (*sc);
9490 poly_offset_int offsetn;
9491 poly_int64 bitposn;
9492 tree base
9493 = extract_base_bit_offset (sc_decl, NULL,
9494 &bitposn, &offsetn);
9495 if (base != decl)
9496 break;
9497 if (scp)
9498 continue;
9499 if ((region_type & ORT_ACC) != 0)
9501 /* This duplicate checking code is currently only
9502 enabled for OpenACC. */
9503 tree d1 = OMP_CLAUSE_DECL (*sc);
9504 tree d2 = OMP_CLAUSE_DECL (c);
9505 while (TREE_CODE (d1) == ARRAY_REF)
9506 d1 = TREE_OPERAND (d1, 0);
9507 while (TREE_CODE (d2) == ARRAY_REF)
9508 d2 = TREE_OPERAND (d2, 0);
9509 if (TREE_CODE (d1) == INDIRECT_REF)
9510 d1 = TREE_OPERAND (d1, 0);
9511 if (TREE_CODE (d2) == INDIRECT_REF)
9512 d2 = TREE_OPERAND (d2, 0);
9513 while (TREE_CODE (d1) == COMPONENT_REF)
9514 if (TREE_CODE (d2) == COMPONENT_REF
9515 && TREE_OPERAND (d1, 1)
9516 == TREE_OPERAND (d2, 1))
9518 d1 = TREE_OPERAND (d1, 0);
9519 d2 = TREE_OPERAND (d2, 0);
9521 else
9522 break;
9523 if (d1 == d2)
9525 error_at (OMP_CLAUSE_LOCATION (c),
9526 "%qE appears more than once in map "
9527 "clauses", OMP_CLAUSE_DECL (c));
9528 remove = true;
9529 break;
9532 if (maybe_lt (offset1, offsetn)
9533 || (known_eq (offset1, offsetn)
9534 && maybe_lt (bitpos1, bitposn)))
9536 if (ptr || attach_detach)
9537 scp = sc;
9538 else
9539 break;
9542 if (remove)
9543 break;
9544 if (!attach)
9545 OMP_CLAUSE_SIZE (*osc)
9546 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
9547 size_one_node);
9548 if (ptr || attach_detach)
9550 tree cl = insert_struct_comp_map (code, c, NULL,
9551 *prev_list_p, scp);
9552 if (sc == prev_list_p)
9554 *sc = cl;
9555 prev_list_p = NULL;
9557 else
9559 *prev_list_p = OMP_CLAUSE_CHAIN (c);
9560 list_p = prev_list_p;
9561 prev_list_p = NULL;
9562 OMP_CLAUSE_CHAIN (c) = *sc;
9563 *sc = cl;
9564 continue;
9567 else if (*sc != c)
9569 *list_p = OMP_CLAUSE_CHAIN (c);
9570 OMP_CLAUSE_CHAIN (c) = *sc;
9571 *sc = c;
9572 continue;
9576 else if ((code == OACC_ENTER_DATA
9577 || code == OACC_EXIT_DATA
9578 || code == OACC_DATA
9579 || code == OACC_PARALLEL
9580 || code == OACC_KERNELS
9581 || code == OACC_SERIAL)
9582 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9584 gomp_map_kind k = (code == OACC_EXIT_DATA
9585 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9586 OMP_CLAUSE_SET_MAP_KIND (c, k);
9589 if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
9591 /* Don't gimplify *pd fully at this point, as the base
9592 will need to be adjusted during omp lowering. */
9593 auto_vec<tree, 10> expr_stack;
9594 tree *p = pd;
9595 while (handled_component_p (*p)
9596 || TREE_CODE (*p) == INDIRECT_REF
9597 || TREE_CODE (*p) == ADDR_EXPR
9598 || TREE_CODE (*p) == MEM_REF
9599 || TREE_CODE (*p) == NON_LVALUE_EXPR)
9601 expr_stack.safe_push (*p);
9602 p = &TREE_OPERAND (*p, 0);
9604 for (int i = expr_stack.length () - 1; i >= 0; i--)
9606 tree t = expr_stack[i];
9607 if (TREE_CODE (t) == ARRAY_REF
9608 || TREE_CODE (t) == ARRAY_RANGE_REF)
9610 if (TREE_OPERAND (t, 2) == NULL_TREE)
9612 tree low = unshare_expr (array_ref_low_bound (t));
9613 if (!is_gimple_min_invariant (low))
9615 TREE_OPERAND (t, 2) = low;
9616 if (gimplify_expr (&TREE_OPERAND (t, 2),
9617 pre_p, NULL,
9618 is_gimple_reg,
9619 fb_rvalue) == GS_ERROR)
9620 remove = true;
9623 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
9624 NULL, is_gimple_reg,
9625 fb_rvalue) == GS_ERROR)
9626 remove = true;
9627 if (TREE_OPERAND (t, 3) == NULL_TREE)
9629 tree elmt_size = array_ref_element_size (t);
9630 if (!is_gimple_min_invariant (elmt_size))
9632 elmt_size = unshare_expr (elmt_size);
9633 tree elmt_type
9634 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t,
9635 0)));
9636 tree factor
9637 = size_int (TYPE_ALIGN_UNIT (elmt_type));
9638 elmt_size
9639 = size_binop (EXACT_DIV_EXPR, elmt_size,
9640 factor);
9641 TREE_OPERAND (t, 3) = elmt_size;
9642 if (gimplify_expr (&TREE_OPERAND (t, 3),
9643 pre_p, NULL,
9644 is_gimple_reg,
9645 fb_rvalue) == GS_ERROR)
9646 remove = true;
9649 else if (gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
9650 NULL, is_gimple_reg,
9651 fb_rvalue) == GS_ERROR)
9652 remove = true;
9654 else if (TREE_CODE (t) == COMPONENT_REF)
9656 if (TREE_OPERAND (t, 2) == NULL_TREE)
9658 tree offset = component_ref_field_offset (t);
9659 if (!is_gimple_min_invariant (offset))
9661 offset = unshare_expr (offset);
9662 tree field = TREE_OPERAND (t, 1);
9663 tree factor
9664 = size_int (DECL_OFFSET_ALIGN (field)
9665 / BITS_PER_UNIT);
9666 offset = size_binop (EXACT_DIV_EXPR, offset,
9667 factor);
9668 TREE_OPERAND (t, 2) = offset;
9669 if (gimplify_expr (&TREE_OPERAND (t, 2),
9670 pre_p, NULL,
9671 is_gimple_reg,
9672 fb_rvalue) == GS_ERROR)
9673 remove = true;
9676 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
9677 NULL, is_gimple_reg,
9678 fb_rvalue) == GS_ERROR)
9679 remove = true;
9682 for (; expr_stack.length () > 0; )
9684 tree t = expr_stack.pop ();
9686 if (TREE_CODE (t) == ARRAY_REF
9687 || TREE_CODE (t) == ARRAY_RANGE_REF)
9689 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))
9690 && gimplify_expr (&TREE_OPERAND (t, 1), pre_p,
9691 NULL, is_gimple_val,
9692 fb_rvalue) == GS_ERROR)
9693 remove = true;
9697 else if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
9698 fb_lvalue) == GS_ERROR)
9700 remove = true;
9701 break;
9704 if (!remove
9705 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
9706 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
9707 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
9708 && OMP_CLAUSE_CHAIN (c)
9709 && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
9710 && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9711 == GOMP_MAP_ALWAYS_POINTER)
9712 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9713 == GOMP_MAP_ATTACH_DETACH)
9714 || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
9715 == GOMP_MAP_TO_PSET)))
9716 prev_list_p = list_p;
9718 break;
9720 else
9722 /* DECL_P (decl) == true */
9723 tree *sc;
9724 if (struct_map_to_clause
9725 && (sc = struct_map_to_clause->get (decl)) != NULL
9726 && OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_STRUCT
9727 && decl == OMP_CLAUSE_DECL (*sc))
9729 /* We have found a map of the whole structure after a
9730 leading GOMP_MAP_STRUCT has been created, so refill the
9731 leading clause into a map of the whole structure
9732 variable, and remove the current one.
9733 TODO: we should be able to remove some maps of the
9734 following structure element maps if they are of
9735 compatible TO/FROM/ALLOC type. */
9736 OMP_CLAUSE_SET_MAP_KIND (*sc, OMP_CLAUSE_MAP_KIND (c));
9737 OMP_CLAUSE_SIZE (*sc) = unshare_expr (OMP_CLAUSE_SIZE (c));
9738 remove = true;
9739 break;
9742 flags = GOVD_MAP | GOVD_EXPLICIT;
9743 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
9744 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
9745 flags |= GOVD_MAP_ALWAYS_TO;
9747 if ((code == OMP_TARGET
9748 || code == OMP_TARGET_DATA
9749 || code == OMP_TARGET_ENTER_DATA
9750 || code == OMP_TARGET_EXIT_DATA)
9751 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9753 for (struct gimplify_omp_ctx *octx = outer_ctx; octx;
9754 octx = octx->outer_context)
9756 splay_tree_node n
9757 = splay_tree_lookup (octx->variables,
9758 (splay_tree_key) OMP_CLAUSE_DECL (c));
9759 /* If this is contained in an outer OpenMP region as a
9760 firstprivate value, remove the attach/detach. */
9761 if (n && (n->value & GOVD_FIRSTPRIVATE))
9763 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FIRSTPRIVATE_POINTER);
9764 goto do_add;
9768 enum gomp_map_kind map_kind = (code == OMP_TARGET_EXIT_DATA
9769 ? GOMP_MAP_DETACH
9770 : GOMP_MAP_ATTACH);
9771 OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
9774 goto do_add;
9776 case OMP_CLAUSE_AFFINITY:
9777 gimplify_omp_affinity (list_p, pre_p);
9778 remove = true;
9779 break;
9780 case OMP_CLAUSE_DEPEND:
9781 if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
9783 tree deps = OMP_CLAUSE_DECL (c);
9784 while (deps && TREE_CODE (deps) == TREE_LIST)
9786 if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
9787 && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
9788 gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
9789 pre_p, NULL, is_gimple_val, fb_rvalue);
9790 deps = TREE_CHAIN (deps);
9792 break;
9794 else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
9795 break;
9796 if (handled_depend_iterators == -1)
9797 handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
9798 if (handled_depend_iterators)
9800 if (handled_depend_iterators == 2)
9801 remove = true;
9802 break;
9804 if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
9806 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
9807 NULL, is_gimple_val, fb_rvalue);
9808 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
9810 if (error_operand_p (OMP_CLAUSE_DECL (c)))
9812 remove = true;
9813 break;
9815 OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
9816 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
9817 is_gimple_val, fb_rvalue) == GS_ERROR)
9819 remove = true;
9820 break;
9822 if (code == OMP_TASK)
9823 ctx->has_depend = true;
9824 break;
9826 case OMP_CLAUSE_TO:
9827 case OMP_CLAUSE_FROM:
9828 case OMP_CLAUSE__CACHE_:
9829 decl = OMP_CLAUSE_DECL (c);
9830 if (error_operand_p (decl))
9832 remove = true;
9833 break;
9835 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9836 OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
9837 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
9838 if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
9839 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
9841 remove = true;
9842 break;
9844 if (!DECL_P (decl))
9846 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
9847 NULL, is_gimple_lvalue, fb_lvalue)
9848 == GS_ERROR)
9850 remove = true;
9851 break;
9853 break;
9855 goto do_notice;
9857 case OMP_CLAUSE_USE_DEVICE_PTR:
9858 case OMP_CLAUSE_USE_DEVICE_ADDR:
9859 flags = GOVD_EXPLICIT;
9860 goto do_add;
9862 case OMP_CLAUSE_IS_DEVICE_PTR:
9863 flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
9864 goto do_add;
9866 do_add:
9867 decl = OMP_CLAUSE_DECL (c);
9868 do_add_decl:
9869 if (error_operand_p (decl))
9871 remove = true;
9872 break;
9874 if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
9876 tree t = omp_member_access_dummy_var (decl);
9877 if (t)
9879 tree v = DECL_VALUE_EXPR (decl);
9880 DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
9881 if (outer_ctx)
9882 omp_notice_variable (outer_ctx, t, true);
9885 if (code == OACC_DATA
9886 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9887 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
9888 flags |= GOVD_MAP_0LEN_ARRAY;
9889 omp_add_variable (ctx, decl, flags);
9890 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
9891 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
9892 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
9893 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
9895 struct gimplify_omp_ctx *pctx
9896 = code == OMP_TARGET ? outer_ctx : ctx;
9897 if (pctx)
9898 omp_add_variable (pctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
9899 GOVD_LOCAL | GOVD_SEEN);
9900 if (pctx
9901 && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
9902 && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
9903 find_decl_expr,
9904 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
9905 NULL) == NULL_TREE)
9906 omp_add_variable (pctx,
9907 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
9908 GOVD_LOCAL | GOVD_SEEN);
9909 gimplify_omp_ctxp = pctx;
9910 push_gimplify_context ();
9912 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
9913 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
9915 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
9916 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
9917 pop_gimplify_context
9918 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
9919 push_gimplify_context ();
9920 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
9921 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
9922 pop_gimplify_context
9923 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
9924 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
9925 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
9927 gimplify_omp_ctxp = outer_ctx;
9929 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
9930 && OMP_CLAUSE_LASTPRIVATE_STMT (c))
9932 gimplify_omp_ctxp = ctx;
9933 push_gimplify_context ();
9934 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
9936 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
9937 NULL, NULL);
9938 TREE_SIDE_EFFECTS (bind) = 1;
9939 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
9940 OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
9942 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
9943 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
9944 pop_gimplify_context
9945 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
9946 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
9948 gimplify_omp_ctxp = outer_ctx;
9950 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
9951 && OMP_CLAUSE_LINEAR_STMT (c))
9953 gimplify_omp_ctxp = ctx;
9954 push_gimplify_context ();
9955 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
9957 tree bind = build3 (BIND_EXPR, void_type_node, NULL,
9958 NULL, NULL);
9959 TREE_SIDE_EFFECTS (bind) = 1;
9960 BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
9961 OMP_CLAUSE_LINEAR_STMT (c) = bind;
9963 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
9964 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
9965 pop_gimplify_context
9966 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
9967 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
9969 gimplify_omp_ctxp = outer_ctx;
9971 if (notice_outer)
9972 goto do_notice;
9973 break;
9975 case OMP_CLAUSE_COPYIN:
9976 case OMP_CLAUSE_COPYPRIVATE:
9977 decl = OMP_CLAUSE_DECL (c);
9978 if (error_operand_p (decl))
9980 remove = true;
9981 break;
9983 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
9984 && !remove
9985 && !omp_check_private (ctx, decl, true))
9987 remove = true;
9988 if (is_global_var (decl))
9990 if (DECL_THREAD_LOCAL_P (decl))
9991 remove = false;
9992 else if (DECL_HAS_VALUE_EXPR_P (decl))
9994 tree value = get_base_address (DECL_VALUE_EXPR (decl));
9996 if (value
9997 && DECL_P (value)
9998 && DECL_THREAD_LOCAL_P (value))
9999 remove = false;
10002 if (remove)
10003 error_at (OMP_CLAUSE_LOCATION (c),
10004 "copyprivate variable %qE is not threadprivate"
10005 " or private in outer context", DECL_NAME (decl));
10007 do_notice:
10008 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10009 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10010 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
10011 && outer_ctx
10012 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
10013 || (region_type == ORT_WORKSHARE
10014 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10015 && (OMP_CLAUSE_REDUCTION_INSCAN (c)
10016 || code == OMP_LOOP)))
10017 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
10018 || (code == OMP_LOOP
10019 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10020 && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
10021 == ORT_COMBINED_TEAMS))))
10023 splay_tree_node on
10024 = splay_tree_lookup (outer_ctx->variables,
10025 (splay_tree_key)decl);
10026 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
10028 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10029 && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10030 && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
10031 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
10032 && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
10033 == POINTER_TYPE))))
10034 omp_firstprivatize_variable (outer_ctx, decl);
10035 else
10037 omp_add_variable (outer_ctx, decl,
10038 GOVD_SEEN | GOVD_SHARED);
10039 if (outer_ctx->outer_context)
10040 omp_notice_variable (outer_ctx->outer_context, decl,
10041 true);
10045 if (outer_ctx)
10046 omp_notice_variable (outer_ctx, decl, true);
10047 if (check_non_private
10048 && region_type == ORT_WORKSHARE
10049 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
10050 || decl == OMP_CLAUSE_DECL (c)
10051 || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10052 && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10053 == ADDR_EXPR
10054 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10055 == POINTER_PLUS_EXPR
10056 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
10057 (OMP_CLAUSE_DECL (c), 0), 0))
10058 == ADDR_EXPR)))))
10059 && omp_check_private (ctx, decl, false))
10061 error ("%s variable %qE is private in outer context",
10062 check_non_private, DECL_NAME (decl));
10063 remove = true;
10065 break;
10067 case OMP_CLAUSE_DETACH:
10068 flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
10069 goto do_add;
10071 case OMP_CLAUSE_IF:
10072 if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
10073 && OMP_CLAUSE_IF_MODIFIER (c) != code)
10075 const char *p[2];
10076 for (int i = 0; i < 2; i++)
10077 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
10079 case VOID_CST: p[i] = "cancel"; break;
10080 case OMP_PARALLEL: p[i] = "parallel"; break;
10081 case OMP_SIMD: p[i] = "simd"; break;
10082 case OMP_TASK: p[i] = "task"; break;
10083 case OMP_TASKLOOP: p[i] = "taskloop"; break;
10084 case OMP_TARGET_DATA: p[i] = "target data"; break;
10085 case OMP_TARGET: p[i] = "target"; break;
10086 case OMP_TARGET_UPDATE: p[i] = "target update"; break;
10087 case OMP_TARGET_ENTER_DATA:
10088 p[i] = "target enter data"; break;
10089 case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
10090 default: gcc_unreachable ();
10092 error_at (OMP_CLAUSE_LOCATION (c),
10093 "expected %qs %<if%> clause modifier rather than %qs",
10094 p[0], p[1]);
10095 remove = true;
10097 /* Fall through. */
10099 case OMP_CLAUSE_FINAL:
10100 OMP_CLAUSE_OPERAND (c, 0)
10101 = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
10102 /* Fall through. */
10104 case OMP_CLAUSE_SCHEDULE:
10105 case OMP_CLAUSE_NUM_THREADS:
10106 case OMP_CLAUSE_NUM_TEAMS:
10107 case OMP_CLAUSE_THREAD_LIMIT:
10108 case OMP_CLAUSE_DIST_SCHEDULE:
10109 case OMP_CLAUSE_DEVICE:
10110 case OMP_CLAUSE_PRIORITY:
10111 case OMP_CLAUSE_GRAINSIZE:
10112 case OMP_CLAUSE_NUM_TASKS:
10113 case OMP_CLAUSE_FILTER:
10114 case OMP_CLAUSE_HINT:
10115 case OMP_CLAUSE_ASYNC:
10116 case OMP_CLAUSE_WAIT:
10117 case OMP_CLAUSE_NUM_GANGS:
10118 case OMP_CLAUSE_NUM_WORKERS:
10119 case OMP_CLAUSE_VECTOR_LENGTH:
10120 case OMP_CLAUSE_WORKER:
10121 case OMP_CLAUSE_VECTOR:
10122 if (OMP_CLAUSE_OPERAND (c, 0)
10123 && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0)))
10125 if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0)))
10127 remove = true;
10128 break;
10130 /* All these clauses care about value, not a particular decl,
10131 so try to force it into a SSA_NAME or fresh temporary. */
10132 OMP_CLAUSE_OPERAND (c, 0)
10133 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0),
10134 pre_p, NULL, true);
10136 break;
10138 case OMP_CLAUSE_GANG:
10139 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
10140 is_gimple_val, fb_rvalue) == GS_ERROR)
10141 remove = true;
10142 if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
10143 is_gimple_val, fb_rvalue) == GS_ERROR)
10144 remove = true;
10145 break;
10147 case OMP_CLAUSE_NOWAIT:
10148 nowait = 1;
10149 break;
10151 case OMP_CLAUSE_ORDERED:
10152 case OMP_CLAUSE_UNTIED:
10153 case OMP_CLAUSE_COLLAPSE:
10154 case OMP_CLAUSE_TILE:
10155 case OMP_CLAUSE_AUTO:
10156 case OMP_CLAUSE_SEQ:
10157 case OMP_CLAUSE_INDEPENDENT:
10158 case OMP_CLAUSE_MERGEABLE:
10159 case OMP_CLAUSE_PROC_BIND:
10160 case OMP_CLAUSE_SAFELEN:
10161 case OMP_CLAUSE_SIMDLEN:
10162 case OMP_CLAUSE_NOGROUP:
10163 case OMP_CLAUSE_THREADS:
10164 case OMP_CLAUSE_SIMD:
10165 case OMP_CLAUSE_BIND:
10166 case OMP_CLAUSE_IF_PRESENT:
10167 case OMP_CLAUSE_FINALIZE:
10168 break;
10170 case OMP_CLAUSE_ORDER:
10171 ctx->order_concurrent = true;
10172 break;
10174 case OMP_CLAUSE_DEFAULTMAP:
10175 enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
10176 switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
10178 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
10179 gdmkmin = GDMK_SCALAR;
10180 gdmkmax = GDMK_POINTER;
10181 break;
10182 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
10183 gdmkmin = GDMK_SCALAR;
10184 gdmkmax = GDMK_SCALAR_TARGET;
10185 break;
10186 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
10187 gdmkmin = gdmkmax = GDMK_AGGREGATE;
10188 break;
10189 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
10190 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
10191 break;
10192 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
10193 gdmkmin = gdmkmax = GDMK_POINTER;
10194 break;
10195 default:
10196 gcc_unreachable ();
10198 for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
10199 switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
10201 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
10202 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
10203 break;
10204 case OMP_CLAUSE_DEFAULTMAP_TO:
10205 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
10206 break;
10207 case OMP_CLAUSE_DEFAULTMAP_FROM:
10208 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
10209 break;
10210 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
10211 ctx->defaultmap[gdmk] = GOVD_MAP;
10212 break;
10213 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
10214 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10215 break;
10216 case OMP_CLAUSE_DEFAULTMAP_NONE:
10217 ctx->defaultmap[gdmk] = 0;
10218 break;
10219 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
10220 switch (gdmk)
10222 case GDMK_SCALAR:
10223 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10224 break;
10225 case GDMK_SCALAR_TARGET:
10226 ctx->defaultmap[gdmk] = (lang_GNU_Fortran ()
10227 ? GOVD_MAP : GOVD_FIRSTPRIVATE);
10228 break;
10229 case GDMK_AGGREGATE:
10230 case GDMK_ALLOCATABLE:
10231 ctx->defaultmap[gdmk] = GOVD_MAP;
10232 break;
10233 case GDMK_POINTER:
10234 ctx->defaultmap[gdmk] = GOVD_MAP;
10235 if (!lang_GNU_Fortran ())
10236 ctx->defaultmap[gdmk] |= GOVD_MAP_0LEN_ARRAY;
10237 break;
10238 default:
10239 gcc_unreachable ();
10241 break;
10242 default:
10243 gcc_unreachable ();
10245 break;
10247 case OMP_CLAUSE_ALIGNED:
10248 decl = OMP_CLAUSE_DECL (c);
10249 if (error_operand_p (decl))
10251 remove = true;
10252 break;
10254 if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
10255 is_gimple_val, fb_rvalue) == GS_ERROR)
10257 remove = true;
10258 break;
10260 if (!is_global_var (decl)
10261 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
10262 omp_add_variable (ctx, decl, GOVD_ALIGNED);
10263 break;
10265 case OMP_CLAUSE_NONTEMPORAL:
10266 decl = OMP_CLAUSE_DECL (c);
10267 if (error_operand_p (decl))
10269 remove = true;
10270 break;
10272 omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
10273 break;
10275 case OMP_CLAUSE_ALLOCATE:
10276 decl = OMP_CLAUSE_DECL (c);
10277 if (error_operand_p (decl))
10279 remove = true;
10280 break;
10282 if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL,
10283 is_gimple_val, fb_rvalue) == GS_ERROR)
10285 remove = true;
10286 break;
10288 else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
10289 || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
10290 == INTEGER_CST))
10292 else if (code == OMP_TASKLOOP
10293 || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
10294 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
10295 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
10296 pre_p, NULL, false);
10297 break;
10299 case OMP_CLAUSE_DEFAULT:
10300 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
10301 break;
10303 case OMP_CLAUSE_INCLUSIVE:
10304 case OMP_CLAUSE_EXCLUSIVE:
10305 decl = OMP_CLAUSE_DECL (c);
10307 splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
10308 (splay_tree_key) decl);
10309 if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
10311 error_at (OMP_CLAUSE_LOCATION (c),
10312 "%qD specified in %qs clause but not in %<inscan%> "
10313 "%<reduction%> clause on the containing construct",
10314 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10315 remove = true;
10317 else
10319 n->value |= GOVD_REDUCTION_INSCAN;
10320 if (outer_ctx->region_type == ORT_SIMD
10321 && outer_ctx->outer_context
10322 && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
10324 n = splay_tree_lookup (outer_ctx->outer_context->variables,
10325 (splay_tree_key) decl);
10326 if (n && (n->value & GOVD_REDUCTION) != 0)
10327 n->value |= GOVD_REDUCTION_INSCAN;
10331 break;
10333 case OMP_CLAUSE_NOHOST:
10334 default:
10335 gcc_unreachable ();
10338 if (code == OACC_DATA
10339 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10340 && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
10341 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
10342 remove = true;
10343 if (remove)
10344 *list_p = OMP_CLAUSE_CHAIN (c);
10345 else
10346 list_p = &OMP_CLAUSE_CHAIN (c);
10349 ctx->clauses = *orig_list_p;
10350 gimplify_omp_ctxp = ctx;
10351 if (struct_map_to_clause)
10352 delete struct_map_to_clause;
10353 if (struct_deref_set)
10354 delete struct_deref_set;
10357 /* Return true if DECL is a candidate for shared to firstprivate
10358 optimization. We only consider non-addressable scalars, not
10359 too big, and not references. */
10361 static bool
10362 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
10364 if (TREE_ADDRESSABLE (decl))
10365 return false;
10366 tree type = TREE_TYPE (decl);
10367 if (!is_gimple_reg_type (type)
10368 || TREE_CODE (type) == REFERENCE_TYPE
10369 || TREE_ADDRESSABLE (type))
10370 return false;
10371 /* Don't optimize too large decls, as each thread/task will have
10372 its own. */
10373 HOST_WIDE_INT len = int_size_in_bytes (type);
10374 if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
10375 return false;
10376 if (lang_hooks.decls.omp_privatize_by_reference (decl))
10377 return false;
10378 return true;
10381 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
10382 For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
10383 GOVD_WRITTEN in outer contexts. */
10385 static void
10386 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
10388 for (; ctx; ctx = ctx->outer_context)
10390 splay_tree_node n = splay_tree_lookup (ctx->variables,
10391 (splay_tree_key) decl);
10392 if (n == NULL)
10393 continue;
10394 else if (n->value & GOVD_SHARED)
10396 n->value |= GOVD_WRITTEN;
10397 return;
10399 else if (n->value & GOVD_DATA_SHARE_CLASS)
10400 return;
10404 /* Helper callback for walk_gimple_seq to discover possible stores
10405 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10406 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10407 for those. */
10409 static tree
10410 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
10412 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
10414 *walk_subtrees = 0;
10415 if (!wi->is_lhs)
10416 return NULL_TREE;
10418 tree op = *tp;
10421 if (handled_component_p (op))
10422 op = TREE_OPERAND (op, 0);
10423 else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
10424 && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
10425 op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
10426 else
10427 break;
10429 while (1);
10430 if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
10431 return NULL_TREE;
10433 omp_mark_stores (gimplify_omp_ctxp, op);
10434 return NULL_TREE;
10437 /* Helper callback for walk_gimple_seq to discover possible stores
10438 to omp_shared_to_firstprivate_optimizable_decl_p decls and set
10439 GOVD_WRITTEN if they are GOVD_SHARED in some outer context
10440 for those. */
10442 static tree
10443 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
10444 bool *handled_ops_p,
10445 struct walk_stmt_info *wi)
10447 gimple *stmt = gsi_stmt (*gsi_p);
10448 switch (gimple_code (stmt))
10450 /* Don't recurse on OpenMP constructs for which
10451 gimplify_adjust_omp_clauses already handled the bodies,
10452 except handle gimple_omp_for_pre_body. */
10453 case GIMPLE_OMP_FOR:
10454 *handled_ops_p = true;
10455 if (gimple_omp_for_pre_body (stmt))
10456 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
10457 omp_find_stores_stmt, omp_find_stores_op, wi);
10458 break;
10459 case GIMPLE_OMP_PARALLEL:
10460 case GIMPLE_OMP_TASK:
10461 case GIMPLE_OMP_SECTIONS:
10462 case GIMPLE_OMP_SINGLE:
10463 case GIMPLE_OMP_SCOPE:
10464 case GIMPLE_OMP_TARGET:
10465 case GIMPLE_OMP_TEAMS:
10466 case GIMPLE_OMP_CRITICAL:
10467 *handled_ops_p = true;
10468 break;
10469 default:
10470 break;
10472 return NULL_TREE;
10475 struct gimplify_adjust_omp_clauses_data
10477 tree *list_p;
10478 gimple_seq *pre_p;
10481 /* For all variables that were not actually used within the context,
10482 remove PRIVATE, SHARED, and FIRSTPRIVATE clauses. */
10484 static int
10485 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
10487 tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
10488 gimple_seq *pre_p
10489 = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
10490 tree decl = (tree) n->key;
10491 unsigned flags = n->value;
10492 enum omp_clause_code code;
10493 tree clause;
10494 bool private_debug;
10496 if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
10497 && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
10498 flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
10499 if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
10500 return 0;
10501 if ((flags & GOVD_SEEN) == 0)
10502 return 0;
10503 if ((flags & GOVD_MAP_HAS_ATTACHMENTS) != 0)
10504 return 0;
10505 if (flags & GOVD_DEBUG_PRIVATE)
10507 gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
10508 private_debug = true;
10510 else if (flags & GOVD_MAP)
10511 private_debug = false;
10512 else
10513 private_debug
10514 = lang_hooks.decls.omp_private_debug_clause (decl,
10515 !!(flags & GOVD_SHARED));
10516 if (private_debug)
10517 code = OMP_CLAUSE_PRIVATE;
10518 else if (flags & GOVD_MAP)
10520 code = OMP_CLAUSE_MAP;
10521 if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
10522 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
10524 error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
10525 return 0;
10527 if (VAR_P (decl)
10528 && DECL_IN_CONSTANT_POOL (decl)
10529 && !lookup_attribute ("omp declare target",
10530 DECL_ATTRIBUTES (decl)))
10532 tree id = get_identifier ("omp declare target");
10533 DECL_ATTRIBUTES (decl)
10534 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
10535 varpool_node *node = varpool_node::get (decl);
10536 if (node)
10538 node->offloadable = 1;
10539 if (ENABLE_OFFLOADING)
10540 g->have_offload = true;
10544 else if (flags & GOVD_SHARED)
10546 if (is_global_var (decl))
10548 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
10549 while (ctx != NULL)
10551 splay_tree_node on
10552 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10553 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
10554 | GOVD_PRIVATE | GOVD_REDUCTION
10555 | GOVD_LINEAR | GOVD_MAP)) != 0)
10556 break;
10557 ctx = ctx->outer_context;
10559 if (ctx == NULL)
10560 return 0;
10562 code = OMP_CLAUSE_SHARED;
10563 /* Don't optimize shared into firstprivate for read-only vars
10564 on tasks with depend clause, we shouldn't try to copy them
10565 until the dependencies are satisfied. */
10566 if (gimplify_omp_ctxp->has_depend)
10567 flags |= GOVD_WRITTEN;
10569 else if (flags & GOVD_PRIVATE)
10570 code = OMP_CLAUSE_PRIVATE;
10571 else if (flags & GOVD_FIRSTPRIVATE)
10573 code = OMP_CLAUSE_FIRSTPRIVATE;
10574 if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
10575 && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
10576 && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
10578 error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
10579 "%<target%> construct", decl);
10580 return 0;
10583 else if (flags & GOVD_LASTPRIVATE)
10584 code = OMP_CLAUSE_LASTPRIVATE;
10585 else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
10586 return 0;
10587 else if (flags & GOVD_CONDTEMP)
10589 code = OMP_CLAUSE__CONDTEMP_;
10590 gimple_add_tmp_var (decl);
10592 else
10593 gcc_unreachable ();
10595 if (((flags & GOVD_LASTPRIVATE)
10596 || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
10597 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10598 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10600 tree chain = *list_p;
10601 clause = build_omp_clause (input_location, code);
10602 OMP_CLAUSE_DECL (clause) = decl;
10603 OMP_CLAUSE_CHAIN (clause) = chain;
10604 if (private_debug)
10605 OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
10606 else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
10607 OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
10608 else if (code == OMP_CLAUSE_SHARED
10609 && (flags & GOVD_WRITTEN) == 0
10610 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10611 OMP_CLAUSE_SHARED_READONLY (clause) = 1;
10612 else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
10613 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
10614 else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
10616 tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
10617 OMP_CLAUSE_DECL (nc) = decl;
10618 if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
10619 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
10620 OMP_CLAUSE_DECL (clause)
10621 = build_simple_mem_ref_loc (input_location, decl);
10622 OMP_CLAUSE_DECL (clause)
10623 = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
10624 build_int_cst (build_pointer_type (char_type_node), 0));
10625 OMP_CLAUSE_SIZE (clause) = size_zero_node;
10626 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10627 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
10628 OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
10629 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
10630 OMP_CLAUSE_CHAIN (nc) = chain;
10631 OMP_CLAUSE_CHAIN (clause) = nc;
10632 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10633 gimplify_omp_ctxp = ctx->outer_context;
10634 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
10635 pre_p, NULL, is_gimple_val, fb_rvalue);
10636 gimplify_omp_ctxp = ctx;
10638 else if (code == OMP_CLAUSE_MAP)
10640 int kind;
10641 /* Not all combinations of these GOVD_MAP flags are actually valid. */
10642 switch (flags & (GOVD_MAP_TO_ONLY
10643 | GOVD_MAP_FORCE
10644 | GOVD_MAP_FORCE_PRESENT
10645 | GOVD_MAP_ALLOC_ONLY
10646 | GOVD_MAP_FROM_ONLY))
10648 case 0:
10649 kind = GOMP_MAP_TOFROM;
10650 break;
10651 case GOVD_MAP_FORCE:
10652 kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
10653 break;
10654 case GOVD_MAP_TO_ONLY:
10655 kind = GOMP_MAP_TO;
10656 break;
10657 case GOVD_MAP_FROM_ONLY:
10658 kind = GOMP_MAP_FROM;
10659 break;
10660 case GOVD_MAP_ALLOC_ONLY:
10661 kind = GOMP_MAP_ALLOC;
10662 break;
10663 case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
10664 kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
10665 break;
10666 case GOVD_MAP_FORCE_PRESENT:
10667 kind = GOMP_MAP_FORCE_PRESENT;
10668 break;
10669 default:
10670 gcc_unreachable ();
10672 OMP_CLAUSE_SET_MAP_KIND (clause, kind);
10673 if (DECL_SIZE (decl)
10674 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
10676 tree decl2 = DECL_VALUE_EXPR (decl);
10677 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
10678 decl2 = TREE_OPERAND (decl2, 0);
10679 gcc_assert (DECL_P (decl2));
10680 tree mem = build_simple_mem_ref (decl2);
10681 OMP_CLAUSE_DECL (clause) = mem;
10682 OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
10683 if (gimplify_omp_ctxp->outer_context)
10685 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
10686 omp_notice_variable (ctx, decl2, true);
10687 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
10689 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
10690 OMP_CLAUSE_MAP);
10691 OMP_CLAUSE_DECL (nc) = decl;
10692 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10693 if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
10694 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
10695 else
10696 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
10697 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
10698 OMP_CLAUSE_CHAIN (clause) = nc;
10700 else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
10701 && lang_hooks.decls.omp_privatize_by_reference (decl))
10703 OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
10704 OMP_CLAUSE_SIZE (clause)
10705 = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
10706 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10707 gimplify_omp_ctxp = ctx->outer_context;
10708 gimplify_expr (&OMP_CLAUSE_SIZE (clause),
10709 pre_p, NULL, is_gimple_val, fb_rvalue);
10710 gimplify_omp_ctxp = ctx;
10711 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
10712 OMP_CLAUSE_MAP);
10713 OMP_CLAUSE_DECL (nc) = decl;
10714 OMP_CLAUSE_SIZE (nc) = size_zero_node;
10715 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
10716 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
10717 OMP_CLAUSE_CHAIN (clause) = nc;
10719 else
10720 OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
10722 if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
10724 tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
10725 OMP_CLAUSE_DECL (nc) = decl;
10726 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
10727 OMP_CLAUSE_CHAIN (nc) = chain;
10728 OMP_CLAUSE_CHAIN (clause) = nc;
10729 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10730 gimplify_omp_ctxp = ctx->outer_context;
10731 lang_hooks.decls.omp_finish_clause (nc, pre_p,
10732 (ctx->region_type & ORT_ACC) != 0);
10733 gimplify_omp_ctxp = ctx;
10735 *list_p = clause;
10736 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10737 gimplify_omp_ctxp = ctx->outer_context;
10738 lang_hooks.decls.omp_finish_clause (clause, pre_p,
10739 (ctx->region_type & ORT_ACC) != 0);
10740 if (gimplify_omp_ctxp)
10741 for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
10742 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
10743 && DECL_P (OMP_CLAUSE_SIZE (clause)))
10744 omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
10745 true);
10746 gimplify_omp_ctxp = ctx;
10747 return 0;
10750 static void
10751 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
10752 enum tree_code code)
10754 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
10755 tree *orig_list_p = list_p;
10756 tree c, decl;
10757 bool has_inscan_reductions = false;
10759 if (body)
10761 struct gimplify_omp_ctx *octx;
10762 for (octx = ctx; octx; octx = octx->outer_context)
10763 if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
10764 break;
10765 if (octx)
10767 struct walk_stmt_info wi;
10768 memset (&wi, 0, sizeof (wi));
10769 walk_gimple_seq (body, omp_find_stores_stmt,
10770 omp_find_stores_op, &wi);
10774 if (ctx->add_safelen1)
10776 /* If there are VLAs in the body of simd loop, prevent
10777 vectorization. */
10778 gcc_assert (ctx->region_type == ORT_SIMD);
10779 c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
10780 OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
10781 OMP_CLAUSE_CHAIN (c) = *list_p;
10782 *list_p = c;
10783 list_p = &OMP_CLAUSE_CHAIN (c);
10786 if (ctx->region_type == ORT_WORKSHARE
10787 && ctx->outer_context
10788 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
10790 for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
10791 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10792 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
10794 decl = OMP_CLAUSE_DECL (c);
10795 splay_tree_node n
10796 = splay_tree_lookup (ctx->outer_context->variables,
10797 (splay_tree_key) decl);
10798 gcc_checking_assert (!splay_tree_lookup (ctx->variables,
10799 (splay_tree_key) decl));
10800 omp_add_variable (ctx, decl, n->value);
10801 tree c2 = copy_node (c);
10802 OMP_CLAUSE_CHAIN (c2) = *list_p;
10803 *list_p = c2;
10804 if ((n->value & GOVD_FIRSTPRIVATE) == 0)
10805 continue;
10806 c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
10807 OMP_CLAUSE_FIRSTPRIVATE);
10808 OMP_CLAUSE_DECL (c2) = decl;
10809 OMP_CLAUSE_CHAIN (c2) = *list_p;
10810 *list_p = c2;
10813 while ((c = *list_p) != NULL)
10815 splay_tree_node n;
10816 bool remove = false;
10818 switch (OMP_CLAUSE_CODE (c))
10820 case OMP_CLAUSE_FIRSTPRIVATE:
10821 if ((ctx->region_type & ORT_TARGET)
10822 && (ctx->region_type & ORT_ACC) == 0
10823 && TYPE_ATOMIC (strip_array_types
10824 (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
10826 error_at (OMP_CLAUSE_LOCATION (c),
10827 "%<_Atomic%> %qD in %<firstprivate%> clause on "
10828 "%<target%> construct", OMP_CLAUSE_DECL (c));
10829 remove = true;
10830 break;
10832 if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
10834 decl = OMP_CLAUSE_DECL (c);
10835 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10836 if ((n->value & GOVD_MAP) != 0)
10838 remove = true;
10839 break;
10841 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) = 0;
10842 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) = 0;
10844 /* FALLTHRU */
10845 case OMP_CLAUSE_PRIVATE:
10846 case OMP_CLAUSE_SHARED:
10847 case OMP_CLAUSE_LINEAR:
10848 decl = OMP_CLAUSE_DECL (c);
10849 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10850 remove = !(n->value & GOVD_SEEN);
10851 if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
10852 && code == OMP_PARALLEL
10853 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
10854 remove = true;
10855 if (! remove)
10857 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
10858 if ((n->value & GOVD_DEBUG_PRIVATE)
10859 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
10861 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
10862 || ((n->value & GOVD_DATA_SHARE_CLASS)
10863 == GOVD_SHARED));
10864 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
10865 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
10867 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10868 && ctx->has_depend
10869 && DECL_P (decl))
10870 n->value |= GOVD_WRITTEN;
10871 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10872 && (n->value & GOVD_WRITTEN) == 0
10873 && DECL_P (decl)
10874 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10875 OMP_CLAUSE_SHARED_READONLY (c) = 1;
10876 else if (DECL_P (decl)
10877 && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10878 && (n->value & GOVD_WRITTEN) != 0)
10879 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10880 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
10881 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10882 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10884 else
10885 n->value &= ~GOVD_EXPLICIT;
10886 break;
10888 case OMP_CLAUSE_LASTPRIVATE:
10889 /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
10890 accurately reflect the presence of a FIRSTPRIVATE clause. */
10891 decl = OMP_CLAUSE_DECL (c);
10892 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10893 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
10894 = (n->value & GOVD_FIRSTPRIVATE) != 0;
10895 if (code == OMP_DISTRIBUTE
10896 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
10898 remove = true;
10899 error_at (OMP_CLAUSE_LOCATION (c),
10900 "same variable used in %<firstprivate%> and "
10901 "%<lastprivate%> clauses on %<distribute%> "
10902 "construct");
10904 if (!remove
10905 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10906 && DECL_P (decl)
10907 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
10908 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
10909 if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
10910 remove = true;
10911 break;
10913 case OMP_CLAUSE_ALIGNED:
10914 decl = OMP_CLAUSE_DECL (c);
10915 if (!is_global_var (decl))
10917 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10918 remove = n == NULL || !(n->value & GOVD_SEEN);
10919 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
10921 struct gimplify_omp_ctx *octx;
10922 if (n != NULL
10923 && (n->value & (GOVD_DATA_SHARE_CLASS
10924 & ~GOVD_FIRSTPRIVATE)))
10925 remove = true;
10926 else
10927 for (octx = ctx->outer_context; octx;
10928 octx = octx->outer_context)
10930 n = splay_tree_lookup (octx->variables,
10931 (splay_tree_key) decl);
10932 if (n == NULL)
10933 continue;
10934 if (n->value & GOVD_LOCAL)
10935 break;
10936 /* We have to avoid assigning a shared variable
10937 to itself when trying to add
10938 __builtin_assume_aligned. */
10939 if (n->value & GOVD_SHARED)
10941 remove = true;
10942 break;
10947 else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
10949 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10950 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
10951 remove = true;
10953 break;
10955 case OMP_CLAUSE_NONTEMPORAL:
10956 decl = OMP_CLAUSE_DECL (c);
10957 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
10958 remove = n == NULL || !(n->value & GOVD_SEEN);
10959 break;
10961 case OMP_CLAUSE_MAP:
10962 if (code == OMP_TARGET_EXIT_DATA
10963 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
10965 remove = true;
10966 break;
10968 decl = OMP_CLAUSE_DECL (c);
10969 /* Data clauses associated with reductions must be
10970 compatible with present_or_copy. Warn and adjust the clause
10971 if that is not the case. */
10972 if (ctx->region_type == ORT_ACC_PARALLEL
10973 || ctx->region_type == ORT_ACC_SERIAL)
10975 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
10976 n = NULL;
10978 if (DECL_P (t))
10979 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
10981 if (n && (n->value & GOVD_REDUCTION))
10983 enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
10985 OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
10986 if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
10987 && kind != GOMP_MAP_FORCE_PRESENT
10988 && kind != GOMP_MAP_POINTER)
10990 warning_at (OMP_CLAUSE_LOCATION (c), 0,
10991 "incompatible data clause with reduction "
10992 "on %qE; promoting to %<present_or_copy%>",
10993 DECL_NAME (t));
10994 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
10998 if (!DECL_P (decl))
11000 if ((ctx->region_type & ORT_TARGET) != 0
11001 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
11003 if (TREE_CODE (decl) == INDIRECT_REF
11004 && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
11005 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
11006 == REFERENCE_TYPE))
11007 decl = TREE_OPERAND (decl, 0);
11008 if (TREE_CODE (decl) == COMPONENT_REF)
11010 while (TREE_CODE (decl) == COMPONENT_REF)
11011 decl = TREE_OPERAND (decl, 0);
11012 if (DECL_P (decl))
11014 n = splay_tree_lookup (ctx->variables,
11015 (splay_tree_key) decl);
11016 if (!(n->value & GOVD_SEEN))
11017 remove = true;
11021 break;
11023 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11024 if ((ctx->region_type & ORT_TARGET) != 0
11025 && !(n->value & GOVD_SEEN)
11026 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
11027 && (!is_global_var (decl)
11028 || !lookup_attribute ("omp declare target link",
11029 DECL_ATTRIBUTES (decl))))
11031 remove = true;
11032 /* For struct element mapping, if struct is never referenced
11033 in target block and none of the mapping has always modifier,
11034 remove all the struct element mappings, which immediately
11035 follow the GOMP_MAP_STRUCT map clause. */
11036 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
11038 HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
11039 while (cnt--)
11040 OMP_CLAUSE_CHAIN (c)
11041 = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
11044 else if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
11045 && (code == OMP_TARGET_EXIT_DATA
11046 || code == OACC_EXIT_DATA))
11047 remove = true;
11048 else if (DECL_SIZE (decl)
11049 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
11050 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
11051 && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
11052 && (OMP_CLAUSE_MAP_KIND (c)
11053 != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
11055 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
11056 for these, TREE_CODE (DECL_SIZE (decl)) will always be
11057 INTEGER_CST. */
11058 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
11060 tree decl2 = DECL_VALUE_EXPR (decl);
11061 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11062 decl2 = TREE_OPERAND (decl2, 0);
11063 gcc_assert (DECL_P (decl2));
11064 tree mem = build_simple_mem_ref (decl2);
11065 OMP_CLAUSE_DECL (c) = mem;
11066 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11067 if (ctx->outer_context)
11069 omp_notice_variable (ctx->outer_context, decl2, true);
11070 omp_notice_variable (ctx->outer_context,
11071 OMP_CLAUSE_SIZE (c), true);
11073 if (((ctx->region_type & ORT_TARGET) != 0
11074 || !ctx->target_firstprivatize_array_bases)
11075 && ((n->value & GOVD_SEEN) == 0
11076 || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
11078 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11079 OMP_CLAUSE_MAP);
11080 OMP_CLAUSE_DECL (nc) = decl;
11081 OMP_CLAUSE_SIZE (nc) = size_zero_node;
11082 if (ctx->target_firstprivatize_array_bases)
11083 OMP_CLAUSE_SET_MAP_KIND (nc,
11084 GOMP_MAP_FIRSTPRIVATE_POINTER);
11085 else
11086 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
11087 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
11088 OMP_CLAUSE_CHAIN (c) = nc;
11089 c = nc;
11092 else
11094 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11095 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11096 gcc_assert ((n->value & GOVD_SEEN) == 0
11097 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11098 == 0));
11100 break;
11102 case OMP_CLAUSE_TO:
11103 case OMP_CLAUSE_FROM:
11104 case OMP_CLAUSE__CACHE_:
11105 decl = OMP_CLAUSE_DECL (c);
11106 if (!DECL_P (decl))
11107 break;
11108 if (DECL_SIZE (decl)
11109 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
11111 tree decl2 = DECL_VALUE_EXPR (decl);
11112 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11113 decl2 = TREE_OPERAND (decl2, 0);
11114 gcc_assert (DECL_P (decl2));
11115 tree mem = build_simple_mem_ref (decl2);
11116 OMP_CLAUSE_DECL (c) = mem;
11117 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11118 if (ctx->outer_context)
11120 omp_notice_variable (ctx->outer_context, decl2, true);
11121 omp_notice_variable (ctx->outer_context,
11122 OMP_CLAUSE_SIZE (c), true);
11125 else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11126 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11127 break;
11129 case OMP_CLAUSE_REDUCTION:
11130 if (OMP_CLAUSE_REDUCTION_INSCAN (c))
11132 decl = OMP_CLAUSE_DECL (c);
11133 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11134 if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
11136 remove = true;
11137 error_at (OMP_CLAUSE_LOCATION (c),
11138 "%qD specified in %<inscan%> %<reduction%> clause "
11139 "but not in %<scan%> directive clause", decl);
11140 break;
11142 has_inscan_reductions = true;
11144 /* FALLTHRU */
11145 case OMP_CLAUSE_IN_REDUCTION:
11146 case OMP_CLAUSE_TASK_REDUCTION:
11147 decl = OMP_CLAUSE_DECL (c);
11148 /* OpenACC reductions need a present_or_copy data clause.
11149 Add one if necessary. Emit error when the reduction is private. */
11150 if (ctx->region_type == ORT_ACC_PARALLEL
11151 || ctx->region_type == ORT_ACC_SERIAL)
11153 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11154 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11156 remove = true;
11157 error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
11158 "reduction on %qE", DECL_NAME (decl));
11160 else if ((n->value & GOVD_MAP) == 0)
11162 tree next = OMP_CLAUSE_CHAIN (c);
11163 tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
11164 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
11165 OMP_CLAUSE_DECL (nc) = decl;
11166 OMP_CLAUSE_CHAIN (c) = nc;
11167 lang_hooks.decls.omp_finish_clause (nc, pre_p,
11168 (ctx->region_type
11169 & ORT_ACC) != 0);
11170 while (1)
11172 OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
11173 if (OMP_CLAUSE_CHAIN (nc) == NULL)
11174 break;
11175 nc = OMP_CLAUSE_CHAIN (nc);
11177 OMP_CLAUSE_CHAIN (nc) = next;
11178 n->value |= GOVD_MAP;
11181 if (DECL_P (decl)
11182 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11183 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11184 break;
11186 case OMP_CLAUSE_ALLOCATE:
11187 decl = OMP_CLAUSE_DECL (c);
11188 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11189 if (n != NULL && !(n->value & GOVD_SEEN))
11191 if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR))
11192 != 0
11193 && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0)
11194 remove = true;
11196 if (!remove
11197 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
11198 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST
11199 && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0
11200 || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK
11201 || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS))
11203 tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
11204 n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator);
11205 if (n == NULL)
11207 enum omp_clause_default_kind default_kind
11208 = ctx->default_kind;
11209 ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
11210 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11211 true);
11212 ctx->default_kind = default_kind;
11214 else
11215 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11216 true);
11218 break;
11220 case OMP_CLAUSE_COPYIN:
11221 case OMP_CLAUSE_COPYPRIVATE:
11222 case OMP_CLAUSE_IF:
11223 case OMP_CLAUSE_NUM_THREADS:
11224 case OMP_CLAUSE_NUM_TEAMS:
11225 case OMP_CLAUSE_THREAD_LIMIT:
11226 case OMP_CLAUSE_DIST_SCHEDULE:
11227 case OMP_CLAUSE_DEVICE:
11228 case OMP_CLAUSE_SCHEDULE:
11229 case OMP_CLAUSE_NOWAIT:
11230 case OMP_CLAUSE_ORDERED:
11231 case OMP_CLAUSE_DEFAULT:
11232 case OMP_CLAUSE_UNTIED:
11233 case OMP_CLAUSE_COLLAPSE:
11234 case OMP_CLAUSE_FINAL:
11235 case OMP_CLAUSE_MERGEABLE:
11236 case OMP_CLAUSE_PROC_BIND:
11237 case OMP_CLAUSE_SAFELEN:
11238 case OMP_CLAUSE_SIMDLEN:
11239 case OMP_CLAUSE_DEPEND:
11240 case OMP_CLAUSE_PRIORITY:
11241 case OMP_CLAUSE_GRAINSIZE:
11242 case OMP_CLAUSE_NUM_TASKS:
11243 case OMP_CLAUSE_NOGROUP:
11244 case OMP_CLAUSE_THREADS:
11245 case OMP_CLAUSE_SIMD:
11246 case OMP_CLAUSE_FILTER:
11247 case OMP_CLAUSE_HINT:
11248 case OMP_CLAUSE_DEFAULTMAP:
11249 case OMP_CLAUSE_ORDER:
11250 case OMP_CLAUSE_BIND:
11251 case OMP_CLAUSE_DETACH:
11252 case OMP_CLAUSE_USE_DEVICE_PTR:
11253 case OMP_CLAUSE_USE_DEVICE_ADDR:
11254 case OMP_CLAUSE_IS_DEVICE_PTR:
11255 case OMP_CLAUSE_ASYNC:
11256 case OMP_CLAUSE_WAIT:
11257 case OMP_CLAUSE_INDEPENDENT:
11258 case OMP_CLAUSE_NUM_GANGS:
11259 case OMP_CLAUSE_NUM_WORKERS:
11260 case OMP_CLAUSE_VECTOR_LENGTH:
11261 case OMP_CLAUSE_GANG:
11262 case OMP_CLAUSE_WORKER:
11263 case OMP_CLAUSE_VECTOR:
11264 case OMP_CLAUSE_AUTO:
11265 case OMP_CLAUSE_SEQ:
11266 case OMP_CLAUSE_TILE:
11267 case OMP_CLAUSE_IF_PRESENT:
11268 case OMP_CLAUSE_FINALIZE:
11269 case OMP_CLAUSE_INCLUSIVE:
11270 case OMP_CLAUSE_EXCLUSIVE:
11271 break;
11273 case OMP_CLAUSE_NOHOST:
11274 default:
11275 gcc_unreachable ();
11278 if (remove)
11279 *list_p = OMP_CLAUSE_CHAIN (c);
11280 else
11281 list_p = &OMP_CLAUSE_CHAIN (c);
11284 /* Add in any implicit data sharing. */
11285 struct gimplify_adjust_omp_clauses_data data;
11286 data.list_p = list_p;
11287 data.pre_p = pre_p;
11288 splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
11290 if (has_inscan_reductions)
11291 for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
11292 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11293 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
11295 error_at (OMP_CLAUSE_LOCATION (c),
11296 "%<inscan%> %<reduction%> clause used together with "
11297 "%<linear%> clause for a variable other than loop "
11298 "iterator");
11299 break;
11302 gimplify_omp_ctxp = ctx->outer_context;
11303 delete_omp_context (ctx);
11306 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
11307 -1 if unknown yet (simd is involved, won't be known until vectorization)
11308 and 1 if they do. If SCORES is non-NULL, it should point to an array
11309 of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
11310 of the CONSTRUCTS (position -1 if it will never match) followed by
11311 number of constructs in the OpenMP context construct trait. If the
11312 score depends on whether it will be in a declare simd clone or not,
11313 the function returns 2 and there will be two sets of the scores, the first
11314 one for the case that it is not in a declare simd clone, the other
11315 that it is in a declare simd clone. */
11318 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
11319 int *scores)
11321 int matched = 0, cnt = 0;
11322 bool simd_seen = false;
11323 bool target_seen = false;
11324 int declare_simd_cnt = -1;
11325 auto_vec<enum tree_code, 16> codes;
11326 for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
11328 if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
11329 || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
11330 == ORT_TARGET && ctx->code == OMP_TARGET)
11331 || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
11332 || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
11333 || (ctx->region_type == ORT_SIMD
11334 && ctx->code == OMP_SIMD
11335 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
11337 ++cnt;
11338 if (scores)
11339 codes.safe_push (ctx->code);
11340 else if (matched < nconstructs && ctx->code == constructs[matched])
11342 if (ctx->code == OMP_SIMD)
11344 if (matched)
11345 return 0;
11346 simd_seen = true;
11348 ++matched;
11350 if (ctx->code == OMP_TARGET)
11352 if (scores == NULL)
11353 return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
11354 target_seen = true;
11355 break;
11358 else if (ctx->region_type == ORT_WORKSHARE
11359 && ctx->code == OMP_LOOP
11360 && ctx->outer_context
11361 && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
11362 && ctx->outer_context->outer_context
11363 && ctx->outer_context->outer_context->code == OMP_LOOP
11364 && ctx->outer_context->outer_context->distribute)
11365 ctx = ctx->outer_context->outer_context;
11366 ctx = ctx->outer_context;
11368 if (!target_seen
11369 && lookup_attribute ("omp declare simd",
11370 DECL_ATTRIBUTES (current_function_decl)))
11372 /* Declare simd is a maybe case, it is supposed to be added only to the
11373 omp-simd-clone.c added clones and not to the base function. */
11374 declare_simd_cnt = cnt++;
11375 if (scores)
11376 codes.safe_push (OMP_SIMD);
11377 else if (cnt == 0
11378 && constructs[0] == OMP_SIMD)
11380 gcc_assert (matched == 0);
11381 simd_seen = true;
11382 if (++matched == nconstructs)
11383 return -1;
11386 if (tree attr = lookup_attribute ("omp declare variant variant",
11387 DECL_ATTRIBUTES (current_function_decl)))
11389 enum tree_code variant_constructs[5];
11390 int variant_nconstructs = 0;
11391 if (!target_seen)
11392 variant_nconstructs
11393 = omp_constructor_traits_to_codes (TREE_VALUE (attr),
11394 variant_constructs);
11395 for (int i = 0; i < variant_nconstructs; i++)
11397 ++cnt;
11398 if (scores)
11399 codes.safe_push (variant_constructs[i]);
11400 else if (matched < nconstructs
11401 && variant_constructs[i] == constructs[matched])
11403 if (variant_constructs[i] == OMP_SIMD)
11405 if (matched)
11406 return 0;
11407 simd_seen = true;
11409 ++matched;
11413 if (!target_seen
11414 && lookup_attribute ("omp declare target block",
11415 DECL_ATTRIBUTES (current_function_decl)))
11417 if (scores)
11418 codes.safe_push (OMP_TARGET);
11419 else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
11420 ++matched;
11422 if (scores)
11424 for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
11426 int j = codes.length () - 1;
11427 for (int i = nconstructs - 1; i >= 0; i--)
11429 while (j >= 0
11430 && (pass != 0 || declare_simd_cnt != j)
11431 && constructs[i] != codes[j])
11432 --j;
11433 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
11434 *scores++ = j - 1;
11435 else
11436 *scores++ = j;
11438 *scores++ = ((pass == 0 && declare_simd_cnt != -1)
11439 ? codes.length () - 1 : codes.length ());
11441 return declare_simd_cnt == -1 ? 1 : 2;
11443 if (matched == nconstructs)
11444 return simd_seen ? -1 : 1;
11445 return 0;
11448 /* Gimplify OACC_CACHE. */
11450 static void
11451 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
11453 tree expr = *expr_p;
11455 gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
11456 OACC_CACHE);
11457 gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
11458 OACC_CACHE);
11460 /* TODO: Do something sensible with this information. */
11462 *expr_p = NULL_TREE;
11465 /* Helper function of gimplify_oacc_declare. The helper's purpose is to,
11466 if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
11467 kind. The entry kind will replace the one in CLAUSE, while the exit
11468 kind will be used in a new omp_clause and returned to the caller. */
11470 static tree
11471 gimplify_oacc_declare_1 (tree clause)
11473 HOST_WIDE_INT kind, new_op;
11474 bool ret = false;
11475 tree c = NULL;
11477 kind = OMP_CLAUSE_MAP_KIND (clause);
11479 switch (kind)
11481 case GOMP_MAP_ALLOC:
11482 new_op = GOMP_MAP_RELEASE;
11483 ret = true;
11484 break;
11486 case GOMP_MAP_FROM:
11487 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
11488 new_op = GOMP_MAP_FROM;
11489 ret = true;
11490 break;
11492 case GOMP_MAP_TOFROM:
11493 OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
11494 new_op = GOMP_MAP_FROM;
11495 ret = true;
11496 break;
11498 case GOMP_MAP_DEVICE_RESIDENT:
11499 case GOMP_MAP_FORCE_DEVICEPTR:
11500 case GOMP_MAP_FORCE_PRESENT:
11501 case GOMP_MAP_LINK:
11502 case GOMP_MAP_POINTER:
11503 case GOMP_MAP_TO:
11504 break;
11506 default:
11507 gcc_unreachable ();
11508 break;
11511 if (ret)
11513 c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
11514 OMP_CLAUSE_SET_MAP_KIND (c, new_op);
11515 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
11518 return c;
11521 /* Gimplify OACC_DECLARE. */
11523 static void
11524 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
11526 tree expr = *expr_p;
11527 gomp_target *stmt;
11528 tree clauses, t, decl;
11530 clauses = OACC_DECLARE_CLAUSES (expr);
11532 gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
11533 gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
11535 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
11537 decl = OMP_CLAUSE_DECL (t);
11539 if (TREE_CODE (decl) == MEM_REF)
11540 decl = TREE_OPERAND (decl, 0);
11542 if (VAR_P (decl) && !is_oacc_declared (decl))
11544 tree attr = get_identifier ("oacc declare target");
11545 DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
11546 DECL_ATTRIBUTES (decl));
11549 if (VAR_P (decl)
11550 && !is_global_var (decl)
11551 && DECL_CONTEXT (decl) == current_function_decl)
11553 tree c = gimplify_oacc_declare_1 (t);
11554 if (c)
11556 if (oacc_declare_returns == NULL)
11557 oacc_declare_returns = new hash_map<tree, tree>;
11559 oacc_declare_returns->put (decl, c);
11563 if (gimplify_omp_ctxp)
11564 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
11567 stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
11568 clauses);
11570 gimplify_seq_add_stmt (pre_p, stmt);
11572 *expr_p = NULL_TREE;
11575 /* Gimplify the contents of an OMP_PARALLEL statement. This involves
11576 gimplification of the body, as well as scanning the body for used
11577 variables. We need to do this scan now, because variable-sized
11578 decls will be decomposed during gimplification. */
11580 static void
11581 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
11583 tree expr = *expr_p;
11584 gimple *g;
11585 gimple_seq body = NULL;
11587 gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
11588 OMP_PARALLEL_COMBINED (expr)
11589 ? ORT_COMBINED_PARALLEL
11590 : ORT_PARALLEL, OMP_PARALLEL);
11592 push_gimplify_context ();
11594 g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
11595 if (gimple_code (g) == GIMPLE_BIND)
11596 pop_gimplify_context (g);
11597 else
11598 pop_gimplify_context (NULL);
11600 gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
11601 OMP_PARALLEL);
11603 g = gimple_build_omp_parallel (body,
11604 OMP_PARALLEL_CLAUSES (expr),
11605 NULL_TREE, NULL_TREE);
11606 if (OMP_PARALLEL_COMBINED (expr))
11607 gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
11608 gimplify_seq_add_stmt (pre_p, g);
11609 *expr_p = NULL_TREE;
11612 /* Gimplify the contents of an OMP_TASK statement. This involves
11613 gimplification of the body, as well as scanning the body for used
11614 variables. We need to do this scan now, because variable-sized
11615 decls will be decomposed during gimplification. */
11617 static void
11618 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
11620 tree expr = *expr_p;
11621 gimple *g;
11622 gimple_seq body = NULL;
11624 if (OMP_TASK_BODY (expr) == NULL_TREE)
11625 for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
11626 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
11627 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
11629 error_at (OMP_CLAUSE_LOCATION (c),
11630 "%<mutexinoutset%> kind in %<depend%> clause on a "
11631 "%<taskwait%> construct");
11632 break;
11635 gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
11636 omp_find_clause (OMP_TASK_CLAUSES (expr),
11637 OMP_CLAUSE_UNTIED)
11638 ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
11640 if (OMP_TASK_BODY (expr))
11642 push_gimplify_context ();
11644 g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
11645 if (gimple_code (g) == GIMPLE_BIND)
11646 pop_gimplify_context (g);
11647 else
11648 pop_gimplify_context (NULL);
11651 gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
11652 OMP_TASK);
11654 g = gimple_build_omp_task (body,
11655 OMP_TASK_CLAUSES (expr),
11656 NULL_TREE, NULL_TREE,
11657 NULL_TREE, NULL_TREE, NULL_TREE);
11658 if (OMP_TASK_BODY (expr) == NULL_TREE)
11659 gimple_omp_task_set_taskwait_p (g, true);
11660 gimplify_seq_add_stmt (pre_p, g);
11661 *expr_p = NULL_TREE;
11664 /* Helper function for gimplify_omp_for. If *TP is not a gimple constant,
11665 force it into a temporary initialized in PRE_P and add firstprivate clause
11666 to ORIG_FOR_STMT. */
11668 static void
11669 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
11670 tree orig_for_stmt)
11672 if (*tp == NULL || is_gimple_constant (*tp))
11673 return;
11675 *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
11676 /* Reference to pointer conversion is considered useless,
11677 but is significant for firstprivate clause. Force it
11678 here. */
11679 if (type
11680 && TREE_CODE (type) == POINTER_TYPE
11681 && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
11683 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
11684 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
11685 gimplify_and_add (m, pre_p);
11686 *tp = v;
11689 tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
11690 OMP_CLAUSE_DECL (c) = *tp;
11691 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
11692 OMP_FOR_CLAUSES (orig_for_stmt) = c;
11695 /* Gimplify the gross structure of an OMP_FOR statement. */
11697 static enum gimplify_status
11698 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
11700 tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
11701 enum gimplify_status ret = GS_ALL_DONE;
11702 enum gimplify_status tret;
11703 gomp_for *gfor;
11704 gimple_seq for_body, for_pre_body;
11705 int i;
11706 bitmap has_decl_expr = NULL;
11707 enum omp_region_type ort = ORT_WORKSHARE;
11708 bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
11710 orig_for_stmt = for_stmt = *expr_p;
11712 bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
11713 != NULL_TREE);
11714 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
11716 tree *data[4] = { NULL, NULL, NULL, NULL };
11717 gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
11718 inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
11719 find_combined_omp_for, data, NULL);
11720 if (inner_for_stmt == NULL_TREE)
11722 gcc_assert (seen_error ());
11723 *expr_p = NULL_TREE;
11724 return GS_ERROR;
11726 if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
11728 append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
11729 &OMP_FOR_PRE_BODY (for_stmt));
11730 OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
11732 if (OMP_FOR_PRE_BODY (inner_for_stmt))
11734 append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
11735 &OMP_FOR_PRE_BODY (for_stmt));
11736 OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
11739 if (data[0])
11741 /* We have some statements or variable declarations in between
11742 the composite construct directives. Move them around the
11743 inner_for_stmt. */
11744 data[0] = expr_p;
11745 for (i = 0; i < 3; i++)
11746 if (data[i])
11748 tree t = *data[i];
11749 if (i < 2 && data[i + 1] == &OMP_BODY (t))
11750 data[i + 1] = data[i];
11751 *data[i] = OMP_BODY (t);
11752 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
11753 NULL_TREE, make_node (BLOCK));
11754 OMP_BODY (t) = body;
11755 append_to_statement_list_force (inner_for_stmt,
11756 &BIND_EXPR_BODY (body));
11757 *data[3] = t;
11758 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
11759 gcc_assert (*data[3] == inner_for_stmt);
11761 return GS_OK;
11764 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
11765 if (!loop_p
11766 && OMP_FOR_ORIG_DECLS (inner_for_stmt)
11767 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11768 i)) == TREE_LIST
11769 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11770 i)))
11772 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
11773 /* Class iterators aren't allowed on OMP_SIMD, so the only
11774 case we need to solve is distribute parallel for. They are
11775 allowed on the loop construct, but that is already handled
11776 in gimplify_omp_loop. */
11777 gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
11778 && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
11779 && data[1]);
11780 tree orig_decl = TREE_PURPOSE (orig);
11781 tree last = TREE_VALUE (orig);
11782 tree *pc;
11783 for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
11784 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
11785 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
11786 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
11787 && OMP_CLAUSE_DECL (*pc) == orig_decl)
11788 break;
11789 if (*pc == NULL_TREE)
11791 tree *spc;
11792 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
11793 *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
11794 if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
11795 && OMP_CLAUSE_DECL (*spc) == orig_decl)
11796 break;
11797 if (*spc)
11799 tree c = *spc;
11800 *spc = OMP_CLAUSE_CHAIN (c);
11801 OMP_CLAUSE_CHAIN (c) = NULL_TREE;
11802 *pc = c;
11805 if (*pc == NULL_TREE)
11807 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
11809 /* private clause will appear only on inner_for_stmt.
11810 Change it into firstprivate, and add private clause
11811 on for_stmt. */
11812 tree c = copy_node (*pc);
11813 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
11814 OMP_FOR_CLAUSES (for_stmt) = c;
11815 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
11816 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
11818 else
11820 /* lastprivate clause will appear on both inner_for_stmt
11821 and for_stmt. Add firstprivate clause to
11822 inner_for_stmt. */
11823 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
11824 OMP_CLAUSE_FIRSTPRIVATE);
11825 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
11826 OMP_CLAUSE_CHAIN (c) = *pc;
11827 *pc = c;
11828 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
11830 tree c = build_omp_clause (UNKNOWN_LOCATION,
11831 OMP_CLAUSE_FIRSTPRIVATE);
11832 OMP_CLAUSE_DECL (c) = last;
11833 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
11834 OMP_PARALLEL_CLAUSES (*data[1]) = c;
11835 c = build_omp_clause (UNKNOWN_LOCATION,
11836 *pc ? OMP_CLAUSE_SHARED
11837 : OMP_CLAUSE_FIRSTPRIVATE);
11838 OMP_CLAUSE_DECL (c) = orig_decl;
11839 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
11840 OMP_PARALLEL_CLAUSES (*data[1]) = c;
11842 /* Similarly, take care of C++ range for temporaries, those should
11843 be firstprivate on OMP_PARALLEL if any. */
11844 if (data[1])
11845 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
11846 if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
11847 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11848 i)) == TREE_LIST
11849 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
11850 i)))
11852 tree orig
11853 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
11854 tree v = TREE_CHAIN (orig);
11855 tree c = build_omp_clause (UNKNOWN_LOCATION,
11856 OMP_CLAUSE_FIRSTPRIVATE);
11857 /* First add firstprivate clause for the __for_end artificial
11858 decl. */
11859 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
11860 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
11861 == REFERENCE_TYPE)
11862 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
11863 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
11864 OMP_PARALLEL_CLAUSES (*data[1]) = c;
11865 if (TREE_VEC_ELT (v, 0))
11867 /* And now the same for __for_range artificial decl if it
11868 exists. */
11869 c = build_omp_clause (UNKNOWN_LOCATION,
11870 OMP_CLAUSE_FIRSTPRIVATE);
11871 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
11872 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
11873 == REFERENCE_TYPE)
11874 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
11875 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
11876 OMP_PARALLEL_CLAUSES (*data[1]) = c;
11881 switch (TREE_CODE (for_stmt))
11883 case OMP_FOR:
11884 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
11886 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
11887 OMP_CLAUSE_SCHEDULE))
11888 error_at (EXPR_LOCATION (for_stmt),
11889 "%qs clause may not appear on non-rectangular %qs",
11890 "schedule", "for");
11891 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
11892 error_at (EXPR_LOCATION (for_stmt),
11893 "%qs clause may not appear on non-rectangular %qs",
11894 "ordered", "for");
11896 break;
11897 case OMP_DISTRIBUTE:
11898 if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
11899 && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
11900 OMP_CLAUSE_DIST_SCHEDULE))
11901 error_at (EXPR_LOCATION (for_stmt),
11902 "%qs clause may not appear on non-rectangular %qs",
11903 "dist_schedule", "distribute");
11904 break;
11905 case OACC_LOOP:
11906 ort = ORT_ACC;
11907 break;
11908 case OMP_TASKLOOP:
11909 if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
11910 ort = ORT_UNTIED_TASKLOOP;
11911 else
11912 ort = ORT_TASKLOOP;
11913 break;
11914 case OMP_SIMD:
11915 ort = ORT_SIMD;
11916 break;
11917 default:
11918 gcc_unreachable ();
11921 /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
11922 clause for the IV. */
11923 if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
11925 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
11926 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
11927 decl = TREE_OPERAND (t, 0);
11928 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
11929 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11930 && OMP_CLAUSE_DECL (c) == decl)
11932 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
11933 break;
11937 if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
11938 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
11939 loop_p && TREE_CODE (for_stmt) != OMP_SIMD
11940 ? OMP_LOOP : TREE_CODE (for_stmt));
11942 if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
11943 gimplify_omp_ctxp->distribute = true;
11945 /* Handle OMP_FOR_INIT. */
11946 for_pre_body = NULL;
11947 if ((ort == ORT_SIMD
11948 || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
11949 && OMP_FOR_PRE_BODY (for_stmt))
11951 has_decl_expr = BITMAP_ALLOC (NULL);
11952 if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
11953 && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
11954 == VAR_DECL)
11956 t = OMP_FOR_PRE_BODY (for_stmt);
11957 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
11959 else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
11961 tree_stmt_iterator si;
11962 for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
11963 tsi_next (&si))
11965 t = tsi_stmt (si);
11966 if (TREE_CODE (t) == DECL_EXPR
11967 && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
11968 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
11972 if (OMP_FOR_PRE_BODY (for_stmt))
11974 if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
11975 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
11976 else
11978 struct gimplify_omp_ctx ctx;
11979 memset (&ctx, 0, sizeof (ctx));
11980 ctx.region_type = ORT_NONE;
11981 gimplify_omp_ctxp = &ctx;
11982 gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
11983 gimplify_omp_ctxp = NULL;
11986 OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
11988 if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
11989 for_stmt = inner_for_stmt;
11991 /* For taskloop, need to gimplify the start, end and step before the
11992 taskloop, outside of the taskloop omp context. */
11993 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
11995 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
11997 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
11998 gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
11999 ? pre_p : &for_pre_body);
12000 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
12001 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12003 tree v = TREE_OPERAND (t, 1);
12004 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12005 for_pre_p, orig_for_stmt);
12006 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12007 for_pre_p, orig_for_stmt);
12009 else
12010 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12011 orig_for_stmt);
12013 /* Handle OMP_FOR_COND. */
12014 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12015 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12017 tree v = TREE_OPERAND (t, 1);
12018 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12019 for_pre_p, orig_for_stmt);
12020 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12021 for_pre_p, orig_for_stmt);
12023 else
12024 gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12025 orig_for_stmt);
12027 /* Handle OMP_FOR_INCR. */
12028 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12029 if (TREE_CODE (t) == MODIFY_EXPR)
12031 decl = TREE_OPERAND (t, 0);
12032 t = TREE_OPERAND (t, 1);
12033 tree *tp = &TREE_OPERAND (t, 1);
12034 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
12035 tp = &TREE_OPERAND (t, 0);
12037 gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
12038 orig_for_stmt);
12042 gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
12043 OMP_TASKLOOP);
12046 if (orig_for_stmt != for_stmt)
12047 gimplify_omp_ctxp->combined_loop = true;
12049 for_body = NULL;
12050 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12051 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
12052 gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12053 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
12055 tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
12056 bool is_doacross = false;
12057 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
12059 is_doacross = true;
12060 gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
12061 (OMP_FOR_INIT (for_stmt))
12062 * 2);
12064 int collapse = 1, tile = 0;
12065 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
12066 if (c)
12067 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
12068 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
12069 if (c)
12070 tile = list_length (OMP_CLAUSE_TILE_LIST (c));
12071 c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
12072 hash_set<tree> *allocate_uids = NULL;
12073 if (c)
12075 allocate_uids = new hash_set<tree>;
12076 for (; c; c = OMP_CLAUSE_CHAIN (c))
12077 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
12078 allocate_uids->add (OMP_CLAUSE_DECL (c));
12080 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12082 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12083 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12084 decl = TREE_OPERAND (t, 0);
12085 gcc_assert (DECL_P (decl));
12086 gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
12087 || POINTER_TYPE_P (TREE_TYPE (decl)));
12088 if (is_doacross)
12090 if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
12092 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12093 if (TREE_CODE (orig_decl) == TREE_LIST)
12095 orig_decl = TREE_PURPOSE (orig_decl);
12096 if (!orig_decl)
12097 orig_decl = decl;
12099 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
12101 else
12102 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12103 gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12106 /* Make sure the iteration variable is private. */
12107 tree c = NULL_TREE;
12108 tree c2 = NULL_TREE;
12109 if (orig_for_stmt != for_stmt)
12111 /* Preserve this information until we gimplify the inner simd. */
12112 if (has_decl_expr
12113 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12114 TREE_PRIVATE (t) = 1;
12116 else if (ort == ORT_SIMD)
12118 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12119 (splay_tree_key) decl);
12120 omp_is_private (gimplify_omp_ctxp, decl,
12121 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12122 != 1));
12123 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
12125 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12126 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
12127 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12128 OMP_CLAUSE_LASTPRIVATE);
12129 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12130 OMP_CLAUSE_LASTPRIVATE))
12131 if (OMP_CLAUSE_DECL (c3) == decl)
12133 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12134 "conditional %<lastprivate%> on loop "
12135 "iterator %qD ignored", decl);
12136 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12137 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12140 else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
12142 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12143 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12144 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
12145 if ((has_decl_expr
12146 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12147 || TREE_PRIVATE (t))
12149 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12150 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12152 struct gimplify_omp_ctx *outer
12153 = gimplify_omp_ctxp->outer_context;
12154 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12156 if (outer->region_type == ORT_WORKSHARE
12157 && outer->combined_loop)
12159 n = splay_tree_lookup (outer->variables,
12160 (splay_tree_key)decl);
12161 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12163 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12164 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12166 else
12168 struct gimplify_omp_ctx *octx = outer->outer_context;
12169 if (octx
12170 && octx->region_type == ORT_COMBINED_PARALLEL
12171 && octx->outer_context
12172 && (octx->outer_context->region_type
12173 == ORT_WORKSHARE)
12174 && octx->outer_context->combined_loop)
12176 octx = octx->outer_context;
12177 n = splay_tree_lookup (octx->variables,
12178 (splay_tree_key)decl);
12179 if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12181 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12182 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12189 OMP_CLAUSE_DECL (c) = decl;
12190 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12191 OMP_FOR_CLAUSES (for_stmt) = c;
12192 omp_add_variable (gimplify_omp_ctxp, decl, flags);
12193 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12194 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12195 true);
12197 else
12199 bool lastprivate
12200 = (!has_decl_expr
12201 || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
12202 if (TREE_PRIVATE (t))
12203 lastprivate = false;
12204 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
12206 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12207 if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
12208 lastprivate = false;
12211 struct gimplify_omp_ctx *outer
12212 = gimplify_omp_ctxp->outer_context;
12213 if (outer && lastprivate)
12214 omp_lastprivate_for_combined_outer_constructs (outer, decl,
12215 true);
12217 c = build_omp_clause (input_location,
12218 lastprivate ? OMP_CLAUSE_LASTPRIVATE
12219 : OMP_CLAUSE_PRIVATE);
12220 OMP_CLAUSE_DECL (c) = decl;
12221 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12222 OMP_FOR_CLAUSES (for_stmt) = c;
12223 omp_add_variable (gimplify_omp_ctxp, decl,
12224 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
12225 | GOVD_EXPLICIT | GOVD_SEEN);
12226 c = NULL_TREE;
12229 else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
12231 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12232 splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12233 (splay_tree_key) decl);
12234 if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
12235 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12236 OMP_CLAUSE_LASTPRIVATE);
12237 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12238 OMP_CLAUSE_LASTPRIVATE))
12239 if (OMP_CLAUSE_DECL (c3) == decl)
12241 warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12242 "conditional %<lastprivate%> on loop "
12243 "iterator %qD ignored", decl);
12244 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12245 n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12248 else
12249 omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
12251 /* If DECL is not a gimple register, create a temporary variable to act
12252 as an iteration counter. This is valid, since DECL cannot be
12253 modified in the body of the loop. Similarly for any iteration vars
12254 in simd with collapse > 1 where the iterator vars must be
12255 lastprivate. And similarly for vars mentioned in allocate clauses. */
12256 if (orig_for_stmt != for_stmt)
12257 var = decl;
12258 else if (!is_gimple_reg (decl)
12259 || (ort == ORT_SIMD
12260 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
12261 || (allocate_uids && allocate_uids->contains (decl)))
12263 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12264 /* Make sure omp_add_variable is not called on it prematurely.
12265 We call it ourselves a few lines later. */
12266 gimplify_omp_ctxp = NULL;
12267 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
12268 gimplify_omp_ctxp = ctx;
12269 TREE_OPERAND (t, 0) = var;
12271 gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
12273 if (ort == ORT_SIMD
12274 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12276 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12277 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
12278 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
12279 OMP_CLAUSE_DECL (c2) = var;
12280 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
12281 OMP_FOR_CLAUSES (for_stmt) = c2;
12282 omp_add_variable (gimplify_omp_ctxp, var,
12283 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
12284 if (c == NULL_TREE)
12286 c = c2;
12287 c2 = NULL_TREE;
12290 else
12291 omp_add_variable (gimplify_omp_ctxp, var,
12292 GOVD_PRIVATE | GOVD_SEEN);
12294 else
12295 var = decl;
12297 gimplify_omp_ctxp->in_for_exprs = true;
12298 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12300 tree lb = TREE_OPERAND (t, 1);
12301 tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
12302 is_gimple_val, fb_rvalue, false);
12303 ret = MIN (ret, tret);
12304 tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
12305 is_gimple_val, fb_rvalue, false);
12307 else
12308 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12309 is_gimple_val, fb_rvalue, false);
12310 gimplify_omp_ctxp->in_for_exprs = false;
12311 ret = MIN (ret, tret);
12312 if (ret == GS_ERROR)
12313 return ret;
12315 /* Handle OMP_FOR_COND. */
12316 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12317 gcc_assert (COMPARISON_CLASS_P (t));
12318 gcc_assert (TREE_OPERAND (t, 0) == decl);
12320 gimplify_omp_ctxp->in_for_exprs = true;
12321 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12323 tree ub = TREE_OPERAND (t, 1);
12324 tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
12325 is_gimple_val, fb_rvalue, false);
12326 ret = MIN (ret, tret);
12327 tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
12328 is_gimple_val, fb_rvalue, false);
12330 else
12331 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12332 is_gimple_val, fb_rvalue, false);
12333 gimplify_omp_ctxp->in_for_exprs = false;
12334 ret = MIN (ret, tret);
12336 /* Handle OMP_FOR_INCR. */
12337 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12338 switch (TREE_CODE (t))
12340 case PREINCREMENT_EXPR:
12341 case POSTINCREMENT_EXPR:
12343 tree decl = TREE_OPERAND (t, 0);
12344 /* c_omp_for_incr_canonicalize_ptr() should have been
12345 called to massage things appropriately. */
12346 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
12348 if (orig_for_stmt != for_stmt)
12349 break;
12350 t = build_int_cst (TREE_TYPE (decl), 1);
12351 if (c)
12352 OMP_CLAUSE_LINEAR_STEP (c) = t;
12353 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
12354 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
12355 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
12356 break;
12359 case PREDECREMENT_EXPR:
12360 case POSTDECREMENT_EXPR:
12361 /* c_omp_for_incr_canonicalize_ptr() should have been
12362 called to massage things appropriately. */
12363 gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
12364 if (orig_for_stmt != for_stmt)
12365 break;
12366 t = build_int_cst (TREE_TYPE (decl), -1);
12367 if (c)
12368 OMP_CLAUSE_LINEAR_STEP (c) = t;
12369 t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
12370 t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
12371 TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
12372 break;
12374 case MODIFY_EXPR:
12375 gcc_assert (TREE_OPERAND (t, 0) == decl);
12376 TREE_OPERAND (t, 0) = var;
12378 t = TREE_OPERAND (t, 1);
12379 switch (TREE_CODE (t))
12381 case PLUS_EXPR:
12382 if (TREE_OPERAND (t, 1) == decl)
12384 TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
12385 TREE_OPERAND (t, 0) = var;
12386 break;
12389 /* Fallthru. */
12390 case MINUS_EXPR:
12391 case POINTER_PLUS_EXPR:
12392 gcc_assert (TREE_OPERAND (t, 0) == decl);
12393 TREE_OPERAND (t, 0) = var;
12394 break;
12395 default:
12396 gcc_unreachable ();
12399 gimplify_omp_ctxp->in_for_exprs = true;
12400 tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12401 is_gimple_val, fb_rvalue, false);
12402 ret = MIN (ret, tret);
12403 if (c)
12405 tree step = TREE_OPERAND (t, 1);
12406 tree stept = TREE_TYPE (decl);
12407 if (POINTER_TYPE_P (stept))
12408 stept = sizetype;
12409 step = fold_convert (stept, step);
12410 if (TREE_CODE (t) == MINUS_EXPR)
12411 step = fold_build1 (NEGATE_EXPR, stept, step);
12412 OMP_CLAUSE_LINEAR_STEP (c) = step;
12413 if (step != TREE_OPERAND (t, 1))
12415 tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
12416 &for_pre_body, NULL,
12417 is_gimple_val, fb_rvalue, false);
12418 ret = MIN (ret, tret);
12421 gimplify_omp_ctxp->in_for_exprs = false;
12422 break;
12424 default:
12425 gcc_unreachable ();
12428 if (c2)
12430 gcc_assert (c);
12431 OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
12434 if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
12436 for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
12437 if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12438 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
12439 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12440 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
12441 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
12442 && OMP_CLAUSE_DECL (c) == decl)
12444 if (is_doacross && (collapse == 1 || i >= collapse))
12445 t = var;
12446 else
12448 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12449 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12450 gcc_assert (TREE_OPERAND (t, 0) == var);
12451 t = TREE_OPERAND (t, 1);
12452 gcc_assert (TREE_CODE (t) == PLUS_EXPR
12453 || TREE_CODE (t) == MINUS_EXPR
12454 || TREE_CODE (t) == POINTER_PLUS_EXPR);
12455 gcc_assert (TREE_OPERAND (t, 0) == var);
12456 t = build2 (TREE_CODE (t), TREE_TYPE (decl),
12457 is_doacross ? var : decl,
12458 TREE_OPERAND (t, 1));
12460 gimple_seq *seq;
12461 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
12462 seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
12463 else
12464 seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
12465 push_gimplify_context ();
12466 gimplify_assign (decl, t, seq);
12467 gimple *bind = NULL;
12468 if (gimplify_ctxp->temps)
12470 bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
12471 *seq = NULL;
12472 gimplify_seq_add_stmt (seq, bind);
12474 pop_gimplify_context (bind);
12477 if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
12478 for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
12480 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
12481 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12482 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12483 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12484 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12485 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
12486 gcc_assert (COMPARISON_CLASS_P (t));
12487 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12488 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12489 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12493 BITMAP_FREE (has_decl_expr);
12494 delete allocate_uids;
12496 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
12497 || (loop_p && orig_for_stmt == for_stmt))
12499 push_gimplify_context ();
12500 if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
12502 OMP_FOR_BODY (orig_for_stmt)
12503 = build3 (BIND_EXPR, void_type_node, NULL,
12504 OMP_FOR_BODY (orig_for_stmt), NULL);
12505 TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
12509 gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
12510 &for_body);
12512 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
12513 || (loop_p && orig_for_stmt == for_stmt))
12515 if (gimple_code (g) == GIMPLE_BIND)
12516 pop_gimplify_context (g);
12517 else
12518 pop_gimplify_context (NULL);
12521 if (orig_for_stmt != for_stmt)
12522 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12524 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12525 decl = TREE_OPERAND (t, 0);
12526 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12527 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12528 gimplify_omp_ctxp = ctx->outer_context;
12529 var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
12530 gimplify_omp_ctxp = ctx;
12531 omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
12532 TREE_OPERAND (t, 0) = var;
12533 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12534 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12535 TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
12536 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
12537 for (int j = i + 1;
12538 j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
12540 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
12541 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12542 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12543 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12545 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12546 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12548 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
12549 gcc_assert (COMPARISON_CLASS_P (t));
12550 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
12551 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
12553 TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
12554 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
12559 gimplify_adjust_omp_clauses (pre_p, for_body,
12560 &OMP_FOR_CLAUSES (orig_for_stmt),
12561 TREE_CODE (orig_for_stmt));
12563 int kind;
12564 switch (TREE_CODE (orig_for_stmt))
12566 case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
12567 case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
12568 case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
12569 case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
12570 case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
12571 default:
12572 gcc_unreachable ();
12574 if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
12576 gimplify_seq_add_seq (pre_p, for_pre_body);
12577 for_pre_body = NULL;
12579 gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
12580 TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
12581 for_pre_body);
12582 if (orig_for_stmt != for_stmt)
12583 gimple_omp_for_set_combined_p (gfor, true);
12584 if (gimplify_omp_ctxp
12585 && (gimplify_omp_ctxp->combined_loop
12586 || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
12587 && gimplify_omp_ctxp->outer_context
12588 && gimplify_omp_ctxp->outer_context->combined_loop)))
12590 gimple_omp_for_set_combined_into_p (gfor, true);
12591 if (gimplify_omp_ctxp->combined_loop)
12592 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
12593 else
12594 gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
12597 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12599 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12600 gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
12601 gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
12602 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12603 gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
12604 gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
12605 t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12606 gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
12609 /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
12610 constructs with GIMPLE_OMP_TASK sandwiched in between them.
12611 The outer taskloop stands for computing the number of iterations,
12612 counts for collapsed loops and holding taskloop specific clauses.
12613 The task construct stands for the effect of data sharing on the
12614 explicit task it creates and the inner taskloop stands for expansion
12615 of the static loop inside of the explicit task construct. */
12616 if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12618 tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
12619 tree task_clauses = NULL_TREE;
12620 tree c = *gfor_clauses_ptr;
12621 tree *gtask_clauses_ptr = &task_clauses;
12622 tree outer_for_clauses = NULL_TREE;
12623 tree *gforo_clauses_ptr = &outer_for_clauses;
12624 bitmap lastprivate_uids = NULL;
12625 if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
12627 c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
12628 if (c)
12630 lastprivate_uids = BITMAP_ALLOC (NULL);
12631 for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
12632 OMP_CLAUSE_LASTPRIVATE))
12633 bitmap_set_bit (lastprivate_uids,
12634 DECL_UID (OMP_CLAUSE_DECL (c)));
12636 c = *gfor_clauses_ptr;
12638 for (; c; c = OMP_CLAUSE_CHAIN (c))
12639 switch (OMP_CLAUSE_CODE (c))
12641 /* These clauses are allowed on task, move them there. */
12642 case OMP_CLAUSE_SHARED:
12643 case OMP_CLAUSE_FIRSTPRIVATE:
12644 case OMP_CLAUSE_DEFAULT:
12645 case OMP_CLAUSE_IF:
12646 case OMP_CLAUSE_UNTIED:
12647 case OMP_CLAUSE_FINAL:
12648 case OMP_CLAUSE_MERGEABLE:
12649 case OMP_CLAUSE_PRIORITY:
12650 case OMP_CLAUSE_REDUCTION:
12651 case OMP_CLAUSE_IN_REDUCTION:
12652 *gtask_clauses_ptr = c;
12653 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12654 break;
12655 case OMP_CLAUSE_PRIVATE:
12656 if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
12658 /* We want private on outer for and firstprivate
12659 on task. */
12660 *gtask_clauses_ptr
12661 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12662 OMP_CLAUSE_FIRSTPRIVATE);
12663 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12664 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
12665 openacc);
12666 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12667 *gforo_clauses_ptr = c;
12668 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12670 else
12672 *gtask_clauses_ptr = c;
12673 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12675 break;
12676 /* These clauses go into outer taskloop clauses. */
12677 case OMP_CLAUSE_GRAINSIZE:
12678 case OMP_CLAUSE_NUM_TASKS:
12679 case OMP_CLAUSE_NOGROUP:
12680 *gforo_clauses_ptr = c;
12681 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12682 break;
12683 /* Collapse clause we duplicate on both taskloops. */
12684 case OMP_CLAUSE_COLLAPSE:
12685 *gfor_clauses_ptr = c;
12686 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12687 *gforo_clauses_ptr = copy_node (c);
12688 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
12689 break;
12690 /* For lastprivate, keep the clause on inner taskloop, and add
12691 a shared clause on task. If the same decl is also firstprivate,
12692 add also firstprivate clause on the inner taskloop. */
12693 case OMP_CLAUSE_LASTPRIVATE:
12694 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
12696 /* For taskloop C++ lastprivate IVs, we want:
12697 1) private on outer taskloop
12698 2) firstprivate and shared on task
12699 3) lastprivate on inner taskloop */
12700 *gtask_clauses_ptr
12701 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12702 OMP_CLAUSE_FIRSTPRIVATE);
12703 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12704 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
12705 openacc);
12706 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12707 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
12708 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12709 OMP_CLAUSE_PRIVATE);
12710 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
12711 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
12712 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
12713 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
12715 *gfor_clauses_ptr = c;
12716 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12717 *gtask_clauses_ptr
12718 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
12719 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
12720 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
12721 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
12722 gtask_clauses_ptr
12723 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12724 break;
12725 /* Allocate clause we duplicate on task and inner taskloop
12726 if the decl is lastprivate, otherwise just put on task. */
12727 case OMP_CLAUSE_ALLOCATE:
12728 if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
12729 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
12731 /* Additionally, put firstprivate clause on task
12732 for the allocator if it is not constant. */
12733 *gtask_clauses_ptr
12734 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
12735 OMP_CLAUSE_FIRSTPRIVATE);
12736 OMP_CLAUSE_DECL (*gtask_clauses_ptr)
12737 = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
12738 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12740 if (lastprivate_uids
12741 && bitmap_bit_p (lastprivate_uids,
12742 DECL_UID (OMP_CLAUSE_DECL (c))))
12744 *gfor_clauses_ptr = c;
12745 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12746 *gtask_clauses_ptr = copy_node (c);
12747 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
12749 else
12751 *gtask_clauses_ptr = c;
12752 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
12754 break;
12755 default:
12756 gcc_unreachable ();
12758 *gfor_clauses_ptr = NULL_TREE;
12759 *gtask_clauses_ptr = NULL_TREE;
12760 *gforo_clauses_ptr = NULL_TREE;
12761 BITMAP_FREE (lastprivate_uids);
12762 g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
12763 g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
12764 NULL_TREE, NULL_TREE, NULL_TREE);
12765 gimple_omp_task_set_taskloop_p (g, true);
12766 g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
12767 gomp_for *gforo
12768 = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
12769 gimple_omp_for_collapse (gfor),
12770 gimple_omp_for_pre_body (gfor));
12771 gimple_omp_for_set_pre_body (gfor, NULL);
12772 gimple_omp_for_set_combined_p (gforo, true);
12773 gimple_omp_for_set_combined_into_p (gfor, true);
12774 for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
12776 tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
12777 tree v = create_tmp_var (type);
12778 gimple_omp_for_set_index (gforo, i, v);
12779 t = unshare_expr (gimple_omp_for_initial (gfor, i));
12780 gimple_omp_for_set_initial (gforo, i, t);
12781 gimple_omp_for_set_cond (gforo, i,
12782 gimple_omp_for_cond (gfor, i));
12783 t = unshare_expr (gimple_omp_for_final (gfor, i));
12784 gimple_omp_for_set_final (gforo, i, t);
12785 t = unshare_expr (gimple_omp_for_incr (gfor, i));
12786 gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
12787 TREE_OPERAND (t, 0) = v;
12788 gimple_omp_for_set_incr (gforo, i, t);
12789 t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
12790 OMP_CLAUSE_DECL (t) = v;
12791 OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
12792 gimple_omp_for_set_clauses (gforo, t);
12793 if (OMP_FOR_NON_RECTANGULAR (for_stmt))
12795 tree *p1 = NULL, *p2 = NULL;
12796 t = gimple_omp_for_initial (gforo, i);
12797 if (TREE_CODE (t) == TREE_VEC)
12798 p1 = &TREE_VEC_ELT (t, 0);
12799 t = gimple_omp_for_final (gforo, i);
12800 if (TREE_CODE (t) == TREE_VEC)
12802 if (p1)
12803 p2 = &TREE_VEC_ELT (t, 0);
12804 else
12805 p1 = &TREE_VEC_ELT (t, 0);
12807 if (p1)
12809 int j;
12810 for (j = 0; j < i; j++)
12811 if (*p1 == gimple_omp_for_index (gfor, j))
12813 *p1 = gimple_omp_for_index (gforo, j);
12814 if (p2)
12815 *p2 = *p1;
12816 break;
12818 gcc_assert (j < i);
12822 gimplify_seq_add_stmt (pre_p, gforo);
12824 else
12825 gimplify_seq_add_stmt (pre_p, gfor);
12827 if (TREE_CODE (orig_for_stmt) == OMP_FOR)
12829 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12830 unsigned lastprivate_conditional = 0;
12831 while (ctx
12832 && (ctx->region_type == ORT_TARGET_DATA
12833 || ctx->region_type == ORT_TASKGROUP))
12834 ctx = ctx->outer_context;
12835 if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
12836 for (tree c = gimple_omp_for_clauses (gfor);
12837 c; c = OMP_CLAUSE_CHAIN (c))
12838 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12839 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
12840 ++lastprivate_conditional;
12841 if (lastprivate_conditional)
12843 struct omp_for_data fd;
12844 omp_extract_for_data (gfor, &fd, NULL);
12845 tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
12846 lastprivate_conditional);
12847 tree var = create_tmp_var_raw (type);
12848 tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
12849 OMP_CLAUSE_DECL (c) = var;
12850 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
12851 gimple_omp_for_set_clauses (gfor, c);
12852 omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
12855 else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
12857 unsigned lastprivate_conditional = 0;
12858 for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
12859 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12860 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
12861 ++lastprivate_conditional;
12862 if (lastprivate_conditional)
12864 struct omp_for_data fd;
12865 omp_extract_for_data (gfor, &fd, NULL);
12866 tree type = unsigned_type_for (fd.iter_type);
12867 while (lastprivate_conditional--)
12869 tree c = build_omp_clause (UNKNOWN_LOCATION,
12870 OMP_CLAUSE__CONDTEMP_);
12871 OMP_CLAUSE_DECL (c) = create_tmp_var (type);
12872 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
12873 gimple_omp_for_set_clauses (gfor, c);
12878 if (ret != GS_ALL_DONE)
12879 return GS_ERROR;
12880 *expr_p = NULL_TREE;
12881 return GS_ALL_DONE;
12884 /* Helper for gimplify_omp_loop, called through walk_tree. */
12886 static tree
12887 replace_reduction_placeholders (tree *tp, int *walk_subtrees, void *data)
12889 if (DECL_P (*tp))
12891 tree *d = (tree *) data;
12892 if (*tp == OMP_CLAUSE_REDUCTION_PLACEHOLDER (d[0]))
12894 *tp = OMP_CLAUSE_REDUCTION_PLACEHOLDER (d[1]);
12895 *walk_subtrees = 0;
12897 else if (*tp == OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d[0]))
12899 *tp = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d[1]);
12900 *walk_subtrees = 0;
12903 return NULL_TREE;
12906 /* Gimplify the gross structure of an OMP_LOOP statement. */
12908 static enum gimplify_status
12909 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
12911 tree for_stmt = *expr_p;
12912 tree clauses = OMP_FOR_CLAUSES (for_stmt);
12913 struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
12914 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
12915 int i;
12917 /* If order is not present, the behavior is as if order(concurrent)
12918 appeared. */
12919 tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
12920 if (order == NULL_TREE)
12922 order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
12923 OMP_CLAUSE_CHAIN (order) = clauses;
12924 OMP_FOR_CLAUSES (for_stmt) = clauses = order;
12927 tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
12928 if (bind == NULL_TREE)
12930 if (!flag_openmp) /* flag_openmp_simd */
12932 else if (octx && (octx->region_type & ORT_TEAMS) != 0)
12933 kind = OMP_CLAUSE_BIND_TEAMS;
12934 else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
12935 kind = OMP_CLAUSE_BIND_PARALLEL;
12936 else
12938 for (; octx; octx = octx->outer_context)
12940 if ((octx->region_type & ORT_ACC) != 0
12941 || octx->region_type == ORT_NONE
12942 || octx->region_type == ORT_IMPLICIT_TARGET)
12943 continue;
12944 break;
12946 if (octx == NULL && !in_omp_construct)
12947 error_at (EXPR_LOCATION (for_stmt),
12948 "%<bind%> clause not specified on a %<loop%> "
12949 "construct not nested inside another OpenMP construct");
12951 bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
12952 OMP_CLAUSE_CHAIN (bind) = clauses;
12953 OMP_CLAUSE_BIND_KIND (bind) = kind;
12954 OMP_FOR_CLAUSES (for_stmt) = bind;
12956 else
12957 switch (OMP_CLAUSE_BIND_KIND (bind))
12959 case OMP_CLAUSE_BIND_THREAD:
12960 break;
12961 case OMP_CLAUSE_BIND_PARALLEL:
12962 if (!flag_openmp) /* flag_openmp_simd */
12964 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12965 break;
12967 for (; octx; octx = octx->outer_context)
12968 if (octx->region_type == ORT_SIMD
12969 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
12971 error_at (EXPR_LOCATION (for_stmt),
12972 "%<bind(parallel)%> on a %<loop%> construct nested "
12973 "inside %<simd%> construct");
12974 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12975 break;
12977 kind = OMP_CLAUSE_BIND_PARALLEL;
12978 break;
12979 case OMP_CLAUSE_BIND_TEAMS:
12980 if (!flag_openmp) /* flag_openmp_simd */
12982 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12983 break;
12985 if ((octx
12986 && octx->region_type != ORT_IMPLICIT_TARGET
12987 && octx->region_type != ORT_NONE
12988 && (octx->region_type & ORT_TEAMS) == 0)
12989 || in_omp_construct)
12991 error_at (EXPR_LOCATION (for_stmt),
12992 "%<bind(teams)%> on a %<loop%> region not strictly "
12993 "nested inside of a %<teams%> region");
12994 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
12995 break;
12997 kind = OMP_CLAUSE_BIND_TEAMS;
12998 break;
12999 default:
13000 gcc_unreachable ();
13003 for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
13004 switch (OMP_CLAUSE_CODE (*pc))
13006 case OMP_CLAUSE_REDUCTION:
13007 if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
13009 error_at (OMP_CLAUSE_LOCATION (*pc),
13010 "%<inscan%> %<reduction%> clause on "
13011 "%qs construct", "loop");
13012 OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
13014 if (OMP_CLAUSE_REDUCTION_TASK (*pc))
13016 error_at (OMP_CLAUSE_LOCATION (*pc),
13017 "invalid %<task%> reduction modifier on construct "
13018 "other than %<parallel%>, %qs or %<sections%>",
13019 lang_GNU_Fortran () ? "do" : "for");
13020 OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
13022 pc = &OMP_CLAUSE_CHAIN (*pc);
13023 break;
13024 case OMP_CLAUSE_LASTPRIVATE:
13025 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13027 tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13028 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13029 if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
13030 break;
13031 if (OMP_FOR_ORIG_DECLS (for_stmt)
13032 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13033 i)) == TREE_LIST
13034 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13035 i)))
13037 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13038 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
13039 break;
13042 if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
13044 error_at (OMP_CLAUSE_LOCATION (*pc),
13045 "%<lastprivate%> clause on a %<loop%> construct refers "
13046 "to a variable %qD which is not the loop iterator",
13047 OMP_CLAUSE_DECL (*pc));
13048 *pc = OMP_CLAUSE_CHAIN (*pc);
13049 break;
13051 pc = &OMP_CLAUSE_CHAIN (*pc);
13052 break;
13053 default:
13054 pc = &OMP_CLAUSE_CHAIN (*pc);
13055 break;
13058 TREE_SET_CODE (for_stmt, OMP_SIMD);
13060 int last;
13061 switch (kind)
13063 case OMP_CLAUSE_BIND_THREAD: last = 0; break;
13064 case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
13065 case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
13067 for (int pass = 1; pass <= last; pass++)
13069 if (pass == 2)
13071 tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
13072 append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
13073 *expr_p = make_node (OMP_PARALLEL);
13074 TREE_TYPE (*expr_p) = void_type_node;
13075 OMP_PARALLEL_BODY (*expr_p) = bind;
13076 OMP_PARALLEL_COMBINED (*expr_p) = 1;
13077 SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
13078 tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
13079 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13080 if (OMP_FOR_ORIG_DECLS (for_stmt)
13081 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
13082 == TREE_LIST))
13084 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13085 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
13087 *pc = build_omp_clause (UNKNOWN_LOCATION,
13088 OMP_CLAUSE_FIRSTPRIVATE);
13089 OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
13090 pc = &OMP_CLAUSE_CHAIN (*pc);
13094 tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
13095 tree *pc = &OMP_FOR_CLAUSES (t);
13096 TREE_TYPE (t) = void_type_node;
13097 OMP_FOR_BODY (t) = *expr_p;
13098 SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
13099 for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
13100 switch (OMP_CLAUSE_CODE (c))
13102 case OMP_CLAUSE_BIND:
13103 case OMP_CLAUSE_ORDER:
13104 case OMP_CLAUSE_COLLAPSE:
13105 *pc = copy_node (c);
13106 pc = &OMP_CLAUSE_CHAIN (*pc);
13107 break;
13108 case OMP_CLAUSE_PRIVATE:
13109 case OMP_CLAUSE_FIRSTPRIVATE:
13110 /* Only needed on innermost. */
13111 break;
13112 case OMP_CLAUSE_LASTPRIVATE:
13113 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
13115 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13116 OMP_CLAUSE_FIRSTPRIVATE);
13117 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
13118 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13119 pc = &OMP_CLAUSE_CHAIN (*pc);
13121 *pc = copy_node (c);
13122 OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
13123 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13124 if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
13126 if (pass != last)
13127 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
13128 else
13129 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13130 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
13132 pc = &OMP_CLAUSE_CHAIN (*pc);
13133 break;
13134 case OMP_CLAUSE_REDUCTION:
13135 *pc = copy_node (c);
13136 OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
13137 TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13138 OMP_CLAUSE_REDUCTION_INIT (*pc)
13139 = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
13140 OMP_CLAUSE_REDUCTION_MERGE (*pc)
13141 = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
13142 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
13144 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
13145 = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
13146 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13147 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
13148 = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
13149 tree nc = *pc;
13150 tree data[2] = { c, nc };
13151 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (nc),
13152 replace_reduction_placeholders,
13153 data);
13154 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (nc),
13155 replace_reduction_placeholders,
13156 data);
13158 pc = &OMP_CLAUSE_CHAIN (*pc);
13159 break;
13160 default:
13161 gcc_unreachable ();
13163 *pc = NULL_TREE;
13164 *expr_p = t;
13166 return gimplify_omp_for (expr_p, pre_p);
13170 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
13171 of OMP_TARGET's body. */
13173 static tree
13174 find_omp_teams (tree *tp, int *walk_subtrees, void *)
13176 *walk_subtrees = 0;
13177 switch (TREE_CODE (*tp))
13179 case OMP_TEAMS:
13180 return *tp;
13181 case BIND_EXPR:
13182 case STATEMENT_LIST:
13183 *walk_subtrees = 1;
13184 break;
13185 default:
13186 break;
13188 return NULL_TREE;
13191 /* Helper function of optimize_target_teams, determine if the expression
13192 can be computed safely before the target construct on the host. */
13194 static tree
13195 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
13197 splay_tree_node n;
13199 if (TYPE_P (*tp))
13201 *walk_subtrees = 0;
13202 return NULL_TREE;
13204 switch (TREE_CODE (*tp))
13206 case VAR_DECL:
13207 case PARM_DECL:
13208 case RESULT_DECL:
13209 *walk_subtrees = 0;
13210 if (error_operand_p (*tp)
13211 || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
13212 || DECL_HAS_VALUE_EXPR_P (*tp)
13213 || DECL_THREAD_LOCAL_P (*tp)
13214 || TREE_SIDE_EFFECTS (*tp)
13215 || TREE_THIS_VOLATILE (*tp))
13216 return *tp;
13217 if (is_global_var (*tp)
13218 && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
13219 || lookup_attribute ("omp declare target link",
13220 DECL_ATTRIBUTES (*tp))))
13221 return *tp;
13222 if (VAR_P (*tp)
13223 && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
13224 && !is_global_var (*tp)
13225 && decl_function_context (*tp) == current_function_decl)
13226 return *tp;
13227 n = splay_tree_lookup (gimplify_omp_ctxp->variables,
13228 (splay_tree_key) *tp);
13229 if (n == NULL)
13231 if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
13232 return NULL_TREE;
13233 return *tp;
13235 else if (n->value & GOVD_LOCAL)
13236 return *tp;
13237 else if (n->value & GOVD_FIRSTPRIVATE)
13238 return NULL_TREE;
13239 else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13240 == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13241 return NULL_TREE;
13242 return *tp;
13243 case INTEGER_CST:
13244 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13245 return *tp;
13246 return NULL_TREE;
13247 case TARGET_EXPR:
13248 if (TARGET_EXPR_INITIAL (*tp)
13249 || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
13250 return *tp;
13251 return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
13252 walk_subtrees, NULL);
13253 /* Allow some reasonable subset of integral arithmetics. */
13254 case PLUS_EXPR:
13255 case MINUS_EXPR:
13256 case MULT_EXPR:
13257 case TRUNC_DIV_EXPR:
13258 case CEIL_DIV_EXPR:
13259 case FLOOR_DIV_EXPR:
13260 case ROUND_DIV_EXPR:
13261 case TRUNC_MOD_EXPR:
13262 case CEIL_MOD_EXPR:
13263 case FLOOR_MOD_EXPR:
13264 case ROUND_MOD_EXPR:
13265 case RDIV_EXPR:
13266 case EXACT_DIV_EXPR:
13267 case MIN_EXPR:
13268 case MAX_EXPR:
13269 case LSHIFT_EXPR:
13270 case RSHIFT_EXPR:
13271 case BIT_IOR_EXPR:
13272 case BIT_XOR_EXPR:
13273 case BIT_AND_EXPR:
13274 case NEGATE_EXPR:
13275 case ABS_EXPR:
13276 case BIT_NOT_EXPR:
13277 case NON_LVALUE_EXPR:
13278 CASE_CONVERT:
13279 if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13280 return *tp;
13281 return NULL_TREE;
13282 /* And disallow anything else, except for comparisons. */
13283 default:
13284 if (COMPARISON_CLASS_P (*tp))
13285 return NULL_TREE;
13286 return *tp;
13290 /* Try to determine if the num_teams and/or thread_limit expressions
13291 can have their values determined already before entering the
13292 target construct.
13293 INTEGER_CSTs trivially are,
13294 integral decls that are firstprivate (explicitly or implicitly)
13295 or explicitly map(always, to:) or map(always, tofrom:) on the target
13296 region too, and expressions involving simple arithmetics on those
13297 too, function calls are not ok, dereferencing something neither etc.
13298 Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
13299 EXPR based on what we find:
13300 0 stands for clause not specified at all, use implementation default
13301 -1 stands for value that can't be determined easily before entering
13302 the target construct.
13303 If teams construct is not present at all, use 1 for num_teams
13304 and 0 for thread_limit (only one team is involved, and the thread
13305 limit is implementation defined. */
13307 static void
13308 optimize_target_teams (tree target, gimple_seq *pre_p)
13310 tree body = OMP_BODY (target);
13311 tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
13312 tree num_teams = integer_zero_node;
13313 tree thread_limit = integer_zero_node;
13314 location_t num_teams_loc = EXPR_LOCATION (target);
13315 location_t thread_limit_loc = EXPR_LOCATION (target);
13316 tree c, *p, expr;
13317 struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
13319 if (teams == NULL_TREE)
13320 num_teams = integer_one_node;
13321 else
13322 for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
13324 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
13326 p = &num_teams;
13327 num_teams_loc = OMP_CLAUSE_LOCATION (c);
13329 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
13331 p = &thread_limit;
13332 thread_limit_loc = OMP_CLAUSE_LOCATION (c);
13334 else
13335 continue;
13336 expr = OMP_CLAUSE_OPERAND (c, 0);
13337 if (TREE_CODE (expr) == INTEGER_CST)
13339 *p = expr;
13340 continue;
13342 if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
13344 *p = integer_minus_one_node;
13345 continue;
13347 *p = expr;
13348 gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
13349 if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
13350 == GS_ERROR)
13352 gimplify_omp_ctxp = target_ctx;
13353 *p = integer_minus_one_node;
13354 continue;
13356 gimplify_omp_ctxp = target_ctx;
13357 if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
13358 OMP_CLAUSE_OPERAND (c, 0) = *p;
13360 c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
13361 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
13362 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
13363 OMP_TARGET_CLAUSES (target) = c;
13364 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
13365 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
13366 OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
13367 OMP_TARGET_CLAUSES (target) = c;
13370 /* Gimplify the gross structure of several OMP constructs. */
13372 static void
13373 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
13375 tree expr = *expr_p;
13376 gimple *stmt;
13377 gimple_seq body = NULL;
13378 enum omp_region_type ort;
13380 switch (TREE_CODE (expr))
13382 case OMP_SECTIONS:
13383 case OMP_SINGLE:
13384 ort = ORT_WORKSHARE;
13385 break;
13386 case OMP_SCOPE:
13387 ort = ORT_TASKGROUP;
13388 break;
13389 case OMP_TARGET:
13390 ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
13391 break;
13392 case OACC_KERNELS:
13393 ort = ORT_ACC_KERNELS;
13394 break;
13395 case OACC_PARALLEL:
13396 ort = ORT_ACC_PARALLEL;
13397 break;
13398 case OACC_SERIAL:
13399 ort = ORT_ACC_SERIAL;
13400 break;
13401 case OACC_DATA:
13402 ort = ORT_ACC_DATA;
13403 break;
13404 case OMP_TARGET_DATA:
13405 ort = ORT_TARGET_DATA;
13406 break;
13407 case OMP_TEAMS:
13408 ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
13409 if (gimplify_omp_ctxp == NULL
13410 || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
13411 ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
13412 break;
13413 case OACC_HOST_DATA:
13414 ort = ORT_ACC_HOST_DATA;
13415 break;
13416 default:
13417 gcc_unreachable ();
13420 bool save_in_omp_construct = in_omp_construct;
13421 if ((ort & ORT_ACC) == 0)
13422 in_omp_construct = false;
13423 gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
13424 TREE_CODE (expr));
13425 if (TREE_CODE (expr) == OMP_TARGET)
13426 optimize_target_teams (expr, pre_p);
13427 if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
13428 || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
13430 push_gimplify_context ();
13431 gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
13432 if (gimple_code (g) == GIMPLE_BIND)
13433 pop_gimplify_context (g);
13434 else
13435 pop_gimplify_context (NULL);
13436 if ((ort & ORT_TARGET_DATA) != 0)
13438 enum built_in_function end_ix;
13439 switch (TREE_CODE (expr))
13441 case OACC_DATA:
13442 case OACC_HOST_DATA:
13443 end_ix = BUILT_IN_GOACC_DATA_END;
13444 break;
13445 case OMP_TARGET_DATA:
13446 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
13447 break;
13448 default:
13449 gcc_unreachable ();
13451 tree fn = builtin_decl_explicit (end_ix);
13452 g = gimple_build_call (fn, 0);
13453 gimple_seq cleanup = NULL;
13454 gimple_seq_add_stmt (&cleanup, g);
13455 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
13456 body = NULL;
13457 gimple_seq_add_stmt (&body, g);
13460 else
13461 gimplify_and_add (OMP_BODY (expr), &body);
13462 gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
13463 TREE_CODE (expr));
13464 in_omp_construct = save_in_omp_construct;
13466 switch (TREE_CODE (expr))
13468 case OACC_DATA:
13469 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
13470 OMP_CLAUSES (expr));
13471 break;
13472 case OACC_HOST_DATA:
13473 if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
13475 for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13476 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
13477 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
13480 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
13481 OMP_CLAUSES (expr));
13482 break;
13483 case OACC_KERNELS:
13484 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
13485 OMP_CLAUSES (expr));
13486 break;
13487 case OACC_PARALLEL:
13488 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
13489 OMP_CLAUSES (expr));
13490 break;
13491 case OACC_SERIAL:
13492 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
13493 OMP_CLAUSES (expr));
13494 break;
13495 case OMP_SECTIONS:
13496 stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
13497 break;
13498 case OMP_SINGLE:
13499 stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
13500 break;
13501 case OMP_SCOPE:
13502 stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr));
13503 break;
13504 case OMP_TARGET:
13505 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
13506 OMP_CLAUSES (expr));
13507 break;
13508 case OMP_TARGET_DATA:
13509 /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
13510 to be evaluated before the use_device_{ptr,addr} clauses if they
13511 refer to the same variables. */
13513 tree use_device_clauses;
13514 tree *pc, *uc = &use_device_clauses;
13515 for (pc = &OMP_CLAUSES (expr); *pc; )
13516 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
13517 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
13519 *uc = *pc;
13520 *pc = OMP_CLAUSE_CHAIN (*pc);
13521 uc = &OMP_CLAUSE_CHAIN (*uc);
13523 else
13524 pc = &OMP_CLAUSE_CHAIN (*pc);
13525 *uc = NULL_TREE;
13526 *pc = use_device_clauses;
13527 stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
13528 OMP_CLAUSES (expr));
13530 break;
13531 case OMP_TEAMS:
13532 stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
13533 if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
13534 gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
13535 break;
13536 default:
13537 gcc_unreachable ();
13540 gimplify_seq_add_stmt (pre_p, stmt);
13541 *expr_p = NULL_TREE;
13544 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
13545 target update constructs. */
13547 static void
13548 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
13550 tree expr = *expr_p;
13551 int kind;
13552 gomp_target *stmt;
13553 enum omp_region_type ort = ORT_WORKSHARE;
13555 switch (TREE_CODE (expr))
13557 case OACC_ENTER_DATA:
13558 kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA;
13559 ort = ORT_ACC;
13560 break;
13561 case OACC_EXIT_DATA:
13562 kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA;
13563 ort = ORT_ACC;
13564 break;
13565 case OACC_UPDATE:
13566 kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
13567 ort = ORT_ACC;
13568 break;
13569 case OMP_TARGET_UPDATE:
13570 kind = GF_OMP_TARGET_KIND_UPDATE;
13571 break;
13572 case OMP_TARGET_ENTER_DATA:
13573 kind = GF_OMP_TARGET_KIND_ENTER_DATA;
13574 break;
13575 case OMP_TARGET_EXIT_DATA:
13576 kind = GF_OMP_TARGET_KIND_EXIT_DATA;
13577 break;
13578 default:
13579 gcc_unreachable ();
13581 gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
13582 ort, TREE_CODE (expr));
13583 gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
13584 TREE_CODE (expr));
13585 if (TREE_CODE (expr) == OACC_UPDATE
13586 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
13587 OMP_CLAUSE_IF_PRESENT))
13589 /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
13590 clause. */
13591 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13592 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
13593 switch (OMP_CLAUSE_MAP_KIND (c))
13595 case GOMP_MAP_FORCE_TO:
13596 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
13597 break;
13598 case GOMP_MAP_FORCE_FROM:
13599 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
13600 break;
13601 default:
13602 break;
13605 else if (TREE_CODE (expr) == OACC_EXIT_DATA
13606 && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
13607 OMP_CLAUSE_FINALIZE))
13609 /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
13610 semantics. */
13611 bool have_clause = false;
13612 for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13613 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
13614 switch (OMP_CLAUSE_MAP_KIND (c))
13616 case GOMP_MAP_FROM:
13617 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
13618 have_clause = true;
13619 break;
13620 case GOMP_MAP_RELEASE:
13621 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
13622 have_clause = true;
13623 break;
13624 case GOMP_MAP_TO_PSET:
13625 /* Fortran arrays with descriptors must map that descriptor when
13626 doing standalone "attach" operations (in OpenACC). In that
13627 case GOMP_MAP_TO_PSET appears by itself with no preceding
13628 clause (see trans-openmp.c:gfc_trans_omp_clauses). */
13629 break;
13630 case GOMP_MAP_POINTER:
13631 /* TODO PR92929: we may see these here, but they'll always follow
13632 one of the clauses above, and will be handled by libgomp as
13633 one group, so no handling required here. */
13634 gcc_assert (have_clause);
13635 break;
13636 case GOMP_MAP_DETACH:
13637 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
13638 have_clause = false;
13639 break;
13640 case GOMP_MAP_STRUCT:
13641 have_clause = false;
13642 break;
13643 default:
13644 gcc_unreachable ();
13647 stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
13649 gimplify_seq_add_stmt (pre_p, stmt);
13650 *expr_p = NULL_TREE;
13653 /* A subroutine of gimplify_omp_atomic. The front end is supposed to have
13654 stabilized the lhs of the atomic operation as *ADDR. Return true if
13655 EXPR is this stabilized form. */
13657 static bool
13658 goa_lhs_expr_p (tree expr, tree addr)
13660 /* Also include casts to other type variants. The C front end is fond
13661 of adding these for e.g. volatile variables. This is like
13662 STRIP_TYPE_NOPS but includes the main variant lookup. */
13663 STRIP_USELESS_TYPE_CONVERSION (expr);
13665 if (TREE_CODE (expr) == INDIRECT_REF)
13667 expr = TREE_OPERAND (expr, 0);
13668 while (expr != addr
13669 && (CONVERT_EXPR_P (expr)
13670 || TREE_CODE (expr) == NON_LVALUE_EXPR)
13671 && TREE_CODE (expr) == TREE_CODE (addr)
13672 && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
13674 expr = TREE_OPERAND (expr, 0);
13675 addr = TREE_OPERAND (addr, 0);
13677 if (expr == addr)
13678 return true;
13679 return (TREE_CODE (addr) == ADDR_EXPR
13680 && TREE_CODE (expr) == ADDR_EXPR
13681 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
13683 if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
13684 return true;
13685 return false;
13688 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR. If an
13689 expression does not involve the lhs, evaluate it into a temporary.
13690 Return 1 if the lhs appeared as a subexpression, 0 if it did not,
13691 or -1 if an error was encountered. */
13693 static int
13694 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
13695 tree lhs_var)
13697 tree expr = *expr_p;
13698 int saw_lhs;
13700 if (goa_lhs_expr_p (expr, lhs_addr))
13702 *expr_p = lhs_var;
13703 return 1;
13705 if (is_gimple_val (expr))
13706 return 0;
13708 saw_lhs = 0;
13709 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
13711 case tcc_binary:
13712 case tcc_comparison:
13713 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
13714 lhs_var);
13715 /* FALLTHRU */
13716 case tcc_unary:
13717 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
13718 lhs_var);
13719 break;
13720 case tcc_expression:
13721 switch (TREE_CODE (expr))
13723 case TRUTH_ANDIF_EXPR:
13724 case TRUTH_ORIF_EXPR:
13725 case TRUTH_AND_EXPR:
13726 case TRUTH_OR_EXPR:
13727 case TRUTH_XOR_EXPR:
13728 case BIT_INSERT_EXPR:
13729 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
13730 lhs_addr, lhs_var);
13731 /* FALLTHRU */
13732 case TRUTH_NOT_EXPR:
13733 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
13734 lhs_addr, lhs_var);
13735 break;
13736 case COMPOUND_EXPR:
13737 /* Break out any preevaluations from cp_build_modify_expr. */
13738 for (; TREE_CODE (expr) == COMPOUND_EXPR;
13739 expr = TREE_OPERAND (expr, 1))
13740 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
13741 *expr_p = expr;
13742 return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var);
13743 default:
13744 break;
13746 break;
13747 case tcc_reference:
13748 if (TREE_CODE (expr) == BIT_FIELD_REF)
13749 saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
13750 lhs_addr, lhs_var);
13751 break;
13752 default:
13753 break;
13756 if (saw_lhs == 0)
13758 enum gimplify_status gs;
13759 gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
13760 if (gs != GS_ALL_DONE)
13761 saw_lhs = -1;
13764 return saw_lhs;
13767 /* Gimplify an OMP_ATOMIC statement. */
13769 static enum gimplify_status
13770 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
13772 tree addr = TREE_OPERAND (*expr_p, 0);
13773 tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
13774 ? NULL : TREE_OPERAND (*expr_p, 1);
13775 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
13776 tree tmp_load;
13777 gomp_atomic_load *loadstmt;
13778 gomp_atomic_store *storestmt;
13780 tmp_load = create_tmp_reg (type);
13781 if (rhs && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load) < 0)
13782 return GS_ERROR;
13784 if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
13785 != GS_ALL_DONE)
13786 return GS_ERROR;
13788 loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
13789 OMP_ATOMIC_MEMORY_ORDER (*expr_p));
13790 gimplify_seq_add_stmt (pre_p, loadstmt);
13791 if (rhs)
13793 /* BIT_INSERT_EXPR is not valid for non-integral bitfield
13794 representatives. Use BIT_FIELD_REF on the lhs instead. */
13795 if (TREE_CODE (rhs) == BIT_INSERT_EXPR
13796 && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
13798 tree bitpos = TREE_OPERAND (rhs, 2);
13799 tree op1 = TREE_OPERAND (rhs, 1);
13800 tree bitsize;
13801 tree tmp_store = tmp_load;
13802 if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
13803 tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
13804 if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
13805 bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
13806 else
13807 bitsize = TYPE_SIZE (TREE_TYPE (op1));
13808 gcc_assert (TREE_OPERAND (rhs, 0) == tmp_load);
13809 tree t = build2_loc (EXPR_LOCATION (rhs),
13810 MODIFY_EXPR, void_type_node,
13811 build3_loc (EXPR_LOCATION (rhs), BIT_FIELD_REF,
13812 TREE_TYPE (op1), tmp_store, bitsize,
13813 bitpos), op1);
13814 gimplify_and_add (t, pre_p);
13815 rhs = tmp_store;
13817 if (gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
13818 != GS_ALL_DONE)
13819 return GS_ERROR;
13822 if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
13823 rhs = tmp_load;
13824 storestmt
13825 = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
13826 gimplify_seq_add_stmt (pre_p, storestmt);
13827 switch (TREE_CODE (*expr_p))
13829 case OMP_ATOMIC_READ:
13830 case OMP_ATOMIC_CAPTURE_OLD:
13831 *expr_p = tmp_load;
13832 gimple_omp_atomic_set_need_value (loadstmt);
13833 break;
13834 case OMP_ATOMIC_CAPTURE_NEW:
13835 *expr_p = rhs;
13836 gimple_omp_atomic_set_need_value (storestmt);
13837 break;
13838 default:
13839 *expr_p = NULL;
13840 break;
13843 return GS_ALL_DONE;
13846 /* Gimplify a TRANSACTION_EXPR. This involves gimplification of the
13847 body, and adding some EH bits. */
13849 static enum gimplify_status
13850 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
13852 tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
13853 gimple *body_stmt;
13854 gtransaction *trans_stmt;
13855 gimple_seq body = NULL;
13856 int subcode = 0;
13858 /* Wrap the transaction body in a BIND_EXPR so we have a context
13859 where to put decls for OMP. */
13860 if (TREE_CODE (tbody) != BIND_EXPR)
13862 tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
13863 TREE_SIDE_EFFECTS (bind) = 1;
13864 SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
13865 TRANSACTION_EXPR_BODY (expr) = bind;
13868 push_gimplify_context ();
13869 temp = voidify_wrapper_expr (*expr_p, NULL);
13871 body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
13872 pop_gimplify_context (body_stmt);
13874 trans_stmt = gimple_build_transaction (body);
13875 if (TRANSACTION_EXPR_OUTER (expr))
13876 subcode = GTMA_IS_OUTER;
13877 else if (TRANSACTION_EXPR_RELAXED (expr))
13878 subcode = GTMA_IS_RELAXED;
13879 gimple_transaction_set_subcode (trans_stmt, subcode);
13881 gimplify_seq_add_stmt (pre_p, trans_stmt);
13883 if (temp)
13885 *expr_p = temp;
13886 return GS_OK;
13889 *expr_p = NULL_TREE;
13890 return GS_ALL_DONE;
13893 /* Gimplify an OMP_ORDERED construct. EXPR is the tree version. BODY
13894 is the OMP_BODY of the original EXPR (which has already been
13895 gimplified so it's not present in the EXPR).
13897 Return the gimplified GIMPLE_OMP_ORDERED tuple. */
13899 static gimple *
13900 gimplify_omp_ordered (tree expr, gimple_seq body)
13902 tree c, decls;
13903 int failures = 0;
13904 unsigned int i;
13905 tree source_c = NULL_TREE;
13906 tree sink_c = NULL_TREE;
13908 if (gimplify_omp_ctxp)
13910 for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
13911 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
13912 && gimplify_omp_ctxp->loop_iter_var.is_empty ()
13913 && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
13914 || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
13916 error_at (OMP_CLAUSE_LOCATION (c),
13917 "%<ordered%> construct with %<depend%> clause must be "
13918 "closely nested inside a loop with %<ordered%> clause "
13919 "with a parameter");
13920 failures++;
13922 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
13923 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
13925 bool fail = false;
13926 for (decls = OMP_CLAUSE_DECL (c), i = 0;
13927 decls && TREE_CODE (decls) == TREE_LIST;
13928 decls = TREE_CHAIN (decls), ++i)
13929 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
13930 continue;
13931 else if (TREE_VALUE (decls)
13932 != gimplify_omp_ctxp->loop_iter_var[2 * i])
13934 error_at (OMP_CLAUSE_LOCATION (c),
13935 "variable %qE is not an iteration "
13936 "of outermost loop %d, expected %qE",
13937 TREE_VALUE (decls), i + 1,
13938 gimplify_omp_ctxp->loop_iter_var[2 * i]);
13939 fail = true;
13940 failures++;
13942 else
13943 TREE_VALUE (decls)
13944 = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
13945 if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
13947 error_at (OMP_CLAUSE_LOCATION (c),
13948 "number of variables in %<depend%> clause with "
13949 "%<sink%> modifier does not match number of "
13950 "iteration variables");
13951 failures++;
13953 sink_c = c;
13955 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
13956 && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
13958 if (source_c)
13960 error_at (OMP_CLAUSE_LOCATION (c),
13961 "more than one %<depend%> clause with %<source%> "
13962 "modifier on an %<ordered%> construct");
13963 failures++;
13965 else
13966 source_c = c;
13969 if (source_c && sink_c)
13971 error_at (OMP_CLAUSE_LOCATION (source_c),
13972 "%<depend%> clause with %<source%> modifier specified "
13973 "together with %<depend%> clauses with %<sink%> modifier "
13974 "on the same construct");
13975 failures++;
13978 if (failures)
13979 return gimple_build_nop ();
13980 return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
13983 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE. If the
13984 expression produces a value to be used as an operand inside a GIMPLE
13985 statement, the value will be stored back in *EXPR_P. This value will
13986 be a tree of class tcc_declaration, tcc_constant, tcc_reference or
13987 an SSA_NAME. The corresponding sequence of GIMPLE statements is
13988 emitted in PRE_P and POST_P.
13990 Additionally, this process may overwrite parts of the input
13991 expression during gimplification. Ideally, it should be
13992 possible to do non-destructive gimplification.
13994 EXPR_P points to the GENERIC expression to convert to GIMPLE. If
13995 the expression needs to evaluate to a value to be used as
13996 an operand in a GIMPLE statement, this value will be stored in
13997 *EXPR_P on exit. This happens when the caller specifies one
13998 of fb_lvalue or fb_rvalue fallback flags.
14000 PRE_P will contain the sequence of GIMPLE statements corresponding
14001 to the evaluation of EXPR and all the side-effects that must
14002 be executed before the main expression. On exit, the last
14003 statement of PRE_P is the core statement being gimplified. For
14004 instance, when gimplifying 'if (++a)' the last statement in
14005 PRE_P will be 'if (t.1)' where t.1 is the result of
14006 pre-incrementing 'a'.
14008 POST_P will contain the sequence of GIMPLE statements corresponding
14009 to the evaluation of all the side-effects that must be executed
14010 after the main expression. If this is NULL, the post
14011 side-effects are stored at the end of PRE_P.
14013 The reason why the output is split in two is to handle post
14014 side-effects explicitly. In some cases, an expression may have
14015 inner and outer post side-effects which need to be emitted in
14016 an order different from the one given by the recursive
14017 traversal. For instance, for the expression (*p--)++ the post
14018 side-effects of '--' must actually occur *after* the post
14019 side-effects of '++'. However, gimplification will first visit
14020 the inner expression, so if a separate POST sequence was not
14021 used, the resulting sequence would be:
14023 1 t.1 = *p
14024 2 p = p - 1
14025 3 t.2 = t.1 + 1
14026 4 *p = t.2
14028 However, the post-decrement operation in line #2 must not be
14029 evaluated until after the store to *p at line #4, so the
14030 correct sequence should be:
14032 1 t.1 = *p
14033 2 t.2 = t.1 + 1
14034 3 *p = t.2
14035 4 p = p - 1
14037 So, by specifying a separate post queue, it is possible
14038 to emit the post side-effects in the correct order.
14039 If POST_P is NULL, an internal queue will be used. Before
14040 returning to the caller, the sequence POST_P is appended to
14041 the main output sequence PRE_P.
14043 GIMPLE_TEST_F points to a function that takes a tree T and
14044 returns nonzero if T is in the GIMPLE form requested by the
14045 caller. The GIMPLE predicates are in gimple.c.
14047 FALLBACK tells the function what sort of a temporary we want if
14048 gimplification cannot produce an expression that complies with
14049 GIMPLE_TEST_F.
14051 fb_none means that no temporary should be generated
14052 fb_rvalue means that an rvalue is OK to generate
14053 fb_lvalue means that an lvalue is OK to generate
14054 fb_either means that either is OK, but an lvalue is preferable.
14055 fb_mayfail means that gimplification may fail (in which case
14056 GS_ERROR will be returned)
14058 The return value is either GS_ERROR or GS_ALL_DONE, since this
14059 function iterates until EXPR is completely gimplified or an error
14060 occurs. */
14062 enum gimplify_status
14063 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
14064 bool (*gimple_test_f) (tree), fallback_t fallback)
14066 tree tmp;
14067 gimple_seq internal_pre = NULL;
14068 gimple_seq internal_post = NULL;
14069 tree save_expr;
14070 bool is_statement;
14071 location_t saved_location;
14072 enum gimplify_status ret;
14073 gimple_stmt_iterator pre_last_gsi, post_last_gsi;
14074 tree label;
14076 save_expr = *expr_p;
14077 if (save_expr == NULL_TREE)
14078 return GS_ALL_DONE;
14080 /* If we are gimplifying a top-level statement, PRE_P must be valid. */
14081 is_statement = gimple_test_f == is_gimple_stmt;
14082 if (is_statement)
14083 gcc_assert (pre_p);
14085 /* Consistency checks. */
14086 if (gimple_test_f == is_gimple_reg)
14087 gcc_assert (fallback & (fb_rvalue | fb_lvalue));
14088 else if (gimple_test_f == is_gimple_val
14089 || gimple_test_f == is_gimple_call_addr
14090 || gimple_test_f == is_gimple_condexpr
14091 || gimple_test_f == is_gimple_condexpr_for_cond
14092 || gimple_test_f == is_gimple_mem_rhs
14093 || gimple_test_f == is_gimple_mem_rhs_or_call
14094 || gimple_test_f == is_gimple_reg_rhs
14095 || gimple_test_f == is_gimple_reg_rhs_or_call
14096 || gimple_test_f == is_gimple_asm_val
14097 || gimple_test_f == is_gimple_mem_ref_addr)
14098 gcc_assert (fallback & fb_rvalue);
14099 else if (gimple_test_f == is_gimple_min_lval
14100 || gimple_test_f == is_gimple_lvalue)
14101 gcc_assert (fallback & fb_lvalue);
14102 else if (gimple_test_f == is_gimple_addressable)
14103 gcc_assert (fallback & fb_either);
14104 else if (gimple_test_f == is_gimple_stmt)
14105 gcc_assert (fallback == fb_none);
14106 else
14108 /* We should have recognized the GIMPLE_TEST_F predicate to
14109 know what kind of fallback to use in case a temporary is
14110 needed to hold the value or address of *EXPR_P. */
14111 gcc_unreachable ();
14114 /* We used to check the predicate here and return immediately if it
14115 succeeds. This is wrong; the design is for gimplification to be
14116 idempotent, and for the predicates to only test for valid forms, not
14117 whether they are fully simplified. */
14118 if (pre_p == NULL)
14119 pre_p = &internal_pre;
14121 if (post_p == NULL)
14122 post_p = &internal_post;
14124 /* Remember the last statements added to PRE_P and POST_P. Every
14125 new statement added by the gimplification helpers needs to be
14126 annotated with location information. To centralize the
14127 responsibility, we remember the last statement that had been
14128 added to both queues before gimplifying *EXPR_P. If
14129 gimplification produces new statements in PRE_P and POST_P, those
14130 statements will be annotated with the same location information
14131 as *EXPR_P. */
14132 pre_last_gsi = gsi_last (*pre_p);
14133 post_last_gsi = gsi_last (*post_p);
14135 saved_location = input_location;
14136 if (save_expr != error_mark_node
14137 && EXPR_HAS_LOCATION (*expr_p))
14138 input_location = EXPR_LOCATION (*expr_p);
14140 /* Loop over the specific gimplifiers until the toplevel node
14141 remains the same. */
14144 /* Strip away as many useless type conversions as possible
14145 at the toplevel. */
14146 STRIP_USELESS_TYPE_CONVERSION (*expr_p);
14148 /* Remember the expr. */
14149 save_expr = *expr_p;
14151 /* Die, die, die, my darling. */
14152 if (error_operand_p (save_expr))
14154 ret = GS_ERROR;
14155 break;
14158 /* Do any language-specific gimplification. */
14159 ret = ((enum gimplify_status)
14160 lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
14161 if (ret == GS_OK)
14163 if (*expr_p == NULL_TREE)
14164 break;
14165 if (*expr_p != save_expr)
14166 continue;
14168 else if (ret != GS_UNHANDLED)
14169 break;
14171 /* Make sure that all the cases set 'ret' appropriately. */
14172 ret = GS_UNHANDLED;
14173 switch (TREE_CODE (*expr_p))
14175 /* First deal with the special cases. */
14177 case POSTINCREMENT_EXPR:
14178 case POSTDECREMENT_EXPR:
14179 case PREINCREMENT_EXPR:
14180 case PREDECREMENT_EXPR:
14181 ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
14182 fallback != fb_none,
14183 TREE_TYPE (*expr_p));
14184 break;
14186 case VIEW_CONVERT_EXPR:
14187 if ((fallback & fb_rvalue)
14188 && is_gimple_reg_type (TREE_TYPE (*expr_p))
14189 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
14191 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14192 post_p, is_gimple_val, fb_rvalue);
14193 recalculate_side_effects (*expr_p);
14194 break;
14196 /* Fallthru. */
14198 case ARRAY_REF:
14199 case ARRAY_RANGE_REF:
14200 case REALPART_EXPR:
14201 case IMAGPART_EXPR:
14202 case COMPONENT_REF:
14203 ret = gimplify_compound_lval (expr_p, pre_p, post_p,
14204 fallback ? fallback : fb_rvalue);
14205 break;
14207 case COND_EXPR:
14208 ret = gimplify_cond_expr (expr_p, pre_p, fallback);
14210 /* C99 code may assign to an array in a structure value of a
14211 conditional expression, and this has undefined behavior
14212 only on execution, so create a temporary if an lvalue is
14213 required. */
14214 if (fallback == fb_lvalue)
14216 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14217 mark_addressable (*expr_p);
14218 ret = GS_OK;
14220 break;
14222 case CALL_EXPR:
14223 ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
14225 /* C99 code may assign to an array in a structure returned
14226 from a function, and this has undefined behavior only on
14227 execution, so create a temporary if an lvalue is
14228 required. */
14229 if (fallback == fb_lvalue)
14231 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14232 mark_addressable (*expr_p);
14233 ret = GS_OK;
14235 break;
14237 case TREE_LIST:
14238 gcc_unreachable ();
14240 case COMPOUND_EXPR:
14241 ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
14242 break;
14244 case COMPOUND_LITERAL_EXPR:
14245 ret = gimplify_compound_literal_expr (expr_p, pre_p,
14246 gimple_test_f, fallback);
14247 break;
14249 case MODIFY_EXPR:
14250 case INIT_EXPR:
14251 ret = gimplify_modify_expr (expr_p, pre_p, post_p,
14252 fallback != fb_none);
14253 break;
14255 case TRUTH_ANDIF_EXPR:
14256 case TRUTH_ORIF_EXPR:
14258 /* Preserve the original type of the expression and the
14259 source location of the outer expression. */
14260 tree org_type = TREE_TYPE (*expr_p);
14261 *expr_p = gimple_boolify (*expr_p);
14262 *expr_p = build3_loc (input_location, COND_EXPR,
14263 org_type, *expr_p,
14264 fold_convert_loc
14265 (input_location,
14266 org_type, boolean_true_node),
14267 fold_convert_loc
14268 (input_location,
14269 org_type, boolean_false_node));
14270 ret = GS_OK;
14271 break;
14274 case TRUTH_NOT_EXPR:
14276 tree type = TREE_TYPE (*expr_p);
14277 /* The parsers are careful to generate TRUTH_NOT_EXPR
14278 only with operands that are always zero or one.
14279 We do not fold here but handle the only interesting case
14280 manually, as fold may re-introduce the TRUTH_NOT_EXPR. */
14281 *expr_p = gimple_boolify (*expr_p);
14282 if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
14283 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
14284 TREE_TYPE (*expr_p),
14285 TREE_OPERAND (*expr_p, 0));
14286 else
14287 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
14288 TREE_TYPE (*expr_p),
14289 TREE_OPERAND (*expr_p, 0),
14290 build_int_cst (TREE_TYPE (*expr_p), 1));
14291 if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
14292 *expr_p = fold_convert_loc (input_location, type, *expr_p);
14293 ret = GS_OK;
14294 break;
14297 case ADDR_EXPR:
14298 ret = gimplify_addr_expr (expr_p, pre_p, post_p);
14299 break;
14301 case ANNOTATE_EXPR:
14303 tree cond = TREE_OPERAND (*expr_p, 0);
14304 tree kind = TREE_OPERAND (*expr_p, 1);
14305 tree data = TREE_OPERAND (*expr_p, 2);
14306 tree type = TREE_TYPE (cond);
14307 if (!INTEGRAL_TYPE_P (type))
14309 *expr_p = cond;
14310 ret = GS_OK;
14311 break;
14313 tree tmp = create_tmp_var (type);
14314 gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
14315 gcall *call
14316 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
14317 gimple_call_set_lhs (call, tmp);
14318 gimplify_seq_add_stmt (pre_p, call);
14319 *expr_p = tmp;
14320 ret = GS_ALL_DONE;
14321 break;
14324 case VA_ARG_EXPR:
14325 ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
14326 break;
14328 CASE_CONVERT:
14329 if (IS_EMPTY_STMT (*expr_p))
14331 ret = GS_ALL_DONE;
14332 break;
14335 if (VOID_TYPE_P (TREE_TYPE (*expr_p))
14336 || fallback == fb_none)
14338 /* Just strip a conversion to void (or in void context) and
14339 try again. */
14340 *expr_p = TREE_OPERAND (*expr_p, 0);
14341 ret = GS_OK;
14342 break;
14345 ret = gimplify_conversion (expr_p);
14346 if (ret == GS_ERROR)
14347 break;
14348 if (*expr_p != save_expr)
14349 break;
14350 /* FALLTHRU */
14352 case FIX_TRUNC_EXPR:
14353 /* unary_expr: ... | '(' cast ')' val | ... */
14354 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14355 is_gimple_val, fb_rvalue);
14356 recalculate_side_effects (*expr_p);
14357 break;
14359 case INDIRECT_REF:
14361 bool volatilep = TREE_THIS_VOLATILE (*expr_p);
14362 bool notrap = TREE_THIS_NOTRAP (*expr_p);
14363 tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
14365 *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
14366 if (*expr_p != save_expr)
14368 ret = GS_OK;
14369 break;
14372 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14373 is_gimple_reg, fb_rvalue);
14374 if (ret == GS_ERROR)
14375 break;
14377 recalculate_side_effects (*expr_p);
14378 *expr_p = fold_build2_loc (input_location, MEM_REF,
14379 TREE_TYPE (*expr_p),
14380 TREE_OPERAND (*expr_p, 0),
14381 build_int_cst (saved_ptr_type, 0));
14382 TREE_THIS_VOLATILE (*expr_p) = volatilep;
14383 TREE_THIS_NOTRAP (*expr_p) = notrap;
14384 ret = GS_OK;
14385 break;
14388 /* We arrive here through the various re-gimplifcation paths. */
14389 case MEM_REF:
14390 /* First try re-folding the whole thing. */
14391 tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
14392 TREE_OPERAND (*expr_p, 0),
14393 TREE_OPERAND (*expr_p, 1));
14394 if (tmp)
14396 REF_REVERSE_STORAGE_ORDER (tmp)
14397 = REF_REVERSE_STORAGE_ORDER (*expr_p);
14398 *expr_p = tmp;
14399 recalculate_side_effects (*expr_p);
14400 ret = GS_OK;
14401 break;
14403 /* Avoid re-gimplifying the address operand if it is already
14404 in suitable form. Re-gimplifying would mark the address
14405 operand addressable. Always gimplify when not in SSA form
14406 as we still may have to gimplify decls with value-exprs. */
14407 if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
14408 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
14410 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
14411 is_gimple_mem_ref_addr, fb_rvalue);
14412 if (ret == GS_ERROR)
14413 break;
14415 recalculate_side_effects (*expr_p);
14416 ret = GS_ALL_DONE;
14417 break;
14419 /* Constants need not be gimplified. */
14420 case INTEGER_CST:
14421 case REAL_CST:
14422 case FIXED_CST:
14423 case STRING_CST:
14424 case COMPLEX_CST:
14425 case VECTOR_CST:
14426 /* Drop the overflow flag on constants, we do not want
14427 that in the GIMPLE IL. */
14428 if (TREE_OVERFLOW_P (*expr_p))
14429 *expr_p = drop_tree_overflow (*expr_p);
14430 ret = GS_ALL_DONE;
14431 break;
14433 case CONST_DECL:
14434 /* If we require an lvalue, such as for ADDR_EXPR, retain the
14435 CONST_DECL node. Otherwise the decl is replaceable by its
14436 value. */
14437 /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either. */
14438 if (fallback & fb_lvalue)
14439 ret = GS_ALL_DONE;
14440 else
14442 *expr_p = DECL_INITIAL (*expr_p);
14443 ret = GS_OK;
14445 break;
14447 case DECL_EXPR:
14448 ret = gimplify_decl_expr (expr_p, pre_p);
14449 break;
14451 case BIND_EXPR:
14452 ret = gimplify_bind_expr (expr_p, pre_p);
14453 break;
14455 case LOOP_EXPR:
14456 ret = gimplify_loop_expr (expr_p, pre_p);
14457 break;
14459 case SWITCH_EXPR:
14460 ret = gimplify_switch_expr (expr_p, pre_p);
14461 break;
14463 case EXIT_EXPR:
14464 ret = gimplify_exit_expr (expr_p);
14465 break;
14467 case GOTO_EXPR:
14468 /* If the target is not LABEL, then it is a computed jump
14469 and the target needs to be gimplified. */
14470 if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
14472 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
14473 NULL, is_gimple_val, fb_rvalue);
14474 if (ret == GS_ERROR)
14475 break;
14477 gimplify_seq_add_stmt (pre_p,
14478 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
14479 ret = GS_ALL_DONE;
14480 break;
14482 case PREDICT_EXPR:
14483 gimplify_seq_add_stmt (pre_p,
14484 gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
14485 PREDICT_EXPR_OUTCOME (*expr_p)));
14486 ret = GS_ALL_DONE;
14487 break;
14489 case LABEL_EXPR:
14490 ret = gimplify_label_expr (expr_p, pre_p);
14491 label = LABEL_EXPR_LABEL (*expr_p);
14492 gcc_assert (decl_function_context (label) == current_function_decl);
14494 /* If the label is used in a goto statement, or address of the label
14495 is taken, we need to unpoison all variables that were seen so far.
14496 Doing so would prevent us from reporting a false positives. */
14497 if (asan_poisoned_variables
14498 && asan_used_labels != NULL
14499 && asan_used_labels->contains (label)
14500 && !gimplify_omp_ctxp)
14501 asan_poison_variables (asan_poisoned_variables, false, pre_p);
14502 break;
14504 case CASE_LABEL_EXPR:
14505 ret = gimplify_case_label_expr (expr_p, pre_p);
14507 if (gimplify_ctxp->live_switch_vars)
14508 asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
14509 pre_p);
14510 break;
14512 case RETURN_EXPR:
14513 ret = gimplify_return_expr (*expr_p, pre_p);
14514 break;
14516 case CONSTRUCTOR:
14517 /* Don't reduce this in place; let gimplify_init_constructor work its
14518 magic. Buf if we're just elaborating this for side effects, just
14519 gimplify any element that has side-effects. */
14520 if (fallback == fb_none)
14522 unsigned HOST_WIDE_INT ix;
14523 tree val;
14524 tree temp = NULL_TREE;
14525 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
14526 if (TREE_SIDE_EFFECTS (val))
14527 append_to_statement_list (val, &temp);
14529 *expr_p = temp;
14530 ret = temp ? GS_OK : GS_ALL_DONE;
14532 /* C99 code may assign to an array in a constructed
14533 structure or union, and this has undefined behavior only
14534 on execution, so create a temporary if an lvalue is
14535 required. */
14536 else if (fallback == fb_lvalue)
14538 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
14539 mark_addressable (*expr_p);
14540 ret = GS_OK;
14542 else
14543 ret = GS_ALL_DONE;
14544 break;
14546 /* The following are special cases that are not handled by the
14547 original GIMPLE grammar. */
14549 /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
14550 eliminated. */
14551 case SAVE_EXPR:
14552 ret = gimplify_save_expr (expr_p, pre_p, post_p);
14553 break;
14555 case BIT_FIELD_REF:
14556 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14557 post_p, is_gimple_lvalue, fb_either);
14558 recalculate_side_effects (*expr_p);
14559 break;
14561 case TARGET_MEM_REF:
14563 enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
14565 if (TMR_BASE (*expr_p))
14566 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
14567 post_p, is_gimple_mem_ref_addr, fb_either);
14568 if (TMR_INDEX (*expr_p))
14569 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
14570 post_p, is_gimple_val, fb_rvalue);
14571 if (TMR_INDEX2 (*expr_p))
14572 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
14573 post_p, is_gimple_val, fb_rvalue);
14574 /* TMR_STEP and TMR_OFFSET are always integer constants. */
14575 ret = MIN (r0, r1);
14577 break;
14579 case NON_LVALUE_EXPR:
14580 /* This should have been stripped above. */
14581 gcc_unreachable ();
14583 case ASM_EXPR:
14584 ret = gimplify_asm_expr (expr_p, pre_p, post_p);
14585 break;
14587 case TRY_FINALLY_EXPR:
14588 case TRY_CATCH_EXPR:
14590 gimple_seq eval, cleanup;
14591 gtry *try_;
14593 /* Calls to destructors are generated automatically in FINALLY/CATCH
14594 block. They should have location as UNKNOWN_LOCATION. However,
14595 gimplify_call_expr will reset these call stmts to input_location
14596 if it finds stmt's location is unknown. To prevent resetting for
14597 destructors, we set the input_location to unknown.
14598 Note that this only affects the destructor calls in FINALLY/CATCH
14599 block, and will automatically reset to its original value by the
14600 end of gimplify_expr. */
14601 input_location = UNKNOWN_LOCATION;
14602 eval = cleanup = NULL;
14603 gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
14604 if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
14605 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
14607 gimple_seq n = NULL, e = NULL;
14608 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
14609 0), &n);
14610 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
14611 1), &e);
14612 if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
14614 geh_else *stmt = gimple_build_eh_else (n, e);
14615 gimple_seq_add_stmt (&cleanup, stmt);
14618 else
14619 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
14620 /* Don't create bogus GIMPLE_TRY with empty cleanup. */
14621 if (gimple_seq_empty_p (cleanup))
14623 gimple_seq_add_seq (pre_p, eval);
14624 ret = GS_ALL_DONE;
14625 break;
14627 try_ = gimple_build_try (eval, cleanup,
14628 TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
14629 ? GIMPLE_TRY_FINALLY
14630 : GIMPLE_TRY_CATCH);
14631 if (EXPR_HAS_LOCATION (save_expr))
14632 gimple_set_location (try_, EXPR_LOCATION (save_expr));
14633 else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
14634 gimple_set_location (try_, saved_location);
14635 if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
14636 gimple_try_set_catch_is_cleanup (try_,
14637 TRY_CATCH_IS_CLEANUP (*expr_p));
14638 gimplify_seq_add_stmt (pre_p, try_);
14639 ret = GS_ALL_DONE;
14640 break;
14643 case CLEANUP_POINT_EXPR:
14644 ret = gimplify_cleanup_point_expr (expr_p, pre_p);
14645 break;
14647 case TARGET_EXPR:
14648 ret = gimplify_target_expr (expr_p, pre_p, post_p);
14649 break;
14651 case CATCH_EXPR:
14653 gimple *c;
14654 gimple_seq handler = NULL;
14655 gimplify_and_add (CATCH_BODY (*expr_p), &handler);
14656 c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
14657 gimplify_seq_add_stmt (pre_p, c);
14658 ret = GS_ALL_DONE;
14659 break;
14662 case EH_FILTER_EXPR:
14664 gimple *ehf;
14665 gimple_seq failure = NULL;
14667 gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
14668 ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
14669 copy_warning (ehf, *expr_p);
14670 gimplify_seq_add_stmt (pre_p, ehf);
14671 ret = GS_ALL_DONE;
14672 break;
14675 case OBJ_TYPE_REF:
14677 enum gimplify_status r0, r1;
14678 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
14679 post_p, is_gimple_val, fb_rvalue);
14680 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
14681 post_p, is_gimple_val, fb_rvalue);
14682 TREE_SIDE_EFFECTS (*expr_p) = 0;
14683 ret = MIN (r0, r1);
14685 break;
14687 case LABEL_DECL:
14688 /* We get here when taking the address of a label. We mark
14689 the label as "forced"; meaning it can never be removed and
14690 it is a potential target for any computed goto. */
14691 FORCED_LABEL (*expr_p) = 1;
14692 ret = GS_ALL_DONE;
14693 break;
14695 case STATEMENT_LIST:
14696 ret = gimplify_statement_list (expr_p, pre_p);
14697 break;
14699 case WITH_SIZE_EXPR:
14701 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14702 post_p == &internal_post ? NULL : post_p,
14703 gimple_test_f, fallback);
14704 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
14705 is_gimple_val, fb_rvalue);
14706 ret = GS_ALL_DONE;
14708 break;
14710 case VAR_DECL:
14711 case PARM_DECL:
14712 ret = gimplify_var_or_parm_decl (expr_p);
14713 break;
14715 case RESULT_DECL:
14716 /* When within an OMP context, notice uses of variables. */
14717 if (gimplify_omp_ctxp)
14718 omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
14719 ret = GS_ALL_DONE;
14720 break;
14722 case DEBUG_EXPR_DECL:
14723 gcc_unreachable ();
14725 case DEBUG_BEGIN_STMT:
14726 gimplify_seq_add_stmt (pre_p,
14727 gimple_build_debug_begin_stmt
14728 (TREE_BLOCK (*expr_p),
14729 EXPR_LOCATION (*expr_p)));
14730 ret = GS_ALL_DONE;
14731 *expr_p = NULL;
14732 break;
14734 case SSA_NAME:
14735 /* Allow callbacks into the gimplifier during optimization. */
14736 ret = GS_ALL_DONE;
14737 break;
14739 case OMP_PARALLEL:
14740 gimplify_omp_parallel (expr_p, pre_p);
14741 ret = GS_ALL_DONE;
14742 break;
14744 case OMP_TASK:
14745 gimplify_omp_task (expr_p, pre_p);
14746 ret = GS_ALL_DONE;
14747 break;
14749 case OMP_FOR:
14750 case OMP_SIMD:
14751 case OMP_DISTRIBUTE:
14752 case OMP_TASKLOOP:
14753 case OACC_LOOP:
14754 ret = gimplify_omp_for (expr_p, pre_p);
14755 break;
14757 case OMP_LOOP:
14758 ret = gimplify_omp_loop (expr_p, pre_p);
14759 break;
14761 case OACC_CACHE:
14762 gimplify_oacc_cache (expr_p, pre_p);
14763 ret = GS_ALL_DONE;
14764 break;
14766 case OACC_DECLARE:
14767 gimplify_oacc_declare (expr_p, pre_p);
14768 ret = GS_ALL_DONE;
14769 break;
14771 case OACC_HOST_DATA:
14772 case OACC_DATA:
14773 case OACC_KERNELS:
14774 case OACC_PARALLEL:
14775 case OACC_SERIAL:
14776 case OMP_SCOPE:
14777 case OMP_SECTIONS:
14778 case OMP_SINGLE:
14779 case OMP_TARGET:
14780 case OMP_TARGET_DATA:
14781 case OMP_TEAMS:
14782 gimplify_omp_workshare (expr_p, pre_p);
14783 ret = GS_ALL_DONE;
14784 break;
14786 case OACC_ENTER_DATA:
14787 case OACC_EXIT_DATA:
14788 case OACC_UPDATE:
14789 case OMP_TARGET_UPDATE:
14790 case OMP_TARGET_ENTER_DATA:
14791 case OMP_TARGET_EXIT_DATA:
14792 gimplify_omp_target_update (expr_p, pre_p);
14793 ret = GS_ALL_DONE;
14794 break;
14796 case OMP_SECTION:
14797 case OMP_MASTER:
14798 case OMP_MASKED:
14799 case OMP_ORDERED:
14800 case OMP_CRITICAL:
14801 case OMP_SCAN:
14803 gimple_seq body = NULL;
14804 gimple *g;
14805 bool saved_in_omp_construct = in_omp_construct;
14807 in_omp_construct = true;
14808 gimplify_and_add (OMP_BODY (*expr_p), &body);
14809 in_omp_construct = saved_in_omp_construct;
14810 switch (TREE_CODE (*expr_p))
14812 case OMP_SECTION:
14813 g = gimple_build_omp_section (body);
14814 break;
14815 case OMP_MASTER:
14816 g = gimple_build_omp_master (body);
14817 break;
14818 case OMP_ORDERED:
14819 g = gimplify_omp_ordered (*expr_p, body);
14820 break;
14821 case OMP_MASKED:
14822 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p),
14823 pre_p, ORT_WORKSHARE, OMP_MASKED);
14824 gimplify_adjust_omp_clauses (pre_p, body,
14825 &OMP_MASKED_CLAUSES (*expr_p),
14826 OMP_MASKED);
14827 g = gimple_build_omp_masked (body,
14828 OMP_MASKED_CLAUSES (*expr_p));
14829 break;
14830 case OMP_CRITICAL:
14831 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
14832 pre_p, ORT_WORKSHARE, OMP_CRITICAL);
14833 gimplify_adjust_omp_clauses (pre_p, body,
14834 &OMP_CRITICAL_CLAUSES (*expr_p),
14835 OMP_CRITICAL);
14836 g = gimple_build_omp_critical (body,
14837 OMP_CRITICAL_NAME (*expr_p),
14838 OMP_CRITICAL_CLAUSES (*expr_p));
14839 break;
14840 case OMP_SCAN:
14841 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
14842 pre_p, ORT_WORKSHARE, OMP_SCAN);
14843 gimplify_adjust_omp_clauses (pre_p, body,
14844 &OMP_SCAN_CLAUSES (*expr_p),
14845 OMP_SCAN);
14846 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
14847 break;
14848 default:
14849 gcc_unreachable ();
14851 gimplify_seq_add_stmt (pre_p, g);
14852 ret = GS_ALL_DONE;
14853 break;
14856 case OMP_TASKGROUP:
14858 gimple_seq body = NULL;
14860 tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
14861 bool saved_in_omp_construct = in_omp_construct;
14862 gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
14863 OMP_TASKGROUP);
14864 gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
14866 in_omp_construct = true;
14867 gimplify_and_add (OMP_BODY (*expr_p), &body);
14868 in_omp_construct = saved_in_omp_construct;
14869 gimple_seq cleanup = NULL;
14870 tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
14871 gimple *g = gimple_build_call (fn, 0);
14872 gimple_seq_add_stmt (&cleanup, g);
14873 g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
14874 body = NULL;
14875 gimple_seq_add_stmt (&body, g);
14876 g = gimple_build_omp_taskgroup (body, *pclauses);
14877 gimplify_seq_add_stmt (pre_p, g);
14878 ret = GS_ALL_DONE;
14879 break;
14882 case OMP_ATOMIC:
14883 case OMP_ATOMIC_READ:
14884 case OMP_ATOMIC_CAPTURE_OLD:
14885 case OMP_ATOMIC_CAPTURE_NEW:
14886 ret = gimplify_omp_atomic (expr_p, pre_p);
14887 break;
14889 case TRANSACTION_EXPR:
14890 ret = gimplify_transaction (expr_p, pre_p);
14891 break;
14893 case TRUTH_AND_EXPR:
14894 case TRUTH_OR_EXPR:
14895 case TRUTH_XOR_EXPR:
14897 tree orig_type = TREE_TYPE (*expr_p);
14898 tree new_type, xop0, xop1;
14899 *expr_p = gimple_boolify (*expr_p);
14900 new_type = TREE_TYPE (*expr_p);
14901 if (!useless_type_conversion_p (orig_type, new_type))
14903 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
14904 ret = GS_OK;
14905 break;
14908 /* Boolified binary truth expressions are semantically equivalent
14909 to bitwise binary expressions. Canonicalize them to the
14910 bitwise variant. */
14911 switch (TREE_CODE (*expr_p))
14913 case TRUTH_AND_EXPR:
14914 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
14915 break;
14916 case TRUTH_OR_EXPR:
14917 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
14918 break;
14919 case TRUTH_XOR_EXPR:
14920 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
14921 break;
14922 default:
14923 break;
14925 /* Now make sure that operands have compatible type to
14926 expression's new_type. */
14927 xop0 = TREE_OPERAND (*expr_p, 0);
14928 xop1 = TREE_OPERAND (*expr_p, 1);
14929 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
14930 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
14931 new_type,
14932 xop0);
14933 if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
14934 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
14935 new_type,
14936 xop1);
14937 /* Continue classified as tcc_binary. */
14938 goto expr_2;
14941 case VEC_COND_EXPR:
14942 goto expr_3;
14944 case VEC_PERM_EXPR:
14945 /* Classified as tcc_expression. */
14946 goto expr_3;
14948 case BIT_INSERT_EXPR:
14949 /* Argument 3 is a constant. */
14950 goto expr_2;
14952 case POINTER_PLUS_EXPR:
14954 enum gimplify_status r0, r1;
14955 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
14956 post_p, is_gimple_val, fb_rvalue);
14957 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
14958 post_p, is_gimple_val, fb_rvalue);
14959 recalculate_side_effects (*expr_p);
14960 ret = MIN (r0, r1);
14961 break;
14964 default:
14965 switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
14967 case tcc_comparison:
14968 /* Handle comparison of objects of non scalar mode aggregates
14969 with a call to memcmp. It would be nice to only have to do
14970 this for variable-sized objects, but then we'd have to allow
14971 the same nest of reference nodes we allow for MODIFY_EXPR and
14972 that's too complex.
14974 Compare scalar mode aggregates as scalar mode values. Using
14975 memcmp for them would be very inefficient at best, and is
14976 plain wrong if bitfields are involved. */
14978 tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
14980 /* Vector comparisons need no boolification. */
14981 if (TREE_CODE (type) == VECTOR_TYPE)
14982 goto expr_2;
14983 else if (!AGGREGATE_TYPE_P (type))
14985 tree org_type = TREE_TYPE (*expr_p);
14986 *expr_p = gimple_boolify (*expr_p);
14987 if (!useless_type_conversion_p (org_type,
14988 TREE_TYPE (*expr_p)))
14990 *expr_p = fold_convert_loc (input_location,
14991 org_type, *expr_p);
14992 ret = GS_OK;
14994 else
14995 goto expr_2;
14997 else if (TYPE_MODE (type) != BLKmode)
14998 ret = gimplify_scalar_mode_aggregate_compare (expr_p);
14999 else
15000 ret = gimplify_variable_sized_compare (expr_p);
15002 break;
15005 /* If *EXPR_P does not need to be special-cased, handle it
15006 according to its class. */
15007 case tcc_unary:
15008 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15009 post_p, is_gimple_val, fb_rvalue);
15010 break;
15012 case tcc_binary:
15013 expr_2:
15015 enum gimplify_status r0, r1;
15017 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15018 post_p, is_gimple_val, fb_rvalue);
15019 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15020 post_p, is_gimple_val, fb_rvalue);
15022 ret = MIN (r0, r1);
15023 break;
15026 expr_3:
15028 enum gimplify_status r0, r1, r2;
15030 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15031 post_p, is_gimple_val, fb_rvalue);
15032 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15033 post_p, is_gimple_val, fb_rvalue);
15034 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
15035 post_p, is_gimple_val, fb_rvalue);
15037 ret = MIN (MIN (r0, r1), r2);
15038 break;
15041 case tcc_declaration:
15042 case tcc_constant:
15043 ret = GS_ALL_DONE;
15044 goto dont_recalculate;
15046 default:
15047 gcc_unreachable ();
15050 recalculate_side_effects (*expr_p);
15052 dont_recalculate:
15053 break;
15056 gcc_assert (*expr_p || ret != GS_OK);
15058 while (ret == GS_OK);
15060 /* If we encountered an error_mark somewhere nested inside, either
15061 stub out the statement or propagate the error back out. */
15062 if (ret == GS_ERROR)
15064 if (is_statement)
15065 *expr_p = NULL;
15066 goto out;
15069 /* This was only valid as a return value from the langhook, which
15070 we handled. Make sure it doesn't escape from any other context. */
15071 gcc_assert (ret != GS_UNHANDLED);
15073 if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
15075 /* We aren't looking for a value, and we don't have a valid
15076 statement. If it doesn't have side-effects, throw it away.
15077 We can also get here with code such as "*&&L;", where L is
15078 a LABEL_DECL that is marked as FORCED_LABEL. */
15079 if (TREE_CODE (*expr_p) == LABEL_DECL
15080 || !TREE_SIDE_EFFECTS (*expr_p))
15081 *expr_p = NULL;
15082 else if (!TREE_THIS_VOLATILE (*expr_p))
15084 /* This is probably a _REF that contains something nested that
15085 has side effects. Recurse through the operands to find it. */
15086 enum tree_code code = TREE_CODE (*expr_p);
15088 switch (code)
15090 case COMPONENT_REF:
15091 case REALPART_EXPR:
15092 case IMAGPART_EXPR:
15093 case VIEW_CONVERT_EXPR:
15094 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15095 gimple_test_f, fallback);
15096 break;
15098 case ARRAY_REF:
15099 case ARRAY_RANGE_REF:
15100 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15101 gimple_test_f, fallback);
15102 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15103 gimple_test_f, fallback);
15104 break;
15106 default:
15107 /* Anything else with side-effects must be converted to
15108 a valid statement before we get here. */
15109 gcc_unreachable ();
15112 *expr_p = NULL;
15114 else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
15115 && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode
15116 && !is_empty_type (TREE_TYPE (*expr_p)))
15118 /* Historically, the compiler has treated a bare reference
15119 to a non-BLKmode volatile lvalue as forcing a load. */
15120 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
15122 /* Normally, we do not want to create a temporary for a
15123 TREE_ADDRESSABLE type because such a type should not be
15124 copied by bitwise-assignment. However, we make an
15125 exception here, as all we are doing here is ensuring that
15126 we read the bytes that make up the type. We use
15127 create_tmp_var_raw because create_tmp_var will abort when
15128 given a TREE_ADDRESSABLE type. */
15129 tree tmp = create_tmp_var_raw (type, "vol");
15130 gimple_add_tmp_var (tmp);
15131 gimplify_assign (tmp, *expr_p, pre_p);
15132 *expr_p = NULL;
15134 else
15135 /* We can't do anything useful with a volatile reference to
15136 an incomplete type, so just throw it away. Likewise for
15137 a BLKmode type, since any implicit inner load should
15138 already have been turned into an explicit one by the
15139 gimplification process. */
15140 *expr_p = NULL;
15143 /* If we are gimplifying at the statement level, we're done. Tack
15144 everything together and return. */
15145 if (fallback == fb_none || is_statement)
15147 /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
15148 it out for GC to reclaim it. */
15149 *expr_p = NULL_TREE;
15151 if (!gimple_seq_empty_p (internal_pre)
15152 || !gimple_seq_empty_p (internal_post))
15154 gimplify_seq_add_seq (&internal_pre, internal_post);
15155 gimplify_seq_add_seq (pre_p, internal_pre);
15158 /* The result of gimplifying *EXPR_P is going to be the last few
15159 statements in *PRE_P and *POST_P. Add location information
15160 to all the statements that were added by the gimplification
15161 helpers. */
15162 if (!gimple_seq_empty_p (*pre_p))
15163 annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
15165 if (!gimple_seq_empty_p (*post_p))
15166 annotate_all_with_location_after (*post_p, post_last_gsi,
15167 input_location);
15169 goto out;
15172 #ifdef ENABLE_GIMPLE_CHECKING
15173 if (*expr_p)
15175 enum tree_code code = TREE_CODE (*expr_p);
15176 /* These expressions should already be in gimple IR form. */
15177 gcc_assert (code != MODIFY_EXPR
15178 && code != ASM_EXPR
15179 && code != BIND_EXPR
15180 && code != CATCH_EXPR
15181 && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
15182 && code != EH_FILTER_EXPR
15183 && code != GOTO_EXPR
15184 && code != LABEL_EXPR
15185 && code != LOOP_EXPR
15186 && code != SWITCH_EXPR
15187 && code != TRY_FINALLY_EXPR
15188 && code != EH_ELSE_EXPR
15189 && code != OACC_PARALLEL
15190 && code != OACC_KERNELS
15191 && code != OACC_SERIAL
15192 && code != OACC_DATA
15193 && code != OACC_HOST_DATA
15194 && code != OACC_DECLARE
15195 && code != OACC_UPDATE
15196 && code != OACC_ENTER_DATA
15197 && code != OACC_EXIT_DATA
15198 && code != OACC_CACHE
15199 && code != OMP_CRITICAL
15200 && code != OMP_FOR
15201 && code != OACC_LOOP
15202 && code != OMP_MASTER
15203 && code != OMP_MASKED
15204 && code != OMP_TASKGROUP
15205 && code != OMP_ORDERED
15206 && code != OMP_PARALLEL
15207 && code != OMP_SCAN
15208 && code != OMP_SECTIONS
15209 && code != OMP_SECTION
15210 && code != OMP_SINGLE
15211 && code != OMP_SCOPE);
15213 #endif
15215 /* Otherwise we're gimplifying a subexpression, so the resulting
15216 value is interesting. If it's a valid operand that matches
15217 GIMPLE_TEST_F, we're done. Unless we are handling some
15218 post-effects internally; if that's the case, we need to copy into
15219 a temporary before adding the post-effects to POST_P. */
15220 if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
15221 goto out;
15223 /* Otherwise, we need to create a new temporary for the gimplified
15224 expression. */
15226 /* We can't return an lvalue if we have an internal postqueue. The
15227 object the lvalue refers to would (probably) be modified by the
15228 postqueue; we need to copy the value out first, which means an
15229 rvalue. */
15230 if ((fallback & fb_lvalue)
15231 && gimple_seq_empty_p (internal_post)
15232 && is_gimple_addressable (*expr_p))
15234 /* An lvalue will do. Take the address of the expression, store it
15235 in a temporary, and replace the expression with an INDIRECT_REF of
15236 that temporary. */
15237 tree ref_alias_type = reference_alias_ptr_type (*expr_p);
15238 unsigned int ref_align = get_object_alignment (*expr_p);
15239 tree ref_type = TREE_TYPE (*expr_p);
15240 tmp = build_fold_addr_expr_loc (input_location, *expr_p);
15241 gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
15242 if (TYPE_ALIGN (ref_type) != ref_align)
15243 ref_type = build_aligned_type (ref_type, ref_align);
15244 *expr_p = build2 (MEM_REF, ref_type,
15245 tmp, build_zero_cst (ref_alias_type));
15247 else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
15249 /* An rvalue will do. Assign the gimplified expression into a
15250 new temporary TMP and replace the original expression with
15251 TMP. First, make sure that the expression has a type so that
15252 it can be assigned into a temporary. */
15253 gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
15254 *expr_p = get_formal_tmp_var (*expr_p, pre_p);
15256 else
15258 #ifdef ENABLE_GIMPLE_CHECKING
15259 if (!(fallback & fb_mayfail))
15261 fprintf (stderr, "gimplification failed:\n");
15262 print_generic_expr (stderr, *expr_p);
15263 debug_tree (*expr_p);
15264 internal_error ("gimplification failed");
15266 #endif
15267 gcc_assert (fallback & fb_mayfail);
15269 /* If this is an asm statement, and the user asked for the
15270 impossible, don't die. Fail and let gimplify_asm_expr
15271 issue an error. */
15272 ret = GS_ERROR;
15273 goto out;
15276 /* Make sure the temporary matches our predicate. */
15277 gcc_assert ((*gimple_test_f) (*expr_p));
15279 if (!gimple_seq_empty_p (internal_post))
15281 annotate_all_with_location (internal_post, input_location);
15282 gimplify_seq_add_seq (pre_p, internal_post);
15285 out:
15286 input_location = saved_location;
15287 return ret;
15290 /* Like gimplify_expr but make sure the gimplified result is not itself
15291 a SSA name (but a decl if it were). Temporaries required by
15292 evaluating *EXPR_P may be still SSA names. */
15294 static enum gimplify_status
15295 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
15296 bool (*gimple_test_f) (tree), fallback_t fallback,
15297 bool allow_ssa)
15299 enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
15300 gimple_test_f, fallback);
15301 if (! allow_ssa
15302 && TREE_CODE (*expr_p) == SSA_NAME)
15303 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
15304 return ret;
15307 /* Look through TYPE for variable-sized objects and gimplify each such
15308 size that we find. Add to LIST_P any statements generated. */
15310 void
15311 gimplify_type_sizes (tree type, gimple_seq *list_p)
15313 if (type == NULL || type == error_mark_node)
15314 return;
15316 const bool ignored_p
15317 = TYPE_NAME (type)
15318 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
15319 && DECL_IGNORED_P (TYPE_NAME (type));
15320 tree t;
15322 /* We first do the main variant, then copy into any other variants. */
15323 type = TYPE_MAIN_VARIANT (type);
15325 /* Avoid infinite recursion. */
15326 if (TYPE_SIZES_GIMPLIFIED (type))
15327 return;
15329 TYPE_SIZES_GIMPLIFIED (type) = 1;
15331 switch (TREE_CODE (type))
15333 case INTEGER_TYPE:
15334 case ENUMERAL_TYPE:
15335 case BOOLEAN_TYPE:
15336 case REAL_TYPE:
15337 case FIXED_POINT_TYPE:
15338 gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
15339 gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
15341 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
15343 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
15344 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
15346 break;
15348 case ARRAY_TYPE:
15349 /* These types may not have declarations, so handle them here. */
15350 gimplify_type_sizes (TREE_TYPE (type), list_p);
15351 gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
15352 /* Ensure VLA bounds aren't removed, for -O0 they should be variables
15353 with assigned stack slots, for -O1+ -g they should be tracked
15354 by VTA. */
15355 if (!ignored_p
15356 && TYPE_DOMAIN (type)
15357 && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
15359 t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
15360 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
15361 DECL_IGNORED_P (t) = 0;
15362 t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
15363 if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
15364 DECL_IGNORED_P (t) = 0;
15366 break;
15368 case RECORD_TYPE:
15369 case UNION_TYPE:
15370 case QUAL_UNION_TYPE:
15371 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
15372 if (TREE_CODE (field) == FIELD_DECL)
15374 gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
15375 /* Likewise, ensure variable offsets aren't removed. */
15376 if (!ignored_p
15377 && (t = DECL_FIELD_OFFSET (field))
15378 && VAR_P (t)
15379 && DECL_ARTIFICIAL (t))
15380 DECL_IGNORED_P (t) = 0;
15381 gimplify_one_sizepos (&DECL_SIZE (field), list_p);
15382 gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
15383 gimplify_type_sizes (TREE_TYPE (field), list_p);
15385 break;
15387 case POINTER_TYPE:
15388 case REFERENCE_TYPE:
15389 /* We used to recurse on the pointed-to type here, which turned out to
15390 be incorrect because its definition might refer to variables not
15391 yet initialized at this point if a forward declaration is involved.
15393 It was actually useful for anonymous pointed-to types to ensure
15394 that the sizes evaluation dominates every possible later use of the
15395 values. Restricting to such types here would be safe since there
15396 is no possible forward declaration around, but would introduce an
15397 undesirable middle-end semantic to anonymity. We then defer to
15398 front-ends the responsibility of ensuring that the sizes are
15399 evaluated both early and late enough, e.g. by attaching artificial
15400 type declarations to the tree. */
15401 break;
15403 default:
15404 break;
15407 gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
15408 gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
15410 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
15412 TYPE_SIZE (t) = TYPE_SIZE (type);
15413 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
15414 TYPE_SIZES_GIMPLIFIED (t) = 1;
15418 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
15419 a size or position, has had all of its SAVE_EXPRs evaluated.
15420 We add any required statements to *STMT_P. */
15422 void
15423 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
15425 tree expr = *expr_p;
15427 /* We don't do anything if the value isn't there, is constant, or contains
15428 A PLACEHOLDER_EXPR. We also don't want to do anything if it's already
15429 a VAR_DECL. If it's a VAR_DECL from another function, the gimplifier
15430 will want to replace it with a new variable, but that will cause problems
15431 if this type is from outside the function. It's OK to have that here. */
15432 if (expr == NULL_TREE
15433 || is_gimple_constant (expr)
15434 || TREE_CODE (expr) == VAR_DECL
15435 || CONTAINS_PLACEHOLDER_P (expr))
15436 return;
15438 *expr_p = unshare_expr (expr);
15440 /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
15441 if the def vanishes. */
15442 gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
15444 /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
15445 FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
15446 as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs. */
15447 if (is_gimple_constant (*expr_p))
15448 *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
15451 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
15452 containing the sequence of corresponding GIMPLE statements. If DO_PARMS
15453 is true, also gimplify the parameters. */
15455 gbind *
15456 gimplify_body (tree fndecl, bool do_parms)
15458 location_t saved_location = input_location;
15459 gimple_seq parm_stmts, parm_cleanup = NULL, seq;
15460 gimple *outer_stmt;
15461 gbind *outer_bind;
15463 timevar_push (TV_TREE_GIMPLIFY);
15465 init_tree_ssa (cfun);
15467 /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
15468 gimplification. */
15469 default_rtl_profile ();
15471 gcc_assert (gimplify_ctxp == NULL);
15472 push_gimplify_context (true);
15474 if (flag_openacc || flag_openmp)
15476 gcc_assert (gimplify_omp_ctxp == NULL);
15477 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
15478 gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
15481 /* Unshare most shared trees in the body and in that of any nested functions.
15482 It would seem we don't have to do this for nested functions because
15483 they are supposed to be output and then the outer function gimplified
15484 first, but the g++ front end doesn't always do it that way. */
15485 unshare_body (fndecl);
15486 unvisit_body (fndecl);
15488 /* Make sure input_location isn't set to something weird. */
15489 input_location = DECL_SOURCE_LOCATION (fndecl);
15491 /* Resolve callee-copies. This has to be done before processing
15492 the body so that DECL_VALUE_EXPR gets processed correctly. */
15493 parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
15495 /* Gimplify the function's body. */
15496 seq = NULL;
15497 gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
15498 outer_stmt = gimple_seq_first_nondebug_stmt (seq);
15499 if (!outer_stmt)
15501 outer_stmt = gimple_build_nop ();
15502 gimplify_seq_add_stmt (&seq, outer_stmt);
15505 /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
15506 not the case, wrap everything in a GIMPLE_BIND to make it so. */
15507 if (gimple_code (outer_stmt) == GIMPLE_BIND
15508 && (gimple_seq_first_nondebug_stmt (seq)
15509 == gimple_seq_last_nondebug_stmt (seq)))
15511 outer_bind = as_a <gbind *> (outer_stmt);
15512 if (gimple_seq_first_stmt (seq) != outer_stmt
15513 || gimple_seq_last_stmt (seq) != outer_stmt)
15515 /* If there are debug stmts before or after outer_stmt, move them
15516 inside of outer_bind body. */
15517 gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
15518 gimple_seq second_seq = NULL;
15519 if (gimple_seq_first_stmt (seq) != outer_stmt
15520 && gimple_seq_last_stmt (seq) != outer_stmt)
15522 second_seq = gsi_split_seq_after (gsi);
15523 gsi_remove (&gsi, false);
15525 else if (gimple_seq_first_stmt (seq) != outer_stmt)
15526 gsi_remove (&gsi, false);
15527 else
15529 gsi_remove (&gsi, false);
15530 second_seq = seq;
15531 seq = NULL;
15533 gimple_seq_add_seq_without_update (&seq,
15534 gimple_bind_body (outer_bind));
15535 gimple_seq_add_seq_without_update (&seq, second_seq);
15536 gimple_bind_set_body (outer_bind, seq);
15539 else
15540 outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
15542 DECL_SAVED_TREE (fndecl) = NULL_TREE;
15544 /* If we had callee-copies statements, insert them at the beginning
15545 of the function and clear DECL_VALUE_EXPR_P on the parameters. */
15546 if (!gimple_seq_empty_p (parm_stmts))
15548 tree parm;
15550 gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
15551 if (parm_cleanup)
15553 gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
15554 GIMPLE_TRY_FINALLY);
15555 parm_stmts = NULL;
15556 gimple_seq_add_stmt (&parm_stmts, g);
15558 gimple_bind_set_body (outer_bind, parm_stmts);
15560 for (parm = DECL_ARGUMENTS (current_function_decl);
15561 parm; parm = DECL_CHAIN (parm))
15562 if (DECL_HAS_VALUE_EXPR_P (parm))
15564 DECL_HAS_VALUE_EXPR_P (parm) = 0;
15565 DECL_IGNORED_P (parm) = 0;
15569 if ((flag_openacc || flag_openmp || flag_openmp_simd)
15570 && gimplify_omp_ctxp)
15572 delete_omp_context (gimplify_omp_ctxp);
15573 gimplify_omp_ctxp = NULL;
15576 pop_gimplify_context (outer_bind);
15577 gcc_assert (gimplify_ctxp == NULL);
15579 if (flag_checking && !seen_error ())
15580 verify_gimple_in_seq (gimple_bind_body (outer_bind));
15582 timevar_pop (TV_TREE_GIMPLIFY);
15583 input_location = saved_location;
15585 return outer_bind;
15588 typedef char *char_p; /* For DEF_VEC_P. */
15590 /* Return whether we should exclude FNDECL from instrumentation. */
15592 static bool
15593 flag_instrument_functions_exclude_p (tree fndecl)
15595 vec<char_p> *v;
15597 v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
15598 if (v && v->length () > 0)
15600 const char *name;
15601 int i;
15602 char *s;
15604 name = lang_hooks.decl_printable_name (fndecl, 1);
15605 FOR_EACH_VEC_ELT (*v, i, s)
15606 if (strstr (name, s) != NULL)
15607 return true;
15610 v = (vec<char_p> *) flag_instrument_functions_exclude_files;
15611 if (v && v->length () > 0)
15613 const char *name;
15614 int i;
15615 char *s;
15617 name = DECL_SOURCE_FILE (fndecl);
15618 FOR_EACH_VEC_ELT (*v, i, s)
15619 if (strstr (name, s) != NULL)
15620 return true;
15623 return false;
15626 /* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
15627 node for the function we want to gimplify.
15629 Return the sequence of GIMPLE statements corresponding to the body
15630 of FNDECL. */
15632 void
15633 gimplify_function_tree (tree fndecl)
15635 gimple_seq seq;
15636 gbind *bind;
15638 gcc_assert (!gimple_body (fndecl));
15640 if (DECL_STRUCT_FUNCTION (fndecl))
15641 push_cfun (DECL_STRUCT_FUNCTION (fndecl));
15642 else
15643 push_struct_function (fndecl);
15645 /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
15646 if necessary. */
15647 cfun->curr_properties |= PROP_gimple_lva;
15649 if (asan_sanitize_use_after_scope ())
15650 asan_poisoned_variables = new hash_set<tree> ();
15651 bind = gimplify_body (fndecl, true);
15652 if (asan_poisoned_variables)
15654 delete asan_poisoned_variables;
15655 asan_poisoned_variables = NULL;
15658 /* The tree body of the function is no longer needed, replace it
15659 with the new GIMPLE body. */
15660 seq = NULL;
15661 gimple_seq_add_stmt (&seq, bind);
15662 gimple_set_body (fndecl, seq);
15664 /* If we're instrumenting function entry/exit, then prepend the call to
15665 the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
15666 catch the exit hook. */
15667 /* ??? Add some way to ignore exceptions for this TFE. */
15668 if (flag_instrument_function_entry_exit
15669 && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
15670 /* Do not instrument extern inline functions. */
15671 && !(DECL_DECLARED_INLINE_P (fndecl)
15672 && DECL_EXTERNAL (fndecl)
15673 && DECL_DISREGARD_INLINE_LIMITS (fndecl))
15674 && !flag_instrument_functions_exclude_p (fndecl))
15676 tree x;
15677 gbind *new_bind;
15678 gimple *tf;
15679 gimple_seq cleanup = NULL, body = NULL;
15680 tree tmp_var, this_fn_addr;
15681 gcall *call;
15683 /* The instrumentation hooks aren't going to call the instrumented
15684 function and the address they receive is expected to be matchable
15685 against symbol addresses. Make sure we don't create a trampoline,
15686 in case the current function is nested. */
15687 this_fn_addr = build_fold_addr_expr (current_function_decl);
15688 TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
15690 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
15691 call = gimple_build_call (x, 1, integer_zero_node);
15692 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
15693 gimple_call_set_lhs (call, tmp_var);
15694 gimplify_seq_add_stmt (&cleanup, call);
15695 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
15696 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
15697 gimplify_seq_add_stmt (&cleanup, call);
15698 tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
15700 x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
15701 call = gimple_build_call (x, 1, integer_zero_node);
15702 tmp_var = create_tmp_var (ptr_type_node, "return_addr");
15703 gimple_call_set_lhs (call, tmp_var);
15704 gimplify_seq_add_stmt (&body, call);
15705 x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
15706 call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
15707 gimplify_seq_add_stmt (&body, call);
15708 gimplify_seq_add_stmt (&body, tf);
15709 new_bind = gimple_build_bind (NULL, body, NULL);
15711 /* Replace the current function body with the body
15712 wrapped in the try/finally TF. */
15713 seq = NULL;
15714 gimple_seq_add_stmt (&seq, new_bind);
15715 gimple_set_body (fndecl, seq);
15716 bind = new_bind;
15719 if (sanitize_flags_p (SANITIZE_THREAD)
15720 && param_tsan_instrument_func_entry_exit)
15722 gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
15723 gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
15724 gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
15725 /* Replace the current function body with the body
15726 wrapped in the try/finally TF. */
15727 seq = NULL;
15728 gimple_seq_add_stmt (&seq, new_bind);
15729 gimple_set_body (fndecl, seq);
15732 DECL_SAVED_TREE (fndecl) = NULL_TREE;
15733 cfun->curr_properties |= PROP_gimple_any;
15735 pop_cfun ();
15737 dump_function (TDI_gimple, fndecl);
15740 /* Return a dummy expression of type TYPE in order to keep going after an
15741 error. */
15743 static tree
15744 dummy_object (tree type)
15746 tree t = build_int_cst (build_pointer_type (type), 0);
15747 return build2 (MEM_REF, type, t, t);
15750 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
15751 builtin function, but a very special sort of operator. */
15753 enum gimplify_status
15754 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
15755 gimple_seq *post_p ATTRIBUTE_UNUSED)
15757 tree promoted_type, have_va_type;
15758 tree valist = TREE_OPERAND (*expr_p, 0);
15759 tree type = TREE_TYPE (*expr_p);
15760 tree t, tag, aptag;
15761 location_t loc = EXPR_LOCATION (*expr_p);
15763 /* Verify that valist is of the proper type. */
15764 have_va_type = TREE_TYPE (valist);
15765 if (have_va_type == error_mark_node)
15766 return GS_ERROR;
15767 have_va_type = targetm.canonical_va_list_type (have_va_type);
15768 if (have_va_type == NULL_TREE
15769 && POINTER_TYPE_P (TREE_TYPE (valist)))
15770 /* Handle 'Case 1: Not an array type' from c-common.c/build_va_arg. */
15771 have_va_type
15772 = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
15773 gcc_assert (have_va_type != NULL_TREE);
15775 /* Generate a diagnostic for requesting data of a type that cannot
15776 be passed through `...' due to type promotion at the call site. */
15777 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
15778 != type)
15780 static bool gave_help;
15781 bool warned;
15782 /* Use the expansion point to handle cases such as passing bool (defined
15783 in a system header) through `...'. */
15784 location_t xloc
15785 = expansion_point_location_if_in_system_header (loc);
15787 /* Unfortunately, this is merely undefined, rather than a constraint
15788 violation, so we cannot make this an error. If this call is never
15789 executed, the program is still strictly conforming. */
15790 auto_diagnostic_group d;
15791 warned = warning_at (xloc, 0,
15792 "%qT is promoted to %qT when passed through %<...%>",
15793 type, promoted_type);
15794 if (!gave_help && warned)
15796 gave_help = true;
15797 inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
15798 promoted_type, type);
15801 /* We can, however, treat "undefined" any way we please.
15802 Call abort to encourage the user to fix the program. */
15803 if (warned)
15804 inform (xloc, "if this code is reached, the program will abort");
15805 /* Before the abort, allow the evaluation of the va_list
15806 expression to exit or longjmp. */
15807 gimplify_and_add (valist, pre_p);
15808 t = build_call_expr_loc (loc,
15809 builtin_decl_implicit (BUILT_IN_TRAP), 0);
15810 gimplify_and_add (t, pre_p);
15812 /* This is dead code, but go ahead and finish so that the
15813 mode of the result comes out right. */
15814 *expr_p = dummy_object (type);
15815 return GS_ALL_DONE;
15818 tag = build_int_cst (build_pointer_type (type), 0);
15819 aptag = build_int_cst (TREE_TYPE (valist), 0);
15821 *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
15822 valist, tag, aptag);
15824 /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
15825 needs to be expanded. */
15826 cfun->curr_properties &= ~PROP_gimple_lva;
15828 return GS_OK;
15831 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
15833 DST/SRC are the destination and source respectively. You can pass
15834 ungimplified trees in DST or SRC, in which case they will be
15835 converted to a gimple operand if necessary.
15837 This function returns the newly created GIMPLE_ASSIGN tuple. */
15839 gimple *
15840 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
15842 tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
15843 gimplify_and_add (t, seq_p);
15844 ggc_free (t);
15845 return gimple_seq_last_stmt (*seq_p);
15848 inline hashval_t
15849 gimplify_hasher::hash (const elt_t *p)
15851 tree t = p->val;
15852 return iterative_hash_expr (t, 0);
15855 inline bool
15856 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
15858 tree t1 = p1->val;
15859 tree t2 = p2->val;
15860 enum tree_code code = TREE_CODE (t1);
15862 if (TREE_CODE (t2) != code
15863 || TREE_TYPE (t1) != TREE_TYPE (t2))
15864 return false;
15866 if (!operand_equal_p (t1, t2, 0))
15867 return false;
15869 /* Only allow them to compare equal if they also hash equal; otherwise
15870 results are nondeterminate, and we fail bootstrap comparison. */
15871 gcc_checking_assert (hash (p1) == hash (p2));
15873 return true;